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