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/06/09 02:43:54 UTC

svn commit: r189672 - in /incubator/beehive/trunk/netui: src/pageflow/org/apache/beehive/netui/pageflow/ src/pageflow/org/apache/beehive/netui/pageflow/internal/ src/pageflow/org/apache/beehive/netui/script/common/ src/util/schema/netui-config/ test/webapps/drt/coreWeb/WEB-INF/ test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/ test/webapps/drt/coreWeb/miniTests/flowControllerFactory/ test/webapps/drt/testRecorder/config/ test/webapps/drt/testRecorder/tests/

Author: rich
Date: Wed Jun  8 17:43:51 2005
New Revision: 189672

URL: http://svn.apache.org/viewcvs?rev=189672&view=rev
Log:
Fix for http://issues.apache.org/jira/browse/BEEHIVE-783 : Page Flow factory should be configurable

Also made FacesBackingBeanFactory work the same way as FlowControllerFactory -- obtained through a static get(), uses RequestContext, and overridden in beehive-netui-config, the same way that FlowControllerFactory is overridden.

tests: bvt in netui, bvt.myfaces/bvt.jsf-ri in netui/test/webapps/jsf (WinXP)
BB: self (linux)


Added:
    incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FacesBackingBeanFactory.java
      - copied, changed from r188692, incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/FacesBackingBeanFactory.java
    incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.java   (with props)
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java   (with props)
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java   (with props)
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp   (with props)
    incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml   (with props)
Removed:
    incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/FacesBackingBeanFactory.java
Modified:
    incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.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/PageFlowContextListener.java
    incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java
    incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
    incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/beehive-netui-config.xml
    incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml

Copied: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FacesBackingBeanFactory.java (from r188692, incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/FacesBackingBeanFactory.java)
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FacesBackingBeanFactory.java?p2=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FacesBackingBeanFactory.java&p1=incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/FacesBackingBeanFactory.java&r1=188692&r2=189672&rev=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/FacesBackingBeanFactory.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FacesBackingBeanFactory.java Wed Jun  8 17:43:51 2005
@@ -15,31 +15,96 @@
  *
  * $Header:$
  */
-package org.apache.beehive.netui.pageflow.internal;
+package org.apache.beehive.netui.pageflow;
 
-import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
-import org.apache.beehive.netui.pageflow.FacesBackingBean;
-import org.apache.beehive.netui.pageflow.PageFlowUtils;
+import org.apache.beehive.netui.pageflow.internal.InternalConstants;
+import org.apache.beehive.netui.pageflow.internal.InternalUtils;
+import org.apache.beehive.netui.pageflow.internal.AnnotationReader;
 import org.apache.beehive.netui.pageflow.handler.Handlers;
+import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
 import org.apache.beehive.netui.util.internal.FileUtils;
 import org.apache.beehive.netui.util.logging.Logger;
+import org.apache.beehive.netui.util.config.bean.PageflowFactories;
+import org.apache.beehive.netui.util.config.bean.PageflowFactory;
+import org.apache.beehive.netui.util.config.ConfigUtil;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.ServletContext;
 
 
-
+/**
+ * Factory for creating "backing beans" for JavaServer Faces pages.
+ */ 
 public class FacesBackingBeanFactory
