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