1
2
3
4
5
6
7
8
9
10
11
12
13
14
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><catalog></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><catalog></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
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
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
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
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
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
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
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
239
240 }
241
242
243 }