org.apache.struts.tiles.TilesRequestProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ibis-struts Show documentation
Show all versions of ibis-struts Show documentation
Base project: http://central.maven.org/maven2/struts/struts/1.2.9/
This version of Struts doesn't throw java.io.NotSerializableException when the application server wants to persist sessions and makes renderFocusJavascript return valid xml
The newest version!
/*
* $Id: TilesRequestProcessor.java 164703 2005-04-26 01:28:13Z niallp $
*
* Copyright 1999-2005 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.tiles;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.config.ForwardConfig;
import org.apache.struts.config.ModuleConfig;
/**
* RequestProcessor contains the processing logic that
* the Struts controller servlet performs as it receives each servlet request
* from the container.
* This processor subclasses the Struts RequestProcessor in order to intercept calls to forward
* or include. When such calls are done, the Tiles processor checks if the specified URI
* is a definition name. If true, the definition is retrieved and included. If
* false, the original URI is included or a forward is performed.
*
* Actually, catching is done by overloading the following methods:
*
* - {@link #processForwardConfig(HttpServletRequest,HttpServletResponse,ForwardConfig)}
* - {@link #internalModuleRelativeForward(String, HttpServletRequest , HttpServletResponse)}
* - {@link #internalModuleRelativeInclude(String, HttpServletRequest , HttpServletResponse)}
*
*
* @since Struts 1.1
*/
public class TilesRequestProcessor extends RequestProcessor {
/**
* Definitions factory.
*/
protected DefinitionsFactory definitionsFactory = null;
/**
* Commons Logging instance.
*/
protected static Log log = LogFactory.getLog(TilesRequestProcessor.class);
/**
* Initialize this request processor instance.
*
* @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 {
super.init(servlet, moduleConfig);
this.initDefinitionsMapping();
}
/**
* Read component instance mapping configuration file.
* This is where we read files properties.
*/
protected void initDefinitionsMapping() throws ServletException {
// Retrieve and set factory for this modules
definitionsFactory =
(
(TilesUtilStrutsImpl) TilesUtil
.getTilesUtil())
.getDefinitionsFactory(
getServletContext(),
moduleConfig);
if (definitionsFactory == null) { // problem !
log.info(
"Definition Factory not found for module '"
+ moduleConfig.getPrefix()
+ "'. "
+ "Have you declared the appropriate plugin in struts-config.xml ?");
return;
}
log.info(
"Tiles definition factory found for request processor '"
+ moduleConfig.getPrefix()
+ "'.");
}
/**
* Process a Tile definition name.
* This method tries to process the parameter definitionName
as a definition name.
* It returns true
if a definition has been processed, or false
otherwise.
* Parameter contextRelative
is not used in this implementation.
*
* @param definitionName Definition name to insert.
* @param contextRelative Is the definition marked contextRelative ?
* @param request Current page request.
* @param response Current page response.
* @return true
if the method has processed uri as a definition name, false
otherwise.
*/
protected boolean processTilesDefinition(
String definitionName,
boolean contextRelative,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Do we do a forward (original behavior) or an include ?
boolean doInclude = false;
// Controller associated to a definition, if any
Controller controller = null;
// Computed uri to include
String uri = null;
ComponentContext tileContext = null;
try {
// Get current tile context if any.
// If context exist, we will do an include
tileContext = ComponentContext.getContext(request);
doInclude = (tileContext != null);
ComponentDefinition definition = null;
// Process tiles definition names only if a definition factory exist,
// and definition is found.
if (definitionsFactory != null) {
// Get definition of tiles/component corresponding to uri.
try {
definition =
definitionsFactory.getDefinition(
definitionName,
request,
getServletContext());
} catch (NoSuchDefinitionException ex) {
// Ignore not found
log.debug("NoSuchDefinitionException " + ex.getMessage());
}
if (definition != null) { // We have a definition.
// We use it to complete missing attribute in context.
// We also get uri, controller.
uri = definition.getPath();
controller = definition.getOrCreateController();
if (tileContext == null) {
tileContext =
new ComponentContext(definition.getAttributes());
ComponentContext.setContext(tileContext, request);
} else {
tileContext.addMissing(definition.getAttributes());
}
}
}
// Process definition set in Action, if any.
definition = DefinitionsUtil.getActionDefinition(request);
if (definition != null) { // We have a definition.
// We use it to complete missing attribute in context.
// We also overload uri and controller if set in definition.
if (definition.getPath() != null) {
uri = definition.getPath();
}
if (definition.getOrCreateController() != null) {
controller = definition.getOrCreateController();
}
if (tileContext == null) {
tileContext =
new ComponentContext(definition.getAttributes());
ComponentContext.setContext(tileContext, request);
} else {
tileContext.addMissing(definition.getAttributes());
}
}
} catch (java.lang.InstantiationException ex) {
log.error("Can't create associated controller", ex);
throw new ServletException(
"Can't create associated controller",
ex);
} catch (DefinitionsFactoryException ex) {
throw new ServletException(ex);
}
// Have we found a definition ?
if (uri == null) {
return false;
}
// Execute controller associated to definition, if any.
if (controller != null) {
try {
controller.execute(
tileContext,
request,
response,
getServletContext());
} catch (Exception e) {
throw new ServletException(e);
}
}
// If request comes from a previous Tile, do an include.
// This allows to insert an action in a Tile.
if (log.isDebugEnabled()) {
log.debug("uri=" + uri + " doInclude=" + doInclude);
}
if (doInclude) {
doInclude(uri, request, response);
} else {
doForward(uri, request, response); // original behavior
}
return true;
}
/**
* Do a forward using request dispatcher.
* Uri is a valid uri. If response has already been commited, do an include
* instead.
* @param uri Uri or Definition name to forward.
* @param request Current page request.
* @param response Current page response.
*/
protected void doForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
if (response.isCommitted()) {
this.doInclude(uri, request, response);
} else {
super.doForward(uri, request, response);
}
}
/**
* Overloaded method from Struts' RequestProcessor.
* Forward or redirect to the specified destination by the specified
* mechanism.
* This method catches the Struts' actionForward call. It checks if the
* actionForward is done on a Tiles definition name. If true, process the
* definition and insert it. If false, call the original parent's method.
* @param request The servlet request we are processing.
* @param response The servlet response we are creating.
* @param forward The ActionForward controlling where we go next.
*
* @exception IOException if an input/output error occurs.
* @exception ServletException if a servlet exception occurs.
*/
protected void processForwardConfig(
HttpServletRequest request,
HttpServletResponse response,
ForwardConfig forward)
throws IOException, ServletException {
// Required by struts contract
if (forward == null) {
return;
}
if (log.isDebugEnabled()) {
log.debug(
"processForwardConfig("
+ forward.getPath()
+ ", "
+ forward.getContextRelative()
+ ")");
}
// Try to process the definition.
if (processTilesDefinition(forward.getPath(),
forward.getContextRelative(),
request,
response)) {
if (log.isDebugEnabled()) {
log.debug(
" '" + forward.getPath() + "' - processed as definition");
}
return;
}
if (log.isDebugEnabled()) {
log.debug(" '" + forward.getPath() + "' - processed as uri");
}
// forward doesn't contain a definition, let parent do processing
super.processForwardConfig(request, response, forward);
}
/**
* Catch the call to a module relative forward.
* If the specified uri is a tiles definition name, insert it.
* Otherwise, parent processing is called.
* Do a module relative forward to specified uri using request dispatcher.
* Uri is relative to the current module. The real uri is computed by
* prefixing the module name.
* This method is used internally and is not part of the public
* API. It is advised to not use it in subclasses.
* @param uri Module-relative URI to forward to.
* @param request Current page request.
* @param response Current page response.
* @since Struts 1.1
*/
protected void internalModuleRelativeForward(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
if (processTilesDefinition(uri, false, request, response)) {
return;
}
super.internalModuleRelativeForward(uri, request, response);
}
/**
* Do a module relative include to specified uri using request dispatcher.
* Uri is relative to the current module. The real uri is computed by
* prefixing the module name.
* This method is used internally and is not part of the public
* API. It is advised to not use it in subclasses.
* @param uri Module-relative URI to forward to.
* @param request Current page request.
* @param response Current page response.
* @since Struts 1.1
*/
protected void internalModuleRelativeInclude(
String uri,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
if (processTilesDefinition(uri, false, request, response)) {
return;
}
super.internalModuleRelativeInclude(uri, request, response);
}
/**
* Get associated definition factory.
*/
public DefinitionsFactory getDefinitionsFactory() {
return definitionsFactory;
}
}