Clover coverage report - Code Coverage for tapestry release 4.0.2
Coverage timestamp: Thu Apr 13 2006 10:52:06 EDT
file stats: LOC: 323   Methods: 11
NCLOC: 142   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ApplicationServlet.java 50% 75% 81.8% 74.6%
coverage coverage
 1    // Copyright 2004, 2005 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.util.Locale;
 19   
 20    import javax.servlet.ServletConfig;
 21    import javax.servlet.ServletContext;
 22    import javax.servlet.ServletException;
 23    import javax.servlet.http.HttpServlet;
 24    import javax.servlet.http.HttpServletRequest;
 25    import javax.servlet.http.HttpServletResponse;
 26   
 27    import org.apache.commons.logging.Log;
 28    import org.apache.commons.logging.LogFactory;
 29    import org.apache.hivemind.ClassResolver;
 30    import org.apache.hivemind.ErrorHandler;
 31    import org.apache.hivemind.Registry;
 32    import org.apache.hivemind.Resource;
 33    import org.apache.hivemind.impl.DefaultClassResolver;
 34    import org.apache.hivemind.impl.RegistryBuilder;
 35    import org.apache.hivemind.impl.StrictErrorHandler;
 36    import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
 37    import org.apache.hivemind.util.ContextResource;
 38    import org.apache.tapestry.services.ApplicationInitializer;
 39    import org.apache.tapestry.services.ServletRequestServicer;
 40    import org.apache.tapestry.util.exception.ExceptionAnalyzer;
 41   
 42    /**
 43    * Links a servlet container with a Tapestry application. The servlet init parameter
 44    * <code>org.apache.tapestry.application-specification</code> should be set to the complete
 45    * resource path (within the classpath) to the application specification, i.e.,
 46    * <code>/com/foo/bar/MyApp.application</code>. As of release 4.0, this servlet will also create
 47    * a HiveMind Registry and manage it.
 48    *
 49    * @author Howard Lewis Ship
 50    * @see org.apache.tapestry.services.ApplicationInitializer
 51    * @see org.apache.tapestry.services.ServletRequestServicer
 52    */
 53   
 54    public class ApplicationServlet extends HttpServlet
 55    {
 56    private static final long serialVersionUID = -8046042689991538059L;
 57   
 58    /**
 59    * Prefix used to store the HiveMind Registry into the ServletContext. This string is suffixed
 60    * with the servlet name (in case multiple Tapestry applications are executing within a single
 61    * web application).
 62    *
 63    * @since 4.0
 64    */
 65   
 66    private static final String REGISTRY_KEY_PREFIX = "org.apache.tapestry.Registry:";
 67   
 68    private static final Log LOG = LogFactory.getLog(ApplicationServlet.class);
 69   
 70    /**
 71    * Invokes {@link #doService(HttpServletRequest, HttpServletResponse)}.
 72    *
 73    * @since 1.0.6
 74    */
 75   
 76  123 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,
 77    ServletException
 78    {
 79  123 doService(request, response);
 80    }
 81   
 82    /**
 83    * @since 2.3
 84    */
 85   
 86    private ClassResolver _resolver;
 87   
 88    /**
 89    * The key used to store the registry into the ServletContext.
 90    *
 91    * @since 4.0
 92    */
 93   
 94    private String _registryKey;
 95   
 96    /**
 97    * @since 4.0
 98    */
 99   
 100    private Registry _registry;
 101   
 102    /**
 103    * @since 4.0
 104    */
 105    private ServletRequestServicer _requestServicer;
 106   
 107    /**
 108    * Handles the GET and POST requests. Performs the following:
 109    * <ul>
 110    * <li>Construct a {@link RequestContext}
 111    * <li>Invoke {@link #getEngine(RequestContext)}to get or create the {@link IEngine}
 112    * <li>Invoke {@link IEngine#service(RequestContext)}on the application
 113    * </ul>
 114    */
 115   
 116  123 protected void doService(HttpServletRequest request, HttpServletResponse response)
 117    throws IOException, ServletException
 118    {
 119  123 try
 120    {
 121  123 _registry.setupThread();
 122   
 123  123 _requestServicer.service(request, response);
 124    }
 125    catch (ServletException ex)
 126    {
 127  0 log("ServletException", ex);
 128   
 129  0 show(ex);
 130   
 131    // Rethrow it.
 132   
 133  0 throw ex;
 134    }
 135    catch (IOException ex)
 136    {
 137  0 log("IOException", ex);
 138   
 139  0 show(ex);
 140   
 141    // Rethrow it.
 142   
 143  0 throw ex;
 144    }
 145    finally
 146    {
 147  123 _registry.cleanupThread();
 148    }
 149    }
 150   
 151  0 protected void show(Exception ex)
 152    {
 153  0 System.err.println("\n\n**********************************************************\n\n");
 154   
 155  0 new ExceptionAnalyzer().reportException(ex, System.err);
 156   
 157  0 System.err.println("\n**********************************************************\n");
 158   
 159    }
 160   
 161    /**
 162    * Invokes {@link #doService(HttpServletRequest, HttpServletResponse)}.
 163    */
 164   
 165  0 public void doPost(HttpServletRequest request, HttpServletResponse response)
 166    throws IOException, ServletException
 167    {
 168  0 doService(request, response);
 169    }
 170   
 171    /**
 172    * Reads the application specification when the servlet is first initialized. All
 173    * {@link IEngine engine instances}will have access to the specification via the servlet.
 174    *
 175    * @see #constructApplicationSpecification()
 176    * @see #createResourceResolver()
 177    */
 178   
 179  39 public void init(ServletConfig config) throws ServletException
 180    {
 181  39 String name = config.getServletName();
 182   
 183  39 _registryKey = REGISTRY_KEY_PREFIX + name;
 184   
 185  39 long startTime = System.currentTimeMillis();
 186  39 long elapsedToRegistry = 0;
 187   
 188  39 super.init(config);
 189   
 190  39 _resolver = createClassResolver();
 191   
 192  39 try
 193    {
 194  39 _registry = constructRegistry(config);
 195   
 196  39 elapsedToRegistry = System.currentTimeMillis() - startTime;
 197   
 198  39 initializeApplication();
 199   
 200  39 config.getServletContext().setAttribute(_registryKey, _registry);
 201    }
 202    catch (Exception ex)
 203    {
 204  0 show(ex);
 205   
 206  0 throw new ServletException(TapestryMessages.servletInitFailure(ex), ex);
 207    }
 208   
 209  39 long elapsedOverall = System.currentTimeMillis() - startTime;
 210   
 211  39 LOG.info(TapestryMessages.servletInit(name, elapsedToRegistry, elapsedOverall));
 212    }
 213   
 214    /**
 215    * Invoked from {@link #init(ServletConfig)}to create a resource resolver for the servlet
 216    * (which will utlimately be shared and used through the application).
 217    * <p>
 218    * This implementation constructs a {@link DefaultResourceResolver}, subclasses may provide a
 219    * different implementation.
 220    *
 221    * @see #getResourceResolver()
 222    * @since 2.3
 223    */
 224   
 225  39 protected ClassResolver createClassResolver()
 226    {
 227  39 return new DefaultClassResolver();
 228    }
 229   
 230    /**
 231    * Invoked from {@link #init(ServletConfig)}to construct the Registry to be used by the
 232    * application.
 233    * <p>
 234    * This looks in the standard places (on the classpath), but also in the WEB-INF/name and
 235    * WEB-INF folders (where name is the name of the servlet).
 236    *
 237    * @since 4.0
 238    */
 239  39 protected Registry constructRegistry(ServletConfig config)
 240    {
 241  39 ErrorHandler errorHandler = constructErrorHandler(config);
 242   
 243  39 RegistryBuilder builder = new RegistryBuilder(errorHandler);
 244   
 245  39 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(_resolver));
 246   
 247  39 String name = config.getServletName();
 248  39 ServletContext context = config.getServletContext();
 249   
 250  39 addModuleIfExists(builder, context, "/WEB-INF/" + name + "/hivemodule.xml");
 251  39 addModuleIfExists(builder, context, "/WEB-INF/hivemodule.xml");
 252   
 253  39 return builder.constructRegistry(Locale.getDefault());
 254    }
 255   
 256    /**
 257    * Invoked by {@link #constructRegistry(ServletConfig)} to create and return an
 258    * {@link ErrorHandler} instance to be used when constructing the Registry (and then to handle
 259    * any runtime exceptions). This implementation returns a new instance of
 260    * {@link org.apache.hivemind.impl.StrictErrorHandler}.
 261    *
 262    * @since 4.0
 263    */
 264  39 protected ErrorHandler constructErrorHandler(ServletConfig config)
 265    {
 266  39 return new StrictErrorHandler();
 267    }
 268   
 269    /**
 270    * Looks for a file in the servlet context; if it exists, it is expected to be a HiveMind module
 271    * descriptor, and is added to the builder.
 272    *
 273    * @since 4.0
 274    */
 275   
 276  78 protected void addModuleIfExists(RegistryBuilder builder, ServletContext context, String path)
 277    {
 278  78 Resource r = new ContextResource(context, path);
 279   
 280  78 if (r.getResourceURL() == null)
 281  78 return;
 282   
 283  0 builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(_resolver, r));
 284    }
 285   
 286    /**
 287    * Invoked from {@link #init(ServletConfig)}, after the registry has been constructed, to
 288    * bootstrap the application via the <code>tapestry.MasterApplicationInitializer</code>
 289    * service.
 290    *
 291    * @since 4.0
 292    */
 293  39 protected void initializeApplication()
 294    {
 295  39 ApplicationInitializer ai = (ApplicationInitializer) _registry.getService(
 296    "tapestry.init.MasterInitializer",
 297    ApplicationInitializer.class);
 298   
 299  39 ai.initialize(this);
 300   
 301  39 _registry.cleanupThread();
 302   
 303  39 _requestServicer = (ServletRequestServicer) _registry.getService(
 304    "tapestry.request.ServletRequestServicer",
 305    ServletRequestServicer.class);
 306    }
 307   
 308    /**
 309    * Shuts down the registry (if it exists).
 310    *
 311    * @since 4.0
 312    */
 313  39 public void destroy()
 314    {
 315  39 getServletContext().removeAttribute(_registryKey);
 316   
 317  39 if (_registry != null)
 318    {
 319  39 _registry.shutdown();
 320  39 _registry = null;
 321    }
 322    }
 323    }