/*
* Copyright 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.
*
* $Header:$
*/
package org.apache.beehive.netui.pageflow;
import org.apache.beehive.netui.core.factory.Factory;
import org.apache.beehive.netui.core.factory.FactoryUtils;
import org.apache.beehive.netui.util.logging.Logger;
import org.apache.beehive.netui.util.config.ConfigUtil;
import org.apache.beehive.netui.util.config.bean.PageFlowFactoryConfig;
import org.apache.beehive.netui.util.config.bean.PageFlowFactoriesConfig;
import org.apache.beehive.netui.util.config.bean.PageFlowConfig;
import org.apache.beehive.netui.util.config.bean.SharedFlowRefConfig;
import org.apache.beehive.netui.pageflow.internal.InternalUtils;
import org.apache.beehive.netui.pageflow.internal.InternalConstants;
import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig;
import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
import org.apache.beehive.netui.pageflow.handler.Handlers;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ControllerConfig;
import org.apache.struts.action.ActionServlet;
import java.io.IOException;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Iterator;
/**
* Factory for creating {@link FlowController}s - user {@link PageFlowController}s and {@link SharedFlowController}s.
*/
public class FlowControllerFactory
extends Factory
{
private static final Logger _log = Logger.getInstance( FlowControllerFactory.class );
private static final String CONTEXT_ATTR = InternalConstants.ATTR_PREFIX + "fcFactory";
private transient ReloadableClassHandler _rch;
protected FlowControllerFactory()
{
}
protected void onCreate()
{
}
static void init( ServletContext servletContext )
{
PageFlowFactoriesConfig factoriesBean = ConfigUtil.getConfig().getPageFlowFactories();
FlowControllerFactory factory = null;
if ( factoriesBean != null )
{
PageFlowFactoryConfig fcFactoryBean = factoriesBean.getPageFlowFactory();
factory = ( FlowControllerFactory ) FactoryUtils.getFactory( servletContext, fcFactoryBean, FlowControllerFactory.class );
}
if ( factory == null ) factory = new FlowControllerFactory();
factory.reinit( servletContext );
servletContext.setAttribute( CONTEXT_ATTR, factory );
}
/**
* Called to reinitialize this instance, most importantly after it has been serialized/deserialized.
*
* @param servletContext the current ServletContext.
*/
protected void reinit( ServletContext servletContext )
{
super.reinit( servletContext );
if ( _rch == null ) _rch = Handlers.get( servletContext ).getReloadableClassHandler();
}
/**
* Get a FlowControllerFactory.
*
* @param servletContext the current ServletContext.
* @return a FlowControllerFactory for the given ServletContext. It may or may not be a cached instance.
*/
public static FlowControllerFactory get( ServletContext servletContext )
{
FlowControllerFactory factory = ( FlowControllerFactory ) servletContext.getAttribute( CONTEXT_ATTR );
assert factory != null
: FlowControllerFactory.class.getName() + " was not found in ServletContext attribute " + CONTEXT_ATTR;
factory.reinit( servletContext );
return factory;
}
/**
* Get the page flow instance that should be associated with the given request. If it doesn't exist, create it.
* If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
* stored as the current page flow.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @return the {@link PageFlowController} for the request, or <code>null</code> if none was found.
*/
public PageFlowController getPageFlowForRequest( RequestContext context )
throws InstantiationException, IllegalAccessException
{
String servletPath = InternalUtils.getDecodedServletPath( context.getHttpRequest() );
return getPageFlowForPath( context, servletPath );
}
/**
* Get the page flow instance that should be associated with the given path. If it doesn't exist, create it.
* If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
* stored as the current page flow.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param path a <strong>webapp-relative</strong> path. The path should not contain the webapp context path.
* @return the {@link PageFlowController} for the given path, or <code>null</code> if none was found.
*/
public PageFlowController getPageFlowForPath( RequestContext context, String path )
throws InstantiationException, IllegalAccessException
{
HttpServletRequest request = context.getHttpRequest();
HttpServletResponse response = context.getHttpResponse();
PageFlowController cur = PageFlowUtils.getCurrentPageFlow( request, getServletContext() );
String parentDir = PageFlowUtils.getModulePathForRelativeURI( path );
//
// Reinitialize transient data that may have been lost on session failover.
//
if ( cur != null ) cur.reinitialize( request, response, getServletContext() );
//
// If there's no current PageFlow, or if the current PageFlowController has a module path that
// is incompatible with the current request URI, then create the appropriate PageFlowController.
//
if ( cur == null || ! PageFlowUtils.getModulePathForRelativeURI( cur.getURI() ).equals( parentDir ) )
{
try
{
String className = InternalUtils.getFlowControllerClassName( parentDir, request, getServletContext() );
return className != null ? createPageFlow( context, className ) : null;
}
catch ( ClassNotFoundException e )
{
if ( _log.isInfoEnabled() ) _log.info( "No page flow exists for path " + path );
return null;
}
}
return cur;
}
/**
* Create a page flow of the given type. The page flow stack (for nesting) will be cleared or pushed, and the new
* instance will be stored as the current page flow.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param pageFlowClassName the type name of the desired page flow.
* @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
*/
public PageFlowController createPageFlow( RequestContext context, String pageFlowClassName )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
Class pageFlowClass = getFlowControllerClass( pageFlowClassName );
return createPageFlow( context, pageFlowClass );
}
/**
* Create a {@link PageFlowController} of the given type. The PageFlowController stack (for
* nesting) will be cleared or pushed, and the new instance will be stored as the current
* PageFlowController.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param pageFlowClass the type of the desired PageFlowController.
* @return the newly-created PageFlowController, or <code>null</code> if none was found.
*/
public PageFlowController createPageFlow( RequestContext context, Class pageFlowClass )
throws InstantiationException, IllegalAccessException
{
if ( ! PageFlowController.class.isAssignableFrom( pageFlowClass ) ) return null;
//
// First check if this is a request for a "long lived" page flow. If so, try
// PageFlowUtils.getCurrentPageFlow again, with the longLived flag.
//
HttpServletRequest request = context.getHttpRequest();
HttpServletResponse response = context.getHttpResponse();
ServletContext servletContext = getServletContext();
PageFlowController retVal = null;
String modulePath = InternalUtils.inferModulePathFromClassName( pageFlowClass.getName() );
ModuleConfig mc = ensureModule( modulePath, request, servletContext );
if ( mc == null )
{
_log.error( "Struts module " + modulePath + " not found for " + pageFlowClass.getName()
+ "; cannot create page flow.");
return null;
}
if ( InternalUtils.isLongLived( mc ) )
{
retVal = PageFlowUtils.getLongLivedPageFlow( modulePath, request );
if ( _log.isDebugEnabled() )
{
if ( retVal != null )
{
_log.debug( "Using long lived PageFlowController of type " + pageFlowClass.getName() );
}
}
}
//
// First, see if this is a nested page flow that's already on the stack. Unless "renesting" is explicitly
// enabled, we don't want to allow another instance of this page flow to be nested. This is a common
// browser back-button problem:
// 1) request nested page flow A
// 2) request nested page flow B
// 3) press back button, and execute an action on A.
//
// This logic does not deal with immediate self-nesting (A->A), which is taken care of in
// PageFlowController.forwardTo(). Nested page flows can only self-nest by forwarding to the .jpf URI, not
// indirectly by executing actions on themselves (think about it -- that would be a disaster).
//
boolean createdNew = false;
boolean isNestable = InternalUtils.isNestable( mc );
PageFlowStack pfStack = PageFlowStack.get( request, getServletContext(), false );
if ( isNestable && pfStack != null )
{
PageFlowConfig options = ConfigUtil.getConfig().getPageFlowConfig();
if ( options == null || ! options.isEnableSelfNesting() )
{
int lastIndexOfJpfClass = pfStack.lastIndexOf( request, pageFlowClass );
if ( lastIndexOfJpfClass != -1 )
{
retVal = pfStack.popUntil( request, lastIndexOfJpfClass );
retVal.persistInSession( request, response );
return retVal;
}
}
}
//
// OK, if it's not an existing long lived page flow, and if this wasn't a nested page flow already on the
// stack, then create a new instance.
//
if ( retVal == null )
{
if ( _log.isDebugEnabled() )
{
_log.debug( "Creating PageFlowController of type " + pageFlowClass.getName() );
}
retVal = ( PageFlowController ) getFlowControllerInstance( pageFlowClass );
createdNew = true;
}
//
// Store the previous PageFlowController on the nesting stack (if this one is nestable),
// or destroy the nesting stack.
//
if ( isNestable )
{
//
// Call create() on the newly-created page flow.
//
if ( createdNew ) retVal.create( request, response, servletContext );
PageFlowController current = PageFlowUtils.getCurrentPageFlow( request, getServletContext() );
if ( current != null )
{
if ( _log.isDebugEnabled() )
{
_log.debug( "Pushing PageFlowController " + current + " onto the nesting stack" );
}
if ( pfStack == null ) pfStack = PageFlowStack.get( request, getServletContext(), true );
pfStack.push( current, request );
}
retVal.reinitialize( request, response, servletContext );
retVal.persistInSession( request, response );
}
else
{
//
// Going to a non-nested pageflow. Blow away the pageflow stack.
//
if ( pfStack != null )
{
if ( _log.isDebugEnabled() )
{
_log.debug( "Destroying the PageFlowController stack." );
}
//
// Start popping page flows until 1) there are none left on the stack, or 2) we find
// one of the type we're returning. If (2), we'll use that one (this means that executing
// an action on a nesting page flow while in a nested one will not destroy the nesting
// page flow only to create a new instance of it).
//
PageFlowController onStackAlready = pfStack.popUntil( request, retVal.getClass() );
if ( onStackAlready != null )
{
if ( _log.isDebugEnabled() )
{
_log.debug( "Found a page flow of type " + retVal.getClass() + " in the stack; "
+ "using that instance and stopping destruction of the nesting stack." );
}
retVal = onStackAlready;
retVal.persistInSession( request, response );
}
else
{
//
// We're actually using the newly-created page flow, so call create() on it.
// Note that we make the call to persistInSession *before* create, so the previous flow's
// onDestroy() gets called before the new one's onCreate().
//
retVal.reinitialize( request, response, servletContext );
retVal.persistInSession( request, response );
retVal.create( request, response, servletContext );
}
}
else
{
//
// We're actually using the newly-created page flow, so call create() on it (*after* persisting
// in the session so the previous page flow's onDestroy() gets called before the new one's
// onCreate()).
//
retVal.reinitialize( request, response, servletContext );
retVal.persistInSession( request, response );
if ( createdNew ) retVal.create( request, response, servletContext );
}
}
return retVal;
}
/**
* Create a {@link SharedFlowController} of the given type.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param sharedFlowClassName the type name of the desired SharedFlowController.
* @return the newly-created SharedFlowController, or <code>null</code> if none was found.
*/
public SharedFlowController createSharedFlow( RequestContext context, String sharedFlowClassName )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
Class sharedFlowClass = getFlowControllerClass( sharedFlowClassName );
return createSharedFlow( context, sharedFlowClass );
}
/**
* Create a {@link SharedFlowController} of the given type.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param sharedFlowClass the type of the desired SharedFlowController.
* @return the newly-created SharedFlowController, or <code>null</code> if none was found.
*/
public SharedFlowController createSharedFlow( RequestContext context, Class sharedFlowClass )
throws InstantiationException, IllegalAccessException
{
assert SharedFlowController.class.isAssignableFrom( sharedFlowClass ) : sharedFlowClass.getName();
if ( _log.isDebugEnabled() )
{
_log.debug( "Creating SharedFlowController of type " + sharedFlowClass.getName() );
}
SharedFlowController retVal = ( SharedFlowController ) getFlowControllerInstance( sharedFlowClass );
HttpServletRequest request = context.getHttpRequest();
HttpServletResponse response = context.getHttpResponse();
retVal.create( request, response, getServletContext() );
if ( _log.isDebugEnabled() )
{
_log.debug( "Storing " + retVal + " in the session..." );
}
retVal.persistInSession( request, response );
return retVal;
}
/**
* Get the map of shared flows for the given request. The map is derived from the shared flows
* that are declared (through the <code>sharedFlowRefs</code> attribute of
* {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller @Jpf.Controller}) in the page flow for the request.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @return a Map of shared-flow-name (String) to {@link SharedFlowController}.
* @throws ClassNotFoundException if a declared shared flow class could not be found.
* @throws InstantiationException if a declared shared flow class could not be instantiated.
* @throws IllegalAccessException if a declared shared flow class was not accessible.
*/
public Map/*< String, SharedFlowController >*/ getSharedFlowsForRequest( RequestContext context )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
String path = InternalUtils.getDecodedServletPath( context.getHttpRequest() );
return getSharedFlowsForPath( context, path );
}
/**
* Get the map of shared flows for the given path. The map is derived from the shared flows
* that are declared (through the <code>sharedFlowRefs</code> attribute of
* {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller @Jpf.Controller}) in the page flow for the path.
*
* @param context a {@link RequestContext} object which contains the current request and response.
* @param path a <strong>webapp-relative</strong> path. The path should not contain the webapp context path.
* @return a Map of shared-flow-name (String) to {@link SharedFlowController}.
* @throws ClassNotFoundException if a declared shared flow class could not be found.
* @throws InstantiationException if a declared shared flow class could not be instantiated.
* @throws IllegalAccessException if a declared shared flow class was not accessible.
*/
public Map/*< String, SharedFlowController >*/ getSharedFlowsForPath( RequestContext context, String path )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
String parentDir = PageFlowUtils.getModulePathForRelativeURI( path );
HttpServletRequest request = context.getHttpRequest();
HttpServletResponse response = context.getHttpResponse();
ModuleConfig mc = InternalUtils.ensureModuleConfig( parentDir, request, getServletContext() );
LinkedHashMap/*< String, SharedFlowController >*/ sharedFlows = getDefaultSharedFlows( context );
if ( mc != null )
{
ControllerConfig cc = mc.getControllerConfig();
if ( cc instanceof PageFlowControllerConfig )
{
Map/*< String, String >*/ sharedFlowTypes = ( ( PageFlowControllerConfig ) cc ).getSharedFlowTypes();
if ( sharedFlowTypes != null && sharedFlowTypes.size() > 0 )
{
if ( sharedFlows == null ) sharedFlows = new LinkedHashMap/*< String, SharedFlowController >*/();
for ( Iterator/*<Map.Entry>*/ i = sharedFlowTypes.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = ( Map.Entry ) i.next();
String name = ( String ) entry.getKey();
String type = ( String ) entry.getValue();
addSharedFlow( context, name, type, sharedFlows );
}
return sharedFlows;
}
}
}
//
// Legacy behavior: if there's no shared flow for the request, initialize a GlobalApp instance.
//
SharedFlowController ga = PageFlowUtils.getGlobalApp( request );
if ( ga != null )
{
ga.reinitialize( request, response, getServletContext() );
}
else
{
getGlobalApp( request, response, getServletContext() );
}
return sharedFlows;
}
LinkedHashMap/*< String, SharedFlowController >*/ getDefaultSharedFlows( RequestContext context )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
SharedFlowRefConfig[] defaultRefs = ConfigUtil.getConfig().getSharedFlowRefs();
if ( defaultRefs != null )
{
if ( defaultRefs.length > 0 )
{
LinkedHashMap/*< String, SharedFlowController >*/ sharedFlows = new LinkedHashMap();
for ( int i = 0; i < defaultRefs.length; i++ )
{
SharedFlowRefConfig ref = defaultRefs[i];
if ( _log.isInfoEnabled() )
{
_log.info( "Shared flow of type " + ref.getType() + " is a default shared flow reference "
+ "with name " + ref.getName() );
}
addSharedFlow( context, ref.getName(), ref.getType(), sharedFlows );
}
return sharedFlows;
}
}
return null;
}
private void addSharedFlow( RequestContext context, String name, String type, LinkedHashMap sharedFlows )
throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
HttpServletRequest request = context.getHttpRequest();
SharedFlowController sf = PageFlowUtils.getSharedFlow( type, request );
//
// Reinitialize transient data that may have been lost on session failover.
//
if ( sf != null )
{
sf.reinitialize( request, context.getHttpResponse(), getServletContext() );
}
else
{
sf = createSharedFlow( context, type );
}
if ( ! ( sf instanceof GlobalApp ) ) sharedFlows.put( name, sf );
}
/**
* Get a FlowController class. By default, this loads the class using the thread context class loader.
*
* @param className the name of the {@link FlowController} class to load.
* @return the loaded {@link FlowController} class.
* @throws ClassNotFoundException if the requested class could not be found.
*/
public Class getFlowControllerClass( String className )
throws ClassNotFoundException
{
return _rch.loadClass( className );
}
/**
* Get a FlowController instance, given a FlowController class.
*
* @param flowControllerClass the Class, which must be assignable to {@link FlowController}.
* @return a new FlowController instance.
*/
public FlowController getFlowControllerInstance( Class flowControllerClass )
throws InstantiationException, IllegalAccessException
{
assert FlowController.class.isAssignableFrom( flowControllerClass )
: "Class " + flowControllerClass.getName() + " does not extend " + FlowController.class.getName();
return ( FlowController ) flowControllerClass.newInstance();
}
/**
* Get the page flow instance that should be associated with the given request. If it doesn't exist, create it.
* If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
* stored as the current page flow.
* @deprecated Use {@link #getPageFlowForRequest(RequestContext)} instead.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @param servletContext the current ServletContext.
* @return the {@link PageFlowController} for the request, or <code>null</code> if none was found.
*/
public static PageFlowController getPageFlowForRequest( HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext )
{
return getPageFlowForRelativeURI( request, response, InternalUtils.getDecodedServletPath( request ), servletContext );
}
/**
* Get the page flow instance that should be associated with the given URI. If it doesn't exist, create it.
* If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
* stored as the current page flow.
* @deprecated Use {@link #getPageFlowForPath(RequestContext, String)} instead. The URI must be stripped of the
* webapp context path before being passed.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @param uri a server-relative URI. The URI should contain the webapp context path.
* @param servletContext the current ServletContext.
* @return the {@link PageFlowController} for the given URI, or <code>null</code> if none was found.
*/
public static PageFlowController getPageFlowForURI( HttpServletRequest request, HttpServletResponse response,
String uri, ServletContext servletContext )
{
return getPageFlowForRelativeURI( request, response, PageFlowUtils.getRelativeURI( request, uri, null ),
servletContext );
}
/**
* Get the page flow instance that should be associated with the given path. If it doesn't exist, create it.
* If one is created, the page flow stack (for nesting) will be cleared or pushed, and the new instance will be
* stored as the current page flow.
* @deprecated Use {@link #getPageFlowForPath(RequestContext, String)} instead.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @param path a <strong>webapp-relative</strong> path. The path should not contain the webapp context path.
* @param servletContext the current ServletContext.
* @return the {@link PageFlowController} for the given path, or <code>null</code> if none was found.
*/
public static PageFlowController getPageFlowForRelativeURI( HttpServletRequest request,
HttpServletResponse response, String path,
ServletContext servletContext )
{
try
{
return get( servletContext ).getPageFlowForPath( new RequestContext( request, response ), path );
}
catch ( InstantiationException e )
{
_log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
return null;
}
catch ( IllegalAccessException e )
{
_log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
return null;
}
}
/**
* Create a page flow of the given type. The page flow stack (for nesting) will be cleared or pushed, and the new
* instance will be stored as the current page flow.
* @deprecated Use {@link #createPageFlow(RequestContext, String)} instead.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @param pageFlowClassName the type name of the desired page flow.
* @param servletContext the current ServletContext.
* @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
*/
public static PageFlowController getPageFlow( String pageFlowClassName, HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext )
{
try
{
return get( servletContext ).createPageFlow( new RequestContext( request, response ), pageFlowClassName );
}
catch ( ClassNotFoundException e)
{
if ( _log.isErrorEnabled() ) _log.error( "Requested page flow class " + pageFlowClassName + " not found." );
return null;
}
catch ( InstantiationException e )
{
_log.error( "Could not instantiate PageFlowController of type " + pageFlowClassName, e );
return null;
}
catch ( IllegalAccessException e )
{
_log.error( "Could not instantiate PageFlowController of type " + pageFlowClassName, e );
return null;
}
}
/**
* Get or create the current user session's GlobalApp instance (from the Global.app file).
* @deprecated Global.app is deprecated; use shared flows and {@link #getSharedFlowsForRequest(RequestContext)}.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @return the current session's {@link GlobalApp} instance, or a new one (based on Global.app) if none is found.
* If Global.app does not exist in the current webapp, <code>null</code> is returned.
*/
public static GlobalApp getGlobalApp( HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext )
{
GlobalApp current = PageFlowUtils.getGlobalApp( request );
if ( current != null ) return current;
try
{
try
{
FlowControllerFactory factory = get( servletContext );
SharedFlowController sf =
factory.createSharedFlow( new RequestContext( request, response ), PageFlowConstants.GLOBALAPP_CLASSNAME );
if ( ! ( sf instanceof GlobalApp ) )
{
_log.error( "Class " + PageFlowConstants.GLOBALAPP_CLASSNAME + " is not an instance of "
+ GlobalApp.class.getName() );
return null;
}
return ( GlobalApp ) sf;
}
catch ( InstantiationException e )
{
_log.error( "Could not instantiate Global.app.", e );
return null;
}
catch ( IllegalAccessException e )
{
_log.error( "Could not instantiate Global.app", e );
return null;
}
}
catch ( ClassNotFoundException e )
{
// Ignore -- this is expected if there's no (legacy) Global.app.
return null;
}
}
private static ModuleConfig ensureModule( String modulePath, ServletRequest request,
ServletContext servletContext )
{
ModuleConfig mc = InternalUtils.getModuleConfig( modulePath, servletContext );
if ( mc == null )
{
ActionServlet as = InternalUtils.getActionServlet( servletContext );
if ( as instanceof AutoRegisterActionServlet )
{
AutoRegisterActionServlet das = ( AutoRegisterActionServlet ) as;
try
{
mc = das.ensureModuleRegistered( modulePath, request );
}
catch ( IOException e )
{
_log.error( "Could not register Struts module for path " + modulePath, e );
}
catch ( ServletException e )
{
_log.error( "Could not register Struts module for path " + modulePath, e.getRootCause() );
}
}
}
return mc;
}
/**
* Create a page flow of the given type. The page flow stack (for nesting) will be cleared or pushed, and the new
* instance will be stored as the current page flow.
* @deprecated Use {@link #createPageFlow(RequestContext, Class)} instead.
*
* @param request the current HttpServletRequest.
* @param response the current HttpServletResponse.
* @param pageFlowClass the type of the desired page flow.
* @param servletContext the current ServletContext.
* @return the newly-created {@link PageFlowController}, or <code>null</code> if none was found.
*/
public static PageFlowController getPageFlow( Class pageFlowClass, HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext )
{
try
{
FlowControllerFactory factory = get( servletContext );
return factory.createPageFlow( new RequestContext( request, response ), pageFlowClass );
}
catch ( InstantiationException e )
{
_log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e );
return null;
}
catch ( IllegalAccessException e )
{
_log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e );
return null;
}
}
}