Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/tapestry/ApplicationServlet.java


1   /* $$ Clover has instrumented this file $$ */// Copyright 2004 The Apache Software Foundation
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package org.apache.tapestry;
16  
17  import java.io.IOException;
18  import java.io.InputStream;
19  import java.util.Locale;
20  
21  import javax.servlet.ServletConfig;
22  import javax.servlet.ServletException;
23  import javax.servlet.http.Cookie;
24  import javax.servlet.http.HttpServlet;
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hivemind.ClassResolver;
31  import org.apache.hivemind.Registry;
32  import org.apache.hivemind.impl.DefaultClassResolver;
33  import org.apache.hivemind.impl.RegistryBuilder;
34  import org.apache.tapestry.request.RequestContext;
35  import org.apache.tapestry.services.ApplicationGlobals;
36  import org.apache.tapestry.services.ApplicationInitializer;
37  import org.apache.tapestry.services.RequestServicer;
38  import org.apache.tapestry.spec.IApplicationSpecification;
39  import org.apache.tapestry.util.exception.ExceptionAnalyzer;
40  
41  /**
42   *  Links a servlet container with a Tapestry application.  The servlet has some
43   *  responsibilities related to bootstrapping the application (in terms of
44   *  logging, reading the {@link ApplicationSpecification specification}, etc.).
45   *  It is also responsible for creating or locating the {@link IEngine} and delegating
46   *  incoming requests to it.
47   * 
48   *  <p>The servlet init parameter
49   *  <code>org.apache.tapestry.specification-path</code>
50   *  should be set to the complete resource path (within the classpath)
51   *  to the application specification, i.e.,
52   *  <code>/com/foo/bar/MyApp.application</code>. 
53   *
54   *  <p>In some servlet containers (notably
55   *  <a href="www.bea.com"/>WebLogic</a>)
56   *  it is necessary to invoke {@link HttpSession#setAttribute(String,Object)}
57   *  in order to force a persistent value to be replicated to the other
58   *  servers in the cluster.  Tapestry applications usually only have a single
59   *  persistent value, the {@link IEngine engine}.  For persistence to
60   *  work in such an environment, the
61   *  JVM system property <code>org.apache.tapestry.store-engine</code>
62   *  must be set to <code>true</code>.  This will force the application
63   *  servlet to restore the engine into the {@link HttpSession} at the
64   *  end of each request cycle.
65   * 
66   *  <p>As of release 1.0.1, it is no longer necessary for a {@link HttpSession}
67   *  to be created on the first request cycle.  Instead, the HttpSession is created
68   *  as needed by the {@link IEngine} ... that is, when a visit object is created,
69   *  or when persistent page state is required.  Otherwise, for sessionless requests,
70   *  an {@link IEngine} from a {@link Pool} is used.  Additional work must be done
71   *  so that the {@link IEngine} can change locale <em>without</em> forcing 
72   *  the creation of a session; this involves the servlet and the engine storing
73   *  locale information in a {@link Cookie}.
74   * 
75   * <p>
76   * As of release 3.1, this servlet will also create a HiveMind Registry and manage it.
77   * 
78   *  @author Howard Lewis Ship
79   * 
80   */
81  
82  public class ApplicationServlet extends HttpServlet
83  {public static com.cortexeb.tools.clover.d __CLOVER_3_0 = com.cortexeb.tools.clover.aq.getRecorder(new char[] {67,58,92,119,111,114,107,115,112,97,99,101,92,106,97,107,97,114,116,97,45,116,97,112,101,115,116,114,121,92,102,114,97,109,101,119,111,114,107,92,116,97,114,103,101,116,92,99,108,111,118,101,114,45,100,98},1096998272901L);
84      private static final Log LOG = LogFactory.getLog(ApplicationServlet.class);
85  
86      /**
87       *  Name of the cookie written to the client web browser to
88       *  identify the locale.
89       *
90       */
91  
92      public static final String LOCALE_COOKIE_NAME = "org.apache.tapestry.locale";
93  
94      /**
95       *  The application specification, which is read once and kept in memory
96       *  thereafter.
97       *
98       */
99  
100     private IApplicationSpecification _specification;
101 
102     /**
103      *  Invokes {@link #doService(HttpServletRequest, HttpServletResponse)}.
104      *
105      *  @since 1.0.6
106      *
107      */
108 
109     public void doGet(HttpServletRequest request, HttpServletResponse response)
110         throws IOException, ServletException
111     {try { __CLOVER_3_0.M[129]++;
112         __CLOVER_3_0.S[468]++;doService(request, response);
113     } finally { }}
114 
115     /**
116      *  @since 2.3
117      * 
118      */
119 
120     private ClassResolver _resolver;
121 
122     /**
123      * @since 3.1
124      */
125 
126     private Registry _registry;
127 
128   /**
129    * @since 3.1
130    */
131     private RequestServicer _requestServicer;
132 
133     /**
134      * Handles the GET and POST requests. Performs the following:
135      * <ul>
136      * <li>Construct a {@link RequestContext}
137      * <li>Invoke {@link #getEngine(RequestContext)} to get or create the {@link IEngine}
138      * <li>Invoke {@link IEngine#service(RequestContext)} on the application
139      * </ul>
140      */
141 
142     protected void doService(HttpServletRequest request, HttpServletResponse response)
143         throws IOException, ServletException
144     {try { __CLOVER_3_0.M[130]++;
145         __CLOVER_3_0.S[469]++;try
146         {
147             __CLOVER_3_0.S[470]++;_requestServicer.service(request, response);
148         }
149         catch (ServletException ex)
150         {
151             __CLOVER_3_0.S[471]++;log("ServletException", ex);
152 
153             __CLOVER_3_0.S[472]++;show(ex);
154 
155             // Rethrow it.
156 
157             __CLOVER_3_0.S[473]++;throw ex;
158         }
159         catch (IOException ex)
160         {
161             __CLOVER_3_0.S[474]++;log("IOException", ex);
162 
163             __CLOVER_3_0.S[475]++;show(ex);
164 
165             // Rethrow it.
166 
167             __CLOVER_3_0.S[476]++;throw ex;
168         }
169     } finally { }}
170 
171     protected void show(Exception ex)
172     {try { __CLOVER_3_0.M[131]++;
173         __CLOVER_3_0.S[477]++;System.err.println("\n\n**********************************************************\n\n");
174 
175         __CLOVER_3_0.S[478]++;new ExceptionAnalyzer().reportException(ex, System.err);
176 
177         __CLOVER_3_0.S[479]++;System.err.println("\n**********************************************************\n");
178 
179     } finally { }}
180 
181     /**
182      *  Invokes {@link #doService(HttpServletRequest, HttpServletResponse)}.
183      *
184      *
185      */
186 
187     public void doPost(HttpServletRequest request, HttpServletResponse response)
188         throws IOException, ServletException
189     {try { __CLOVER_3_0.M[132]++;
190         __CLOVER_3_0.S[480]++;doService(request, response);
191     } finally { }}
192 
193     /**
194      *  Returns the application specification, which is read
195      *  by the {@link #init(ServletConfig)} method.
196      *
197      *  @deprecated Use {@link RequestContext#getApplicationSpecification()} instead.
198      */
199 
200     public IApplicationSpecification getApplicationSpecification()
201     {try { __CLOVER_3_0.M[133]++;
202         __CLOVER_3_0.S[481]++;return _specification;
203     } finally { }}
204 
205     /**
206      *  Reads the application specification when the servlet is
207      *  first initialized.  All {@link IEngine engine instances}
208      *  will have access to the specification via the servlet.
209      * 
210      *  @see #getApplicationSpecification()
211      *  @see #constructApplicationSpecification()
212      *  @see #createResourceResolver()
213      *
214      */
215 
216     public void init(ServletConfig config) throws ServletException
217     {try { __CLOVER_3_0.M[134]++;
218         __CLOVER_3_0.S[482]++;super.init(config);
219 
220         __CLOVER_3_0.S[483]++;_resolver = createClassResolver();
221 
222         __CLOVER_3_0.S[484]++;try
223         {
224 
225             __CLOVER_3_0.S[485]++;constructRegistry();
226 
227             __CLOVER_3_0.S[486]++;initializeApplication();
228         }
229         catch (Exception ex)
230         {
231             __CLOVER_3_0.S[487]++;show(ex);
232 
233             __CLOVER_3_0.S[488]++;throw new ServletException(TapestryMessages.servletInitFailure(ex), ex);
234         }
235     } finally { }}
236 
237     /**
238      *  Invoked from {@link #init(ServletConfig)} to create a resource resolver
239      *  for the servlet (which will utlimately be shared and used through the
240      *  application).
241      * 
242      *  <p>This implementation constructs a {@link DefaultResourceResolver}, subclasses
243      *  may provide a different implementation.
244      * 
245      *  @see #getResourceResolver()
246      *  @since 2.3
247      * 
248      */
249 
250     protected ClassResolver createClassResolver() throws ServletException
251     {try { __CLOVER_3_0.M[135]++;
252         __CLOVER_3_0.S[489]++;return new DefaultClassResolver();
253     } finally { }}
254 
255     /**
256      *  Closes the stream, ignoring any exceptions.
257      * 
258      */
259 
260     protected void close(InputStream stream)
261     {try { __CLOVER_3_0.M[136]++;
262         __CLOVER_3_0.S[490]++;try
263         {
264             __CLOVER_3_0.S[491]++;if ((((stream != null) && (++__CLOVER_3_0.CT[105] != 0)) || (++__CLOVER_3_0.CF[105] == 0))){
265                 __CLOVER_3_0.S[492]++;stream.close();}
266         }
267         catch (IOException ex)
268         {
269             // Ignore it.
270         }
271     } finally { }}
272 
273 
274 
275     /**
276      *  Invoked from the {@link IEngine engine}, just prior to starting to
277      *  render a response, when the locale has changed.  The servlet writes a
278      *  {@link Cookie} so that, on subsequent request cycles, an engine localized
279      *  to the selected locale is chosen.
280      *
281      *  <p>At this time, the cookie is <em>not</em> persistent.  That may
282      *  change in subsequent releases.
283      *
284      *  @since 1.0.1
285      */
286 
287     public static void writeLocaleCookie(Locale locale, IEngine engine, RequestContext cycle)
288     {try { __CLOVER_3_0.M[137]++;
289         __CLOVER_3_0.S[493]++;if ((((LOG.isDebugEnabled()) && (++__CLOVER_3_0.CT[106] != 0)) || (++__CLOVER_3_0.CF[106] == 0))){
290             __CLOVER_3_0.S[494]++;LOG.debug("Writing locale cookie " + locale);}
291 
292         __CLOVER_3_0.S[495]++;Cookie cookie = new Cookie(LOCALE_COOKIE_NAME, locale.toString());
293         __CLOVER_3_0.S[496]++;cookie.setPath(engine.getServletPath());
294 
295         __CLOVER_3_0.S[497]++;cycle.addCookie(cookie);
296     } finally { }}
297 
298     /**
299      *  Returns a resource resolver that can access classes and resources related
300      *  to the current web application context.  Relies on
301      *  {@link java.lang.Thread#getContextClassLoader()}, which is set by
302      *  most modern servlet containers.
303      * 
304      *  @since 2.3
305      *
306      */
307 
308     public ClassResolver getClassResolver()
309     {try { __CLOVER_3_0.M[138]++;
310         __CLOVER_3_0.S[498]++;return _resolver;
311     } finally { }}
312 
313     /**
314      * Invoked from {@link #init(ServletConfig)} to construct the Registry to
315      * be used by the application.
316      * 
317      * @since 3.1
318      */
319     protected void constructRegistry()
320     {try { __CLOVER_3_0.M[139]++;
321         // This will expand in the future.
322 
323         __CLOVER_3_0.S[499]++;_registry = RegistryBuilder.constructDefaultRegistry();
324     } finally { }}
325 
326     /**
327      * Invoked from {@link #init(ServletConfig)}, after the registry has
328      * been constructed, to bootstrap the application via the
329      * <code>tapestry.MasterApplicationInitializer</code> service.
330      */
331     protected void initializeApplication()
332     {try { __CLOVER_3_0.M[140]++;
333         __CLOVER_3_0.S[500]++;ApplicationInitializer ai =
334             (ApplicationInitializer) _registry.getService(
335                 "tapestry.init.MasterInitializer",
336                 ApplicationInitializer.class);
337 
338         __CLOVER_3_0.S[501]++;ai.initialize(this);
339 
340         __CLOVER_3_0.S[502]++;_registry.cleanupThread();
341 
342         // This is temporary, since most of the code still gets the
343         // specification from the servlet --- in fact, has to downcase
344         // RequestContext.getServlet() to do so.
345 
346         __CLOVER_3_0.S[503]++;ApplicationGlobals ag =
347             (ApplicationGlobals) _registry.getService(
348                 "tapestry.globals.ApplicationGlobals",
349                 ApplicationGlobals.class);
350 
351         __CLOVER_3_0.S[504]++;_specification = ag.getSpecification();
352 
353         __CLOVER_3_0.S[505]++;_requestServicer =
354             (RequestServicer) _registry.getService(
355                 "tapestry.request.RequestServicerPipeline",
356                 RequestServicer.class);
357     } finally { }}
358 
359     /**
360      * Returns the Registry used by the application.
361      * 
362      * @since 3.1
363      */
364     public Registry getRegistry()
365     {try { __CLOVER_3_0.M[141]++;
366         __CLOVER_3_0.S[506]++;return _registry;
367     } finally { }}
368 
369     /**
370      * Shuts down the registry (if it exists).
371      * 
372      * @since 3.1
373      */
374     public void destroy()
375     {try { __CLOVER_3_0.M[142]++;
376         __CLOVER_3_0.S[507]++;if ((((_registry != null) && (++__CLOVER_3_0.CT[107] != 0)) || (++__CLOVER_3_0.CF[107] == 0))){
377         {
378             __CLOVER_3_0.S[508]++;_registry.shutdown();
379             __CLOVER_3_0.S[509]++;_registry = null;
380         }}
381     } finally { }}
382 
383 }