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.jakarta.servlet; 18 19 import java.io.IOException; 20 21 import org.apache.commons.chain.Catalog; 22 import org.apache.commons.chain.CatalogFactory; 23 import org.apache.commons.chain.Command; 24 import org.apache.commons.chain.web.jakarta.ChainServlet; 25 26 import jakarta.servlet.ServletException; 27 import jakarta.servlet.http.HttpServletRequest; 28 import jakarta.servlet.http.HttpServletResponse; 29 30 /** 31 * Custom subclass of {@link ChainServlet} that also dispatches incoming 32 * requests to a configurable {@link Command} loaded from the specified 33 * {@link Catalog}. 34 * 35 * <p>In addition to the <em>servlet</em> init parameters supported by 36 * {@link ChainServlet}, this class supports the following additional 37 * parameters:</p> 38 * <ul> 39 * <li><strong>org.apache.commons.chain.CATALOG</strong> - Name of the 40 * catalog from which to acquire commands to be executed. If not 41 * specified, the default catalog for this application will be used.</li> 42 * <li><strong>org.apache.commons.chain.COMMAND</strong> - Name of the 43 * {@link Command} (looked up in our configured {@link Catalog} used 44 * to process all incoming servlet requests. If not specified, 45 * defaults to {@code command}.</li> 46 * </ul> 47 * 48 * <p>Also, the {@code org.apache.commons.chain.CONFIG_ATTR} 49 * init parameter is also used to identify the 50 * {@link org.apache.commons.chain.Context} attribute under 51 * which our configured {@link Catalog} will be made available to 52 * {@link Command}s processing our requests, in addition to its definition 53 * of the {@code ServletContext} attribute key under which the 54 * {@link Catalog} is available.</p> 55 */ 56 57 public class ChainProcessor extends ChainServlet { 58 private static final long serialVersionUID = -6817532768031279260L; 59 60 // ------------------------------------------------------ Manifest Constants 61 62 /** 63 * The name of the servlet init parameter containing the name of the 64 * {@link Catalog} to use for processing incoming requests. 65 */ 66 public static final String CATALOG = 67 "org.apache.commons.chain.CATALOG"; 68 69 /** 70 * The default request attribute under which we expose the 71 * {@link Catalog} being used to subordinate {@link Command}s. 72 */ 73 public static final String CATALOG_DEFAULT = 74 "org.apache.commons.chain.CATALOG"; 75 76 /** 77 * The name of the servlet init parameter containing the name of the 78 * {@link Command} (loaded from our configured {@link Catalog} to use 79 * for processing each incoming request. 80 */ 81 public static final String COMMAND = 82 "org.apache.commons.chain.COMMAND"; 83 84 /** 85 * The default command name. 86 */ 87 private static final String COMMAND_DEFAULT = "command"; 88 89 // ------------------------------------------------------ Instance Variables 90 91 /** 92 * The name of the context attribute under which our {@link Catalog} 93 * is stored. This value is also used as the name of the context 94 * attribute under which the catalog is exposed to commands. If not 95 * specified, we will look up commands in the appropriate 96 * {@link Catalog} retrieved from our {@link CatalogFactory} 97 */ 98 private String attribute = null; 99 100 /** 101 * The name of the {@link Catalog} to retrieve from the 102 * {@link CatalogFactory} for this application, or {@code null} 103 * to select the default {@link Catalog}. 104 */ 105 private String catalog = null; 106 107 /** 108 * The name of the {@link Command} to be executed for each incoming 109 * request. 110 */ 111 private String command = null; 112 113 // ------------------------------------------------------------ Constructors 114 115 /** 116 * The Default-Constructor for this class. 117 */ 118 public ChainProcessor() { 119 } 120 121 // --------------------------------------------------------- Servlet Methods 122 123 /** 124 * Clean up as this application is shut down. 125 */ 126 @Override 127 public void destroy() { 128 super.destroy(); 129 attribute = null; 130 catalog = null; 131 command = null; 132 } 133 134 /** 135 * Cache the name of the command we should execute for each request. 136 * 137 * @throws ServletException if an initialization error occurs 138 */ 139 @Override 140 public void init() throws ServletException { 141 super.init(); 142 attribute = getServletConfig().getInitParameter(CONFIG_ATTR); 143 catalog = getServletConfig().getInitParameter(CATALOG); 144 command = getServletConfig().getInitParameter(COMMAND); 145 if (command == null) { 146 command = COMMAND_DEFAULT; 147 } 148 } 149 150 /** 151 * Configure a {@link ServletWebContext} for the current request, and 152 * pass it to the {@code execute()} method of the specified 153 * {@link Command}, loaded from our configured {@link Catalog}. 154 * 155 * @param request The request we are processing 156 * @param response The response we are creating 157 * 158 * @throws IOException if an input/output error occurs 159 * @throws ServletException if a servlet exception occurs 160 */ 161 @Override 162 public void service(HttpServletRequest request, 163 HttpServletResponse response) 164 throws IOException, ServletException { 165 166 ServletWebContext context = 167 new ServletWebContext(getServletContext(), request, response); 168 Catalog<ServletWebContext> theCatalog = null; 169 if (attribute != null) { 170 @SuppressWarnings("unchecked") 171 Catalog<ServletWebContext> catalog = (Catalog<ServletWebContext>) 172 getServletContext().getAttribute(this.attribute); 173 theCatalog = catalog; 174 } else if (catalog != null) { 175 theCatalog = CatalogFactory.<ServletWebContext>getInstance().getCatalog(catalog); 176 } else { 177 theCatalog = CatalogFactory.<ServletWebContext>getInstance().getCatalog(); 178 } 179 if (attribute == null) { 180 request.setAttribute(CATALOG_DEFAULT, theCatalog); 181 } 182 Command<ServletWebContext> command = theCatalog.getCommand(this.command); 183 try { 184 command.execute(context); 185 } catch (Exception e) { 186 throw new ServletException(e); 187 } 188 } 189 }