KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nextapp > echo2 > webrender > WebRenderServlet


1 /*
2  * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3  * Copyright (C) 2002-2005 NextApp, Inc.
4  *
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * Alternatively, the contents of this file may be used under the terms of
18  * either the GNU General Public License Version 2 or later (the "GPL"), or
19  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20  * in which case the provisions of the GPL or the LGPL are applicable instead
21  * of those above. If you wish to allow use of your version of this file only
22  * under the terms of either the GPL or the LGPL, and not to allow others to
23  * use your version of this file under the terms of the MPL, indicate your
24  * decision by deleting the provisions above and replace them with the notice
25  * and other provisions required by the GPL or the LGPL. If you do not delete
26  * the provisions above, a recipient may use your version of this file under
27  * the terms of any one of the MPL, the GPL or the LGPL.
28  */

29
30 package nextapp.echo2.webrender;
31
32 import java.io.IOException JavaDoc;
33
34 import javax.servlet.ServletException JavaDoc;
35 import javax.servlet.http.HttpServlet JavaDoc;
36 import javax.servlet.http.HttpServletRequest JavaDoc;
37 import javax.servlet.http.HttpServletResponse JavaDoc;
38
39 import nextapp.echo2.webrender.service.CoreServices;
40 import nextapp.echo2.webrender.service.DebugPaneService;
41
42 /**
43  * Echo <code>HttpServlet</code> implementation.
44  */

