| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.chain2.web.servlet; |
| |
| import org.apache.commons.chain2.Catalog; |
| import org.apache.commons.chain2.Command; |
| import org.apache.commons.chain2.impl.CatalogFactoryBase; |
| import org.apache.commons.chain2.web.ChainServlet; |
| |
| import javax.servlet.ServletContext; |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import java.io.IOException; |
| |
| /** |
| * <p>Custom subclass of {@link ChainServlet} that also dispatches incoming |
| * requests to a configurable {@link Command} loaded from the specified |
| * {@link Catalog}.</p> |
| * |
| * <p>In addition to the <em>servlet</em> init parameters supported by |
| * {@link ChainServlet}, this class supports the following additional |
| * parameters:</p> |
| * <ul> |
| * <li><strong>org.apache.commons.chain2.CATALOG</strong> - Name of the |
| * catalog from which to acquire commands to be executed. If not |
| * specified, the default catalog for this application will be used.</li> |
| * <li><strong>org.apache.commons.chain2.COMMAND</strong> - Name of the |
| * {@link Command} (looked up in our configured {@link Catalog} used |
| * to process all incoming servlet requests. If not specified, |
| * defaults to <code>command</code>.</li> |
| * </ul> |
| * |
| * <p>Also, the <code>org.apache.commons.chain2.CONFIG_ATTR</code> |
| * init parameter is also used to identify the |
| * {@link org.apache.commons.chain2.Context} attribute under |
| * which our configured {@link Catalog} will be made available to |
| * {@link Command}s processing our requests, in addition to its definition |
| * of the <code>ServletContext</code> attribute key under which the |
| * {@link Catalog} is available.</p> |
| * |
| * @version $Id$ |
| */ |
| public class ChainProcessor extends ChainServlet { |
| |
| // ------------------------------------------------------ Manifest Constants |
| |
| /** |
| * |
| */ |
| private static final long serialVersionUID = 20120724L; |
| |
| /** |
| * <p>The name of the servlet init parameter containing the name of the |
| * {@link Catalog} to use for processing incoming requests.</p> |
| */ |
| public static final String CATALOG = |
| "org.apache.commons.chain2.CATALOG"; |
| |
| /** |
| * <p>The default request attribute under which we expose the |
| * {@link Catalog} being used to subordinate {@link Command}s.</p> |
| */ |
| public static final String CATALOG_DEFAULT = |
| "org.apache.commons.chain2.CATALOG"; |
| |
| /** |
| * <p>The name of the servlet init parameter containing the name of the |
| * {@link Command} (loaded from our configured {@link Catalog} to use |
| * for processing each incoming request.</p> |
| */ |
| public static final String COMMAND = |
| "org.apache.commons.chain2.COMMAND"; |
| |
| /** |
| * <p>The default command name.</p> |
| */ |
| private static final String COMMAND_DEFAULT = "command"; |
| |
| // ------------------------------------------------------ Instance Variables |
| |
| /** |
| * <p>The name of the context attribute under which our {@link Catalog} |
| * is stored. This value is also used as the name of the |
| * context attribute under which the catalog is exposed to commands. |
| * If not specified, we will look up commands in the appropriate |
| * {@link Catalog} retrieved from our {@link CatalogFactoryBase}.</p> |
| */ |
| private String attribute = null; |
| |
| /** |
| * <p>The name of the {@link Catalog} to retrieve from the |
| * {@link CatalogFactoryBase} for this application, or <code>null</code> |
| * to select the default {@link Catalog}.</p> |
| */ |
| private String catalog = null; |
| |
| /** |
| * <p>The name of the {@link Command} to be executed for each incoming |
| * request.</p> |
| */ |
| private String command = null; |
| |
| // --------------------------------------------------------- Servlet Methods |
| |
| /** |
| * <p>Clean up as this application is shut down.</p> |
| */ |
| @Override |
| public void destroy() { |
| super.destroy(); |
| attribute = null; |
| catalog = null; |
| command = null; |
| } |
| |
| /** |
| * <p>Cache the name of the command we should execute for each request.</p> |
| * |
| * @exception ServletException if an initialization error occurs |
| */ |
| @Override |
| public void init() throws ServletException { |
| super.init(); |
| attribute = getServletConfig().getInitParameter(CONFIG_ATTR); |
| catalog = getServletConfig().getInitParameter(CATALOG); |
| command = getServletConfig().getInitParameter(COMMAND); |
| if (command == null) { |
| command = COMMAND_DEFAULT; |
| } |
| } |
| |
| /** |
| * <p>Configure a {@link ServletWebContext} for the current request, and |
| * pass it to the <code>execute()</code> method of the specified |
| * {@link Command}, loaded from our configured {@link Catalog}.</p> |
| * |
| * @param request The request we are processing |
| * @param response The response we are creating |
| * |
| * @exception IOException if an input/output error occurs |
| * @exception ServletException if a servlet exception occurs |
| */ |
| @Override |
| public void service(HttpServletRequest request, HttpServletResponse response) |
| throws IOException, ServletException { |
| |
| ServletWebContext<String, Object> context = |
| new ServletWebContextBase(getServletContext(), request, response); |
| Catalog<String, Object, ServletWebContext<String, Object>> theCatalog; |
| |
| if (attribute != null) { |
| ServletContext servletContext = getServletContext(); |
| Object testAttribute = servletContext.getAttribute(this.attribute); |
| |
| if (testAttribute instanceof Catalog) { |
| /* "attribute" should always contain an instance of a |
| * Catalog class according to the historical chain convention. |
| * Although, we now double-check that it is in fact a catalog |
| * here, we still need to suppress warnings because of the |
| * type erasure of generics. */ |
| @SuppressWarnings("unchecked") |
| Catalog<String, Object, ServletWebContext<String, Object>> attributeCatalog = |
| (Catalog<String, Object, ServletWebContext<String, Object>>)testAttribute; |
| theCatalog = attributeCatalog; |
| } else { |
| String msg = "The object stored as the attribute [" + |
| attribute + "] was not of the expected type [" + |
| "Catalog]"; |
| throw new IllegalArgumentException(msg); |
| } |
| } else if (catalog != null) { |
| theCatalog = CatalogFactoryBase.<String, Object, ServletWebContext<String, Object>>getInstance() |
| .getCatalog(catalog); |
| } else { |
| theCatalog = CatalogFactoryBase.<String, Object, ServletWebContext<String, Object>>getInstance() |
| .getCatalog(); |
| } |
| if (attribute == null) { |
| request.setAttribute(CATALOG_DEFAULT, theCatalog); |
| } |
| Command<String, Object, ServletWebContext<String, Object>> cmd = theCatalog |
| .<Command<String, Object, ServletWebContext<String, Object>>>getCommand(this.command); |
| try { |
| cmd.execute(context); |
| } catch (Exception e) { |
| throw new ServletException(e); |
| } |
| } |
| |
| } |