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