KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > servlet > AutoloadingHiveMindFilter


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 JavaDoc;
18 import java.util.Locale JavaDoc;
19
20 import javax.servlet.Filter JavaDoc;
21 import javax.servlet.FilterChain JavaDoc;
22 import javax.servlet.FilterConfig JavaDoc;
23 import javax.servlet.ServletContext JavaDoc;
24 import javax.servlet.ServletException JavaDoc;
25 import javax.servlet.ServletRequest JavaDoc;
26 import javax.servlet.ServletResponse JavaDoc;
27 import javax.servlet.http.HttpServletRequest JavaDoc;
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.Registry;
33 import org.apache.hivemind.impl.DefaultClassResolver;
34 import org.apache.hivemind.impl.RegistryBuilder;
35
36 /**
37  * Servlet filter that constructs the Registry at startup. It ensures that each request is properly
38  * terminated with a call to
39  * {@link org.apache.hivemind.service.ThreadEventNotifier#fireThreadCleanup()}. It also makes the
40  * Registry available during the request by storing it as a request attribute.
41  * Autodetects hivemind modules by calling {@link RegistryBuilder#autoDetectModules()}.
42  *
43  * Specializations can override the {@link #addWebInfDescriptor(ServletContext, ClassResolver, RegistryBuilder)} method.
44  * to add custom modules.
45  *
46  * @author Howard Lewis Ship
47  */

48 public class AutoloadingHiveMindFilter implements Filter JavaDoc
49 {
50     private static final Log LOG = LogFactory.getLog(AutoloadingHiveMindFilter.class);
51
52     /**
53      * Request attribute key that stores the Registry.
54      */

55
56     static final String JavaDoc REQUEST_KEY = "org.apache.hivemind.RequestRegistry";
57
58     static final String JavaDoc REBUILD_REQUEST_KEY = "org.apache.hivemind.RebuildRegistry";
59
60     private FilterConfig JavaDoc _filterConfig;
61
62     private Registry _registry;
63
64     /**
65      * Constructs a {@link Registry} and stores it into the <code>ServletContext</code>. Any
66      * exception throws is logged.
67      */

68     public void init(FilterConfig JavaDoc config) throws ServletException JavaDoc
69     {
70         _filterConfig = config;
71
72         initializeRegistry();
73
74     }
75
76     private void initializeRegistry()
77     {
78         long startTime = System.currentTimeMillis();
79
80         LOG.info(ServletMessages.filterInit());
81
82         try
83         {
84             _registry = constructRegistry(_filterConfig);
85
86             LOG.info(ServletMessages.constructedRegistry(_registry, System.currentTimeMillis()
87                     - startTime));
88         }
89         catch (Exception JavaDoc ex)
90         {
91             LOG.error(ex.getMessage(), ex);
92         }
93     }
94
95     /**
96      * Invoked from {@link #init(FilterConfig)} to actually construct the Registry. Subclasses may
97      * override if they have specific initialization needs, or have nonstandard rules for finding
98      * HiveMind module deployment descriptors.
99      */

100     protected Registry constructRegistry(FilterConfig JavaDoc config)
101     {
102         RegistryBuilder builder = new RegistryBuilder();
103
104         ClassResolver resolver = new DefaultClassResolver();
105
106         addDefaultModules(builder, resolver);
107
108         addWebInfDescriptor(config.getServletContext(), resolver, builder);
109
110         return builder.constructRegistry(getRegistryLocale());
111     }
112
113     /**
114      * Invoked from {@link #constructRegistry(FilterConfig)} to add an web specific
115      * application descriptor if one exists.
116      *
117      */

118     protected void addWebInfDescriptor(ServletContext JavaDoc context, ClassResolver resolver,
119             RegistryBuilder builder)
120     {
121     }
122
123     /**
124      * Returns the default Locale. Subclasses may override to select a particular locale for the
125      * Registry.
126      */

127     protected Locale JavaDoc getRegistryLocale()
128     {
129         return Locale.getDefault();
130     }
131
132     protected void addDefaultModules(RegistryBuilder builder, ClassResolver resolver)
133     {
134         builder.autoDetectModules();
135     }
136
137     /**
138      * Passes the request to the filter chain, but then invokes {@link Registry#cleanupThread()}
139      * &nbsp; (from a finally block).
140      */

141     public void doFilter(ServletRequest JavaDoc request, ServletResponse JavaDoc response, FilterChain JavaDoc chain)
142             throws IOException JavaDoc, ServletException JavaDoc
143     {
144         try
145         {
146             // I believe the _registry will only be null in a couple of test situations.
147

148             if (_registry != null)
149                 _registry.setupThread();
150
151             request.setAttribute(REQUEST_KEY, _registry);
152
153             chain.doFilter(request, response);
154         }
155         finally
156         {
157             cleanupThread();
158
159             checkRegistryRebuild(request);
160         }
161     }
162
163     private synchronized void checkRegistryRebuild(ServletRequest JavaDoc request)
164     {
165         if (request.getAttribute(REBUILD_REQUEST_KEY) == null)
166             return;
167
168         Registry oldRegistry = _registry;
169
170         // Replace the old Registry with a new one. All other threads, but this
171
// one, will begin using the new Registry. Hopefully, we didn't get
172
// rebuild requests on multiple threads.
173

174         initializeRegistry();
175
176         // Shutdown the old Registry. Perhaps we should sleep for a moment, first,
177
// to help ensure that other threads have "cleared out". If not, we'll see some
178
// instability at the instant we shutdown (i.e., all the proxies will get disabled).
179
// Alternately, we should create a WeakReference based monitor that shuts down the
180
// old registry when it is no longer used by any other threads. For the moment,
181
// this functionality is limited to development-time only (not production), so it isn't
182
// urgent.
183

184         oldRegistry.shutdown();
185     }
186
187     /**
188      * Cleanup the thread, ignoring any exceptions that may be thrown.
189      */

190     private void cleanupThread()
191     {
192         try
193         {
194             _registry.cleanupThread();
195         }
196         catch (Exception JavaDoc ex)
197         {
198             LOG.error(ServletMessages.filterCleanupError(ex), ex);
199         }
200     }
201
202     /**
203      * Invokes {@link Registry#shutdown()}.
204      */

205     public void destroy()
206     {
207         if (_registry != null)
208             _registry.shutdown();
209
210         _filterConfig = null;
211     }
212
213     /**
214      * Returns the {@link Registry} that was stored as a request attribute inside method
215      * {@link #doFilter(ServletRequest, ServletResponse, FilterChain)}.
216      */

217     public static Registry getRegistry(HttpServletRequest JavaDoc request)
218     {
219         return (Registry) request.getAttribute(REQUEST_KEY);
220     }
221
222     /**
223      * Sets a flag in the request that will cause the current Registry to be shutdown and replaced
224      * with a new Registry (at the end of the current request).
225      */

226     public static void rebuildRegistry(HttpServletRequest JavaDoc request)
227     {
228         request.setAttribute(REBUILD_REQUEST_KEY, Boolean.TRUE);
229     }
230
231 }
Popular Tags