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.javax.servlet; 018 019import java.io.IOException; 020 021import javax.servlet.ServletException; 022import javax.servlet.http.HttpServletRequest; 023import javax.servlet.http.HttpServletResponse; 024 025import org.apache.commons.chain.Catalog; 026import org.apache.commons.chain.CatalogFactory; 027import org.apache.commons.chain.Command; 028import org.apache.commons.chain.web.javax.ChainServlet; 029 030/** 031 * Custom subclass of {@link ChainServlet} that also dispatches incoming 032 * requests to a configurable {@link Command} loaded from the specified 033 * {@link Catalog}. 034 * 035 * <p>In addition to the <em>servlet</em> init parameters supported by 036 * {@link ChainServlet}, this class supports the following additional 037 * parameters:</p> 038 * <ul> 039 * <li><strong>org.apache.commons.chain.CATALOG</strong> - Name of the 040 * catalog from which to acquire commands to be executed. If not 041 * specified, the default catalog for this application will be used.</li> 042 * <li><strong>org.apache.commons.chain.COMMAND</strong> - Name of the 043 * {@link Command} (looked up in our configured {@link Catalog} used 044 * to process all incoming servlet requests. If not specified, 045 * defaults to {@code command}.</li> 046 * </ul> 047 * 048 * <p>Also, the {@code org.apache.commons.chain.CONFIG_ATTR} 049 * init parameter is also used to identify the 050 * {@link org.apache.commons.chain.Context} attribute under 051 * which our configured {@link Catalog} will be made available to 052 * {@link Command}s processing our requests, in addition to its definition 053 * of the {@code ServletContext} attribute key under which the 054 * {@link Catalog} is available.</p> 055 */ 056 057public class ChainProcessor extends ChainServlet { 058 private static final long serialVersionUID = -6817532768031279260L; 059 060 // ------------------------------------------------------ Manifest Constants 061 062 /** 063 * The name of the servlet init parameter containing the name of the 064 * {@link Catalog} to use for processing incoming requests. 065 */ 066 public static final String CATALOG = 067 "org.apache.commons.chain.CATALOG"; 068 069 /** 070 * The default request attribute under which we expose the 071 * {@link Catalog} being used to subordinate {@link Command}s. 072 */ 073 public static final String CATALOG_DEFAULT = 074 "org.apache.commons.chain.CATALOG"; 075 076 /** 077 * The name of the servlet init parameter containing the name of the 078 * {@link Command} (loaded from our configured {@link Catalog} to use 079 * for processing each incoming request. 080 */ 081 public static final String COMMAND = 082 "org.apache.commons.chain.COMMAND"; 083 084 /** 085 * The default command name. 086 */ 087 private static final String COMMAND_DEFAULT = "command"; 088 089 // ------------------------------------------------------ Instance Variables 090 091 /** 092 * The name of the context attribute under which our {@link Catalog} 093 * is stored. This value is also used as the name of the context 094 * attribute under which the catalog is exposed to commands. If not 095 * specified, we will look up commands in the appropriate 096 * {@link Catalog} retrieved from our {@link CatalogFactory} 097 */ 098 private String attribute = null; 099 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}