KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > directwebremoting > util > Continuation


1 /*
2  * Copyright 2005 Joe Walker
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.directwebremoting.util;
17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20
21 import javax.servlet.http.HttpServletRequest JavaDoc;
22
23 /**
24  * A wrapper around Jetty Ajax Continuations
25  * @author Joe Walker [joe at getahead dot ltd dot uk]
26  */

27 public class Continuation
28 {
29     /**
30      * Fish the Jetty continuation out of the request if it exists
31      * @param request The http request
32      */

33     public Continuation(HttpServletRequest JavaDoc request)
34     {
35         this.proxy = request.getAttribute(ATTRIBUTE_JETTY_CONTINUATION);
36     }
37
38     /**
39      * Are continuations working?
40      * If this method returns false then all the other methods will fail.
41      * @return true if Jetty continuations are working
42      */

43     public boolean isAvailable()
44     {
45         return proxy != null;
46     }
47
48     /**
49      * Suspend the thread for a maximum of sleepTime milliseconds
50      * @param sleepTime The maximum time to wait
51      * @throws Exception If reflection breaks
52      */

53     public void suspend(long sleepTime) throws Exception JavaDoc
54     {
55         try
56         {
57             suspendMethod.invoke(proxy, new Object JavaDoc[] { new Long JavaDoc(sleepTime) });
58         }
59         catch (InvocationTargetException JavaDoc ex)
60         {
61             rethrowWithoutWrapper(ex);
62         }
63     }
64
65     /**
66      * Resume an continuation.
67      * For Jetty this does not work like a real continuation because it restarts
68      * the http request.
69      * @throws Exception If reflection breaks
70      */

71     public void resume() throws Exception JavaDoc
72     {
73         try
74         {
75             resumeMethod.invoke(proxy, new Object JavaDoc[0]);
76         }
77         catch (InvocationTargetException JavaDoc ex)
78         {
79             rethrowWithoutWrapper(ex);
80         }
81     }
82
83     /**
84      * Accessor for the object associated with this continuation
85      * @return the object associated with this continuation
86      * @throws Exception If reflection breaks
87      */

88     public Object JavaDoc getObject() throws Exception JavaDoc
89     {
90         try
91         {
92             return getObject.invoke(proxy, new Object JavaDoc[0]);
93         }
94         catch (InvocationTargetException JavaDoc ex)
95         {
96             return rethrowWithoutWrapper(ex);
97         }
98     }
99
100     /**
101      * Accessor for the object associated with this continuation
102      * @param object the object associated with this continuation
103      * @throws Exception If reflection breaks
104      */

105     public void setObject(Object JavaDoc object) throws Exception JavaDoc
106     {
107         try
108         {
109             setObject.invoke(proxy, new Object JavaDoc[] { object });
110         }
111         catch (InvocationTargetException JavaDoc ex)
112         {
113             rethrowWithoutWrapper(ex);
114         }
115     }
116
117     /**
118      * We shouldn't be catching Jetty RetryRequests so we rethrow them.
119      * @param th The exception to test for continuation-ness
120      */

121     public static void rethrowIfContinuation(Throwable JavaDoc th)
122     {
123         Throwable JavaDoc ex = th;
124
125         if (ex instanceof InvocationTargetException JavaDoc)
126         {
127             ex = ((InvocationTargetException JavaDoc) ex).getTargetException();
128         }
129
130         // Allow Jetty RequestRetry exception to propogate to container!
131
if ("org.mortbay.jetty.RetryRequest".equals(ex.getClass().getName()))
132         {
133             throw (RuntimeException JavaDoc) ex;
134         }
135     }
136
137     /**
138      * Did we find any of the
139      * @return
140      */

141     public static boolean isJetty()
142     {
143         return isJetty;
144     }
145
146     /**
147      * Unwrap an InvocationTargetException
148      * @param ex The exception to unwrap
149      * @return Nothing. This method will not complete normally
150      * @throws Exception If reflection breaks
151      */

152     private static Object JavaDoc rethrowWithoutWrapper(InvocationTargetException JavaDoc ex) throws Exception JavaDoc
153     {
154         Throwable JavaDoc target = ex.getTargetException();
155         if (target instanceof Exception JavaDoc)
156         {
157             throw (Exception JavaDoc) target;
158         }
159
160         if (target instanceof Error JavaDoc)
161         {
162             throw (Error JavaDoc) target;
163         }
164
165         throw ex;
166     }
167
168     /**
169      * The real continuation object
170      */

171     private Object JavaDoc proxy;
172
173     /**
174      * The log stream
175      */

176     private static final Logger log = Logger.getLogger(Continuation.class);
177
178     /**
179      * The attribute under which Jetty stores it's Contuniations.
180      * TODO: This feels like a mighty hack. I hope Greg doesn't change it without telling us!
181      */

182     private static final String JavaDoc ATTRIBUTE_JETTY_CONTINUATION = "org.mortbay.jetty.ajax.Continuation";
183
184     /**
185      * Jetty code used by reflection to allow it to run outside of Jetty
186      */

187     protected static Class JavaDoc continuationClass;
188
189     /**
190      * How we suspend the continuation
191      */

192     protected static Method JavaDoc suspendMethod;
193
194     /**
195      * How we resume the continuation
196      */

197     protected static Method JavaDoc resumeMethod;
198
199     /**
200      * How we get the associated continuation object
201      */

202     protected static Method JavaDoc getObject;
203
204     /**
205      * How we set the associated continuation object
206      */

207     protected static Method JavaDoc setObject;
208
209     /**
210      * Are we using Jetty at all?
211      */

212     protected static boolean isJetty;
213
214     /**
215      * Can we use Jetty?
216      */

217     static
218     {
219         try
220         {
221             continuationClass = LocalUtil.classForName("org.mortbay.util.ajax.Continuation");
222             suspendMethod = continuationClass.getMethod("suspend", new Class JavaDoc[] { Long.TYPE });
223             resumeMethod = continuationClass.getMethod("resume", new Class JavaDoc[] {});
224             getObject = continuationClass.getMethod("getObject", new Class JavaDoc[] {});
225             setObject = continuationClass.getMethod("setObject", new Class JavaDoc[] { Object JavaDoc.class });
226             isJetty = true;
227         }
228         catch (Exception JavaDoc ex)
229         {
230             isJetty = false;
231             log.debug("No Jetty ContuniationSupport class, using standard Servlet API");
232         }
233     }
234 }
235
Popular Tags