45 public abstract class WebRenderServlet extends HttpServlet JavaDoc {
46     
47     /**
48      * A <code>ThreadLocal</code> reference to the
49      * <code>Connection</code> relevant to the current thread.
50      */

51     private static final ThreadLocal JavaDoc activeConnection = new InheritableThreadLocal JavaDoc();
52     
53     /**
54      * A flag indicating whether caching should be disabled for all services.
55      * This flag is for testing purposes only, and should be disabled for
56      * production use.
57      */

58     public static final boolean DISABLE_CACHING = false;
59     
60     /**
61      * Request parameter identifying requested <code>Service</code>.
62      */

63     public static final String JavaDoc SERVICE_ID_PARAMETER = "serviceId";
64     
65     /**
66      * <code>Service</code> identifier of the 'default' service.
67      * The 'default' service is rendered when a client makes a request
68      * without a service identifier and a session DOES exist.
69      */

70     public static final String JavaDoc SERVICE_ID_DEFAULT = "Echo.Default";
71     
72     /**
73      * <code>Service</code> identifier of the 'new instance' service.
74      * The 'new instance' service is rendered when a client makes a request
75      * without a service identifier and a session DOES NOT exist..
76      */

77     public static final String JavaDoc SERVICE_ID_NEW_INSTANCE = "Echo.NewInstance";
78     
79     /**
80      * <code>Service</code> identifier of the 'session expired' service.
81      * The 'session expired' service is rendered when a client makes a
82      * request that has an identifier and is intended for an active session,
83      * but no session exists.
84      */

85     public static final String JavaDoc SERVICE_ID_SESSION_EXPIRED = "Echo.Expired";
86     
87     /**
88      * Global handler for multipart/form-data encoded HTTP requests.
89      */

90     private static MultipartRequestWrapper multipartRequestWrapper;
91     
92     private static final long startupTime = System.currentTimeMillis();
93     
94     /**
95      * Global <code>ServiceRegistry</code>.
96      */

97     private static final ServiceRegistry services = new ServiceRegistry();
98
99     static {
100         CoreServices.install(services);
101         services.add(DebugPaneService.INSTANCE);
102     }
103     
104     /**
105      * An interface implemented by a supporting object that will handle
106      * multipart/form-data encoded HTTP requests. This type of request is
107      * required for file uploads. Echo does not provide internal support
108      * for file uploads, but instead provides hooks for file-upload handling
109      * components.
110      */

111     public static interface MultipartRequestWrapper {
112     
113         /**
114          * Returns a replacement <code>HttpServletRequest</code> object that
115          * may be used to handle a multipart/form-data encoded HTTP request.
116          *
117          * @param request The HTTP request provided from the servlet container
118          * that has multipart/form-data encoding.
119          * @return An HTTP request that is capable of handling
120          * multipart/form-data encoding.
121          */

122         public HttpServletRequest JavaDoc getWrappedRequest(HttpServletRequest JavaDoc request)
123         throws IOException JavaDoc, ServletException JavaDoc;
124     }
125
126     /**
127      * Returns a reference to the <code>Connection</code> that is
128      * relevant to the current thread, or null if no connection is relevant.
129      *
130      * @return the relevant <code>Connection</code>
131      */

132     public static final Connection getActiveConnection() {
133         return (Connection) activeConnection.get();
134     }
135     
136     /**
137      * Returns the multipart/form-data encoded HTTP request handler.
138      *
139      * @return The multipart/form-data encoded HTTP request handler.
140      * @see #setMultipartRequestWrapper
141      */

142     public static MultipartRequestWrapper getMultipartRequestWrapper() {
143         return multipartRequestWrapper;
144     }
145     
146     /**
147      * Sets the multipart/form-data encoded HTTP request handler.
148      * The multipart request wrapper can only be set one time. It should be set
149      * in a static block of your Echo application. This method will disregard
150      * additional attempts to set the wrapper if the provided wrapper's class
151      * is identical to the existing one. If the wrapper is already set and the
152      * new wrapper object's class is different or the wrapper is null, an
153      * exception is thrown.
154      *
155      * @param multipartRequestWrapper The handler for multipart/form-data
156      * encoded HTTP requests.
157      * @throws IllegalStateException if the application attempts to change
158      * a previously set multipart request handler.
159      */

160     public static final void setMultipartRequestWrapper(MultipartRequestWrapper multipartRequestWrapper) {
161         if (WebRenderServlet.multipartRequestWrapper == null) {
162             WebRenderServlet.multipartRequestWrapper = multipartRequestWrapper;
163         } else {
164             if (multipartRequestWrapper == null ||
165                     !WebRenderServlet.multipartRequestWrapper.getClass().getName().equals(
166                     multipartRequestWrapper.getClass().getName())) {
167                 throw new IllegalStateException JavaDoc("MultipartRequestWrapper already set.");
168             }
169         }
170     }
171     
172     /**
173      * Handles a GET request.
174      *
175      * @see #process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
176      */

177     public final void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
178     throws IOException JavaDoc, ServletException JavaDoc {
179         process(request, response);
180     }
181     
182     /**
183      * Handles a POST request.
184      *
185      * @see #process(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
186      */

187     public final void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
188     throws IOException JavaDoc, ServletException JavaDoc {
189         process(request, response);
190     }
191     
192     /**
193      * Returns the service that corresponds to the specified Id.
194      *
195      * @param id The id of the service to return.
196      * @return The service corresponding to the specified Id.
197      */

198     private static Service getService(UserInstance userInstance, String JavaDoc id) {
199         Service service;
200         
201         service = services.get(id);
202         if (id == null) {
203             if (userInstance == null) {
204                 id = SERVICE_ID_NEW_INSTANCE;
205             } else {
206                 id = SERVICE_ID_DEFAULT;
207             }
208         } else {
209             if (userInstance == null) {
210                 id = SERVICE_ID_SESSION_EXPIRED;
211             }
212         }
213         
214         service = services.get(id);
215
216         if (service == null) {
217             if (SERVICE_ID_DEFAULT.equals(id)) {
218                 throw new RuntimeException JavaDoc("Service not registered: SERVICE_ID_DEFAULT");
219             } else if (SERVICE_ID_NEW_INSTANCE.equals(id)) {
220                 throw new RuntimeException JavaDoc("Service not registered: SERVICE_ID_NEW_INSTANCE");
221             } else if (SERVICE_ID_SESSION_EXPIRED.equals(id)) {
222                 throw new RuntimeException JavaDoc("Service not registered: SERVICE_ID_SESSION_EXPIRED");
223             }
224         }
225         
226         return service;
227     }
228     
229     /**
230      * Retrieves the global <code>ServiceRegistry</code>.
231      *
232      * @return The global <code>ServiceRegistry</code>.
233      */

234     public static ServiceRegistry getServiceRegistry() {
235         return services;
236     }
237     
238     /**
239      * Processes a HTTP request and generates a response.
240      *
241      * @param request the incoming <code>HttpServletRequest</code>
242      * @param response the outgoing <code>HttpServletResponse</code>
243      */

244     protected void process(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
245     throws IOException JavaDoc, ServletException JavaDoc {
246         Connection conn = null;
247         try {
248             conn = new Connection(this, request, response);
249             activeConnection.set(conn);
250             String JavaDoc serviceId = request.getParameter(SERVICE_ID_PARAMETER);
251             Service service = getService(conn.getUserInstance(), serviceId);
252             if (service == null) {
253                 throw new ServletException JavaDoc("Service id \"" + serviceId + "\" not registered.");
254             }
255             int version = service.getVersion();
256             
257             // Set caching directives.
258
if ((!DISABLE_CACHING) && version != Service.DO_NOT_CACHE) {
259                 // Setting all of the following (possibly with the exception of "Expires")
260
// are *absolutely critical* in order to ensure proper caching of resources
261
// with Internet Explorer 6. Without "Last-Modified", IE6 appears to not
262
// cache images properly resulting in an substantially greater than expected
263
// performance impact.
264
response.setHeader("Cache-Control", "max-age=3600");
265                 response.setDateHeader("Expires", System.currentTimeMillis() + (86400000));
266                 response.setDateHeader("Last-Modified", startupTime);
267             } else {
268                 response.setHeader("Pragma", "no-cache");
269                 response.setHeader("Cache-Control", "no-store");
270                 response.setHeader("Expires", "0");
271             }
272             
273             service.service(conn);
274             
275         } catch (ServletException JavaDoc ex) {
276             if (conn != null) {
277                 conn.disposeUserInstance();
278             }
279             throw(ex);
280         } catch (IOException JavaDoc ex) {
281             if (conn != null) {
282                 conn.disposeUserInstance();
283             }
284             throw(ex);
285         } catch (RuntimeException JavaDoc ex) {
286             if (conn != null) {
287                 conn.disposeUserInstance();
288             }
289             throw(ex);
290         } finally {
291             activeConnection.set(null);
292         }
293     }
294 }
295
Popular Tags