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