+        extends Factory
         implements InternalConstants
 {
     private static final Logger _log = Logger.getInstance( FacesBackingBeanFactory.class );
     
+    private static final String CONTEXT_ATTR = InternalConstants.ATTR_PREFIX + "jsfBackingFactory";
+    
+    private ReloadableClassHandler _rch;
+    
+    protected void onCreate()
+    {
+    }
+    
+    protected FacesBackingBeanFactory()
+    {
+    }
+    
+    static void init( ServletContext servletContext )
+    {
+        PageflowFactories factoriesBean = ConfigUtil.getConfig().getPageflowFactories();
+        FacesBackingBeanFactory factory = null;
+        
+        if ( factoriesBean != null )
+        {
+            PageflowFactory fcFactoryBean = factoriesBean.getFlowcontrollerFactory();
+            factory = ( FacesBackingBeanFactory ) getFactory( servletContext, fcFactoryBean, FacesBackingBeanFactory.class );
+        }
+        
+        if ( factory == null ) factory = new FacesBackingBeanFactory();
+        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();
+    }
     
-    public static FacesBackingBean getFacesBackingBeanForRequest( HttpServletRequest request, 
-                                                                  HttpServletResponse response, 
-                                                                  ServletContext servletContext )
+    /**
+     * Get a FacesBackingBeanFactory.
+     * 
+     * @param servletContext the current ServletContext.
+     * @return a FacesBackingBeanFactory for the given ServletContext.  It may or may not be a cached instance.
+     */ 
+    public static FacesBackingBeanFactory get( ServletContext servletContext )
+    {
+        FacesBackingBeanFactory factory = ( FacesBackingBeanFactory ) servletContext.getAttribute( CONTEXT_ATTR );
+        assert factory != null
+                : FacesBackingBeanFactory.class.getName() + " was not found in ServletContext attribute " + CONTEXT_ATTR;
+        factory.reinit( servletContext );
+        return factory;
+    }
+        
+    /**
+     * Get the "backing bean" associated with the JavaServer Faces page for a request.
+     * 
+     * @param requestContext a {@link RequestContext} object which contains the current request and response.
+     */ 
+    public FacesBackingBean getFacesBackingBeanForRequest( RequestContext requestContext )
     {
+        HttpServletRequest request = requestContext.getHttpRequest();
         String uri = InternalUtils.getDecodedServletPath( request );
         assert uri.charAt( 0 ) == '/' : uri;
         String backingClassName = FileUtils.stripFileExtension( uri.substring( 1 ).replace( '/', '.' ) );
@@ -54,7 +119,7 @@
             
             if ( FileUtils.uriEndsWith( uri, FACES_EXTENSION ) || FileUtils.uriEndsWith( uri, JSF_EXTENSION ) )
             {
-                bean = loadFacesBackingBean( request, servletContext, backingClassName );
+                bean = loadFacesBackingBean( requestContext, backingClassName );
                 
                 //
                 // If we didn't create (or failed to create) a backing bean, and if this is a JSF request, then create
@@ -68,9 +133,11 @@
                 //
                 if ( bean != null )
                 {
+                    HttpServletResponse response = requestContext.getHttpResponse();
+                    
                     try
                     {
-                        bean.create( request, response, servletContext );
+                        bean.create( request, response, getServletContext() );
                     }
                     catch ( Exception e )
                     {
@@ -85,7 +152,7 @@
             //
             // We didn't create a backing bean.  If there's one in the session (an inappropriate one), remove it.
             //
-            InternalUtils.removeCurrentFacesBackingBean( request, servletContext );
+            InternalUtils.removeCurrentFacesBackingBean( request, getServletContext() );
         }
         else if ( currentBean != null )
         {
@@ -95,48 +162,62 @@
                             request.getRequestURI() );
             }
             
-            currentBean.reinitialize( request, response, servletContext );
+            currentBean.reinitialize( request, requestContext.getHttpResponse(), getServletContext() );
         }
         
         return currentBean;
     }
     
-    private static FacesBackingBean loadFacesBackingBean( HttpServletRequest request, ServletContext servletContext,
-                                                          String backingClassName )
+    /**
+     * Load a "backing bean" associated with the JavaServer Faces page for a request.
+     * @param requestContext a {@link RequestContext} object which contains the current request and response.
+     * @param backingClassName the name of the backing bean class.
+     * @return an initialized FacesBackingBean, or <code>null</code> if an error occurred.
+     */ 
+    protected FacesBackingBean loadFacesBackingBean( RequestContext requestContext, String backingClassName )
     {
         try
         {
-            Class backingClass =
-                Handlers.get( servletContext ).getReloadableClassHandler().loadCachedClass( backingClassName );
+            Class backingClass = null;
+            
+            try
+            {
+                backingClass = getFacesBackingBeanClass( backingClassName );
+            }
+            catch ( ClassNotFoundException e )
+            {
+                // ignore -- we deal with this and log this immediately below.  getFacesBackingBeanClass() by default
+                // does not throw this exception, but a derived version might.
+            }
                 
             if ( backingClass == null )
             {
                 if ( _log.isTraceEnabled() )
                 {
                     _log.trace( "No backing bean class " + backingClassName + " found for request "
-                                + request.getRequestURI() );
+                                + requestContext.getHttpRequest().getRequestURI() );
                 }
             }
             else
             {
-                AnnotationReader annReader = AnnotationReader.getAnnotationReader( backingClass, servletContext );
+                AnnotationReader annReader = AnnotationReader.getAnnotationReader( backingClass, getServletContext() );
                     
                 if ( annReader.getJpfAnnotation( backingClass, "FacesBacking" ) != null )
                 {
                     if ( _log.isDebugEnabled() )
                     {
                         _log.debug( "Found backing class " + backingClassName + " for request "
-                                    + request.getRequestURI() + "; creating a new instance." );
+                                    + requestContext.getHttpRequest().getRequestURI() + "; creating a new instance." );
                     }
                         
-                    return ( FacesBackingBean ) backingClass.newInstance();
+                    return getFacesBackingBeanInstance( backingClass );
                 }
                 else
                 {
                     if ( _log.isDebugEnabled() )
                     {
                         _log.debug( "Found matching backing class " + backingClassName + " for request " 
-                                    + request.getRequestURI() + ", but it does not have the "
+                                    + requestContext.getHttpRequest().getRequestURI() + ", but it does not have the "
                                     + ANNOTATION_QUALIFIER + "FacesBacking" + " annotation." );
                     }
                 }
@@ -157,5 +238,32 @@
     private static class DefaultFacesBackingBean
         extends FacesBackingBean
     {
+    }
+    
+    /**
+     * Get a FacesBackingBean class.  By default, this loads the class using the thread context class loader.
+     * 
+     * @param className the name of the {@link FacesBackingBean} class to load.
+     * @return the loaded {@link FacesBackingBean} class.
+     * @throws ClassNotFoundException if the requested class could not be found.
+     */ 
+    public Class getFacesBackingBeanClass( String className )
+        throws ClassNotFoundException
+    {
+        return _rch.loadCachedClass( className );
+    }
+    
+    /**
+     * Get a FacesBackingBean instance, given a FacesBackingBean class.
+     * 
+     * @param beanClass the Class, which must be assignable to {@link FacesBackingBean}.
+     * @return a new FacesBackingBean instance.
+     */ 
+    public FacesBackingBean getFacesBackingBeanInstance( Class beanClass )
+        throws InstantiationException, IllegalAccessException
+    {
+        assert FacesBackingBean.class.isAssignableFrom( beanClass )
+                : "Class " + beanClass.getName() + " does not extend " + FacesBackingBean.class.getName();
+        return ( FacesBackingBean ) beanClass.newInstance();
     }
 }

Modified: 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?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/Factory.java Wed Jun  8 17:43:51 2005
@@ -17,22 +17,115 @@
  */
 package org.apache.beehive.netui.pageflow;
 
+import org.apache.beehive.netui.util.config.bean.PageflowFactory;
+import org.apache.beehive.netui.util.config.bean.CustomProperty;
+import org.apache.beehive.netui.util.internal.DiscoveryUtils;
+import org.apache.beehive.netui.util.logging.Logger;
+
 import javax.servlet.ServletContext;
+import java.io.Serializable;
 
 /**
  * Base class for ServletContext-scoped factories.
  */ 
 public abstract class Factory
+        implements Serializable
 {
-    private ServletContext _servletContext;
+    private static final Logger _log = Logger.getInstance( Factory.class );
+    
+    private transient ServletContext _servletContext;
+    private FactoryConfig _config;
 
-    protected Factory( ServletContext servletContext )
+    /**
+     * Called after this factory has been created and initialized.
+     */ 
+    protected void onCreate()
+    {
+    }
+    
+    private void init( ServletContext servletContext, FactoryConfig config )
     {
         _servletContext = servletContext;
+        _config = config;
     }
-
+    
+    /**
+     * Called to reinitialize this instance, most importantly after it has been serialized/deserialized.
+     * 
+     * @param servletContext the current ServletContext.
+     */ 
+    protected void reinit( ServletContext servletContext )
+    {
+        _servletContext = servletContext;
+    }
+    
+    /**
+     * Get the current ServletContext.
+     */ 
     protected ServletContext getServletContext()
     {
         return _servletContext;
     }
-}
+
+    /**
+     * Get the configuration object (containing custom properties) that is associated with this factory.
+     */ 
+    protected FactoryConfig getConfig()
+    {
+        return _config;
+    }
+    
+    static Factory getFactory( ServletContext servletContext, PageflowFactory factoryBean, Class factoryType )
+    {
+        assert Factory.class.isAssignableFrom( factoryType ) : factoryType.getClass().getName();
+        
+        if ( factoryBean == null ) return null;
+        
+        String className = factoryBean.getFactoryClass();
+        ClassLoader cl = DiscoveryUtils.getClassLoader();
+        
+        try
+        {
+            Class actualFactoryType = cl.loadClass( className );
+            
+            if ( ! factoryType.isAssignableFrom( actualFactoryType ) )
+            {
+                _log.error( "Factory class " + actualFactoryType.getName() + " is not derived from "
+                            + factoryType.getName() );
+                return null;
+            }
+            
+            Factory factory = ( Factory ) actualFactoryType.newInstance();
+            CustomProperty[] props = factoryBean.getCustomPropertyArray();
+            FactoryConfig config = new FactoryConfig();
+            
+            if ( props != null )
+            {
+                for ( int i = 0; i < props.length; i++ )
+                {
+                    CustomProperty prop = props[i];
+                    config.addCustomProperty( prop.getName(), prop.getValue() );
+                }
+            }
+            
+            factory.init( servletContext, config );
+            factory.onCreate();
+            
+            return factory;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            _log.error( "Could not load factory class " + className, e );
+        }
+        catch ( InstantiationException e )
+        {
+            _log.error( "Could not instantiate a factory of type " + className, e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            _log.error( "Could not access the default constructor for factory of type " + className, e );
+        }
+        
+        return null;
+    }
+}
\ No newline at end of file

Added: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.java?rev=189672&view=auto
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.java (added)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.java Wed Jun  8 17:43:51 2005
@@ -0,0 +1,42 @@
+/*
+ * 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 java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+
+/**
+ * Configuration object passed to a {@link Factory}.
+ */ 
+public class FactoryConfig
+        implements Serializable
+{
+    private Map/*< String, String >*/ _customProperties = null;
+    
+    void addCustomProperty( String name, String value )
+    {
+        if ( _customProperties == null ) _customProperties = new HashMap();
+        _customProperties.put( name, value );
+    }
+    
+    public String getCustomProperty( String name )
+    {
+        return _customProperties != null ? ( String ) _customProperties.get( name ) : null;
+    }
+}

Propchange: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/FactoryConfig.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?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- 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 Wed Jun  8 17:43:51 2005
@@ -22,7 +22,10 @@
 import org.apache.beehive.netui.util.config.bean.PageflowConfig;
 import org.apache.beehive.netui.util.config.bean.DefaultSharedFlowRefs;
 import org.apache.beehive.netui.util.config.bean.SharedFlowRef;
+import org.apache.beehive.netui.util.config.bean.PageflowFactories;
+import org.apache.beehive.netui.util.config.bean.PageflowFactory;
 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;
@@ -51,14 +54,46 @@
 {
     private static final Logger _log = Logger.getInstance( FlowControllerFactory.class );
     
-    private ReloadableClassHandler _rch;
+    private static final String CONTEXT_ATTR = InternalConstants.ATTR_PREFIX + "fcFactory";
     
-    protected FlowControllerFactory( ServletContext servletContext )
+    private transient ReloadableClassHandler _rch;
+    
+    protected FlowControllerFactory()
+    {
+    }
+    
+    protected void onCreate()
     {
-        super( servletContext );
-        _rch = Handlers.get( servletContext ).getReloadableClassHandler();
     }
     
+    static void init( ServletContext servletContext )
+    {
+        PageflowFactories factoriesBean = ConfigUtil.getConfig().getPageflowFactories();
+        FlowControllerFactory factory = null;
+        
+        if ( factoriesBean != null )
+        {
+            PageflowFactory fcFactoryBean = factoriesBean.getFlowcontrollerFactory();
+            factory = ( FlowControllerFactory ) 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.
      * 
@@ -67,7 +102,11 @@
      */ 
     public static FlowControllerFactory get( ServletContext servletContext )
     {
-        return new FlowControllerFactory( 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;
     }
     
     /**
@@ -232,7 +271,7 @@
                 _log.debug( "Creating PageFlowController of type " + pageFlowClass.getName() );
             }
             
-            retVal = ( PageFlowController ) pageFlowClass.newInstance();
+            retVal = ( PageFlowController ) getFlowControllerInstance( pageFlowClass );
             createdNew = true;
         }
         
@@ -352,7 +391,7 @@
             _log.debug( "Creating SharedFlowController of type " + sharedFlowClass.getName() );
         }
         
-        SharedFlowController retVal = ( SharedFlowController ) sharedFlowClass.newInstance();
+        SharedFlowController retVal = ( SharedFlowController ) getFlowControllerInstance( sharedFlowClass );
         HttpServletRequest request = context.getHttpRequest();
         HttpServletResponse response = context.getHttpResponse();
         retVal.create( request, response, getServletContext() );
@@ -501,6 +540,7 @@
     
     /**
      * 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.
@@ -509,6 +549,20 @@
         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();
     }
     
     /**

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowContextListener.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowContextListener.java?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowContextListener.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowContextListener.java Wed Jun  8 17:43:51 2005
@@ -105,6 +105,8 @@
         LegacySettings.init( servletContext );
         Handlers.init( servletContext );
         URLTemplateDescriptor.getInstance().load( servletContext );
+        FlowControllerFactory.init( servletContext );
+        FacesBackingBeanFactory.init( servletContext );
         initPrefixHandlers();
     }
 

Modified: incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java (original)
+++ incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java Wed Jun  8 17:43:51 2005
@@ -32,10 +32,10 @@
 import org.apache.beehive.netui.pageflow.GlobalApp;
 import org.apache.beehive.netui.pageflow.PageFlowController;
 import org.apache.beehive.netui.pageflow.PageFlowUtils;
-import org.apache.beehive.netui.pageflow.SharedFlowController;
 import org.apache.beehive.netui.pageflow.internal.AnyBeanActionForm;
 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
-import org.apache.beehive.netui.pageflow.internal.FacesBackingBeanFactory;
+import org.apache.beehive.netui.pageflow.FacesBackingBeanFactory;
+import org.apache.beehive.netui.pageflow.RequestContext;
 import org.apache.beehive.netui.script.el.NetUIUpdateVariableResolver;
 import org.apache.beehive.netui.util.logging.Logger;
 
@@ -159,7 +159,7 @@
         // @todo: need to wrap this in checks for JSP 1.2
         // @todo: feature: need to add support for chaining in user-code to run when setting implicit objects on the request
         FacesBackingBean fbb =
-            FacesBackingBeanFactory.getFacesBackingBeanForRequest(request, response, servletContext);
+            FacesBackingBeanFactory.get(servletContext).getFacesBackingBeanForRequest(new RequestContext(request, response));
         loadPageFlow(request, curJpf, fbb);
         
         // @todo: need to move bundleMap creation to a BundleMapFactory

Modified: incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd (original)
+++ incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd Wed Jun  8 17:43:51 2005
@@ -12,6 +12,7 @@
                 <xsd:element name="pageflow-action-interceptors" type="netui:pageflow-action-interceptors" minOccurs="0" maxOccurs="1"/>
                 <xsd:element name="pageflow-handlers" type="netui:pageflow-handlers" minOccurs="0" maxOccurs="1"/>
                 <xsd:element name="pageflow-config" type="netui:pageflow-config" minOccurs="0" maxOccurs="1"/>
+                <xsd:element name="pageflow-factories" type="netui:pageflow-factories" minOccurs="0" maxOccurs="1"/>
                 <xsd:element name="default-shared-flow-refs" type="netui:default-shared-flow-refs" minOccurs="0" maxOccurs="1"/>
                 <xsd:element name="type-converters" type="netui:type-converters" minOccurs="0" maxOccurs="1"/>
                 <xsd:element name="jsp-tag-config" type="netui:jsp-tag-config" minOccurs="0" maxOccurs="1"/>
@@ -144,6 +145,20 @@
                 </xsd:simpleType>
             </xsd:element>
             <xsd:element name="module-config-locators" type="netui:module-config-locators" minOccurs="0" maxOccurs="1"/>
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:complexType name="pageflow-factory">
+        <xsd:sequence>
+            <xsd:element name="factory-class" type="xsd:string" minOccurs="1" maxOccurs="1"/>
+            <xsd:element name="custom-property" type="netui:custom-property" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:complexType name="pageflow-factories">
+        <xsd:sequence>
+            <xsd:element name="flowcontroller-factory" type="netui:pageflow-factory" minOccurs="0" maxOccurs="1"/>
+            <xsd:element name="faces-backing-bean-factory" type="netui:pageflow-factory" minOccurs="0" maxOccurs="1"/>
         </xsd:sequence>
     </xsd:complexType>
     

Modified: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/beehive-netui-config.xml
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/beehive-netui-config.xml?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/beehive-netui-config.xml (original)
+++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/beehive-netui-config.xml Wed Jun  8 17:43:51 2005
@@ -155,6 +155,16 @@
             </module-config-locator>
         </module-config-locators>
     </pageflow-config>
+
+    <pageflow-factories>
+        <flowcontroller-factory>
+            <factory-class>miniTests.flowControllerFactory.TestFactory</factory-class>
+            <custom-property>
+                <name>initVal</name>
+                <value>got it!</value>
+            </custom-property>
+        </flowcontroller-factory>
+    </pageflow-factories>
     
     <default-shared-flow-refs>
         <shared-flow-ref>

Added: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java?rev=189672&view=auto
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java (added)
+++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java Wed Jun  8 17:43:51 2005
@@ -0,0 +1,34 @@
+package miniTests.flowControllerFactory;
+
+import org.apache.beehive.netui.pageflow.PageFlowController;
+import org.apache.beehive.netui.pageflow.annotations.Jpf;
+
+/**
+ * The factory miniTests.flowControllerFactory.TestFactory loads this class on a request for
+ * /miniTests/flowControllerFactory/Controller.jpf.
+ */
+@Jpf.Controller(
+    simpleActions={
+        @Jpf.SimpleAction(name="begin", path="index.jsp")
+    }
+)
+public class Controller
+    extends PageFlowController
+{
+    private String _initVal;
+
+    /**
+     * Note that this page flow class couldn't be constructed by the framework normally, since it
+     * doesn't have a default constructor.  The factory miniTests.flowControllerFactory.TestFactory
+     * knows how to construct it.
+     */
+    public Controller(String initVal)
+    {
+        _initVal = initVal;
+    }
+
+    public String getInitVal()
+    {
+        return _initVal;
+    }
+}

Propchange: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/Controller.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java?rev=189672&view=auto
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java (added)
+++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java Wed Jun  8 17:43:51 2005
@@ -0,0 +1,38 @@
+package miniTests.flowControllerFactory;
+
+import org.apache.beehive.netui.pageflow.FlowControllerFactory;
+import org.apache.beehive.netui.pageflow.FlowController;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Used in the FlowControllerFactory test.  Enabled in beehive-netui-config.xml.
+ */
+public class TestFactory
+    extends FlowControllerFactory
+{
+    public FlowController getFlowControllerInstance(Class flowControllerClass)
+        throws IllegalAccessException, InstantiationException
+    {
+        if (flowControllerClass.getName().equals("miniTests.flowControllerFactory.Controller"))
+        {
+            try
+            {
+                Constructor ctor = flowControllerClass.getConstructor(new Class[]{ String.class });
+                String initVal = getConfig().getCustomProperty( "initVal" );
+                return (FlowController) ctor.newInstance(new Object[]{ initVal });
+            }
+            catch (InvocationTargetException e)
+            {
+                throw new RuntimeException(e);   // won't happen in this test.
+            }
+            catch (NoSuchMethodException e)
+            {
+                throw new RuntimeException(e);   // won't happen in this test.
+            }
+        }
+
+        return super.getFlowControllerInstance(flowControllerClass);
+    }
+}

Propchange: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/WEB-INF/src/miniTests/flowControllerFactory/TestFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp?rev=189672&view=auto
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp (added)
+++ incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp Wed Jun  8 17:43:51 2005
@@ -0,0 +1,24 @@
+<%@ page language="java" contentType="text/html;charset=UTF-8"%>
+<%@ taglib prefix="netui" uri="http://beehive.apache.org/netui/tags-html-1.0"%>
+<%@ taglib prefix="netui-data" uri="http://beehive.apache.org/netui/tags-databinding-1.0"%>
+<%@ taglib prefix="netui-template" uri="http://beehive.apache.org/netui/tags-template-1.0"%>
+
+
+<netui:html>
+    <head>
+        <netui:base/>
+    </head>
+    <netui:body>
+        <h3>${pageFlow.URI}</h3>
+
+        The factory <code>miniTests.flowControllerFactory.TestFactory</code> has created this page
+        flow instance.  It sets a property in the page flow's constructor (where normally, the
+        framework would call the default constructor).
+        <br/>
+        <br/>
+        init val: <b>${pageFlow.initVal}</b>
+    </netui:body>
+</netui:html>
+
+  
+

Propchange: incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/miniTests/flowControllerFactory/index.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml?rev=189672&r1=189671&r2=189672&view=diff
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml (original)
+++ incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml Wed Jun  8 17:43:51 2005
@@ -3739,6 +3739,19 @@
          </features>
       </test>
       <test>
+         <name>FlowControllerFactory</name>
+         <description>Test to ensure that a FlowControllerFactory can be specified through &lt;flowcontroller-factory&gt; in beehive-netui-config.xml</description>
+         <webapp>coreWeb</webapp>
+         <categories>
+            <category>bvt</category>
+            <category>bvt.struts11</category>
+            <category>corePageFlow</category>
+         </categories>
+         <features>
+            <feature>Pluggability</feature>
+         </features>
+      </test>
+      <test>
          <name>FormatSelect</name>
          <description>Test default values, directly binding to Page Flow</description>
          <webapp>coreWeb</webapp>

Added: incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml
URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml?rev=189672&view=auto
==============================================================================
--- incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml (added)
+++ incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml Wed Jun  8 17:43:51 2005
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session">
+   <ses:sessionName>FlowControllerFactory</ses:sessionName>
+   <ses:tester>rich</ses:tester>
+   <ses:startDate>08 Jun 2005, 04:55:40.097 PM MDT</ses:startDate>
+   <ses:description>Test to ensure that a FlowControllerFactory can be specified through &lt;flowcontroller-factory> in beehive-netui-config.xml</ses:description>
+   <ses:tests>
+      <ses:test>
+         <ses:testNumber>1</ses:testNumber>
+         <ses:request>
+            <ses:protocol>HTTP</ses:protocol>
+            <ses:protocolVersion>1.1</ses:protocolVersion>
+            <ses:host>localhost</ses:host>
+            <ses:port>8080</ses:port>
+            <ses:uri>/coreWeb/miniTests/flowControllerFactory/Controller.jpf</ses:uri>
+            <ses:method>GET</ses:method>
+            <ses:parameters/>
+            <ses:cookies>
+               <ses:cookie>
+                  <ses:name>JSESSIONID</ses:name>
+                  <ses:value>54E371D5412909A7833FCF5C05A5E735</ses:value>
+               </ses:cookie>
+               <ses:cookie>
+                  <ses:name>nde-textsize</ses:name>
+                  <ses:value>16px</ses:value>
+               </ses:cookie>
+            </ses:cookies>
+            <ses:headers>
+               <ses:header>
+                  <ses:name>accept</ses:name>
+                  <ses:value>text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-charset</ses:name>
+                  <ses:value>ISO-8859-1,utf-8;q=0.7,*;q=0.7</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-encoding</ses:name>
+                  <ses:value>gzip,deflate</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>accept-language</ses:name>
+                  <ses:value>en-us,en;q=0.5</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>connection</ses:name>
+                  <ses:value>keep-alive</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>cookie</ses:name>
+                  <ses:value>JSESSIONID=54E371D5412909A7833FCF5C05A5E735; nde-textsize=16px</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>host</ses:name>
+                  <ses:value>localhost:8080</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>keep-alive</ses:name>
+                  <ses:value>300</ses:value>
+               </ses:header>
+               <ses:header>
+                  <ses:name>user-agent</ses:name>
+                  <ses:value>Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4</ses:value>
+               </ses:header>
+            </ses:headers>
+         </ses:request>
+         <ses:response>
+            <ses:statusCode>200</ses:statusCode>
+            <ses:reason/>
+            <ses:responseBody><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+
+    <head>
+        <base href="http://localhost:8080/coreWeb/miniTests/flowControllerFactory/index.jsp">
+    </head>
+    <body>
+        <h3>/miniTests/flowControllerFactory/Controller.jpf</h3>
+
+        The factory <code>miniTests.flowControllerFactory.TestFactory</code> has created this page
+        flow instance.  It sets a property in the page flow's constructor (where normally, the
+        framework would call the default constructor).
+        <br/>
+        <br/>
+        init val: <b>got it!</b>
+    </body>
+
+</html>]]></ses:responseBody>
+         </ses:response>
+      </ses:test>
+   </ses:tests>
+   <ses:endDate>08 Jun 2005, 04:55:46.266 PM MDT</ses:endDate>
+   <ses:testCount>1</ses:testCount>
+</ses:recorderSession>

Propchange: incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/FlowControllerFactory.xml
------------------------------------------------------------------------------
    svn:eol-style = native