001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.chain.web.jakarta; 018 019import java.io.IOException; 020 021import org.apache.commons.chain.Catalog; 022import org.apache.commons.chain.CatalogFactory; 023import org.apache.commons.chain.config.ConfigParser; 024import org.slf4j.Logger; 025import org.slf4j.LoggerFactory; 026 027import jakarta.servlet.ServletConfig; 028import jakarta.servlet.ServletContext; 029import jakarta.servlet.ServletException; 030import jakarta.servlet.http.HttpServlet; 031import jakarta.servlet.http.HttpServletRequest; 032import jakarta.servlet.http.HttpServletResponse; 033 034/** 035 * {@code Servlet} that automatically scans chain configuration files 036 * in the current web application at startup time, and exposes the result in a 037 * {@link Catalog} under a specified servlet context attribute. The following 038 * <em>servlet</em> init parameters are utilized: 039 * <ul> 040 * <li><strong>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</strong> - 041 * comma-delimited list of chain configuration resources to be loaded 042 * via {@code ClassLoader.getResource()} calls. If not specified, 043 * no class loader resources will be loaded.</li> 044 * <li><strong>org.apache.commons.chain.CONFIG_WEB_RESOURCE</strong> - 045 * comma-delimited list of chain configuration webapp resources 046 * to be loaded. If not specified, no web application resources 047 * will be loaded.</li> 048 * <li><strong>org.apache.commons.chain.CONFIG_ATTR</strong> - 049 * Name of the servlet context attribute under which the 050 * resulting {@link Catalog} will be created or updated. 051 * If not specified, it is expected that parsed resources will 052 * contain {@code <catalog>} elements (which will 053 * cause registration of the created {@link Catalog}s into 054 * the {@link CatalogFactory} for this application, and no 055 * servet context attribute will be created. 056 * <strong>NOTE</strong> - This parameter is deprecated.</li> 057 * <li><strong>org.apache.commons.chain.RULE_SET</strong> - 058 * Fully qualified class name of a Digester {@code RuleSet} 059 * implementation to use for parsing configuration resources (this 060 * class must have a public zero-args constructor). If not defined, 061 * the standard {@code RuleSet} implementation will be used.</li> 062 * </ul> 063 * 064 * <p>When a web application that has configured this servlet is 065 * started, it will acquire the {@link Catalog} under the specified servlet 066 * context attribute key, creating a new one if there is none already there. 067 * This {@link Catalog} will then be populated by scanning configuration 068 * resources from the following sources (loaded in this order):</p> 069 * <ul> 070 * <li>Resources loaded from specified resource paths from the 071 * webapp's class loader (via {@code ClassLoader.getResource()}).</li> 072 * <li>Resources loaded from specified resource paths in the web application 073 * archive (via {@code ServetContext.getResource()}).</li> 074 * </ul> 075 * 076 * <p>If no attribute key is specified, on the other hand, parsed configuration 077 * resources are expected to contain {@code <catalog>} elements, 078 * and the catalogs will be registered with the {@link CatalogFactory} 079 * for this web application.</p> 080 * 081 * <p>This class runs on Servlet 2.2 or later. If you are running on a 082 * Servlet 2.3 or later system, you should also consider using 083 * {@link ChainListener} to initialize your {@link Catalog}. Note that 084 * {@link ChainListener} uses parameters of the same names, but they are 085 * <em>context</em> init parameters instead of <em>servlet</em> init 086 * parameters. Because of this, you can use both facilities in the 087 * same application, if desired.</p> 088 * 089 * @author Matthew J. Sgarlata 090 * @author Craig R. McClanahan 091 * @author Ted Husted 092 */ 093public class ChainServlet extends HttpServlet { 094 private static final long serialVersionUID = 4833344945293509188L; 095 096 // ------------------------------------------------------ Manifest Constants 097 098 /** 099 * 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}