1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.cometd.continuation;
16
17 import java.io.IOException;
18 import java.util.List;
19
20 import javax.servlet.ServletException;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23
24 import org.mortbay.cometd.AbstractBayeux;
25 import org.mortbay.cometd.AbstractCometdServlet;
26 import org.mortbay.cometd.ClientImpl;
27 import org.mortbay.cometd.MessageImpl;
28 import org.mortbay.cometd.Transport;
29 import org.mortbay.util.ajax.Continuation;
30 import org.mortbay.util.ajax.ContinuationSupport;
31
32 import dojox.cometd.Extension;
33 import dojox.cometd.Message;
34
35
36
37
38
39
40 public class ContinuationCometdServlet extends AbstractCometdServlet
41 {
42
43 protected AbstractBayeux newBayeux()
44 {
45 return new ContinuationBayeux();
46 }
47
48
49 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
50 {
51 doPost(req,resp);
52 }
53
54
55 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
56 {
57
58 Object clientObj=req.getAttribute(CLIENT_ATTR);
59 ContinuationClient client=(clientObj instanceof ClientImpl)?(ContinuationClient)clientObj:null;
60 Transport transport=null;
61 boolean connect=false;
62 int num_msgs=-1;
63
64
65 if (client!=null)
66 {
67
68 transport=(Transport)req.getAttribute(TRANSPORT_ATTR);
69 transport.setResponse(resp);
70 }
71 else
72 {
73 Message[] messages = getMessages(req);
74 num_msgs=messages.length;
75
76
77 String jsonpParam=req.getParameter("jsonp");
78
79
80 try
81 {
82 for (Message message : messages)
83 {
84 if (jsonpParam!=null)
85 message.put("jsonp",jsonpParam);
86
87 if (client==null)
88 {
89 client=(ContinuationClient)_bayeux.getClient((String)message.get(AbstractBayeux.CLIENT_FIELD));
90
91
92 if (client==null)
93 {
94
95 String browser_id=browserId(req);
96 if (browser_id==null)
97 browser_id=newBrowserId(req,resp);
98
99 if (transport==null)
100 {
101 transport=_bayeux.newTransport(client,message);
102 transport.setResponse(resp);
103 }
104 _bayeux.handle(null,transport,message);
105 message=null;
106
107 continue;
108 }
109 else
110 {
111 String browser_id=browserId(req);
112 if (browser_id!=null && (client.getBrowserId()==null || !client.getBrowserId().equals(browser_id)))
113 client.setBrowserId(browser_id);
114
115
116 if (transport==null)
117 {
118 transport=_bayeux.newTransport(client,message);
119 transport.setResponse(resp);
120 }
121
122
123 if (!transport.resumePoll())
124 client.responsePending();
125 }
126 }
127
128 String channel=_bayeux.handle(client,transport,message);
129 connect|=AbstractBayeux.META_CONNECT.equals(channel);
130 }
131 }
132 finally
133 {
134 if (transport!=null && client!=null && !transport.resumePoll())
135 client.responded();
136
137 for (Message message : messages)
138 ((MessageImpl)message).decRef();
139 }
140 }
141
142
143 if (transport!=null)
144 {
145 Message pollReply=transport.getPollReply();
146 if (pollReply!=null)
147 {
148 if (_bayeux.isLogDebug())
149 _bayeux.logDebug("doPost: transport is polling");
150 long timeout=client.getTimeout();
151 if (timeout==0)
152 timeout=_bayeux.getTimeout();
153
154 Continuation continuation=ContinuationSupport.getContinuation(req,client);
155 if (!continuation.isPending())
156 client.access();
157
158
159 synchronized (client)
160 {
161 if (!client.hasMessages() && !continuation.isPending()&& num_msgs<=1)
162 {
163
164 ((ContinuationClient)client).setContinuation(continuation);
165 req.setAttribute(CLIENT_ATTR,client);
166 req.setAttribute(TRANSPORT_ATTR,transport);
167 continuation.suspend(timeout);
168 }
169 continuation.reset();
170 }
171
172 ((ContinuationClient)client).setContinuation(null);
173 transport.setPollReply(null);
174
175 for (Extension e:_bayeux.getExtensions())
176 pollReply=e.sendMeta(pollReply);
177 transport.send(pollReply);
178 }
179 else if (client!=null)
180 {
181 client.access();
182 }
183 }
184
185
186 if (client!=null)
187 {
188 List<Message> messages = null;
189 Message message = null;
190 synchronized(client)
191 {
192 switch (client.getMessages())
193 {
194 case 0:
195 break;
196 case 1:
197 message = client.takeMessage();
198 break;
199 default:
200 messages = client.takeMessages();
201 break;
202 }
203
204 if (!_asyncDeliver)
205 {
206 try
207 {
208 if (message!=null)
209 transport.send(message);
210 else if (messages!=null)
211 transport.send(messages);
212
213 transport.complete();
214 resp.flushBuffer();
215
216 if (transport.resumePoll())
217 client.resume();
218
219 return;
220 }
221 catch(Throwable e)
222 {
223
224 if (message!=null)
225 client.returnMessage(message);
226 else if (messages!=null)
227 client.returnMessages(messages);
228
229 if (e instanceof ServletException)
230 throw (ServletException)e;
231 if (e instanceof IOException)
232 throw (IOException)e;
233 if (e instanceof RuntimeException)
234 throw (RuntimeException)e;
235 if (e instanceof Error)
236 throw (Error)e;
237 if (e instanceof ThreadDeath)
238 throw (ThreadDeath)e;
239 throw new ServletException(e);
240 }
241 }
242 }
243
244 if (message!=null)
245 transport.send(message);
246 else if (messages!=null)
247 transport.send(messages);
248
249 if (transport.resumePoll())
250 client.resume();
251 }
252
253 if (transport!=null)
254 transport.complete();
255 }
256 }