1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.simject.remoting.server;
17
18 import java.beans.XMLDecoder;
19 import java.beans.XMLEncoder;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.util.StringTokenizer;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29
30 import javax.servlet.ServletException;
31 import javax.servlet.http.HttpServlet;
32 import javax.servlet.http.HttpServletRequest;
33 import javax.servlet.http.HttpServletResponse;
34
35 import org.simject.SimFactory;
36 import org.simject.util.Protocol;
37 import org.simject.util.SimConstants;
38
39
40
41
42
43
44
45 @SuppressWarnings("serial")
46 public class SimServerServlet extends HttpServlet {
47
48 private final static Logger logger = Logger
49 .getLogger(SimServerServlet.class.getName());
50
51
52
53
54 private final static String SIMJECT_CONFIG = "simjectConfig";
55
56
57
58
59 private SimFactory simFactory;
60
61 @Override
62 public void init() throws ServletException {
63 if (this.simFactory == null) {
64
65 final String configFile = this.getServletContext()
66 .getInitParameter(SIMJECT_CONFIG);
67
68 this.simFactory = new SimFactory(configFile);
69 }
70 }
71
72 @Override
73 protected void doPost(final HttpServletRequest req,
74 final HttpServletResponse resp) throws ServletException,
75 IOException {
76 this.invokeMethod(req, resp);
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 private void invokeMethod(final HttpServletRequest req,
95 final HttpServletResponse resp) throws IOException {
96
97 Object result = null;
98 try {
99
100 final String className = this.getClassName(req);
101
102 final Class<?> clazz = Class.forName(className);
103
104 final Object obj = this.simFactory.getResource(clazz);
105
106 final Object[] args = this.getArguments(req);
107
108 final String methodString = req
109 .getHeader(SimConstants.PARAM_METHOD);
110
111
112 final String paramTypesString = req
113 .getHeader(SimConstants.PARAM_TYPES);
114
115 logger.info("Request for class <" + clazz.getName() + "> method <"
116 + methodString + "> params <" + paramTypesString + ">");
117
118 if (paramTypesString == null) {
119
120 final Method method = obj.getClass().getMethod(methodString);
121 result = method.invoke(obj);
122 } else {
123
124
125 final Class<?>[] parameterTypes = this
126 .getParameterTypes(paramTypesString);
127 final Method method = obj.getClass().getMethod(methodString,
128 parameterTypes);
129
130 result = method.invoke(obj, args);
131 }
132 } catch (Exception e) {
133
134
135 logger.log(Level.INFO, "Exception occured during invocation", e);
136 result = e;
137 }
138 if (result != null) {
139 if (req.getContentType().equals(Protocol.Xml.getContentType())) {
140 this.sendXmlResponse(resp, result);
141 } else {
142 this.sendBinaryResponse(resp, result);
143 }
144 }
145 }
146
147
148
149
150
151
152
153
154 private void sendBinaryResponse(final HttpServletResponse resp,
155 final Object result) throws IOException {
156 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
157 final ObjectOutputStream oos = new ObjectOutputStream(baos);
158 oos.writeObject(result);
159 oos.close();
160
161 resp.setContentType(Protocol.Binary.getContentType());
162 resp.getOutputStream().write(baos.toByteArray());
163 }
164
165
166
167
168
169
170
171
172 private void sendXmlResponse(final HttpServletResponse resp,
173 final Object result) throws IOException {
174 resp.setContentType(Protocol.Xml.getContentType());
175 final XMLEncoder encoder = new XMLEncoder(resp.getOutputStream());
176 encoder.writeObject(result);
177 }
178
179
180
181
182
183
184
185
186 private Class<?>[] getParameterTypes(final String parameterString)
187 throws ClassNotFoundException {
188 Class<?>[] parameters = new Class[0];
189 if (parameterString != null) {
190
191 final StringTokenizer stokenizer = new StringTokenizer(
192 parameterString, SimConstants.PARAM_TYPE_DELIM);
193 parameters = new Class[stokenizer.countTokens()];
194 int index = 0;
195 while (stokenizer.hasMoreTokens()) {
196 final String className = stokenizer.nextToken();
197
198 final Class<?> clazz = Class.forName(className);
199 parameters[index] = clazz;
200 index++;
201 }
202 }
203 return parameters;
204 }
205
206
207
208
209
210
211
212
213
214 private Object[] getArguments(final HttpServletRequest req)
215 throws IOException, ClassNotFoundException {
216
217 Object args = null;
218 if (req.getContentType().equals(Protocol.Xml.getContentType())) {
219 final XMLDecoder decoder = new XMLDecoder(req.getInputStream());
220 args = decoder.readObject();
221 } else {
222 final ObjectInputStream ois = new ObjectInputStream(req
223 .getInputStream());
224 args = ois.readObject();
225 }
226
227 return (Object[]) args;
228 }
229
230
231
232
233
234
235
236 private String getClassName(final HttpServletRequest req) {
237 final StringTokenizer stokenzier = new StringTokenizer(req
238 .getPathInfo(), "/");
239 String[] tokens = new String[stokenzier.countTokens()];
240 int index = 0;
241 while (stokenzier.hasMoreTokens()) {
242 tokens[index] = stokenzier.nextToken();
243 index++;
244 }
245 return tokens[0];
246 }
247
248 @Override
249 protected void doGet(final HttpServletRequest req,
250 final HttpServletResponse resp) throws ServletException,
251 IOException {
252 this.doPost(req, resp);
253 }
254 }