You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ri...@apache.org on 2005/02/03 21:57:53 UTC
svn commit: r151229 [1/2] - in incubator/beehive/trunk/netui:
src/compiler/org/apache/beehive/netui/compiler/
src/compiler/org/apache/beehive/netui/compiler/genmodel/
src/compiler/org/apache/beehive/netui/compiler/grammar/
src/pageflow/org/apache/beehive/netui/pageflow/
src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/
src/pageflow/org/apache/beehive/netui/pageflow/handler/
src/pageflow/org/apache/beehive/netui/pageflow/internal/
src/util/org/apache/beehive/netui/util/ src/webapp-template/default/WEB-INF/
test/webapps/drt/coreWeb/WEB-INF/src/mockportal/
test/webapps/drt/coreWeb/miniTests/generics/
test/webapps/drt/coreWeb/miniTests/passAssignableFormBeanToAction/
test/webapps/drt/testRecorder/config/ test/webapps/drt/testRecorder/tests/
Author: rich
Date: Thu Feb 3 12:57:47 2005
New Revision: 151229
URL: http://svn.apache.org/viewcvs?view=rev&rev=151229
Log:
Fixes for:
- http://issues.apache.org/jira/browse/BEEHIVE-233 : page flow actions can't use generic type-variables as arguments
- http://issues.apache.org/jira/browse/BEEHIVE-234 : Confusing errors when hitting a page flow whose class is missing or not accessible
- http://issues.apache.org/jira/browse/BEEHIVE-238 : Invalid error for missing returnAction on an abstract nested page flow
Also, replaced all the static methods in FlowControllerFactory with instance methods (and a static get()), so the factory itself could be plugged in the future.
DRT/BVT: netui (WinXP)
BB: self (linux)
Added:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java (with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/generics/
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/generics/Controller.jpf (with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/generics/index.jsp (with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/passAssignableFormBeanToAction/
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/passAssignableFormBeanToAction/Controller.jpf (with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/passAssignableFormBeanToAction/index.jsp (with props)
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/Generics.xml (with props)
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/PassAssignableFormBeanToAction.xml (with props)
Modified:
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/PageFlowChecker.java
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionModel.java
incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/MemberFieldType.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/AutoRegisterActionServlet.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/DynamicSubappActionServlet.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowActionServlet.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowController.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowPageFilter.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowUtils.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/RequestContext.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/PageFlowNavigationHandler.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/handler/FlowControllerHandlerContext.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/InternalUtils.java
incubator/beehive/trunk/netui/src/util/org/apache/beehive/netui/util/netui.properties
incubator/beehive/trunk/netui/src/webapp-template/default/WEB-INF/netui-validator-rules.xml
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/mockportal/MockPortletTag.java
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/CompilerUtils.java Thu Feb 3 12:57:47 2005
@@ -28,6 +28,7 @@
import com.sun.mirror.type.DeclaredType;
import com.sun.mirror.type.InterfaceType;
import com.sun.mirror.type.ArrayType;
+import com.sun.mirror.type.TypeVariable;
import com.sun.mirror.util.SourcePosition;
import com.sun.mirror.util.DeclarationVisitor;
import com.sun.mirror.util.Declarations;
@@ -1171,5 +1172,16 @@
{
return _val;
}
+ }
+
+ public static TypeMirror getGenericBoundsType( TypeMirror type )
+ {
+ if ( type instanceof TypeVariable )
+ {
+ Collection< ReferenceType > bounds = ( ( TypeVariable ) type ).getDeclaration().getBounds();
+ return bounds.size() > 0 ? bounds.iterator().next() : type;
+ }
+
+ return type;
}
}
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/FlowControllerChecker.java Thu Feb 3 12:57:47 2005
@@ -28,6 +28,8 @@
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.type.DeclaredType;
import com.sun.mirror.type.ClassType;
+import com.sun.mirror.type.TypeVariable;
+import com.sun.mirror.type.ReferenceType;
import java.io.File;
import java.io.IOException;
@@ -436,7 +438,7 @@
if ( nParameters > 0 )
{
- TypeMirror argType = parameters.iterator().next().getType();
+ TypeMirror argType = CompilerUtils.getGenericBoundsType( parameters.iterator().next().getType() );
if ( ! ( argType instanceof DeclaredType ) )
{
@@ -504,7 +506,8 @@
if ( memberForm != null )
{
- TypeMirror memberFormType = memberForm.getType();
+ TypeMirror memberFormType = CompilerUtils.getGenericBoundsType( memberForm.getType() );
+
String memberFormTypeName =
memberFormType instanceof DeclaredType
? CompilerUtils.getDeclaration( ( DeclaredType ) memberFormType ).getQualifiedName()
@@ -517,7 +520,7 @@
}
else
{
- if ( ! CompilerUtils.isAssignableFrom( argTypeDecl, memberForm.getType() ))
+ if ( ! CompilerUtils.isAssignableFrom( argTypeDecl, memberFormType ))
{
getDiagnostics().addError( method, "error.action-mismatched-form", USE_FORM_BEAN_ATTR,
formMemberName, memberFormTypeName );
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/PageFlowChecker.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/PageFlowChecker.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/PageFlowChecker.java (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/PageFlowChecker.java Thu Feb 3 12:57:47 2005
@@ -236,8 +236,10 @@
//
// Make sure every .jpf has a begin action if the class isn't abstract.
//
+ boolean isAbstract = CompilerUtils.hasModifier( jpfClass, Modifier.ABSTRACT );
+
if ( ! WebappPathOrActionType.actionExists( BEGIN_ACTION_NAME, jpfClass, null, getEnv(), getFlowControllerInfo(), true )
- && ! CompilerUtils.hasModifier( jpfClass, Modifier.ABSTRACT ) )
+ && ! isAbstract )
{
getDiagnostics().addError( jpfClass, "error.no-begin-action" );
}
@@ -247,10 +249,11 @@
//
if ( getFlowControllerInfo().isNested() )
{
- if ( getFlowControllerInfo().countReturnActions() == 0 )
+ if ( ! isAbstract && getFlowControllerInfo().countReturnActions() == 0 )
{
getDiagnostics().addError( jpfClass, "error.no-return-action",
- ANNOTATION_INTERFACE_PREFIX + FORWARD_TAG_NAME );
+ ANNOTATION_INTERFACE_PREFIX + FORWARD_TAG_NAME,
+ RETURN_ACTION_ATTR );
}
}
}
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/diagnostics.properties Thu Feb 3 12:57:47 2005
@@ -21,7 +21,7 @@
error.no-begin-action = There is no begin action defined for this PageFlowController.
error.no-return-action = \
-There is no {0} annotation with the returnAction attribute defined for this nested PageFlowController.
+There is no {0} annotation with the {1} attribute defined for this nested PageFlowController.
warning.file-not-found = File "{0}" could not be found in the web application.
error.file-not-found = File "{0}" could not be found in the web application.
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionModel.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionModel.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionModel.java (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/genmodel/GenActionModel.java Thu Feb 3 12:57:47 2005
@@ -185,7 +185,8 @@
if ( params.size() > 0 )
{
assert params.size() == 1 : params.size(); // checker should catch this
- formBeanName = addFormBean( params.iterator().next().getType(), parentApp );
+ TypeMirror paramType = CompilerUtils.getGenericBoundsType( params.iterator().next().getType() );
+ formBeanName = addFormBean( paramType, parentApp );
}
return formBeanName;
@@ -193,6 +194,7 @@
protected String addFormBean( TypeMirror paramType, GenStrutsApp parentApp )
{
+ paramType = CompilerUtils.getGenericBoundsType( paramType );
assert paramType instanceof DeclaredType : paramType.getClass().getName(); // checker should enforce this
TypeDeclaration decl = CompilerUtils.getDeclaration( ( DeclaredType ) paramType );
String formBeanName = parentApp.addFormBean( decl, this );
Modified: incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/MemberFieldType.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/MemberFieldType.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/MemberFieldType.java (original)
+++ incubator/beehive/trunk/netui/src/compiler/org/apache/beehive/netui/compiler/grammar/MemberFieldType.java Thu Feb 3 12:57:47 2005
@@ -25,6 +25,7 @@
import com.sun.mirror.declaration.MemberDeclaration;
import com.sun.mirror.declaration.FieldDeclaration;
import com.sun.mirror.declaration.AnnotationTypeElementDeclaration;
+import com.sun.mirror.type.TypeMirror;
import java.util.Collection;
@@ -53,11 +54,12 @@
{
if ( field.getSimpleName().equals( fieldName ) )
{
+ TypeMirror fieldType = CompilerUtils.getGenericBoundsType( field.getType() );
+
if ( _requiredSuperclassName != null
- && ! CompilerUtils.isAssignableFrom( _requiredSuperclassName, field.getType(), getEnv() ) )
+ && ! CompilerUtils.isAssignableFrom( _requiredSuperclassName, fieldType, getEnv() ) )
{
- addError( member, "error.wrong-field-type",
- new Object[]{ fieldName, _requiredSuperclassName } );
+ addError( member, "error.wrong-field-type", new Object[]{ fieldName, _requiredSuperclassName } );
return null;
}
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/AutoRegisterActionServlet.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/AutoRegisterActionServlet.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/AutoRegisterActionServlet.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/AutoRegisterActionServlet.java Thu Feb 3 12:57:47 2005
@@ -92,15 +92,15 @@
private static final ModuleConfig NONEXISTANT_MODULE_CONFIG = new NonexistantModuleConfig();
- public void init( ServletConfig servletConfig )
+ public void init()
throws ServletException
{
- super.init( servletConfig );
- _handlers = Handlers.get( servletConfig.getServletContext() );
- setupModuleConfigLocators( servletConfig );
+ super.init();
+ _handlers = Handlers.get( getServletContext() );
+ setupModuleConfigLocators();
}
- private void setupModuleConfigLocators( ServletConfig servletConfig )
+ private void setupModuleConfigLocators()
{
ModuleConfigLocator[] defaultLocators = getDefaultModuleConfigLocators();
ArrayList< ModuleConfigLocator > locators = new ArrayList< ModuleConfigLocator >();
@@ -133,7 +133,7 @@
//
// Look for ModuleConfigLocators specified in web.xml (deprecated method for specifying them).
//
- String configLocatorList = servletConfig.getInitParameter( MODULE_CONFIG_LOCATOR_CLASS_ATTR );
+ String configLocatorList = getServletConfig().getInitParameter( MODULE_CONFIG_LOCATOR_CLASS_ATTR );
if ( configLocatorList != null )
{
@@ -669,6 +669,7 @@
//
// If we're not in production mode, send a diagnostic on the response; otherwise, simply send a 404.
//
+ if ( modulePath.length() == 0 ) modulePath = "/";
InternalUtils.sendDevTimeError( "PageFlow_NoModuleConf", null, HttpServletResponse.SC_NOT_FOUND,
request, response, servletContext, relativeURI, modulePath );
}
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/DynamicSubappActionServlet.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/DynamicSubappActionServlet.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/DynamicSubappActionServlet.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/DynamicSubappActionServlet.java Thu Feb 3 12:57:47 2005
@@ -37,9 +37,9 @@
{
private static final Logger _log = Logger.getInstance( DynamicSubappActionServlet.class );
- public void init( ServletConfig config ) throws ServletException
+ public void init() throws ServletException
{
- super.init( config );
+ super.init();
if ( _log.isWarnEnabled() )
{
Added: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java?view=auto&rev=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java (added)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java Thu Feb 3 12:57:47 2005
@@ -0,0 +1,35 @@
+/*
+ * 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 javax.servlet.ServletContext;
+
+public abstract class Factory
+{
+ private ServletContext _servletContext;
+
+ protected Factory( ServletContext servletContext )
+ {
+ _servletContext = servletContext;
+ }
+
+ protected ServletContext getServletContext()
+ {
+ return _servletContext;
+ }
+}
Propchange: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FlowControllerFactory.java Thu Feb 3 12:57:47 2005
@@ -22,11 +22,14 @@
import org.apache.beehive.netui.util.config.bean.PageflowConfig;
import org.apache.beehive.netui.pageflow.internal.InternalUtils;
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;
@@ -38,57 +41,63 @@
/**
- * Factory for creating {@link FlowController}s - user {@link PageFlowController}s and
- * Global.app.
+ * 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 ReloadableClassHandler _rch;
+
+ protected FlowControllerFactory( ServletContext servletContext )
+ {
+ super( servletContext );
+ _rch = Handlers.get( servletContext ).getReloadableClassHandler();
+ }
/**
- * Get the {@link PageFlowController} instance that should be associated with the given request,
- * based on the path of the request URI. If it doesn't exist, create it.
- * The PageFlowController stack (for nesting) will be cleared or pushed, and the new instance
- * will be stored as the current PageFlowController.
+ * Get a FlowControllerFactory.
*
- * @param request the current HttpServletRequest.
* @param servletContext the current ServletContext.
- * @return the PageFlowController for the request, or <code>null</code> if none was found
- * and none could be created.
- */
- public static PageFlowController getPageFlowForRequest( HttpServletRequest request, HttpServletResponse response,
- ServletContext servletContext )
+ * @return a FlowControllerFactory for the given ServletContext. It may or may not be a cached instance.
+ */
+ public static FlowControllerFactory get( ServletContext servletContext )
{
- return getPageFlowForRelativeURI( request, response, InternalUtils.getDecodedServletPath( request ), servletContext );
- }
+ return new FlowControllerFactory( servletContext );
+ }
- public static PageFlowController getPageFlowForURI( HttpServletRequest request, HttpServletResponse response,
- String uri, ServletContext servletContext )
+ /**
+ * 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
{
- return getPageFlowForRelativeURI( request, response, PageFlowUtils.getRelativeURI( request, uri, null ),
- servletContext );
- }
+ String servletPath = InternalUtils.getDecodedServletPath( context.getHttpRequest() );
+ return getPageFlowForPath( context, servletPath );
+ }
/**
- * Get the {@link PageFlowController} instance that should be associated with the given URI.
- * If it doesn't exist, create it. The PageFlowController stack (for
- * nesting) will be cleared or pushed, and the new instance will be stored as the current
- * PageFlowController.
+ * 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 request the current HttpServletRequest.
- * @param response the current HttpServletResponse.
- * @param relativeURI the webapp-relative URI for the page flow.
- * @param servletContext the current ServletContext.
- * @return the PageFlowController for the request, or <code>null</code> if none was found
- * and none could be created.
+ * @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 static PageFlowController getPageFlowForRelativeURI( HttpServletRequest request,
- HttpServletResponse response, String relativeURI,
- ServletContext servletContext )
+ public PageFlowController getPageFlowForPath( RequestContext context, String path )
+ throws InstantiationException, IllegalAccessException
{
+ HttpServletRequest request = context.getHttpRequest();
+ HttpServletResponse response = context.getHttpResponse();
PageFlowController cur = PageFlowUtils.getCurrentPageFlow( request );
- String parentDir = PageFlowUtils.getModulePathForRelativeURI( relativeURI );
+ String parentDir = PageFlowUtils.getModulePathForRelativeURI( path );
//
// If there's no current PageFlow, or if the current PageFlowController has a module path that
@@ -96,32 +105,302 @@
//
if ( cur == null || ! PageFlowUtils.getModulePathForRelativeURI( cur.getURI() ).equals( parentDir ) )
{
- String jpfClassName = InternalUtils.getFlowControllerClassName( parentDir, request, servletContext );
- return jpfClassName != null ? getPageFlow( jpfClassName, request, response, servletContext ) : null;
+ 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;
+ }
}
//
// Reinitialize transient data that may have been lost on session failover.
//
- cur.reinitialize( request, response, servletContext );
+ cur.reinitialize( request, response, getServletContext() );
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 );
}
- public static Map<String, SharedFlowController> getSharedFlowsForRequest( HttpServletRequest request,
- HttpServletResponse response,
- ServletContext servletContext )
+ /**
+ * 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
{
- String relativeURI = InternalUtils.getDecodedServletPath( request );
- return getSharedFlowsForRelativeURI( request, response, relativeURI, servletContext );
+ 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, false );
+
+ if ( isNestable && pfStack != null )
+ {
+ PageflowConfig options = ConfigUtil.getConfig().getPageflowConfig();
+
+ if ( options == null || ! options.getEnableRenesting() )
+ {
+ 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 ) pageFlowClass.newInstance();
+ 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.
+ //
+ retVal.create( request, response, servletContext );
+ PageFlowController current = PageFlowUtils.getCurrentPageFlow( request );
+
+ if ( current != null )
+ {
+ if ( _log.isDebugEnabled() )
+ {
+ _log.debug( "Pushing PageFlowController " + current + " onto the nesting stack" );
+ }
+
+ if ( pfStack == null ) pfStack = PageFlowStack.get( request, true );
+ pfStack.push( current, request );
+ }
+
+ 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;
}
- public static Map<String, SharedFlowController> getSharedFlowsForRelativeURI( HttpServletRequest request,
- HttpServletResponse response,
- String relativeURI,
- ServletContext servletContext )
+ /**
+ * 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 ) sharedFlowClass.newInstance();
+ 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}) 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 parentDir = PageFlowUtils.getModulePathForRelativeURI( relativeURI );
- ModuleConfig mc = InternalUtils.ensureModuleConfig( parentDir, request, servletContext );
+ 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}) 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() );
if ( mc != null )
{
@@ -147,21 +426,14 @@
//
if ( sf != null )
{
- sf.reinitialize( request, response, servletContext );
+ sf.reinitialize( request, context.getHttpResponse(), getServletContext() );
}
else
{
- try
- {
- sf = getSharedFlow( className, request, response, servletContext );
- }
- catch ( ClassNotFoundException e )
- {
- _log.error( "Requested shared flow class " + className + " not found." );
- }
+ sf = createSharedFlow( context, className );
}
- if ( sf != null && ! ( sf instanceof GlobalApp ) ) sharedFlows.put( name, sf );
+ if ( ! ( sf instanceof GlobalApp ) ) sharedFlows.put( name, sf );
}
return sharedFlows;
@@ -176,48 +448,140 @@
if ( ga != null )
{
- ga.reinitialize( request, response, servletContext );
+ ga.reinitialize( request, response, getServletContext() );
}
else
{
- getGlobalApp( request, response, servletContext );
+ getGlobalApp( request, response, getServletContext() );
}
return null;
}
/**
- * Get the {@link PageFlowController} for the given type. The PageFlowController stack (for
- * nesting) will be cleared or pushed, and the new instance will be stored as the current
- * PageFlowController.
+ * 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 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 jpfClassName the name of the desired PageFlowController class.
* @param request the current HttpServletRequest.
- * @return the current user session's PageFlowController if it is of the requested type,
- * or a newly-created one, or <code>null</code> if none could be found or created.
+ * @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 getPageFlow( String jpfClassName, HttpServletRequest request,
+ 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
{
- Class jpfClass = InternalUtils.getReloadableClass( jpfClassName, servletContext );
- return getPageFlow( jpfClass, request, response, servletContext );
+ return get( servletContext ).createPageFlow( new RequestContext( request, response ), pageFlowClassName );
}
catch ( ClassNotFoundException e)
{
- if ( _log.isErrorEnabled() ) _log.error( "Requested page flow class " + jpfClassName + " not found." );
+ 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.
- * @return the current session's 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.
+ * @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 )
@@ -227,17 +591,31 @@
try
{
- SharedFlowController sf =
- getSharedFlow( PageFlowConstants.GLOBALAPP_CLASSNAME, request, response, servletContext );
-
- if ( ! ( sf instanceof GlobalApp ) )
+ 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( "Class " + PageFlowConstants.GLOBALAPP_CLASSNAME + " is not an instance of "
- + GlobalApp.class.getName() );
+ _log.error( "Could not instantiate Global.app.", e );
+ return null;
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( "Could not instantiate Global.app", e );
return null;
}
-
- return ( GlobalApp ) sf;
}
catch ( ClassNotFoundException e )
{
@@ -246,15 +624,7 @@
}
}
- public static SharedFlowController getSharedFlow( String sharedFlowClassName, HttpServletRequest request,
- HttpServletResponse response, ServletContext servletContext )
- throws ClassNotFoundException
- {
- Class sfClass = InternalUtils.getReloadableClass( sharedFlowClassName, servletContext );
- return getSharedFlow( sfClass, request, response, servletContext );
- }
-
- private static ModuleConfig ensureModule( String modulePath, HttpServletRequest request,
+ private static ModuleConfig ensureModule( String modulePath, ServletRequest request,
ServletContext servletContext )
{
ModuleConfig mc = InternalUtils.getModuleConfig( modulePath, servletContext );
@@ -286,227 +656,32 @@
}
/**
- * Get the {@link PageFlowController} for the given type. The PageFlowController stack (for
- * nesting) will be cleared or pushed, and the new instance will be stored as the current
- * PageFlowController.
+ * 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 jpfClass the desired PageFlowController class.
* @param request the current HttpServletRequest.
- * @return the current user session's PageFlowController if it is of the requested type,
- * or a newly-created one, or <code>null</code> if none could be found or created.
+ * @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 jpfClass, HttpServletRequest request,
+ public static PageFlowController getPageFlow( Class pageFlowClass, HttpServletRequest request,
HttpServletResponse response, ServletContext servletContext )
{
- if ( ! PageFlowController.class.isAssignableFrom( jpfClass ) )
- {
- return null;
- }
-
try
{
- //
- // First check if this is a request for a "long lived" page flow. If so, try
- // PageFlowUtils.getCurrentPageFlow again, with the longLived flag.
- //
- PageFlowController retVal = null;
- String modulePath = InternalUtils.inferModulePathFromClassName( jpfClass.getName() );
- ModuleConfig mc = ensureModule( modulePath, request, servletContext );
-
- if ( mc == null )
- {
- _log.error( "Struts module " + modulePath + " not found for " + jpfClass.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 " + jpfClass.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, false );
-
- if ( isNestable && pfStack != null )
- {
- PageflowConfig options = ConfigUtil.getConfig().getPageflowConfig();
-
- if ( options == null || ! options.getEnableRenesting() )
- {
- int lastIndexOfJpfClass = pfStack.lastIndexOf( request, jpfClass );
-
- 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 " + jpfClass.getName() );
- }
-
- retVal = ( PageFlowController ) jpfClass.newInstance();
- 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.
- //
- retVal.create( request, response, servletContext );
- PageFlowController current = PageFlowUtils.getCurrentPageFlow( request );
-
- if ( current != null )
- {
- if ( _log.isDebugEnabled() )
- {
- _log.debug( "Pushing PageFlowController " + current + " onto the nesting stack" );
- }
-
- if ( pfStack == null ) pfStack = PageFlowStack.get( request, true );
- pfStack.push( current, request );
- }
-
- 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;
- }
- catch ( InstantiationException e )
- {
- _log.error( "Could not instantiate PageFlowController of type " + jpfClass.getName(), e );
- return null;
- }
- catch ( IllegalAccessException e )
- {
- _log.error( "Could not instantiate PageFlowController of type " + jpfClass.getName(), e );
- return null;
- }
- }
-
- public static SharedFlowController getSharedFlow( Class sfClass, HttpServletRequest request,
- HttpServletResponse response, ServletContext servletContext )
- {
- assert SharedFlowController.class.isAssignableFrom( sfClass ) : sfClass.getName();
-
- if ( _log.isDebugEnabled() )
- {
- _log.debug( "Creating SharedFlowController of type " + sfClass.getName() );
- }
-
- try
- {
- SharedFlowController retVal = ( SharedFlowController ) sfClass.newInstance();
- retVal.create( request, response, servletContext );
-
- if ( _log.isDebugEnabled() )
- {
- _log.debug( "Storing " + retVal + " in the session..." );
- }
-
- retVal.persistInSession( request, response );
- return retVal;
+ FlowControllerFactory factory = get( servletContext );
+ return factory.createPageFlow( new RequestContext( request, response ), pageFlowClass );
}
catch ( InstantiationException e )
{
- _log.error( "Could not instantiate SharedFlowController of type " + sfClass.getName(), e );
+ _log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e );
return null;
}
catch ( IllegalAccessException e )
{
- _log.error( "Could not instantiate SharedFlowController of type " + sfClass.getName(), e );
+ _log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e );
return null;
}
}
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowActionServlet.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowActionServlet.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowActionServlet.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowActionServlet.java Thu Feb 3 12:57:47 2005
@@ -98,19 +98,20 @@
}
}
- public void init( ServletConfig config )
+ public void init()
throws ServletException
{
+ super.init();
+
//
// Ensure that PageFlowContextListener gets to do its initializations, even if it's not registered in web.xml.
//
- ServletContext servletContext = config.getServletContext();
+ ServletContext servletContext = getServletContext();
+
if ( ! PageFlowContextListener.isInit( servletContext ) )
{
PageFlowContextListener.performInitializations( servletContext );
}
-
- super.init( config );
}
/**
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowController.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowController.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowController.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowController.java Thu Feb 3 12:57:47 2005
@@ -824,8 +824,22 @@
_log.debug( "Self-nesting page flow " + getURI() );
}
- // This will cause the right pageflow stack stuff to happen.
- FlowControllerFactory.getPageFlow( getClass(), request, response, getServletContext() );
+ try
+ {
+ // This will cause the right pageflow stack stuff to happen.
+ RequestContext rc = new RequestContext( request, response );
+ FlowControllerFactory.get( getServletContext() ).createPageFlow( rc, getClass() );
+ }
+ catch ( IllegalAccessException e )
+ {
+ // This should never happen -- if we successfully created this page flow once, we can do it again.
+ assert false : e;
+ _log.error( e );
+ }
+ catch ( InstantiationException e )
+ {
+ _log.error( "Could not create PageFlowController instance of type " + getClass().getName(), e );
+ }
}
}
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowPageFilter.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowPageFilter.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowPageFilter.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowPageFilter.java Thu Feb 3 12:57:47 2005
@@ -36,7 +36,6 @@
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
-import org.apache.struts.action.RequestProcessor;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.Globals;
@@ -59,6 +58,7 @@
{
private ServletContext _servletContext;
private ServletContainerAdapter _servletContainerAdapter;
+ private FlowControllerFactory _flowControllerFactory;
private static final Logger _log = Logger.getInstance( PageFlowPageFilter.class );
@@ -73,6 +73,7 @@
{
_servletContext = servletContext;
_servletContainerAdapter = AdapterManager.getServletContainerAdapter( _servletContext );
+ _flowControllerFactory = FlowControllerFactory.get( servletContext );
}
public void init( FilterConfig filterConfig ) throws ServletException
@@ -85,6 +86,7 @@
}
_servletContainerAdapter = AdapterManager.getServletContainerAdapter( _servletContext );
+ _flowControllerFactory = FlowControllerFactory.get( _servletContext );
}
protected abstract Set getValidFileExtensions();
@@ -170,38 +172,53 @@
MessageResources prevMessageResources = ( MessageResources ) request.getAttribute( Globals.MESSAGES_KEY );
initializeModule( httpRequest, httpResponse );
- //
- // Initialize shared flows for the current request.
- //
- Map< String, SharedFlowController > sharedFlows =
- FlowControllerFactory.getSharedFlowsForRequest( httpRequest, httpResponse, _servletContext );
- ImplicitObjectUtil.loadSharedFlow( request, sharedFlows );
- ImplicitObjectUtil.loadGlobalApp( request, PageFlowUtils.getGlobalApp( httpRequest ) );
-
- //
- // Make sure that the current PageFlowController is set up for this request.
- //
- PageFlowController curJpf =
- FlowControllerFactory.getPageFlowForRequest( httpRequest, httpResponse, _servletContext );
-
- //
- // If there is no pageflow for the current Struts module, than fall back to default
- // Struts behavior, which is *not* to allow a page request to set the current module.
- //
- if ( curJpf == null )
+ try
{
- InternalUtils.setCurrentModule( prevModuleConfig, request );
- request.setAttribute( Globals.MESSAGES_KEY, prevMessageResources );
+ //
+ // Initialize shared flows for the current request.
+ //
+ RequestContext requestContext = new RequestContext( request, response );
+ Map< String, SharedFlowController > sharedFlows =
+ _flowControllerFactory.getSharedFlowsForRequest( requestContext );
+ ImplicitObjectUtil.loadSharedFlow( request, sharedFlows );
+ ImplicitObjectUtil.loadGlobalApp( request, PageFlowUtils.getGlobalApp( httpRequest ) );
+
+ //
+ // Make sure that the current PageFlowController is set up for this request.
+ //
+ PageFlowController curJpf = _flowControllerFactory.getPageFlowForRequest( requestContext );
+
+ //
+ // If there is no pageflow for the current Struts module, than fall back to default
+ // Struts behavior, which is *not* to allow a page request to set the current module.
+ //
+ if ( curJpf == null )
+ {
+ InternalUtils.setCurrentModule( prevModuleConfig, request );
+ request.setAttribute( Globals.MESSAGES_KEY, prevMessageResources );
+ }
+
+
+ if ( _log.isDebugEnabled() )
+ {
+ _log.debug( "Current PageFlowController is: " + curJpf );
+ _log.debug( "Continuing with filter chain..." );
+ }
+
+ runPage( curJpf, httpRequest, httpResponse, chain );
}
-
-
- if ( _log.isDebugEnabled() )
+ catch ( ClassNotFoundException e )
{
- _log.debug( "Current PageFlowController is: " + curJpf );
- _log.debug( "Continuing with filter chain..." );
+ throw new ServletException( e );
+ }
+ catch ( InstantiationException e )
+ {
+ throw new ServletException( e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ throw new ServletException( e );
}
-
- runPage( curJpf, httpRequest, httpResponse, chain );
}
finally
{
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java Thu Feb 3 12:57:47 2005
@@ -126,6 +126,7 @@
private Map< String, List< ActionMapping > > _overloadedActions = new HashMap< String, List< ActionMapping > >();
private ServletContainerAdapter _servletContainerAdapter;
private Handlers _handlers;
+ private FlowControllerFactory _flowControllerFactory;
private LegacySettings _legacySettings;
private ConcurrentHashMap< String, Class > _pageServletClasses = new ConcurrentHashMap< String, Class >();
private PageFlowPageFilter _pageServletFilter;
@@ -538,30 +539,40 @@
_log.info( "Attempting to instantiate SharedFlowControllers for request " + request.getRequestURI() );
}
- Map< String, SharedFlowController > sharedFlows =
- FlowControllerFactory.getSharedFlowsForRequest( request, response, servletContext );
- ImplicitObjectUtil.loadSharedFlow( request, sharedFlows );
- ImplicitObjectUtil.loadGlobalApp( request, PageFlowUtils.getGlobalApp( request ) );
-
FlowController currentFlowController = null;
- if ( flowControllerClassName != null )
+ try
{
- try
+ RequestContext requestContext = new RequestContext( request, response );
+ Map< String, SharedFlowController > sharedFlows =
+ _flowControllerFactory.getSharedFlowsForRequest( requestContext );
+ ImplicitObjectUtil.loadSharedFlow( request, sharedFlows );
+ ImplicitObjectUtil.loadGlobalApp( request, PageFlowUtils.getGlobalApp( request ) );
+
+ if ( flowControllerClassName != null )
{
- currentFlowController =
- InternalUtils.getFlowController( flowControllerClassName, request, response, servletContext );
+ currentFlowController = getFlowController( requestContext, flowControllerClassName );
RequestValues.setCurrentFlowController( request, currentFlowController );
}
- catch ( ClassNotFoundException e )
+ else
{
- _log.error( "Could not find FlowController class " + flowControllerClassName, e );
- throw new ServletException( e );
+ RequestValues.removeCurrentFlowController( request );
}
}
- else
+ catch ( ClassNotFoundException e )
{
- RequestValues.removeCurrentFlowController( request );
+ _log.error( "Could not find FlowController class " + flowControllerClassName, e );
+ throw new ServletException( e );
+ }
+ catch ( InstantiationException e )
+ {
+ _log.error( "Could not instantiate FlowController of type " + flowControllerClassName, e );
+ throw new ServletException( e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( "Could not instantiate FlowController of type " + flowControllerClassName, e );
+ throw new ServletException( e );
}
//
@@ -595,6 +606,49 @@
}
}
+ private FlowController getFlowController( RequestContext requestContext, String fcClassName )
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException
+ {
+ Class fcClass = _flowControllerFactory.getFlowControllerClass( fcClassName );
+ HttpServletRequest request = requestContext.getHttpRequest();
+ HttpServletResponse response = requestContext.getHttpResponse();
+
+ if ( PageFlowController.class.isAssignableFrom( fcClass ) )
+ {
+ PageFlowController current = PageFlowUtils.getCurrentPageFlow( request );
+
+ if ( current != null && current.getClass().equals( fcClass ) )
+ {
+ if ( _log.isDebugEnabled() )
+ {
+ _log.debug( "Using current page flow: " + current );
+ }
+
+ //
+ // Reinitialize transient data that may have been lost on session failover.
+ //
+ current.reinitialize( request, response, getServletContext() );
+ return current;
+ }
+
+ return _flowControllerFactory.createPageFlow( new RequestContext( request, response ), fcClass );
+ }
+ else
+ {
+ assert SharedFlowController.class.isAssignableFrom( fcClass ) : fcClass.getName();
+
+ SharedFlowController current = PageFlowUtils.getSharedFlow( fcClass.getName(), request );
+
+ if ( current != null )
+ {
+ current.reinitialize( request, response, getServletContext() );
+ return current;
+ }
+
+ return _flowControllerFactory.createSharedFlow( new RequestContext( request, response ), fcClass );
+ }
+ }
+
private boolean handleException( Throwable th, FlowController fc, HttpServletRequest request,
HttpServletResponse response )
{
@@ -651,6 +705,7 @@
_log.error( msg.toString() );
}
+ if ( modulePath.length() == 0 ) modulePath = "/";
InternalUtils.sendDevTimeError( "PageFlow_NoModuleConf", null,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, request, response,
getServletContext(), uri, modulePath );
@@ -1001,6 +1056,7 @@
_servletContainerAdapter = AdapterManager.getServletContainerAdapter( getServletContext() );
_legacySettings = LegacySettings.get( getServletContext() );
_handlers = Handlers.get( getServletContext() );
+ _flowControllerFactory = FlowControllerFactory.get( getServletContext() );
//
// Cache a list of overloaded actions for each overloaded action path (actions are overloaded by form bean type).
@@ -1563,8 +1619,7 @@
Map attrs = new HashMap();
String queryString = null;
ServletContext servletContext = getServletContext();
- assert context.getRequest() instanceof HttpServletRequest : "don't support ServletRequest currently.";
- HttpServletRequest request = ( HttpServletRequest ) context.getRequest();
+ HttpServletRequest request = ( ( RequestContext ) context ).getHttpRequest();
for ( Enumeration e = request.getAttributeNames(); e.hasMoreElements(); )
{
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowUtils.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowUtils.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowUtils.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowUtils.java Thu Feb 3 12:57:47 2005
@@ -1003,8 +1003,23 @@
public static GlobalApp ensureGlobalApp( HttpServletRequest request, HttpServletResponse response,
ServletContext servletContext )
{
- Map< String, SharedFlowController > sf =
- FlowControllerFactory.getSharedFlowsForRequest( request, response, servletContext );
+ try
+ {
+ FlowControllerFactory.get( servletContext ).getSharedFlowsForRequest( new RequestContext( request, response ) );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ _log.error( e );
+ }
+ catch ( InstantiationException e )
+ {
+ _log.error( e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( e );
+ }
+
return getGlobalApp( request );
}
@@ -1092,7 +1107,21 @@
HttpServletResponse response,
ServletContext servletContext )
{
- return FlowControllerFactory.getPageFlowForRequest( request, response, servletContext );
+ try
+ {
+ FlowControllerFactory factory = FlowControllerFactory.get( servletContext );
+ return factory.getPageFlowForRequest( new RequestContext( request, response ) );
+ }
+ catch ( InstantiationException e )
+ {
+ _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
+ }
+
+ return null;
}
/**
@@ -1108,7 +1137,7 @@
_log.warn( "could not get ServletContext from request " + request );
}
- return FlowControllerFactory.getPageFlowForRequest( request, response, servletContext );
+ return ensureCurrentPageFlow( request, response, servletContext );
}
/**
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/RequestContext.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/RequestContext.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/RequestContext.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/RequestContext.java Thu Feb 3 12:57:47 2005
@@ -19,6 +19,8 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
public class RequestContext
{
@@ -39,5 +41,17 @@
public ServletResponse getResponse()
{
return _response;
+ }
+
+ HttpServletRequest getHttpRequest()
+ {
+ assert _request instanceof HttpServletRequest : "HttpServletRequest is currently required";
+ return ( HttpServletRequest ) _request;
+ }
+
+ HttpServletResponse getHttpResponse()
+ {
+ assert _response instanceof HttpServletResponse : "HttpServletResponse is currently required";
+ return ( HttpServletResponse ) _response;
}
}
Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/PageFlowNavigationHandler.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/PageFlowNavigationHandler.java?view=diff&r1=151228&r2=151229
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/PageFlowNavigationHandler.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/faces/internal/PageFlowNavigationHandler.java Thu Feb 3 12:57:47 2005
@@ -30,6 +30,7 @@
import org.apache.beehive.netui.pageflow.PageFlowUtils;
import org.apache.beehive.netui.pageflow.PageFlowConstants;
import org.apache.beehive.netui.pageflow.FlowControllerFactory;
+import org.apache.beehive.netui.pageflow.RequestContext;
import org.apache.beehive.netui.pageflow.internal.InternalConstants;
import org.apache.beehive.netui.util.logging.Logger;
@@ -76,39 +77,53 @@
return;
}
- ServletContext servletContext = ( ServletContext ) extContext;
- PageFlowController pfc = FlowControllerFactory.getPageFlowForRequest( httpRequest, httpResponse, servletContext );
- PageFlowUtils.getCurrentPageFlow( httpRequest );
-
- if ( pfc != null )
+ try
{
- if ( outcome != null )
+ ServletContext servletContext = ( ServletContext ) extContext;
+ FlowControllerFactory fcFactory = FlowControllerFactory.get( servletContext );
+ PageFlowController pfc = fcFactory.getPageFlowForRequest( new RequestContext( httpRequest, httpResponse ) );
+ PageFlowUtils.getCurrentPageFlow( httpRequest );
+
+ if ( pfc != null )
{
- String actionURI = outcome + PageFlowConstants.ACTION_EXTENSION;
-
- if ( _log.isDebugEnabled() )
- {
- _log.debug( "Forwarding to " + actionURI );
- }
-
- context.responseComplete();
- context.setViewRoot( null );
- httpRequest.setAttribute( ALREADY_FORWARDED_ATTR, Boolean.TRUE );
-
- try
- {
- httpRequest.getRequestDispatcher( actionURI ).forward( httpRequest, httpResponse );
- }
- catch ( IOException e )
- {
- _log.error( "Could not forward to " + actionURI, e );
- }
- catch ( ServletException e )
+ if ( outcome != null )
{
- _log.error( "Could not forward to " + actionURI, e.getRootCause() );
+ String actionURI = outcome + PageFlowConstants.ACTION_EXTENSION;
+
+ if ( _log.isDebugEnabled() )
+ {
+ _log.debug( "Forwarding to " + actionURI );
+ }
+
+ context.responseComplete();
+ context.setViewRoot( null );
+ httpRequest.setAttribute( ALREADY_FORWARDED_ATTR, Boolean.TRUE );
+
+ try
+ {
+ httpRequest.getRequestDispatcher( actionURI ).forward( httpRequest, httpResponse );
+ }
+ catch ( IOException e )
+ {
+ _log.error( "Could not forward to " + actionURI, e );
+ }
+ catch ( ServletException e )
+ {
+ _log.error( "Could not forward to " + actionURI, e.getRootCause() );
+ }
}
+
+ return;
}
-
+ }
+ catch ( InstantiationException e )
+ {
+ _log.error( "Could not instantiate PageFlowController for request " + httpRequest.getRequestURI(), e );
+ return;
+ }
+ catch ( IllegalAccessException e )
+ {
+ _log.error( "Could not instantiate PageFlowController for request " + httpRequest.getRequestURI(), e );
return;
}
}