Skip to content

Commit 22577df

Browse files
author
jossonsmith
committed
Refactor SimpleRPCHttpServlet into a container servlet so that developers
have no more need to extend servlet for every SimpleRPCRunnable.
1 parent 98c6b57 commit 22577df

File tree

5 files changed

+307
-8
lines changed

5 files changed

+307
-8
lines changed

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCHttpServlet.java

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
import java.io.IOException;
1818
import java.io.InputStream;
1919
import java.io.PrintWriter;
20+
import java.lang.reflect.Constructor;
21+
import java.lang.reflect.InvocationTargetException;
22+
import java.util.HashSet;
23+
import java.util.Iterator;
24+
import java.util.Set;
2025
import javax.servlet.ServletException;
2126
import javax.servlet.http.HttpServlet;
2227
import javax.servlet.http.HttpServletRequest;
@@ -29,14 +34,77 @@
2934
*
3035
* 2006-10-10
3136
*/
32-
public abstract class SimpleRPCHttpServlet extends HttpServlet {
37+
public class SimpleRPCHttpServlet extends HttpServlet {
3338

3439
private static final long serialVersionUID = -3852449040495978018L;
3540

36-
protected SimpleRPCRunnable runnable;
41+
protected Set runnables = new HashSet();
3742

38-
public abstract void initSimpleRPC(HttpServletRequest req, HttpServletResponse resp);
43+
protected Set mappings = new HashSet();
44+
45+
protected SimpleRPCRunnable getRunnableByURL(String url) {
46+
int lastIndexOf = url.lastIndexOf('/');
47+
String shortURL = null;
48+
if (lastIndexOf == url.length() - 1) {
49+
lastIndexOf = url.lastIndexOf('/', lastIndexOf - 1);
50+
if (lastIndexOf == -1) {
51+
return null; // should never happen!
52+
}
53+
shortURL = url.substring(lastIndexOf + 1, url.length() - 1);
54+
} else {
55+
shortURL = url.substring(lastIndexOf + 1);
56+
}
57+
if (runnables.contains(shortURL)) {
58+
if (url != null) {
59+
Object obj = getNewInstanceByClassName(shortURL);
60+
if (obj != null && obj instanceof SimpleRPCRunnable) {
61+
return (SimpleRPCRunnable) obj;
62+
}
63+
}
64+
}
65+
for (Iterator iter = mappings.iterator(); iter.hasNext();) {
66+
String mappingStr = (String) iter.next();
67+
if (mappingStr != null) {
68+
Object obj = getNewInstanceByClassName(mappingStr);
69+
if (obj != null && obj instanceof SimpleRPCMapping) {
70+
SimpleRPCMapping mapping = (SimpleRPCMapping) obj;
71+
String mappedRunnable = mapping.getRunnableClassName(shortURL);
72+
if (mappedRunnable != null) {
73+
obj = getNewInstanceByClassName(mappedRunnable);
74+
if (obj != null && obj instanceof SimpleRPCRunnable) {
75+
return (SimpleRPCRunnable) obj;
76+
}
77+
}
78+
}
79+
}
80+
}
81+
return null;
82+
}
3983

84+
public Object getNewInstanceByClassName(String className) {
85+
try {
86+
Class runnableClass = Class.forName(className);
87+
if (runnableClass != null) {
88+
Constructor constructor = runnableClass.getConstructor(new Class[0]);
89+
return constructor.newInstance(new Object[0]);
90+
}
91+
} catch (SecurityException e) {
92+
e.printStackTrace();
93+
} catch (IllegalArgumentException e) {
94+
e.printStackTrace();
95+
} catch (ClassNotFoundException e) {
96+
e.printStackTrace();
97+
} catch (NoSuchMethodException e) {
98+
e.printStackTrace();
99+
} catch (InstantiationException e) {
100+
e.printStackTrace();
101+
} catch (IllegalAccessException e) {
102+
e.printStackTrace();
103+
} catch (InvocationTargetException e) {
104+
e.printStackTrace();
105+
}
106+
return null;
107+
}
40108
public static String readAll(InputStream res) {
41109
try {
42110
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -53,9 +121,37 @@ public static String readAll(InputStream res) {
53121
return null;
54122
}
55123

124+
/* (non-Javadoc)
125+
* @see javax.servlet.GenericServlet#init()
126+
*/
127+
public void init() throws ServletException {
128+
String runnableStr = getInitParameter("simple.rpc.runnables");
129+
if (runnableStr != null) {
130+
String[] splits = runnableStr.trim().split("\\s*[,;:]\\s*");
131+
for (int i = 0; i < splits.length; i++) {
132+
String trim = splits[i].trim();
133+
if (trim.length() != 0) {
134+
runnables.add(trim);
135+
}
136+
}
137+
}
138+
String mappingStr = getInitParameter("simple.rpc.mappings");
139+
if (mappingStr != null) {
140+
String[] splits = mappingStr.trim().split("\\s*[,;:]\\s*");
141+
for (int i = 0; i < splits.length; i++) {
142+
String trim = splits[i].trim();
143+
if (trim.length() != 0) {
144+
mappings.add(trim);
145+
}
146+
}
147+
}
148+
}
149+
56150
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
151+
SimpleRPCRunnable runnable = getRunnableByURL(req.getPathInfo());
57152
if (runnable == null) {
58-
initSimpleRPC(req, resp);
153+
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
154+
return;
59155
}
60156
PrintWriter writer = resp.getWriter();
61157
resp.setContentType("text/plain");
@@ -67,8 +163,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
67163
}
68164

69165
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
166+
SimpleRPCRunnable runnable = getRunnableByURL(req.getPathInfo());
70167
if (runnable == null) {
71-
initSimpleRPC(req, resp);
168+
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
169+
return;
72170
}
73171
PrintWriter writer = resp.getWriter();
74172
resp.setContentType("text/plain");
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*******************************************************************************
2+
* Java2Script Pacemaker (http://j2s.sourceforge.net)
3+
*
4+
* Copyright (c) 2006 ognize.com and others.
5+
* All rights reserved. This program and the accompanying materials
6+
* are made available under the terms of the Eclipse Public License v1.0
7+
* which accompanies this distribution, and is available at
8+
* http://www.eclipse.org/legal/epl-v10.html
9+
*
10+
* Contributors:
11+
* ognize.com - initial API and implementation
12+
*******************************************************************************/
13+
14+
package net.sf.j2s.ajax;
15+
16+
/**
17+
* This class gives developers an optional way to map those long Simple RPC URL into short URL.
18+
* This class may help to publish Simple RPC services. It is OK to not use this class.
19+
*
20+
* @author zhou renjian
21+
*
22+
* 2006-12-19
23+
*/
24+
public class SimpleRPCMapping {
25+
private String[][] map = new String[8][];
26+
27+
/**
28+
* Return the SimpleRPCRunnable service class name by the given relative URL.
29+
* This method will called in server side.
30+
*
31+
* @param relativeURL
32+
* @return SimpleRPCRunnable serivce class name if relative URL is mapped, or null.
33+
*/
34+
public String getRunnableClassName(String relativeURL) {
35+
for (int i = 0; i < map.length; i++) {
36+
if (map[i] != null) {
37+
if (relativeURL.equals(map[i][0])) {
38+
return map[i][1];
39+
}
40+
}
41+
}
42+
return null;
43+
}
44+
45+
/**
46+
* Return the short url for the given class name.
47+
* This method will be called in client side.
48+
*
49+
* @param clazzName
50+
* @return SimpleRPCRunnable service short url if the service is registered, or null
51+
*/
52+
public String getRunnableURL(String clazzName) {
53+
for (int i = 0; i < map.length; i++) {
54+
if (map[i] != null) {
55+
if (clazzName.equals(map[i][1])) {
56+
return map[i][0];
57+
}
58+
}
59+
}
60+
return null;
61+
}
62+
63+
/**
64+
* Add mapping pair.
65+
* @param url
66+
* @param clazzName
67+
* @return whether the map is updated or not.
68+
*/
69+
public boolean add(String url, String clazzName) {
70+
int length = map.length;
71+
if (url == null && clazzName == null) {
72+
return false;
73+
}
74+
if (url == null) { // delete clazzName specified item
75+
for (int i = 0; i < length; i++) {
76+
if (map[i] != null) {
77+
if (clazzName.equals(map[i][1])) {
78+
map[i] = null;
79+
return true; // return true for updated
80+
}
81+
}
82+
}
83+
return false;
84+
}
85+
/*
86+
* Different class names may map to the same relative URL.
87+
*
88+
if (clazzName == null) { // delete url specified item
89+
for (int i = 0; i < length; i++) {
90+
if (map[i] != null) {
91+
if (url.equals(map[i][0])) {
92+
map[i] = null;
93+
return true; // return true for updated
94+
}
95+
}
96+
}
97+
return false;
98+
}
99+
*/
100+
for (int i = 0; i < length; i++) {
101+
if (map[i] != null) {
102+
if (/*url.equals(map[i][0]) || */clazzName.equals(map[i][1])) {
103+
// just return and do not update it!
104+
return false;
105+
}
106+
}
107+
}
108+
for (int i = 0; i < length; i++) {
109+
if (map[i] == null) {
110+
map[i] = new String[2];
111+
map[i][0] = url;
112+
map[i][1] = clazzName;
113+
return true;
114+
}
115+
}
116+
String[][] newMap = new String[length + 8][];
117+
for (int i = 0; i < length; i++) {
118+
newMap[i] = map[i];
119+
}
120+
newMap[length] = new String[2];
121+
newMap[length][0] = url;
122+
newMap[length][1] = clazzName;
123+
map = newMap;
124+
return true;
125+
}
126+
}

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCRequest.java

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,76 @@ public static void request(SimpleRPCRunnable runnable) {
5353
}
5454
}
5555

56+
static String getClassNameURL(SimpleRPCRunnable runnable) {
57+
Class oClass = runnable.getClass();
58+
String name = oClass.getName();
59+
while (name.indexOf('$') != -1) {
60+
oClass = oClass.getSuperclass();
61+
if (oClass == null) {
62+
return null; // should never happen!
63+
}
64+
name = oClass.getName();
65+
}
66+
return name;
67+
}
68+
69+
static SimpleRPCMapping[] mappings = new SimpleRPCMapping[4];
70+
71+
public static boolean addMapping(SimpleRPCMapping mapping) {
72+
int length = mappings.length;
73+
for (int i = 0; i < length; i++) {
74+
if (mappings[i] == mapping) {
75+
return false;
76+
}
77+
}
78+
for (int i = 0; i < length; i++) {
79+
if (mappings[i] == null) {
80+
mappings[i] = mapping;
81+
return true;
82+
}
83+
}
84+
SimpleRPCMapping[] newMappings = new SimpleRPCMapping[length + 4];
85+
for (int i = 0; i < length; i++) {
86+
newMappings[i] = mappings[i];
87+
}
88+
newMappings[length] = mapping;
89+
mappings = newMappings;
90+
return true;
91+
}
92+
93+
static String getRunnableURL(final SimpleRPCRunnable runnable) {
94+
String clazzNameURL = getClassNameURL(runnable);
95+
int length = mappings.length;
96+
for (int i = 0; i < length; i++) {
97+
if (mappings[i] != null) {
98+
String shortURL = mappings[i].getRunnableURL(clazzNameURL);
99+
if (shortURL != null) {
100+
clazzNameURL = shortURL;
101+
break;
102+
}
103+
}
104+
}
105+
String url = runnable.baseURL();
106+
if (url == null || url.trim().length() == 0) {
107+
url = clazzNameURL;
108+
} else {
109+
url = url.trim();
110+
if (url.charAt(url.length() - 1) != '/') {
111+
url += '/';
112+
}
113+
url += clazzNameURL;
114+
}
115+
return url;
116+
}
117+
56118
private static void ajaxRequest(final SimpleRPCRunnable runnable) {
57119
final HttpRequest request = new HttpRequest();
58-
request.open(runnable.method(), runnable.url(), true);
120+
String url = getRunnableURL(runnable);
121+
String method = runnable.method();
122+
if (method == null) {
123+
method = "POST";
124+
}
125+
request.open(method, url, true);
59126
request.registerOnReadyStateChange(new XHRCallbackAdapter() {
60127
public void onLoaded() {
61128
runnable.deserialize(request.getResponseText());
@@ -64,4 +131,5 @@ public void onLoaded() {
64131
});
65132
request.send(runnable.serialize());
66133
}
134+
67135
}

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCRunnable.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
*/
2222
public abstract class SimpleRPCRunnable extends SimpleSerializable implements Runnable {
2323

24-
public abstract String url();
24+
public String baseURL() {
25+
return "simplerpc/"; // url is relative to the servlet!
26+
}
2527

2628
public String method() {
2729
return "POST";

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCSWTRequest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ public static void swtRequest(SimpleRPCRunnable runnable) {
3838

3939
private static void swtAJAXRequest(final SimpleRPCRunnable runnable) {
4040
final HttpRequest request = new HttpRequest();
41-
request.open(runnable.method(), runnable.url(), true);
41+
String url = getRunnableURL(runnable);
42+
String method = runnable.method();
43+
if (method == null) {
44+
method = "POST";
45+
}
46+
request.open(method, url, true);
4247
request.registerOnReadyStateChange(new XHRCallbackSWTAdapter() {
4348
public void swtOnLoaded() {
4449
runnable.deserialize(request.getResponseText());

0 commit comments

Comments
 (0)