/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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.struts.chain.legacy;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.chain.Catalog;
import org.apache.commons.chain.CatalogFactory;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.web.servlet.ServletWebContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.chain.Constants;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.upload.MultipartRequestWrapper;
/**
* <p><strong>ComposableRequestProcessor</strong> uses the <em>Chain Of
* Resposibility</em> design pattern (as implemented by the commons-chain
* package in Jakarta Commons) to support external configuration of command
* chains to be used. It is configured via the following context initialization
* parameters:</p>
* <ul>
* <li><strong>org.apache.struts.chain.CATALOG_NAME</strong> - Name of the
* <code>Catalog</code> in which we will look up the <code>Command</code>
* to be executed for each request. If not specified, the default value
* is <code>struts</code>.</li>
* <li><strong>org.apache.struts.chain.COMMAND_NAME</strong> - Name of the
* <code>Command</code> which we will execute for each request, to be
* looked up in the specified <code>Catalog</code>. If not specified,
* the default value is <code>servlet-standard</code>.</li>
* </ul>
*
* @version $Rev: 55324 $ $Date: 2004-10-22 19:55:27 +0100 (Fri, 22 Oct 2004) $
* @since Struts 1.1
*/
public class ComposableRequestProcessor extends RequestProcessor {
// ------------------------------------------------------ Manifest Constants
/**
* <p>Name of the context initialization parameter containing the
* name of the <code>Catalog</code> we will use.</p>
*/
private static final String CATALOG_NAME =
"org.apache.struts.chain.CATALOG_NAME";
/**
* <p>Name of the <code>Command</code> to be executed for each request.</p>
*/
private static final String COMMAND_NAME =
"org.apache.struts.chain.COMMAND_NAME";
// ------------------------------------------------------ Instance Variables
/**
* <p>The {@link Catalog} containing all of the available command chains
* for this module.
*/
protected Catalog catalog = null;
/**
* <p>The {@link Command} to be executed for each request.</p>
*/
protected Command command = null;
/**
* <p>The <code>Log</code> instance for this class.</p>
*/
protected static final Log log =
LogFactory.getLog(ComposableRequestProcessor.class);
// ---------------------------------------------------------- Public Methods
/**
* Clean up in preparation for a shutdown of this application.
*/
public void destroy() {
super.destroy();
catalog = null;
command = null;
}
/**
* <p>Initialize this request processor instance.</p>
*
* @param servlet The ActionServlet we are associated with
* @param moduleConfig The ModuleConfig we are associated with.
*
* @throws ServletException If an error occurs during initialization
*/
public void init(ActionServlet servlet,
ModuleConfig moduleConfig)
throws ServletException {
log.info("Initializing composable request processor for module prefix '"
+ moduleConfig.getPrefix() + "'");
super.init(servlet, moduleConfig);
String catalogName =
servlet.getServletContext().getInitParameter(CATALOG_NAME);
if (catalogName == null) {
catalogName = "struts";
}
catalog = CatalogFactory.getInstance().getCatalog(catalogName);
if (catalog == null) {
throw new ServletException("Cannot find catalog '" +
catalogName + "'");
}
String commandName =
servlet.getServletContext().getInitParameter(COMMAND_NAME);
if (commandName == null) {
commandName = "servlet-standard";
}
command = catalog.getCommand(commandName);
if (command == null) {
throw new ServletException("Cannot find command '" +
commandName + "'");
}
}
/**
* <p>Process an <code>HttpServletRequest</code> and create the
* corresponding <code>HttpServletResponse</code>.</p>
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a processing exception occurs
*/
public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Wrap the request in the case of a multipart request
request = processMultipart(request);
// Create and populate a Context for this request
ServletWebContext context = new ServletWebContext();
context.initialize(getServletContext(), request, response);
context.put(Constants.ACTION_SERVLET_KEY,
this.servlet);
context.put(Constants.MODULE_CONFIG_KEY,
this.moduleConfig);
// Create and execute the command.
try {
if (log.isDebugEnabled()) {
log.debug("Using processing chain for this request");
}
command.execute(context);
} catch (Exception e) {
// Execute the exception processing chain??
throw new ServletException(e);
}
// Release the context.
context.release();
}
/**
* If this is a multipart request, wrap it with a special wrapper.
* Otherwise, return the request unchanged.
*
* @param request The HttpServletRequest we are processing
*/
protected HttpServletRequest processMultipart(HttpServletRequest request) {
if (!"POST".equalsIgnoreCase(request.getMethod())) {
return (request);
}
String contentType = request.getContentType();
if ((contentType != null) &&
contentType.startsWith("multipart/form-data")) {
return (new MultipartRequestWrapper(request));
} else {
return (request);
}
}
}