View Javadoc

1   /*
2    * Copyright 2003-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.chain.web;
17  
18  
19  import java.io.IOException;
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  import org.apache.commons.chain.Catalog;
27  import org.apache.commons.chain.CatalogFactory;
28  import org.apache.commons.chain.config.ConfigParser;
29  import org.apache.commons.chain.impl.CatalogBase;
30  import org.apache.commons.digester.RuleSet;
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  
34  
35  /***
36   * <p><code>Servlet</code> that automatically scans chain configuration files
37   * in the current web application at startup time, and exposes the result in a
38   * {@link Catalog} under a specified servlet context attribute.  The following
39   * <em>servlet</em> init parameters are utilized:</p>
40   * <ul>
41   * <li><strong>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</strong> -
42   *     comma-delimited list of chain configuration resources to be loaded
43   *     via <code>ClassLoader.getResource()</code> calls.  If not specified,
44   *     no class loader resources will be loaded.</li>
45   * <li><strong>org.apache.commons.chain.CONFIG_WEB_RESOURCE</strong> -
46   *     comma-delimited list of chain configuration webapp resources
47   *     to be loaded.  If not specified, no web application resources
48   *     will be loaded.</li>
49   * <li><strong>org.apache.commons.chain.CONFIG_ATTR</strong> -
50   *     Name of the servlet context attribute under which the
51   *     resulting {@link Catalog} will be created or updated.
52   *     If not specified, it is expected that parsed resources will
53   *     contain <code>&lt;catalog&gt;</code> elements (which will
54   *     cause registration of the created {@link Catalog}s into
55   *     the {@link CatalogFactory} for this application, and no
56   *     servet context attribute will be created.
57   *     <strong>NOTE</strong> - This parameter is deprecated.</p>
58   * <li><strong>org.apache.commons.chain.RULE_SET</strong> -
59   *     Fully qualified class name of a Digester <code>RuleSet</code>
60   *     implementation to use for parsing configuration resources (this
61   *     class must have a public zero-args constructor).  If not defined,
62   *     the standard <code>RuleSet</code> implementation will be used.</li>
63   * </ul>
64   *
65   * <p>When a web application that has configured this servlet is
66   * started, it will acquire the {@link Catalog} under the specified servlet
67   * context attribute key, creating a new one if there is none already there.
68   * This {@link Catalog} will then be populated by scanning configuration
69   * resources from the following sources (loaded in this order):</p>
70   * <ul>
71   * <li>Resources loaded from specified resource paths from the
72   *     webapp's class loader (via <code>ClassLoader.getResource()</code>).</li>
73   * <li>Resources loaded from specified resource paths in the web application
74   *     archive (via <code>ServetContext.getResource()</code>).</li>
75   * </ul>
76   *
77   * <p>If no attribute key is specified, on the other hand, parsed configuration
78   * resources are expected to contain <code>&lt;catalog&gt;</code> elements,
79   * and the catalogs will be registered with the {@link CatalogFactory}
80   * for this web application.</p>
81   *
82   * <p>This class runs on Servlet 2.2 or later.  If you are running on a
83   * Servlet 2.3 or later system, you should also consider using
84   * {@link ChainListener} to initialize your {@link Catalog}.  Note that
85   * {@link ChainListener} uses parameters of the same names, but they are
86   * <em>context</em> init parameters instead of <em>servlet</em> init
87   * parameters. Because of this, you can use both facilities in the
88   * same application, if desired.</p>
89   *
90   * @author Matthew J. Sgarlata
91   * @author Craig R. McClanahan
92   * @author Ted Husted
93   */
94  
95  public class ChainServlet extends HttpServlet {
96  
97  
98      // ------------------------------------------------------ Manifest Constants
99  
100 
101     /***
102      * <p>The name of the context init parameter containing the name of the
103      * servlet context attribute under which our resulting {@link Catalog}
104      * will be stored.</p>
105      */
106     public static final String CONFIG_ATTR =
107         "org.apache.commons.chain.CONFIG_ATTR";
108 
109 
110     /***
111      * <p>The name of the context init parameter containing a comma-delimited
112      * list of class loader resources to be scanned.</p>
113      */
114     public static final String CONFIG_CLASS_RESOURCE =
115         "org.apache.commons.chain.CONFIG_CLASS_RESOURCE";
116 
117 
118     /***
119      * <p>The name of the context init parameter containing a comma-delimited
120      * list of web applicaton resources to be scanned.</p>
121      */
122     public static final String CONFIG_WEB_RESOURCE =
123         "org.apache.commons.chain.CONFIG_WEB_RESOURCE";
124 
125 
126     /***
127      * <p>The name of the context init parameter containing the fully
128      * qualified class name of the <code>RuleSet</code> implementation
129      * for configuring our {@link ConfigParser}.</p>
130      */
131     public static final String RULE_SET =
132         "org.apache.commons.chain.RULE_SET";
133 
134 
135     // --------------------------------------------------------- Servlet Methods
136 
137 
138     /***
139      * <p>Clean up after ourselves as this application shuts down.</p>
140      */
141     public void destroy() {
142 
143         ServletConfig config = getServletConfig();
144         ServletContext context = getServletContext();
145         String attr = config.getInitParameter(CONFIG_ATTR);
146         if (attr != null) {
147             context.removeAttribute(attr);
148         }
149         CatalogFactory.clear();
150 
151     }
152 
153 
154     /***
155      * <p>Create (if necessary) and configure a {@link Catalog} from the
156      * servlet init parameters that have been specified.</p>
157      *
158      * @throws ServletException if the servlet could not be initialized
159      */
160     public void init() throws ServletException {
161 
162         Log log = LogFactory.getLog(ChainServlet.class);
163         ServletConfig config = getServletConfig();
164         ServletContext context = getServletContext();
165         if (log.isInfoEnabled()) {
166             log.info("Initializing chain servlet '"
167                      + config.getServletName() + "'");
168         }
169 
170         // Retrieve servlet init parameters that we need
171         String attr = config.getInitParameter(CONFIG_ATTR);
172         String classResources =
173             context.getInitParameter(CONFIG_CLASS_RESOURCE);
174         String ruleSet = context.getInitParameter(RULE_SET);
175         String webResources = context.getInitParameter(CONFIG_WEB_RESOURCE);
176 
177         // Retrieve or create the Catalog instance we may be updating
178         Catalog catalog = null;
179         if (attr != null) {
180             catalog = (Catalog) context.getAttribute(attr);
181             if (catalog == null) {
182                 catalog = new CatalogBase();
183             }
184         }
185 
186         // Construct the configuration resource parser we will use
187         ConfigParser parser = new ConfigParser();
188         if (ruleSet != null) {
189             try {
190                 ClassLoader loader =
191                     Thread.currentThread().getContextClassLoader();
192                 if (loader == null) {
193                     loader = this.getClass().getClassLoader();
194                 }
195                 Class clazz = loader.loadClass(ruleSet);
196                 parser.setRuleSet((RuleSet) clazz.newInstance());
197             } catch (Exception e) {
198                 throw new ServletException("Exception initalizing RuleSet '"
199                                            + ruleSet + "' instance", e);
200             }
201         }
202 
203         // Parse the resources specified in our init parameters (if any)
204         if (attr == null) {
205             ChainResources.parseClassResources
206                 (classResources, parser);
207             ChainResources.parseWebResources
208                 (context, webResources, parser);
209         } else {
210             ChainResources.parseClassResources
211                 (catalog, classResources, parser);
212             ChainResources.parseWebResources
213                 (catalog, context, webResources, parser);
214         }
215 
216         // Expose the completed catalog (if requested)
217         if (attr != null) {
218             context.setAttribute(attr, catalog);
219         }
220 
221     }
222 
223 
224     /***
225      * <p>Does nothing; this servlet's only purpose is to initialize a Chain
226      * and store it in the servlet context.</p>
227      *
228      * @param request the request issued by the client
229      * @param response the response to be returned to the cliengt
230      *
231      * @throws javax.servlet.ServletException (this exception is never thrown)
232      * @throws java.io.IOException (this exception is never thrown)
233      */
234     public void service(HttpServletRequest request,
235                         HttpServletResponse response)
236         throws ServletException, IOException {
237 
238           // do nothing
239 
240     }
241 
242 
243 }