Clover coverage report - Code Coverage for hivemind release 1.1
Coverage timestamp: Tue Oct 25 2005 10:47:07 EDT
file stats: LOC: 250   Methods: 12
NCLOC: 123   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
HiveMindFilter.java 100% 100% 100% 100%
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.hivemind.servlet;
 16   
 17    import java.io.IOException;
 18    import java.util.Locale;
 19   
 20    import javax.servlet.Filter;
 21    import javax.servlet.FilterChain;
 22    import javax.servlet.FilterConfig;
 23    import javax.servlet.ServletContext;
 24    import javax.servlet.ServletException;
 25    import javax.servlet.ServletRequest;
 26    import javax.servlet.ServletResponse;
 27    import javax.servlet.http.HttpServletRequest;
 28   
 29    import org.apache.commons.logging.Log;
 30    import org.apache.commons.logging.LogFactory;
 31    import org.apache.hivemind.ClassResolver;
 32    import org.apache.hivemind.ModuleDescriptorProvider;
 33    import org.apache.hivemind.Registry;
 34    import org.apache.hivemind.impl.DefaultClassResolver;
 35    import org.apache.hivemind.impl.RegistryBuilder;
 36    import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
 37    import org.apache.hivemind.util.ContextResource;
 38   
 39    /**
 40    * Servlet filter that constructs the Registry at startup. It ensures that each request is properly
 41    * terminated with a call to
 42    * {@link org.apache.hivemind.service.ThreadEventNotifier#fireThreadCleanup()}. It also makes the
 43    * Registry available during the request by storing it as a request attribute.
 44    *
 45    * @author Howard Lewis Ship
 46    */
 47    public class HiveMindFilter implements Filter
 48    {
 49    private static final Log LOG = LogFactory.getLog(HiveMindFilter.class);
 50   
 51    /**
 52    * Request attribute key that stores the Registry.
 53    */
 54   
 55    static final String REQUEST_KEY = "org.apache.hivemind.RequestRegistry";
 56   
 57    static final String REBUILD_REQUEST_KEY = "org.apache.hivemind.RebuildRegistry";
 58   
 59    /** @since 1.1 */
 60    static final String HIVE_MODULE_XML = "/WEB-INF/hivemodule.xml";
 61   
 62    private FilterConfig _filterConfig;
 63   
 64    private Registry _registry;
 65   
 66    /**
 67    * Constructs a {@link Registry} and stores it into the <code>ServletContext</code>. Any
 68    * exception throws is logged.
 69    */
 70  4 public void init(FilterConfig config) throws ServletException
 71    {
 72  4 _filterConfig = config;
 73   
 74  4 initializeRegistry();
 75   
 76    }
 77   
 78  5 private void initializeRegistry()
 79    {
 80  5 long startTime = System.currentTimeMillis();
 81   
 82  5 LOG.info(ServletMessages.filterInit());
 83   
 84  5 try
 85    {
 86  5 _registry = constructRegistry(_filterConfig);
 87   
 88  4 LOG.info(ServletMessages.constructedRegistry(_registry, System.currentTimeMillis()
 89    - startTime));
 90    }
 91    catch (Exception ex)
 92    {
 93  1 LOG.error(ex.getMessage(), ex);
 94    }
 95    }
 96   
 97    /**
 98    * Invoked from {@link #init(FilterConfig)} to actually construct the Registry. Subclasses may
 99    * override if they have specific initialization needs, or have nonstandard rules for finding
 100    * HiveMind module deployment descriptors.
 101    */
 102  4 protected Registry constructRegistry(FilterConfig config)
 103    {
 104  4 RegistryBuilder builder = new RegistryBuilder();
 105   
 106  4 ClassResolver resolver = new DefaultClassResolver();
 107   
 108  4 builder.addModuleDescriptorProvider(getModuleDescriptorProvider(resolver));
 109   
 110  4 addWebInfDescriptor(config.getServletContext(), resolver, builder);
 111   
 112  4 return builder.constructRegistry(getRegistryLocale());
 113    }
 114   
 115    /**
 116    * Invoked from {@link #constructRegistry(FilterConfig)} to add WEB-INF/hivemodule.xml to
 117    * the registry, if it exists.
 118    *
 119    * @since 1.1
 120    */
 121   
 122  4 protected void addWebInfDescriptor(ServletContext context, ClassResolver resolver,
 123    RegistryBuilder builder)
 124    {
 125  4 ContextResource r = new ContextResource(context, HIVE_MODULE_XML);
 126   
 127  4 if (r.getResourceURL() != null)
 128    {
 129  1 ModuleDescriptorProvider provider = new XmlModuleDescriptorProvider(resolver, r);
 130   
 131  1 builder.addModuleDescriptorProvider(provider);
 132    }
 133    }
 134   
 135    /**
 136    * Returns the default Locale. Subclasses may override to select a particular locale for the
 137    * Registry.
 138    */
 139  4 protected Locale getRegistryLocale()
 140    {
 141  4 return Locale.getDefault();
 142    }
 143   
 144    /**
 145    * Returns the {@link ModuleDescriptorProvider} to be used to construct the Registry. This
 146    * implementation returns the default {@link XmlModuleDescriptorProvider}. May be overridden by
 147    * subclasses.
 148    *
 149    * @since 1.1
 150    */
 151  4 protected ModuleDescriptorProvider getModuleDescriptorProvider(ClassResolver resolver)
 152    {
 153  4 return new XmlModuleDescriptorProvider(resolver);
 154    }
 155   
 156    /**
 157    * Passes the request to the filter chain, but then invokes {@link Registry#cleanupThread()}
 158    * &nbsp; (from a finally block).
 159    */
 160  4 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
 161    throws IOException, ServletException
 162    {
 163  4 try
 164    {
 165    // I believe the _registry will only be null in a couple of test situations.
 166   
 167  4 if (_registry != null)
 168  2 _registry.setupThread();
 169   
 170  4 request.setAttribute(REQUEST_KEY, _registry);
 171   
 172  4 chain.doFilter(request, response);
 173    }
 174    finally
 175    {
 176  4 cleanupThread();
 177   
 178  4 checkRegistryRebuild(request);
 179    }
 180    }
 181   
 182  4 private synchronized void checkRegistryRebuild(ServletRequest request)
 183    {
 184  4 if (request.getAttribute(REBUILD_REQUEST_KEY) == null)
 185  3 return;
 186   
 187  1 Registry oldRegistry = _registry;
 188   
 189    // Replace the old Registry with a new one. All other threads, but this
 190    // one, will begin using the new Registry. Hopefully, we didn't get
 191    // rebuild requests on multiple threads.
 192   
 193  1 initializeRegistry();
 194   
 195    // Shutdown the old Registry. Perhaps we should sleep for a moment, first,
 196    // to help ensure that other threads have "cleared out". If not, we'll see some
 197    // instability at the instant we shutdown (i.e., all the proxies will get disabled).
 198    // Alternately, we should create a WeakReference based monitor that shuts down the
 199    // old registry when it is no longer used by any other threads. For the moment,
 200    // this functionality is limited to development-time only (not production), so it isn't
 201    // urgent.
 202   
 203  1 oldRegistry.shutdown();
 204    }
 205   
 206    /**
 207    * Cleanup the thread, ignoring any exceptions that may be thrown.
 208    */
 209  4 private void cleanupThread()
 210    {
 211  4 try
 212    {
 213  4 _registry.cleanupThread();
 214    }
 215    catch (Exception ex)
 216    {
 217  2 LOG.error(ServletMessages.filterCleanupError(ex), ex);
 218    }
 219    }
 220   
 221    /**
 222    * Invokes {@link Registry#shutdown()}.
 223    */
 224  3 public void destroy()
 225    {
 226  3 if (_registry != null)
 227  1 _registry.shutdown();
 228   
 229  3 _filterConfig = null;
 230    }
 231   
 232    /**
 233    * Returns the {@link Registry} that was stored as a request attribute inside method
 234    * {@link #doFilter(ServletRequest, ServletResponse, FilterChain)}.
 235    */
 236  1 public static Registry getRegistry(HttpServletRequest request)
 237    {
 238  1 return (Registry) request.getAttribute(REQUEST_KEY);
 239    }
 240   
 241    /**
 242    * Sets a flag in the request that will cause the current Registry to be shutdown and replaced
 243    * with a new Registry (at the end of the current request).
 244    */
 245  1 public static void rebuildRegistry(HttpServletRequest request)
 246    {
 247  1 request.setAttribute(REBUILD_REQUEST_KEY, Boolean.TRUE);
 248    }
 249   
 250    }