1 package org.eclipse.jetty.continuation;
2
3 import java.io.IOException;
4
5 import javax.servlet.AsyncContext;
6 import javax.servlet.AsyncEvent;
7 import javax.servlet.AsyncListener;
8 import javax.servlet.DispatcherType;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.ServletResponseWrapper;
12
13
14
15
16
17
18
19
20
21 public class Servlet3Continuation implements Continuation
22 {
23
24
25 private final static ContinuationThrowable __exception = new ContinuationThrowable();
26
27 private final ServletRequest _request;
28 private ServletResponse _response;
29 private AsyncContext _context;
30 private final AsyncListener _listener = new AsyncListener()
31 {
32 public void onComplete(AsyncEvent event) throws IOException
33 {
34 }
35
36 public void onTimeout(AsyncEvent event) throws IOException
37 {
38 _initial=false;
39 }
40 };
41
42 private volatile boolean _initial=true;
43 private volatile boolean _resumed=false;
44 private volatile boolean _expired=false;
45 private volatile boolean _responseWrapped=false;
46
47 public Servlet3Continuation(ServletRequest request)
48 {
49 _request=request;
50 }
51
52
53 public void addContinuationListener(final ContinuationListener listener)
54 {
55 _request.addAsyncListener(new AsyncListener()
56 {
57 public void onComplete(final AsyncEvent event) throws IOException
58 {
59 listener.onComplete(Servlet3Continuation.this);
60 }
61
62 public void onTimeout(AsyncEvent event) throws IOException
63 {
64 _expired=true;
65 listener.onTimeout(Servlet3Continuation.this);
66 }
67 });
68 }
69
70 public void complete()
71 {
72 AsyncContext context=_context;
73 if (context==null)
74 throw new IllegalStateException();
75 _context.complete();
76 }
77
78 public ServletResponse getServletResponse()
79 {
80 return _response;
81 }
82
83 public boolean isExpired()
84 {
85 return _expired;
86 }
87
88 public boolean isInitial()
89 {
90
91 return _initial&&_request.getDispatcherType()!=DispatcherType.ASYNC;
92 }
93
94 public boolean isResumed()
95 {
96 return _resumed;
97 }
98
99 public boolean isSuspended()
100 {
101 return _request.isAsyncStarted();
102 }
103
104 public void keepWrappers()
105 {
106 _responseWrapped=true;
107 }
108
109 public void resume()
110 {
111 AsyncContext context=_context;
112 if (context==null)
113 throw new IllegalStateException();
114 _resumed=true;
115 _context.dispatch();
116 }
117
118 public void setTimeout(long timeoutMs)
119 {
120 _request.setAsyncTimeout(timeoutMs);
121 }
122
123 public void suspend(ServletResponse response)
124 {
125 _response=response;
126 _responseWrapped=response instanceof ServletResponseWrapper;
127 _request.addAsyncListener(_listener);
128 _resumed=false;
129 _expired=false;
130 _context=_request.startAsync();
131 }
132
133 public void suspend()
134 {
135 _request.addAsyncListener(_listener);
136 _resumed=false;
137 _expired=false;
138 _context=_request.startAsync();
139 }
140
141 public boolean isResponseWrapped()
142 {
143 return _responseWrapped;
144 }
145
146
147
148
149
150
151 public Object getAttribute(String name)
152 {
153 return _request.getAttribute(name);
154 }
155
156
157
158
159
160
161 public void removeAttribute(String name)
162 {
163 _request.removeAttribute(name);
164 }
165
166
167
168
169
170 public void setAttribute(String name, Object attribute)
171 {
172 _request.setAttribute(name,attribute);
173 }
174
175
176
177
178
179
180 public void undispatch()
181 {
182 if (isSuspended())
183 {
184 if (ContinuationFilter.__debug)
185 throw new ContinuationThrowable();
186 throw __exception;
187 }
188 throw new IllegalStateException("!suspended");
189 }
190 }