• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18 
19 package org.eclipse.jetty.continuation;
20 
21 import java.util.ArrayList;
22 import java.util.List;
23 
24 import javax.servlet.ServletRequest;
25 import javax.servlet.ServletResponse;
26 import javax.servlet.ServletResponseWrapper;
27 
28 import org.mortbay.log.Log;
29 import org.mortbay.log.Logger;
30 
31 /* ------------------------------------------------------------ */
32 /**
33  * This implementation of Continuation is used by {@link ContinuationSupport}
34  * when it detects that the application is deployed in a jetty-6 server.
35  * This continuation requires the {@link ContinuationFilter} to be deployed.
36  */
37 public class Jetty6Continuation implements ContinuationFilter.FilteredContinuation
38 {
39     private static final Logger LOG = Log.getLogger(Jetty6Continuation.class.getName());
40 
41     // Exception reused for all continuations
42     // Turn on debug in ContinuationFilter to see real stack trace.
43     private final static ContinuationThrowable __exception = new ContinuationThrowable();
44 
45     private final ServletRequest _request;
46     private ServletResponse _response;
47     private final org.mortbay.util.ajax.Continuation _j6Continuation;
48 
49     private Throwable _retry;
50     private int _timeout;
51     private boolean _initial=true;
52     private volatile boolean _completed=false;
53     private volatile boolean _resumed=false;
54     private volatile boolean _expired=false;
55     private boolean _responseWrapped=false;
56     private List<ContinuationListener> _listeners;
57 
Jetty6Continuation(ServletRequest request, org.mortbay.util.ajax.Continuation continuation)58     public Jetty6Continuation(ServletRequest request, org.mortbay.util.ajax.Continuation continuation)
59     {
60         if (!ContinuationFilter._initialized)
61         {
62             LOG.warn("!ContinuationFilter installed",null,null);
63             throw new IllegalStateException("!ContinuationFilter installed");
64         }
65         _request=request;
66         _j6Continuation=continuation;
67     }
68 
addContinuationListener(final ContinuationListener listener)69     public void addContinuationListener(final ContinuationListener listener)
70     {
71         if (_listeners==null)
72             _listeners=new ArrayList<ContinuationListener>();
73         _listeners.add(listener);
74     }
75 
complete()76     public void complete()
77     {
78         synchronized(this)
79         {
80             if (_resumed)
81                 throw new IllegalStateException();
82             _completed=true;
83             if (_j6Continuation.isPending())
84                 _j6Continuation.resume();
85         }
86     }
87 
88     /* ------------------------------------------------------------ */
89     /**
90      * @see org.eclipse.jetty.continuation.Continuation#getAttribute(java.lang.String)
91      */
getAttribute(String name)92     public Object getAttribute(String name)
93     {
94         return _request.getAttribute(name);
95     }
96 
97     /* ------------------------------------------------------------ */
98     /**
99      * @see org.eclipse.jetty.continuation.Continuation#removeAttribute(java.lang.String)
100      */
removeAttribute(String name)101     public void removeAttribute(String name)
102     {
103         _request.removeAttribute(name);
104     }
105 
106     /* ------------------------------------------------------------ */
107     /**
108      * @see org.eclipse.jetty.continuation.Continuation#setAttribute(java.lang.String, java.lang.Object)
109      */
setAttribute(String name, Object attribute)110     public void setAttribute(String name, Object attribute)
111     {
112         _request.setAttribute(name,attribute);
113     }
114 
115     /* ------------------------------------------------------------ */
getServletResponse()116     public ServletResponse getServletResponse()
117     {
118         return _response;
119     }
120 
121     /* ------------------------------------------------------------ */
isExpired()122     public boolean isExpired()
123     {
124         return _expired;
125     }
126 
127     /* ------------------------------------------------------------ */
isInitial()128     public boolean isInitial()
129     {
130         return _initial;
131     }
132 
133     /* ------------------------------------------------------------ */
isResumed()134     public boolean isResumed()
135     {
136         return _resumed;
137     }
138 
139     /* ------------------------------------------------------------ */
isSuspended()140     public boolean isSuspended()
141     {
142         return _retry!=null;
143     }
144 
145     /* ------------------------------------------------------------ */
resume()146     public void resume()
147     {
148         synchronized(this)
149         {
150             if (_completed)
151                 throw new IllegalStateException();
152             _resumed=true;
153             if (_j6Continuation.isPending())
154                 _j6Continuation.resume();
155         }
156     }
157 
158     /* ------------------------------------------------------------ */
setTimeout(long timeoutMs)159     public void setTimeout(long timeoutMs)
160     {
161         _timeout=(timeoutMs>Integer.MAX_VALUE)?Integer.MAX_VALUE:(int)timeoutMs;
162     }
163 
164     /* ------------------------------------------------------------ */
165     /**
166      * @see org.eclipse.jetty.continuation.Continuation#suspend(javax.servlet.ServletResponse)
167      */
suspend(ServletResponse response)168     public void suspend(ServletResponse response)
169     {
170         try
171         {
172             _response=response;
173             _responseWrapped=_response instanceof ServletResponseWrapper;
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     /* ------------------------------------------------------------ */
suspend()186     public void suspend()
187     {
188         try
189         {
190             _response=null;
191             _responseWrapped=false;
192             _resumed=false;
193             _expired=false;
194             _completed=false;
195             _j6Continuation.suspend(_timeout);
196         }
197         catch(Throwable retry)
198         {
199             _retry=retry;
200         }
201     }
202 
203     /* ------------------------------------------------------------ */
isResponseWrapped()204     public boolean isResponseWrapped()
205     {
206         return _responseWrapped;
207     }
208 
209     /* ------------------------------------------------------------ */
210     /**
211      * @see org.eclipse.jetty.continuation.Continuation#undispatch()
212      */
undispatch()213     public void undispatch()
214     {
215         if (isSuspended())
216         {
217             if (ContinuationFilter.__debug)
218                 throw new ContinuationThrowable();
219             throw __exception;
220         }
221         throw new IllegalStateException("!suspended");
222     }
223 
224     /* ------------------------------------------------------------ */
enter(ServletResponse response)225     public boolean enter(ServletResponse response)
226     {
227         _response=response;
228         _expired=!_j6Continuation.isResumed();
229 
230         if (_initial)
231             return true;
232 
233         _j6Continuation.reset();
234 
235         if (_expired)
236         {
237             if (_listeners!=null)
238             {
239                 for (ContinuationListener l: _listeners)
240                     l.onTimeout(this);
241             }
242         }
243 
244         return !_completed;
245     }
246 
247     /* ------------------------------------------------------------ */
exit()248     public boolean exit()
249     {
250         _initial=false;
251 
252         Throwable th=_retry;
253         _retry=null;
254         if (th instanceof Error)
255             throw (Error)th;
256         if (th instanceof RuntimeException)
257             throw (RuntimeException)th;
258 
259         if (_listeners!=null)
260         {
261             for (ContinuationListener l: _listeners)
262                 l.onComplete(this);
263         }
264 
265         return true;
266     }
267 }
268