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