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