1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.continuation;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import javax.servlet.AsyncContext;
26 import javax.servlet.AsyncEvent;
27 import javax.servlet.AsyncListener;
28 import javax.servlet.DispatcherType;
29 import javax.servlet.ServletRequest;
30 import javax.servlet.ServletResponse;
31 import javax.servlet.ServletResponseWrapper;
32
33
34
35
36
37
38
39
40 public class Servlet3Continuation implements Continuation
41 {
42
43
44 private final static ContinuationThrowable __exception = new ContinuationThrowable();
45
46 private final ServletRequest _request;
47 private ServletResponse _response;
48 private AsyncContext _context;
49 private List<AsyncListener> _listeners=new ArrayList<AsyncListener>();
50 private volatile boolean _initial=true;
51 private volatile boolean _resumed=false;
52 private volatile boolean _expired=false;
53 private volatile boolean _responseWrapped=false;
54
55 private long _timeoutMs=-1;
56
57
58 public Servlet3Continuation(ServletRequest request)
59 {
60 _request=request;
61
62 _listeners.add(new AsyncListener()
63 {
64 public void onComplete(AsyncEvent event) throws IOException
65 {
66 }
67
68 public void onError(AsyncEvent event) throws IOException
69 {
70 }
71
72 public void onStartAsync(AsyncEvent event) throws IOException
73 {
74 event.getAsyncContext().addListener(this);
75 }
76
77 public void onTimeout(AsyncEvent event) throws IOException
78 {
79 _initial=false;
80 event.getAsyncContext().dispatch();
81 }
82 });
83 }
84
85
86 public void addContinuationListener(final ContinuationListener listener)
87 {
88 AsyncListener wrapped = new AsyncListener()
89 {
90 public void onComplete(final AsyncEvent event) throws IOException
91 {
92 listener.onComplete(Servlet3Continuation.this);
93 }
94
95 public void onError(AsyncEvent event) throws IOException
96 {
97 listener.onComplete(Servlet3Continuation.this);
98 }
99
100 public void onStartAsync(AsyncEvent event) throws IOException
101 {
102 event.getAsyncContext().addListener(this);
103 }
104
105 public void onTimeout(AsyncEvent event) throws IOException
106 {
107 _expired=true;
108 listener.onTimeout(Servlet3Continuation.this);
109 }
110 };
111
112 if (_context!=null)
113 _context.addListener(wrapped);
114 else
115 _listeners.add(wrapped);
116 }
117
118
119 public void complete()
120 {
121 AsyncContext context=_context;
122 if (context==null)
123 throw new IllegalStateException();
124 _context.complete();
125 }
126
127
128 public ServletResponse getServletResponse()
129 {
130 return _response;
131 }
132
133
134 public boolean isExpired()
135 {
136 return _expired;
137 }
138
139
140 public boolean isInitial()
141 {
142
143 return _initial&&_request.getDispatcherType()!=DispatcherType.ASYNC;
144 }
145
146
147 public boolean isResumed()
148 {
149 return _resumed;
150 }
151
152
153 public boolean isSuspended()
154 {
155 return _request.isAsyncStarted();
156 }
157
158
159 public void keepWrappers()
160 {
161 _responseWrapped=true;
162 }
163
164
165 public void resume()
166 {
167 AsyncContext context=_context;
168 if (context==null)
169 throw new IllegalStateException();
170 _resumed=true;
171 _context.dispatch();
172 }
173
174
175 public void setTimeout(long timeoutMs)
176 {
177 _timeoutMs=timeoutMs;
178 if (_context!=null)
179 _context.setTimeout(timeoutMs);
180 }
181
182
183 public void suspend(ServletResponse response)
184 {
185 _response=response;
186 _responseWrapped=response instanceof ServletResponseWrapper;
187 _resumed=false;
188 _expired=false;
189 _context=_request.startAsync();
190 _context.setTimeout(_timeoutMs);
191
192 for (AsyncListener listener:_listeners)
193 _context.addListener(listener);
194 _listeners.clear();
195 }
196
197
198 public void suspend()
199 {
200 _resumed=false;
201 _expired=false;
202 _context=_request.startAsync();
203 _context.setTimeout(_timeoutMs);
204
205 for (AsyncListener listener:_listeners)
206 _context.addListener(listener);
207 _listeners.clear();
208 }
209
210
211 public boolean isResponseWrapped()
212 {
213 return _responseWrapped;
214 }
215
216
217
218
219
220 public Object getAttribute(String name)
221 {
222 return _request.getAttribute(name);
223 }
224
225
226
227
228
229 public void removeAttribute(String name)
230 {
231 _request.removeAttribute(name);
232 }
233
234
235
236
237
238 public void setAttribute(String name, Object attribute)
239 {
240 _request.setAttribute(name,attribute);
241 }
242
243
244
245
246
247 public void undispatch()
248 {
249 if (isSuspended())
250 {
251 if (ContinuationFilter.__debug)
252 throw new ContinuationThrowable();
253 throw __exception;
254 }
255 throw new IllegalStateException("!suspended");
256 }
257 }