1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.chain.web.javax;
18
19 import java.io.IOException;
20
21 import javax.servlet.ServletConfig;
22 import javax.servlet.ServletContext;
23 import javax.servlet.ServletException;
24 import javax.servlet.http.HttpServlet;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.apache.commons.chain.Catalog;
29 import org.apache.commons.chain.CatalogFactory;
30 import org.apache.commons.chain.config.ConfigParser;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35 * {@code Servlet} that automatically scans chain configuration files
36 * in the current web application at startup time, and exposes the result in a
37 * {@link Catalog} under a specified servlet context attribute. The following
38 * <em>servlet</em> init parameters are utilized:
39 * <ul>
40 * <li><strong>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</strong> -
41 * comma-delimited list of chain configuration resources to be loaded
42 * via {@code ClassLoader.getResource()} calls. If not specified,
43 * no class loader resources will be loaded.</li>
44 * <li><strong>org.apache.commons.chain.CONFIG_WEB_RESOURCE</strong> -
45 * comma-delimited list of chain configuration webapp resources
46 * to be loaded. If not specified, no web application resources
47 * will be loaded.</li>
48 * <li><strong>org.apache.commons.chain.CONFIG_ATTR</strong> -
49 * Name of the servlet context attribute under which the
50 * resulting {@link Catalog} will be created or updated.
51 * If not specified, it is expected that parsed resources will
52 * contain {@code <catalog>} elements (which will
53 * cause registration of the created {@link Catalog}s into
54 * the {@link CatalogFactory} for this application, and no
55 * servet context attribute will be created.
56 * <strong>NOTE</strong> - This parameter is deprecated.</li>
57 * <li><strong>org.apache.commons.chain.RULE_SET</strong> -
58 * Fully qualified class name of a Digester {@code RuleSet}
59 * implementation to use for parsing configuration resources (this
60 * class must have a public zero-args constructor). If not defined,
61 * the standard {@code RuleSet} implementation will be used.</li>
62 * </ul>
63 *
64 * <p>When a web application that has configured this servlet is
65 * started, it will acquire the {@link Catalog} under the specified servlet
66 * context attribute key, creating a new one if there is none already there.
67 * This {@link Catalog} will then be populated by scanning configuration
68 * resources from the following sources (loaded in this order):</p>
69 * <ul>
70 * <li>Resources loaded from specified resource paths from the
71 * webapp's class loader (via {@code ClassLoader.getResource()}).</li>
72 * <li>Resources loaded from specified resource paths in the web application
73 * archive (via {@code ServetContext.getResource()}).</li>
74 * </ul>
75 *
76 * <p>If no attribute key is specified, on the other hand, parsed configuration
77 * resources are expected to contain {@code <catalog>} elements,
78 * and the catalogs will be registered with the {@link CatalogFactory}
79 * for this web application.</p>
80 *
81 * <p>This class runs on Servlet 2.2 or later. If you are running on a
82 * Servlet 2.3 or later system, you should also consider using
83 * {@link ChainListener} to initialize your {@link Catalog}. Note that
84 * {@link ChainListener} uses parameters of the same names, but they are
85 * <em>context</em> init parameters instead of <em>servlet</em> init
86 * parameters. Because of this, you can use both facilities in the
87 * same application, if desired.</p>
88 *
89 * @author Matthew J. Sgarlata
90 * @author Craig R. McClanahan
91 * @author Ted Husted
92 */
93 public class ChainServlet extends HttpServlet {
94 private static final long serialVersionUID = 4833344945293509188L;
95
96 // ------------------------------------------------------ Manifest Constants
97
98 /**
99 * The name of the context init parameter containing the name of the
100 * servlet context attribute under which our resulting {@link Catalog}
101 * will be stored.
102 */
103 public static final String CONFIG_ATTR = ChainInit.CONFIG_ATTR;
104
105 /**
106 * The name of the context init parameter containing a comma-delimited
107 * list of class loader resources to be scanned.
108 */
109 public static final String CONFIG_CLASS_RESOURCE =
110 ChainInit.CONFIG_CLASS_RESOURCE;
111
112 /**
113 * The name of the context init parameter containing a comma-delimited
114 * list of web application resources to be scanned.
115 */
116 public static final String CONFIG_WEB_RESOURCE =
117 ChainInit.CONFIG_WEB_RESOURCE;
118
119 /**
120 * The name of the context init parameter containing the fully
121 * qualified class name of the {@code RuleSet} implementation
122 * for configuring our {@link ConfigParser}.
123 */
124 public static final String RULE_SET = ChainInit.RULE_SET;
125
126 // ------------------------------------------------------------ Constructors
127
128 /**
129 * The Default-Constructor for this class.
130 */
131 public ChainServlet() {
132 }
133
134 // --------------------------------------------------------- Servlet Methods
135
136 /**
137 * Clean up after ourselves as this application shuts down.
138 */
139 @Override
140 public void destroy() {
141 final ServletConfig config = getServletConfig();
142 final ServletContext context = getServletContext();
143 ChainInit.destroy(context, config.getInitParameter(CONFIG_ATTR));
144 }
145
146 /**
147 * Create (if necessary) and configure a {@link Catalog} from the
148 * servlet init parameters that have been specified.
149 *
150 * @throws ServletException if the servlet could not be initialized
151 */
152 @Override
153 public void init() throws ServletException {
154 final Logger logger = LoggerFactory.getLogger(ChainServlet.class);
155 final ServletConfig config = getServletConfig();
156 final ServletContext context = getServletContext();
157 logger.info("Initializing chain servlet '{}'", config.getServletName());
158
159 ChainInit.initialize(context, config.getInitParameter(CONFIG_ATTR), logger, false);
160 }
161
162 /**
163 * Does nothing; this servlet's only purpose is to initialize a Chain
164 * and store it in the servlet context.
165 *
166 * @param request the request issued by the client
167 * @param response the response to be returned to the cliengt
168 *
169 * @throws ServletException this exception is never thrown
170 * @throws IOException this exception is never thrown
171 */
172 @Override
173 public void service(HttpServletRequest request,
174 HttpServletResponse response)
175 throws ServletException, IOException {
176
177 // do nothing
178 }
179 }