1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.cometd;
16
17 import java.io.FileNotFoundException;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.servlet.ServletException;
26 import javax.servlet.http.Cookie;
27 import javax.servlet.http.HttpServlet;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.mortbay.cometd.filter.JSONDataFilter;
32 import org.mortbay.log.Log;
33 import org.mortbay.util.ajax.JSON;
34
35 import dojox.cometd.Bayeux;
36 import dojox.cometd.DataFilter;
37 import dojox.cometd.Message;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 public abstract class AbstractCometdServlet extends HttpServlet
104 {
105 public static final String CLIENT_ATTR="org.mortbay.cometd.client";
106 public static final String TRANSPORT_ATTR="org.mortbay.cometd.transport";
107 public static final String MESSAGE_PARAM="message";
108 public static final String TUNNEL_INIT_PARAM="tunnelInit";
109 public static final String HTTP_CLIENT_ID="BAYEUX_HTTP_CLIENT";
110 public final static String BROWSER_ID="BAYEUX_BROWSER";
111
112 protected AbstractBayeux _bayeux;
113 protected boolean _asyncDeliver=false;
114
115 public AbstractBayeux getBayeux()
116 {
117 return _bayeux;
118 }
119
120 protected abstract AbstractBayeux newBayeux();
121
122 public void init() throws ServletException
123 {
124 synchronized (AbstractCometdServlet.class)
125 {
126 _bayeux=(AbstractBayeux)getServletContext().getAttribute(Bayeux.DOJOX_COMETD_BAYEUX);
127 if (_bayeux==null)
128 {
129 _bayeux=newBayeux();
130 }
131 }
132
133 synchronized(_bayeux)
134 {
135 boolean was_initialized=_bayeux.isInitialized();
136 _bayeux.initialize(getServletContext());
137
138 if (!was_initialized)
139 {
140 String filters=getInitParameter("filters");
141 if (filters!=null)
142 {
143 try
144 {
145 InputStream is = getServletContext().getResourceAsStream(filters);
146 if (is==null)
147 throw new FileNotFoundException(filters);
148
149 Object[] objects=(Object[])JSON.parse(new InputStreamReader(getServletContext().getResourceAsStream(filters),"utf-8"));
150 for (int i=0; objects!=null&&i<objects.length; i++)
151 {
152 Map<?,?> filter_def=(Map<?,?>)objects[i];
153
154 String fc = (String)filter_def.get("class");
155 if (fc!=null)
156 Log.warn(filters+" file uses deprecated \"class\" name. Use \"filter\" instead");
157 else
158 fc=(String)filter_def.get("filter");
159 Class<?> c=Thread.currentThread().getContextClassLoader().loadClass(fc);
160 DataFilter filter=(DataFilter)c.newInstance();
161
162 if (filter instanceof JSONDataFilter)
163 ((JSONDataFilter)filter).init(filter_def.get("init"));
164
165 _bayeux.getChannel((String)filter_def.get("channels"),true).addDataFilter(filter);
166 }
167 }
168 catch (Exception e)
169 {
170 getServletContext().log("Could not parse: "+filters,e);
171 throw new ServletException(e);
172 }
173 }
174
175 String timeout=getInitParameter("timeout");
176 if (timeout!=null)
177 _bayeux.setTimeout(Long.parseLong(timeout));
178
179 String maxInterval=getInitParameter("maxInterval");
180 if (maxInterval!=null)
181 _bayeux.setMaxInterval(Long.parseLong(maxInterval));
182
183 String commentedJSON=getInitParameter("JSONCommented");
184 _bayeux.setJSONCommented(commentedJSON!=null && Boolean.parseBoolean(commentedJSON));
185
186 String l=getInitParameter("logLevel");
187 if (l!=null&&l.length()>0)
188 _bayeux.setLogLevel(Integer.parseInt(l));
189
190 String interval=getInitParameter("interval");
191 if (interval!=null)
192 _bayeux.setInterval(Long.parseLong(interval));
193
194 String mfInterval=getInitParameter("multiFrameInterval");
195 if (mfInterval!=null)
196 _bayeux.setMultiFrameInterval(Integer.parseInt(mfInterval));
197
198 String requestAvailable=getInitParameter("requestAvailable");
199 _bayeux.setRequestAvailable(requestAvailable!=null && Boolean.parseBoolean(requestAvailable));
200
201 String direct=getInitParameter("directDeliver");
202 if (direct!=null)
203 _bayeux.setDirectDeliver(Boolean.parseBoolean(direct));
204
205 String async=getInitParameter("asyncDeliver");
206 if (async!=null)
207 _asyncDeliver = Boolean.parseBoolean(async);
208
209 _bayeux.generateAdvice();
210 }
211 }
212
213 getServletContext().setAttribute(Bayeux.DOJOX_COMETD_BAYEUX,_bayeux);
214 }
215
216 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
217 {
218 if (_bayeux.isRequestAvailable())
219 _bayeux.setCurrentRequest(req);
220 try
221 {
222 super.service(req,resp);
223 }
224 finally
225 {
226 if (_bayeux.isRequestAvailable())
227 _bayeux.setCurrentRequest(null);
228 }
229 }
230
231
232 protected String browserId(HttpServletRequest request)
233 {
234 Cookie[] cookies = request.getCookies();
235 if (cookies!=null)
236 {
237 for (Cookie cookie : cookies)
238 {
239 if (BROWSER_ID.equals(cookie.getName()))
240 return cookie.getValue();
241 }
242 }
243
244 return null;
245 }
246
247 protected String newBrowserId(HttpServletRequest request,HttpServletResponse response)
248 {
249 String browser_id=Long.toHexString(request.getRemotePort())+
250 Long.toString(_bayeux.getRandom(),36)+
251 Long.toString(System.currentTimeMillis(),36)+
252 Long.toString(request.getRemotePort(),36);
253
254 Cookie cookie = new Cookie(BROWSER_ID,browser_id);
255 cookie.setPath("/");
256 cookie.setMaxAge(-1);
257 response.addCookie(cookie);
258 return browser_id;
259 }
260
261 private static Message[] __EMPTY_BATCH=new Message[0];
262
263 protected Message[] getMessages(HttpServletRequest request) throws IOException
264 {
265 String fodder=null;
266 try
267 {
268
269 if (request.getContentType() != null && !request.getContentType().startsWith("application/x-www-form-urlencoded"))
270 {
271 return _bayeux.parse(request.getReader());
272 }
273
274 String[] batches=request.getParameterValues(MESSAGE_PARAM);
275
276 if (batches==null || batches.length==0)
277 return __EMPTY_BATCH;
278
279 if (batches.length==0)
280 {
281 fodder=batches[0];
282 return _bayeux.parse(fodder);
283 }
284
285 List<Message> messages = new ArrayList<Message>();
286 for (int i=0;i<batches.length;i++)
287 {
288 if (batches[i]==null)
289 continue;
290
291 fodder=batches[i];
292 _bayeux.parseTo(fodder,messages);
293
294 }
295
296 return messages.toArray(new Message[messages.size()]);
297 }
298 catch(IOException e)
299 {
300 throw e;
301 }
302 catch(Exception e)
303 {
304 throw new Error(fodder,e);
305 }
306 }
307
308 }