myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfreed...@apache.org
Subject svn commit: r1139083 [1/2] - in /myfaces/portlet-bridge/core/branches/refactored_3.0.x: controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/ impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/ impl/src/main/java/org/apache/myfa...
Date Thu, 23 Jun 2011 21:45:13 GMT
Author: mfreedman
Date: Thu Jun 23 21:45:13 2011
New Revision: 1139083

URL: http://svn.apache.org/viewvc?rev=1139083&view=rev
Log:
Latest set of updates -- primarily cleaned up scope use/management (its now tied to the viewId) + fixed PORTLETBRIDGE-215 in this code line.

Modified:
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeContext.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeController.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScope.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScopeManager.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/context/BridgeContextImpl.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/controller/BridgeControllerImpl.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeImpl.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeManagerImpl.java
    myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeContext.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeContext.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeContext.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeContext.java Thu Jun 23 21:45:13 2011
@@ -22,6 +22,8 @@ import javax.portlet.PortletContext;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletResponse;
 import javax.portlet.faces.Bridge;
+import javax.portlet.faces.BridgeDefaultViewNotSpecifiedException;
+import javax.portlet.faces.BridgeInvalidViewPathException;
 
 /**
  * The <CODE>BridgeContext</CODE> contains the runtime specific state the bridge
@@ -352,6 +354,99 @@ public abstract class BridgeContext 
    * @return
    */
   public abstract String getViewHistory(String mode);
+  
+  /**
+   *  Returns the Faces (viewid) target as described by the request. Note:  This value must always be calculated (never cached).  The value must
+   *  reflect the target described by the request object contained in the <code>ExternalContext</code>
+   *  if available.  If not, then the target is computed from the <code>BridgeContext's
+   *  PortletRequest</code>
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the Faces (viewid) target as described by the request.  Returns <code>null</code>
+   * if the request doesn't explicitly specify a target or if the target specified in the request doesn't match the 
+   * request's <code>PortletMode</code>.  When a target viewId is returned it may contain contain (an optional)
+   * query string if not specifically excluded.
+   */
+  public abstract String getFacesViewIdFromRequest(boolean excludeQueryString) 
+    throws BridgeInvalidViewPathException;
+  
+  /**
+   *  Returns the Faces (viewid) currently targeted. Note:  This value must always be calculated
+   *  (never cached).  If the <code>FacesContext</code> has
+   *  a current <code>UIViewRoot</code>, it returns its id.  Otherwise it computes the 
+   *  target <code>viewId</code> as follows:  returns the result of calling
+   *  <code>getFacesViewIdFromRequest()</code> if not null otherwise return the result of
+   *  <code>getDefaultViewIdForRequest()</code>.
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the Faces (viewid) target as described by the request.  
+   */
+  public abstract String getFacesViewId(boolean excludeQueryString) 
+    throws BridgeInvalidViewPathException;  
+  
+  /**
+   *  Returns the Bridge request scope corresponding to current view and mode.
+   *  I.e. the result of calling <code>getFacesViewId</code>
+   *  and <code>PortletRequest.getPortletMode().toString()</code>.
+   * 
+   * @return the current Bridge request scope or null if no scope corresponding to the current view and mode
+   */
+  public abstract BridgeRequestScope getBridgeScope();
+  
+  /**
+   *  Returns the Bridge request scope corresponding to passed viewId and mode.
+   *
+   * @param viewId scope's viewId
+   * @param mode scope's portlet mode
+   * @return the current Bridge request scope or null if no scope corresponding to the current view and mode
+   */
+  public abstract BridgeRequestScope getBridgeScope(String viewId, String mode);
+  
+  /**
+   *
+   * @return the Bridge's RequestScopeManager used by this portlet
+   */
+  public abstract BridgeRequestScopeManager getBridgeRequestScopeManager();
+  
+  /**
+   *  Returns the Faces (viewid) target as represented in the path. Basically, this does a path to viewId mapping
+   *  based on the Faces servlet mappings in the web.xml.  I.e. if Faces is suffix mapped (*.jsf) then a path of /foo.jsf
+   *  will return foo.jsp (or whatever is the configured mapping from .jsf to .xxx).  If Faces is prefix mapped (/faces/*) then a path
+   *  of /faces/foo.jsp will return foo.jsp.  Note:  
+   *  
+   * @param path contains encoded viewId to be extracted.  <code>path</code> can either contain the context path or be relative to it.
+   * If <code>path</code> contains a query string it is ignored.
+   * 
+   * @return the target viewId extracted from the path.  This viewId will never contain a query string.
+   */
+  public abstract String getFacesViewIdFromPath(String path) 
+    throws BridgeInvalidViewPathException; 
+  
+  /**
+   *  Returns the default Faces (viewid) target configured for the current request's
+   *  <code>PortletMode</code>. The value must use the request contained in the
+   *  <code>ExternalContext</code> if available.  If not, then the target is computed from the <code>BridgeContext's
+   *  PortletRequest</code>
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the default Faces (viewid) target configured for the current request's
+   *  <code>PortletMode</code>.  The return value may contain contain (an optional)
+   * query string if not specifically excluded.
+   */
+  public abstract String getDefaultFacesViewIdForRequest(boolean excludeQueryString) 
+    throws BridgeDefaultViewNotSpecifiedException;
 
 
     // ---------------------------------------------------------- Static Methods

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeController.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeController.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeController.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeController.java Thu Jun 23 21:45:13 2011
@@ -17,6 +17,8 @@ import javax.portlet.faces.BridgeUniniti
 
 public interface BridgeController 
 {
+  public static final String IGNORE_BRIDGE_SCOPE = "org.apache.myfaces.portlet.bridge.ignoreBridgeScope";
+    
   public void init(BridgeConfig config) throws BridgeException;
   
   public void destroy();

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScope.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScope.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScope.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScope.java Thu Jun 23 21:45:13 2011
@@ -22,8 +22,6 @@ import java.util.concurrent.ConcurrentMa
  * which a scope manager can use to identify this scope and as the gatekeeper 
  * of specific attributes that are excluded from the scope.<br>
  * 
- * The id is a construction of a manager provider prefix followed by a colon 
- * followed by a BridgeRequestScope generated unique id.  <br>
  * 
  * The BridgeRequestScope's main function is to prevent excluded attributes from
  * being added to itself.  The excluded attributes are comprised of those defined
@@ -33,21 +31,38 @@ import java.util.concurrent.ConcurrentMa
 public interface BridgeRequestScope extends ConcurrentMap<String, Object>
 {
   
-  /**
-   * Note: All implementations of the BridgeRequestScope are expected/required to 
-   * have constructors whose first parameter is a String prefixId.  This parameter
-   * is a client defined prefix to use in the scope Id so the client (scope manager)
-   * can easily and quickly locate encoded groups of scopes to remove them
-   */
- 
 
  /**
    * 
-   * @return unique string id representing this scope.  Its value is prefixed by 
-   *         whatever prefix has been previously set on it.
+   * @return unique string id representing this scope.
    */
  public String getId();
  
+ 
+  /**
+    * 
+    * @return unique string id representing the portlet to which this scope pertains.
+    */
+  public String getPortletId();
+  
+  /**
+    * 
+    * @return unique string id representing the sesssion to which this scope pertains.
+    */
+  public String getSessionId();
+  
+  /**
+    * 
+    * @return unique string id representing the Faces viewId to which this scope pertains.
+    */
+  public String getViewId(); 
+  
+  /**
+    * 
+    * @return unique string id representing the Portlet mode to which this scope pertains.
+    */
+  public String getPortletMode(); 
+  
  /**
    * Sets a new List of excluded attribute names.  The names follow the syntax
    * described in the specification.  Any currently set attribute names are

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScopeManager.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScopeManager.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScopeManager.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/controller-api/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeRequestScopeManager.java Thu Jun 23 21:45:13 2011
@@ -28,23 +28,77 @@ import javax.portlet.faces.BridgeWriteBe
 public interface BridgeRequestScopeManager
 {
   /**
-   * Create a new empty RequestScope.  As a by product of this call
-   * the manager should set the RequestScope prefix in a manner that allows it to 
-   * manage the various remove methods.
+   * Create a new empty RequestScope.  
    * @param ctx
+   * @param portletName name of the portlet to which this scope pertains
+   * @param sessionId a unique identifier for the user session in which this scope pertains
+   * @param viewId the faces viewId of this scope
+   * @param portletMode the mode this scope pertains to
    * @return the new BridgeRequestScope
    */
-  public BridgeRequestScope createRequestScope(BridgeContext ctx);
+  public BridgeRequestScope createRequestScope(BridgeContext ctx, String portletName, String sessionId,  String viewId, String portletMode);
+  
+  /**
+   * Create a new empty RequestScope.  Scope qualifiers portletId, sessionId, and portletMode are taken from the current request object
+   * in the <code>BridgeContext</code>.
+   * @param ctx
+   * @param viewId the faces viewId of this scope
+   * @return the new BridgeRequestScope
+   */
+  public BridgeRequestScope createRequestScope(BridgeContext ctx, String viewId);
   
   /**
    * Returns the BridgeRequestScope corresponding to the supplied key (id)
    * @param ctx
    * @param id BridgeRequestScope's id
-   * @return the BridgeRequestScope that corresponds to the supplied key
+   * @return the BridgeRequestScope that corresponds to the supplied key or null if no match
    */
   public BridgeRequestScope getRequestScopeById(BridgeContext ctx, String id);
   
   /**
+   * Returns the BridgeRequestScope corresponding to the portletId, sessionId, viewId and portletMode.
+   * 
+   * @param ctx
+   * @param portletName uniquely identifies this portlet.
+   * @param sessionId uniquely identifies a user context (session)
+   * @param viewId Faces view to which this scope pertains
+   * @param portletMode portlet mode that this scope represents
+   * @return the BridgeRequestScope that corresponds to the supplied key or null if no match
+   */
+  public BridgeRequestScope getRequestScope(BridgeContext ctx, String portletName, String sessionId,  String viewId, String portletMode);
+  
+  
+  /**
+   * Returns the BridgeRequestScope corresponding to the portletId, sessionId, viewId and portletMode.
+   * PortletName and sessionId are taken from the current request/portlet config
+   * 
+   * @param ctx
+   * @param viewId Faces view to which this scope pertains
+   * @param portletMode portlet mode that this scope represents
+   * @return the BridgeRequestScope that corresponds to the supplied key or null if no match
+   */
+  public BridgeRequestScope getRequestScope(BridgeContext ctx, String viewId, String portletMode);
+  
+  /**
+   * Returns the BridgeRequestScope corresponding to the portletId, sessionId, viewId and portletMode.
+   * PortletName, sessionId, and portletMode are taken from the current request/portlet config
+   * 
+   * @param ctx
+   * @param viewId Faces view to which this scope pertains
+   * @return the BridgeRequestScope that corresponds to the supplied key or null if no match
+   */
+  public BridgeRequestScope getRequestScope(BridgeContext ctx, String viewId);
+  
+  /**
+   * Returns the BridgeRequestScope corresponding to the portletId, sessionId, viewId and portletMode.
+   * PortletName, sessionId, and portletMode and viewId are taken from the current bridge context
+   * 
+   * @param ctx
+   * @return the BridgeRequestScope that corresponds to the supplied key or null if no match
+   */
+  public BridgeRequestScope getRequestScope(BridgeContext ctx);
+  
+  /**
    * Removes the specific BridgeRequestScope (from management) that
    * corresponds to the supplied key.
    * @param ctx
@@ -58,18 +112,75 @@ public interface BridgeRequestScopeManag
    * Removes the supplied BridgeRequestScope from management.
    * @param ctx
    * @param scope
+   * @return scope that was removed or null -- if scope not in the repository. (Note: scope
+   * is cleared before being returned)
+   */
+  public BridgeRequestScope removeRequestScope(BridgeContext ctx, BridgeRequestScope scope);
+  
+  /**
+   * Removes the request scope pertaining to the portletId, sessionId, viewId and portletMode.
+   * This operation is a noop if a match is not found.
+   * 
+   * @param ctx
+   * @param portletName uniquely identifies this portlet.
+   * @param sessionId uniquely identifies a user context (session)
+   * @param viewId Faces view to which this scope pertains
+   * @param portletMode portlet mode that this scope represents
+   * @return scope that was removed or null. (Note: scope
+   * is cleared before being returned)
    */
-  public void removeRequestScope(BridgeContext ctx, BridgeRequestScope scope);
+  public BridgeRequestScope removeRequestScope(BridgeContext ctx, String portletName, String sessionId,  String viewId, String portletMode);
+  
+  
+  /**
+   * Removes the request scope pertaining to the portletId, sessionId, viewId and portletMode.
+   * Portletname and sessionId are taken from the current request/portlet config
+   * This operation is a noop if a match is not found.
+   * 
+   * @param ctx
+   * @param viewId Faces view to which this scope pertains
+   * @param portletMode portlet mode that this scope represents
+   * @return scope that was removed or null. (Note: scope
+   * is cleared before being returned)
+   */
+  public BridgeRequestScope removeRequestScope(BridgeContext ctx, String viewId, String portletMode);
+  
+  /**
+   * Removes the request scope pertaining to the portletId, sessionId, viewId and portletMode.
+   * PortletName, sessionId, and portletMode are taken from the current request/portlet config
+   * This operation is a noop if a match is not found.
+   * 
+   * @param ctx
+   * @param viewId Faces view to which this scope pertains
+   * @return scope that was removed or null. (Note: scope
+   * is cleared before being returned)
+   */
+  public BridgeRequestScope removeRequestScope(BridgeContext ctx, String viewId);
   
   
   /**
    * Removes all the BridgeRequestScope's currently by managed by this manager
+   * for the specific portlet that is identified <code>portletName</code>.
+   * @param ctx
+   */
+  public void removeRequestScopesByPortlet(BridgeContext ctx, String portletId);
+  
+  /**
+   * Removes all the BridgeRequestScope's currently by managed by this manager
    * for the specific portlet that is identified in the PortletConfig object
    * obtainable from the BridgeContext.
    * @param ctx
    */
   public void removeRequestScopesByPortlet(BridgeContext ctx);
   
+  /**
+   * Removes all the  BridgeRequestScope's currently by managed by this manager
+   * for the session identified by <code>sessionId</code>.
+   * 
+   * @param ctx
+   */
+  public void removeRequestScopesBySession(BridgeContext ctx, String sessionId);
+  
   
   /**
    * Removes all the  BridgeRequestScope's currently by managed by this manager
@@ -79,4 +190,6 @@ public interface BridgeRequestScopeManag
    */
   public void removeRequestScopesBySession(BridgeContext ctx);
   
+
+  
 }
\ No newline at end of file

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java Thu Jun 23 21:45:13 2011
@@ -19,11 +19,13 @@
 
 package org.apache.myfaces.portlet.faces.bridge;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
 
+import javax.faces.application.ViewHandler;
 import javax.faces.context.FacesContext;
 import javax.faces.event.SystemEvent;
 
@@ -94,16 +96,16 @@ public class BridgeImpl
            NullPointerException
   {
     doFacesRequestPreamble(request, response, Bridge.PortletPhase.ACTION_PHASE);
-    
-    BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.ACTION_PHASE);
-    
+       
     try
     {
+      BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.ACTION_PHASE);
+
       mBridgeController.processPortletAction(bCtx);
     }
     finally
     {
-      doFacesRequestPostScript(bCtx);
+      doFacesRequestPostScript(BridgeContext.getCurrentInstance());
     }
   }
   
@@ -116,16 +118,15 @@ public class BridgeImpl
   {
     doFacesRequestPreamble(request, response, Bridge.PortletPhase.EVENT_PHASE);
     
-    
-    BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.EVENT_PHASE);
-
     try
     {
+      BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.EVENT_PHASE);
+
       mBridgeController.handlePortletEvent(bCtx);
     }
     finally
     {
-      doFacesRequestPostScript(bCtx);
+      doFacesRequestPostScript(BridgeContext.getCurrentInstance());
     }
   }
 
@@ -137,15 +138,15 @@ public class BridgeImpl
   {
     doFacesRequestPreamble(request, response, Bridge.PortletPhase.RENDER_PHASE); 
 
-
-    BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.RENDER_PHASE);
     try
     {
+      BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.RENDER_PHASE);
+
       mBridgeController.renderPortletBody(bCtx);
     }
     finally
     {
-      doFacesRequestPostScript(bCtx);
+      doFacesRequestPostScript(BridgeContext.getCurrentInstance());
     }
   }
 
@@ -157,11 +158,11 @@ public class BridgeImpl
            NullPointerException
   {
     doFacesRequestPreamble(request, response, Bridge.PortletPhase.RESOURCE_PHASE);
-    
-    BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.RESOURCE_PHASE);
-    
+       
     try
     {
+      BridgeContext bCtx = getBridgeContext(request, response, Bridge.PortletPhase.RESOURCE_PHASE);
+
       // Determine whether this is a Faces resource or a regular one.
 
       if (!isFacesResourceRequest(bCtx))
@@ -176,7 +177,7 @@ public class BridgeImpl
     }
     finally
     {
-      doFacesRequestPostScript(bCtx);
+      doFacesRequestPostScript(BridgeContext.getCurrentInstance());
     }
   }
   
@@ -242,6 +243,9 @@ public class BridgeImpl
     {
       throw new BridgeException("BridgeImpl.init(): unable to determine Faces servlet web.xml mapping.");
     }
+    
+    // JSF 2.0 allows a list of suffixes that can replace the extension mapping
+    bConfig.setFacesSuffixes(parseFacesSuffixes(bConfig));
 
     // Set defaults for each mode's last active view session attribute
     bConfig.setDefaultViewMappings((Map<String,String>) portletContext.getAttribute(
@@ -338,11 +342,24 @@ public class BridgeImpl
   
   private void doFacesRequestPostScript(BridgeContext bCtx)
   {
+    if (bCtx == null) return;
+    
     // Per spec remove the phase attribute.
     bCtx.getPortletRequest().removeAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
     
     releaseBridgeContext(bCtx);
   }
+  
+  private List<String> parseFacesSuffixes(BridgeConfig bConfig)
+  {
+    String suffixString = bConfig.getPortletConfig().getPortletContext().getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+    if (suffixString == null)
+    {
+      suffixString = ViewHandler.DEFAULT_SUFFIX;
+    }
+    
+    return Arrays.asList(suffixString.split(" "));
+  }
 
   private void processFacesConfiguration(BridgeConfig config)
   {

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/context/BridgeContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/context/BridgeContextImpl.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/context/BridgeContextImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/context/BridgeContextImpl.java Thu Jun 23 21:45:13 2011
@@ -12,7 +12,10 @@
 
 package org.apache.myfaces.portlet.faces.bridge.context;
 
+import java.net.MalformedURLException;
+
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -28,6 +31,7 @@ import javax.el.ELContextListener;
 import javax.faces.FactoryFinder;
 import javax.faces.application.ApplicationFactory;
 
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
 
 import javax.faces.render.ResponseStateManager;
@@ -37,8 +41,15 @@ import javax.portlet.PortletRequest;
 import javax.portlet.PortletResponse;
 import javax.portlet.faces.Bridge;
 
+import javax.portlet.faces.BridgeDefaultViewNotSpecifiedException;
+import javax.portlet.faces.BridgeInvalidViewPathException;
+
 import org.apache.myfaces.portlet.faces.bridge.BridgeConfig;
 import org.apache.myfaces.portlet.faces.bridge.BridgeContext;
+import org.apache.myfaces.portlet.faces.bridge.BridgeRequestScope;
+import org.apache.myfaces.portlet.faces.bridge.BridgeRequestScopeManager;
+import org.apache.myfaces.portlet.faces.bridge.controller.BridgeControllerImpl;
+import org.apache.myfaces.portlet.faces.bridge.scope.BridgeRequestScopeManagerImpl;
 import org.apache.myfaces.portlet.faces.el.PortletELContextImpl;
 import org.apache.myfaces.portlet.faces.util.QueryString;
 
@@ -63,7 +74,9 @@ import org.apache.myfaces.portlet.faces.
 public class BridgeContextImpl extends BridgeContext implements ELContextListener 
 {
   
-  private final String BRIDGE_CONTEXT_HAS_INITED_VIEW_HISTORY = "org.apache.myfaces.portlet.faces.bridge.context.hasInitializedViewHistory";
+  private static final String BRIDGE_CONTEXT_HAS_INITED_VIEW_HISTORY = "org.apache.myfaces.portlet.faces.bridge.context.hasInitializedViewHistory";
+  private static final String REQUEST_SCOPE_MANAGER = "org.apache.myfaces.portlet.faces.requestScopeManager";
+
   
   private PortletContext mPortletContext;
   private PortletRequest mPortletRequest;
@@ -354,6 +367,7 @@ public class BridgeContextImpl extends B
   public void setRenderRedirectQueryString(String queryString)
   {
     mRenderRedirectQueryString = queryString;
+    setRenderRedirect(true);
   }
   
   
@@ -589,6 +603,448 @@ public class BridgeContextImpl extends B
     return (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(key.append(Bridge.VIEWID_HISTORY).append('.').append(mode).toString());
   }
   
+  /**
+   *  Returns the Faces (viewid) target as described by the request. Note:  This value must always be calculated (never cached).  The value must
+   *  reflect the target described by the request object contained in the <code>ExternalContext</code>
+   *  if available.  If not, then the target is computed from the <code>BridgeContext's
+   *  PortletRequest</code>
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the Faces (viewid) target as described by the request.  Returns <code>null</code>
+   * if the request doesn't explicitly specify a target or if the target specified in the request doesn't match the 
+   * request's <code>PortletMode</code>.  When a target viewId is returned it may contain contain (an optional)
+   * query string if not specifically excluded.
+   */
+  public String getFacesViewIdFromRequest(boolean excludeQueryString)
+    throws BridgeInvalidViewPathException
+  {
+    FacesContext fCtx = FacesContext.getCurrentInstance();
+    
+    if (fCtx == null)
+    {
+      return getViewId(mPortletRequest, excludeQueryString);
+    }
+    else
+    {
+      return getViewId((PortletRequest) fCtx.getExternalContext().getRequest(), excludeQueryString);
+    }
+  }
+  
+  /**
+   *  Returns the Faces (viewid) currently targeted. Note:  This value must always be calculated
+   *  (never cached).  If the <code>FacesContext</code> has
+   *  a current <code>UIViewRoot</code>, it returns its id.  Otherwise it computes the 
+   *  target <code>viewId</code> as follows:  returns the result of calling
+   *  <code>getFacesViewIdFromRequest()</code> if not null otherwise return the result of
+   *  <code>getDefaultViewIdForRequest()</code>.
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the Faces (viewid) target as described by the request.  
+   */
+  public String getFacesViewId(boolean excludeQueryString) 
+    throws BridgeInvalidViewPathException
+  {
+    String viewId = null;
+    FacesContext fCtx = FacesContext.getCurrentInstance();
+    
+    if (fCtx != null && fCtx.getViewRoot() != null)
+    {
+      viewId = fCtx.getViewRoot().getViewId();
+    }
+    else
+    {
+      viewId = getFacesViewIdFromRequest(excludeQueryString);
+      if (viewId == null)
+      {
+        viewId = getDefaultFacesViewIdForRequest(excludeQueryString);
+      }
+    }
+    return viewId;
+  }
+  
+  /**
+   *  Returns the Bridge request scope corresponding to current view and mode.
+   *  I.e. the result of calling <code>getFacesViewId</code>
+   *  and <code>PortletRequest.getPortletMode().toString()</code>.
+   * 
+   * @return the current Bridge request scope or null if no scope corresponding to the current view and mode
+   */
+  public BridgeRequestScope getBridgeScope()
+  {
+    return getBridgeRequestScopeManager().getRequestScope(this);
+  }
+  
+  /**
+   *  Returns the Bridge request scope corresponding to passed viewId and mode.
+   *
+   * @param viewId scope's viewId
+   * @param mode scope's portlet mode
+   * @return the current Bridge request scope or null if no scope corresponding to the current view and mode
+   */
+  public BridgeRequestScope getBridgeScope(String viewId, String mode)
+  {
+    return getBridgeRequestScopeManager().getRequestScope(this, viewId, mode);
+  }
+  
+  
+  public BridgeRequestScopeManager getBridgeRequestScopeManager()
+  {
+    BridgeRequestScopeManager scopeManager = (BridgeRequestScopeManager) getPortletContext().getAttribute(REQUEST_SCOPE_MANAGER);
+
+    if (scopeManager == null)
+    {
+      scopeManager = createBridgeRequestScopeManager();
+    }
+    return scopeManager;
+  }
+  
+  private synchronized BridgeRequestScopeManager createBridgeRequestScopeManager()
+  {
+    BridgeRequestScopeManager scopeManager = (BridgeRequestScopeManager) mPortletContext.getAttribute(REQUEST_SCOPE_MANAGER);
+    if (scopeManager == null)
+    {
+      mPortletContext.setAttribute(REQUEST_SCOPE_MANAGER, new BridgeRequestScopeManagerImpl(mBridgeConfig));
+      // get after put to ensure we get the one that actually stuck
+      scopeManager = (BridgeRequestScopeManager) mPortletContext.getAttribute(REQUEST_SCOPE_MANAGER);
+    }
+    return scopeManager;
+  }
+  
+  /**
+   *  Returns the Faces (viewid) target as represented in the path. Basically, this does a path to viewId mapping
+   *  based on the Faces servlet mappings in the web.xml.  I.e. if Faces is suffix mapped (*.jsf) then a path of /foo.jsf
+   *  will return foo.jsp (or whatever is the configured mapping from .jsf to .xxx).  If Faces is prefix mapped (/faces/*) then a path
+   *  of /faces/foo.jsp will return foo.jsp.  Note:  
+   *  
+   * @param path contains encoded viewId to be extracted.  <code>path</code> can either contain the context path or be relative to it.
+   * If <code>path</code> contains a query string it is ignored.
+   * 
+   * @return the target viewId extracted from the path.  This viewId will never contain a query string.
+   */
+  public String getFacesViewIdFromPath(String path) 
+    throws BridgeInvalidViewPathException
+  {
+    // Get a string that holds the path after the Context-Path through the
+    // target
+
+    // First remove the query string
+    int i = path.indexOf("?");
+    if (i != -1)
+    {
+      path = path.substring(0, i);
+    }
+
+    // Now remove up through the ContextPath
+    String ctxPath = getPortletRequest().getContextPath();
+    i = path.indexOf(ctxPath);
+    if (i != -1)
+    {
+      path = path.substring(i + ctxPath.length());
+    }
+
+    String viewId = null;
+    // Okay now figure out whether this is prefix or suffixed mapped
+    List<String> facesMappings = getBridgeConfig().getFacesServletMappings();
+    List<String> facesSuffixes = getBridgeConfig().getFacesSuffixes();
+    if (isSuffixedMapped(path, facesMappings))
+    {
+      viewId = 
+          viewIdFromSuffixMapping(path, facesSuffixes);
+    }
+    else if (isPrefixedMapped(path, facesMappings))
+    {
+      viewId = viewIdFromPrefixMapping(path, facesMappings);
+    }
+    else
+    {
+      // Not a Faces URL
+      viewId = null;
+    }
+    return viewId;
+  }
+  
+  /**
+   *  Returns the default Faces (viewid) target configured for the current request's
+   *  <code>PortletMode</code>. The value must use the request contained in the
+   *  <code>ExternalContext</code> if available.  If not, then the target is computed from the <code>BridgeContext's
+   *  PortletRequest</code>
+   *  
+   * @param excludeQueryString if <code>true</code> then only the target Faces viewId is returned regardless of whether the viewId contains
+   * a query string.  I.e. unlike core Faces, the bridge allows the default viewIds and viewIds in the Faces navigation rules to contain query strings
+   * that augment the view.  For example one can include a new mode in a Faces navigation rule.  This boolean controls whether this extra query string
+   * portion of a viewid is returned or not.
+   * 
+   * @return Returns the default Faces (viewid) target configured for the current request's
+   *  <code>PortletMode</code>.  The return value may contain contain (an optional)
+   * query string if not specifically excluded.
+   */
+  public String getDefaultFacesViewIdForRequest(boolean excludeQueryString) 
+    throws BridgeDefaultViewNotSpecifiedException
+  {
+    FacesContext fCtx = FacesContext.getCurrentInstance();
+    PortletRequest request = null;
+    String viewId = null;
+    
+    if (fCtx == null)
+    {
+      request = mPortletRequest;
+    }
+    else
+    {
+      request = (PortletRequest) fCtx.getExternalContext().getRequest();
+    }
+    
+    viewId = mBridgeConfig.getDefaultViewMappings().get(request.getPortletMode().toString());
+    if (viewId != null)
+    {
+      if (!excludeQueryString)
+      {
+        return viewId;
+      }
+      else
+      {
+        return excludeQueryString(viewId);
+      }
+    }
+    {
+      throw new BridgeDefaultViewNotSpecifiedException();
+    }
+    
+    
+
+  }
+  
+  private String getViewId(PortletRequest request, boolean excludeQueryString)
+    throws BridgeDefaultViewNotSpecifiedException, BridgeInvalidViewPathException
+  {
+    boolean modeChanged = false;
+    String requestedMode = request.getPortletMode().toString();
+    
+    // See if the portlet has specified the target view
+    String viewId = (String) request.getAttribute(Bridge.VIEW_ID);
+    String viewPath = null;
+    if (viewId == null)
+    {
+      viewPath = (String) request.getAttribute(Bridge.VIEW_PATH);
+      if (viewPath != null)
+      {
+        //convert the view path into a viewId
+        viewId = getViewIdFromPath(viewPath);
+        if (viewId == null)
+        {
+          throw new BridgeInvalidViewPathException("Unable to resolve faces viewId: "
+              + viewPath);
+        }
+      }
+    }
+      
+    // Normal case is its returned in the render parameter
+    if (viewId == null)
+    {
+     // Read the target from the request parameter
+        
+      viewId = request.getParameter(mBridgeConfig.getViewIdRenderParameterName());
+
+      // TODO:
+      if (viewId != null) mBridgeConfig.getLogger().log("BridgeContextImpl.getViewId: found jsf target viewId = " + viewId);
+
+      // ViewIds stored in RenderParams are encoded with the Mode to which they apply
+      // Ensure current request Mode matches before using the viewId portion
+      if (viewId != null)
+      {
+        int i = viewId.indexOf(':');
+        if (i >= 0 )
+        {
+      
+          String mode = viewId.substring(0, i);
+          viewId = viewId.substring(i+1);
+          if (!mode.equalsIgnoreCase(requestedMode))
+          {
+            modeChanged = true;
+            viewId = null; // didn't match so don't use it
+          }
+        }
+      }
+    }
+    if (viewId != null && excludeQueryString)
+    {
+      viewId = excludeQueryString(viewId);
+    }
+
+    return viewId;
+  }
+  
+  private String excludeQueryString(String url)
+  {
+    int queryStart = url.indexOf('?');
+    if (queryStart != -1)
+    {
+      return url.substring(0, queryStart);
+    }
+    else
+    {
+      return url;
+    }
+  }
+  
+  private String getViewIdFromPath(String url)
+  {
+    // Get a string that holds the path after the Context-Path through the
+    // target
+
+    // First remove the query string
+    int i = url.indexOf("?");
+    if (i != -1)
+    {
+      url = url.substring(0, i);
+    }
+
+    // Now remove up through the ContextPath
+    String ctxPath = mPortletRequest.getContextPath();
+    i = url.indexOf(ctxPath);
+    if (i != -1)
+    {
+      url = url.substring(i + ctxPath.length());
+    }
+
+    String viewId = null;
+    // Okay now figure out whether this is prefix or suffixed mapped
+    List<String> facesMappings = mBridgeConfig.getFacesServletMappings();
+    List<String> facesSuffixes = mBridgeConfig.getFacesSuffixes();
+    if (isSuffixedMapped(url, facesMappings))
+    {
+      viewId = 
+          viewIdFromSuffixMapping(url, facesSuffixes);
+    }
+    else if (isPrefixedMapped(url, facesMappings))
+    {
+      viewId = viewIdFromPrefixMapping(url, facesMappings);
+    }
+    else
+    {
+      // Not a Faces URL
+      viewId = null;
+    }
+    return viewId;
+  }
+  
+  private boolean isSuffixedMapped(String url, List<String> mappings)
+  {
+    // see if the viewId terminates with an extension
+    // if non-null value contains *.XXX where XXX is the extension
+    String ext = extensionMappingFromViewId(url);
+    return ext != null && mappings.contains(ext);
+  }
+  
+  private String viewIdFromSuffixMapping(String url, List<String> suffixes)
+  {
+    int i = url.lastIndexOf(".");
+    if (i != -1)
+    {
+      for (String suffix : suffixes)
+      {
+        if (suffix.startsWith("."))
+        {
+          url = url.substring(0, i) + suffix;
+        }
+        else
+        {
+          // shouldn't happen
+          url = url.substring(0, i) + "." + suffix;
+        }
+        // now verify if this exists
+        String testPath = url.startsWith("/") ? url : "/"+url;
+        try
+        {
+          if (mPortletContext.getResource(testPath) != null)
+          {
+            break;
+          }
+        } catch (MalformedURLException m)
+        {
+            // TODO: didn't expect to get here
+        }
+      }
+    }
+    return url;
+  }
+  
+
+
+  private boolean isPrefixedMapped(String url, List<String> mappings)
+  {
+    for (int i = 0; i < mappings.size(); i++)
+    {
+      String prefix = null;
+      String mapping = mappings.get(i);
+      if (mapping.startsWith("/"))
+      {
+        int j = mapping.lastIndexOf("/*");
+        if (j != -1)
+        {
+          prefix = mapping.substring(0, j);
+        }
+      }
+      if (prefix != null && url.startsWith(prefix))
+      {
+        return true;
+      }
+    }
+    return false;
+  }  
+  
+  private String viewIdFromPrefixMapping(String url, List<String> mappings)
+  {
+    for (int i = 0; i < mappings.size(); i++)
+    {
+      String prefix = null;
+      String mapping = mappings.get(i);
+      if (mapping.startsWith("/"))
+      {
+        int j = mapping.lastIndexOf("/*");
+        if (j != -1)
+        {
+          prefix = mapping.substring(0, j);
+        }
+      }
+      if (prefix != null && url.startsWith(prefix))
+      {
+        return url.substring(prefix.length());
+      }
+    }
+    return null;
+  }  
+  
+  private String extensionMappingFromViewId(String viewId)
+  {
+    // first remove/ignore any querystring
+    int i = viewId.indexOf('?');
+    if (i != -1)
+    {
+      viewId = viewId.substring(0, i);
+    }
+
+    int extLoc = viewId.lastIndexOf('.');
+
+    if (extLoc != -1 && extLoc > viewId.lastIndexOf('/'))
+    {
+      StringBuilder sb = new StringBuilder("*");
+      sb.append(viewId.substring(extLoc));
+      return sb.toString();
+    }
+    return null;
+  }
+
+
+  
   private void initViewHistoryWithDefaults()
   {
     // Only gets inited the first time the bridge receives a request -- we keep a flag on the BridgeConfig object to indicate 
@@ -596,7 +1052,7 @@ public class BridgeContextImpl extends B
     
     Boolean hasInitializedViewHistory = (Boolean) getBridgeConfig().getAttributes().get(BRIDGE_CONTEXT_HAS_INITED_VIEW_HISTORY);
     
-    if (hasInitializedViewHistory != null && hasInitializedViewHistory.booleanValue())
+    if (hasInitializedViewHistory == null || !hasInitializedViewHistory.booleanValue())
     {
       Map<String, String> viewIdDefaultMap = getBridgeConfig().getDefaultViewMappings();
   
@@ -612,32 +1068,10 @@ public class BridgeContextImpl extends B
         
         setViewHistory(mode, modeView, false);
       }
+      getBridgeConfig().getAttributes().put(BRIDGE_CONTEXT_HAS_INITED_VIEW_HISTORY, Boolean.TRUE);
     }
   }
   
-  private String encodeMode(String mode, String viewId)
-  {
-    // if the viewId doesn't otherwise contain a mode param, encode it
-    // this is done so its already encoded in the viewid when developer uses
-    // to return to the mode/view
-    StringBuffer sb = new StringBuffer(viewId.length() + 30);
-    int queryStart = viewId.indexOf('?');
-    if (queryStart < 0)
-    {
-      return sb.append(viewId)
-        .append('?')
-        .append(Bridge.PORTLET_MODE_PARAMETER)
-        .append('=')
-        .append(mode)
-        .toString();
-    }
-    else
-    {
-      QueryString qs = new QueryString(viewId.substring(queryStart + 1), "UTF8");
-      qs.setParameter(Bridge.PORTLET_MODE_PARAMETER, mode);
-      return sb.append(viewId.substring(0, queryStart + 1)).append(qs.toString()).toString();
-    }
-  }
     
   
   /**

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/controller/BridgeControllerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/controller/BridgeControllerImpl.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/controller/BridgeControllerImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/controller/BridgeControllerImpl.java Thu Jun 23 21:45:13 2011
@@ -124,24 +124,14 @@ public class BridgeControllerImpl
   public static final String PORTLET_NAME_ATTRIBUTE = "org.apache.myfaces.portlet.faces.portletName";
   public static final String VIEWID_QUERYSTRING_ATTRIBUTE = "org.apache.myfaces.portlet.faces.viewIdQueryString";
 
-  private static final String REQUEST_SCOPE_MANAGER = "org.apache.myfaces.portlet.faces.requestScopeManager";
-  private static final String REQUEST_SCOPE_LOCK = "org.apache.myfaces.portlet.faces.requestScopeLock";
-  private static final String REQUEST_SCOPE_MAP = "org.apache.myfaces.portlet.faces.requestScopeMap";
-  private static final String SCOPE_VIEW_KEY = "org.apache.myfaces.portlet.faces.includeInScope.scopeViewKey";
-  private static final String REQUEST_SCOPE_LISTENER = "org.apache.myfaces.portlet.faces.requestScopeWatch";
   public static final String FACES_VIEWROOT = "org.apache.myfaces.portlet.faces.includeInScope.facesViewRoot";
   private static final String FACES_MESSAGES = "org.apache.myfaces.portlet.faces.includeInScope.facesMessages";
   public static final String REQUEST_PARAMETERS = "org.apache.myfaces.portlet.faces.includeInScope.requestParameters";
   public static final String PREEXISTING_ATTRIBUTE_NAMES = "org.apache.myfaces.portlet.faces.preExistingAttributeNames";
   private static final String REQUEST_SCOPE_ID_RENDER_PARAM = "__jpfbReqScopeId";
-  private static final String NULL_VIEW_STATE_PARAM_VALUE = "org.apache.myfaces.portlet.faces.nullViewState";
   private static final String CACHED_VIEWROOT_LOCALE = "org.apache.myfaces.portlet.faces.cachedViewRootLocale";
   private static final String PROCESSED_PUBLIC_PARAMS ="org.apache.myfaces.portlet.faces.processedPublicParams";
   public static final String SAVED_VIEW_STATE = "org.apache.myfaces.portlet.faces.includeInScope.savedViewState";
-  private static final String CHILD_RESOURCE_REQUEST_SCOPE_MAP = "org.apache.myfaces.portlet.faces.includeInScope.childResourceRequestScopeMap";
-
-
-  private boolean mInitialized = false;
 
   private BridgeConfig mBridgeConfig = null;  
   private FacesContextFactory mFacesContextFactory = null;
@@ -191,12 +181,15 @@ public class BridgeControllerImpl
     // Clear this state here to ensure the following render isn't confused
     // TODO:  can we figure out a way to store this so its autocleared when a scope is restarted?
     clearRenderRedirectCache(bCtx);
+    
+    // Remove any BridgeRequestScope associate with this view/mode
+    bCtx.getBridgeRequestScopeManager().removeRequestScope(bCtx, bCtx.getFacesViewId(true));
        
     try
     {
       // Get the FacesContext instance for this request
       lifecycle = getLifecycle(bCtx);
-      fCtx = getFacesContext(bCtx, lifecycle, null);
+      fCtx = getFacesContext(bCtx, lifecycle);
          
       // An action starts a new bridge request scope -- if the prior scope was managed temporarily on the session -- remove it
       bCtx.getPortletRequest().getPortletSession().removeAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
@@ -213,7 +206,7 @@ public class BridgeControllerImpl
       if (!fCtx.getResponseComplete())
       {
         // navigation didn't redirect
-        encodeStateAwareResponse(bCtx, fCtx, null);
+        encodeStateAwareResponse(bCtx, fCtx);
       }
 
     }
@@ -273,14 +266,12 @@ public class BridgeControllerImpl
 
     FacesContext fCtx = null;
     Lifecycle lifecycle = null;
-    BridgeRequestScope scope = getRequestScope(bCtx);
+    BridgeRequestScope scope = getBridgeRequestScope(bCtx);
     boolean restoredScope = false;
     boolean removeScope = false;
     
     if (scope != null)
     {  
-      // If it was managed on the session, remove it from that scope as event will use render parameter
-      clearBridgeRequestScopeSessionParameter(bCtx);
       restoredScope = restoreBridgeRequestScopeData(bCtx, scope);
     }
     
@@ -288,7 +279,7 @@ public class BridgeControllerImpl
     {
       lifecycle = getLifecycle(bCtx);
       // Get the FacesContext instance for this request
-      fCtx = getFacesContext(bCtx, lifecycle, null);    
+      fCtx = getFacesContext(bCtx, lifecycle);    
         
       // add self as PhaseListener to prevent action phase from executing (after restoreView)
       lifecycle.addPhaseListener(this);
@@ -319,12 +310,14 @@ public class BridgeControllerImpl
         }
       }
 
-
-      encodeStateAwareResponse(bCtx, fCtx, scope);
+      // Navigation may have taken us to another scope -- if so no need to keep around the
+      // one we started with.
+      
+      BridgeRequestScope currentScope = encodeStateAwareResponse(bCtx, fCtx);
 
       // Now check to see if the scope actually was saved -- if not remove the 
       // one we have
-      if (!bCtx.getPreserveBridgeRequestScope())
+      if (scope != null && currentScope != scope)
       {
         removeScope = true;
       }
@@ -347,7 +340,10 @@ public class BridgeControllerImpl
       {
         // Because we automatically copy forward all render parameters when the scope is not carried forward we must clear its param
         //TODO: use real requeststatemanager
-        getBridgeRequestScopeManager(bCtx).removeRequestScope(bCtx, scope);
+        if (scope != null)
+        {
+          bCtx.getBridgeRequestScopeManager().removeRequestScope(bCtx, scope);
+        }
       }
       
       // TODO: add back in
@@ -382,60 +378,22 @@ public class BridgeControllerImpl
            BridgeDefaultViewNotSpecifiedException,
            BridgeUninitializedException
   {
-    // Now we need to determine if view we are going to render is the one
-    // encoded in the request (parameters) or specifically supplied
-    // either by the portlet itself or by a prior render redirect.
-    boolean clientDirectedView = ((bCtx.getPortletRequest().getAttribute(Bridge.VIEW_ID) != null) ||
-        (bCtx.getPortletRequest().getAttribute(Bridge.VIEW_PATH) != null));
-
-    // Now check to see if this is a Refresh (render) that follows a redirect
-    // If it is use the redirect information cached in the session as the basis
-    // for the request. 
-    QueryString redirectParams = getCachedRenderRedirectQueryString(bCtx);
     
-    boolean modeChanged = hasModeChanged(bCtx, redirectParams);
-
-    if (redirectParams != null)
+    if (renderFollowsRenderRedirect(bCtx))
     {
-      if (clientDirectedView || modeChanged)  
-      {
-        // if we are to rely on the render redirect cache we must still
-        // be in the same mode and/or the portlet can't have set an explicit view to use
-        
-        // mode change/direct view set while in redirectDuringRender state
-        // clear this state (as we are no longer in it)
-        // and don't use the data
-        clearRenderRedirectCache(bCtx);
-      }
-      else
-      {
-        // Incoming request may contain new PRP values -- if they do we need to update the RENDER_REDIRECT_VIEWPARAMS
-        redirectParams = updatePRPsInRenderRedirectCache(bCtx);
-        
-      }
+      updateRequestUsingRenderRedirectCache(bCtx);
     }
     
+  
     FacesContext fCtx = null;
     Lifecycle lifecycle = null;
-    BridgeRequestScope scope = getRequestScope(bCtx);
+    BridgeRequestScope scope = getBridgeRequestScope(bCtx);
     boolean restoredScope = false;
     
     
     
     // First render request or a clientDirectedView
-    if (scope == null)
-    {
-      // first request 
-      // create a scope and store in the session until an action occurs
-      // pass null as we aren't a StateAwareResponse
-      scope = getNewBridgeRequestScope(bCtx, bCtx.getPortletRequest(), null);
-    }
-    else if (clientDirectedView)
-    {
-      // Since the client has told us the specific view to use assume we shouldn't use existing scope
-      scope.clear();
-    }
-    else
+    if (scope != null)
     {
       // If available -- restore the bridge request scope before getting the
       // FacesContext in case anything in the context construction relies
@@ -448,7 +406,7 @@ public class BridgeControllerImpl
     {
       // Get the FacesContext instance for this request
       lifecycle = getLifecycle(bCtx);
-      fCtx = getFacesContext(bCtx, lifecycle, redirectParams);
+      fCtx = getFacesContext(bCtx, lifecycle);
       ExternalContext extCtx = fCtx.getExternalContext();
 
       // ensure that isPostback attribute set if VIEW_STATE param exists (though Faces generally
@@ -533,26 +491,19 @@ public class BridgeControllerImpl
   {
 
     FacesContext fCtx = null;
-    BridgeRequestScope scope = null;
+    BridgeRequestScope scope = getBridgeRequestScope(bCtx);
+    if (scope == null)
+    {
+      // don't expect this as we should always have a scope -- but to be safe
+      scope = getNewBridgeRequestScope(bCtx);
+    }
     try
     {
       // Get the FacesContext instance for this request
       Lifecycle lifecycle = getLifecycle(bCtx);
-      fCtx = getFacesContext(bCtx, lifecycle, null);
+      fCtx = getFacesContext(bCtx, lifecycle);
       ExternalContext extCtx = fCtx.getExternalContext();
      
-      // getting the scopeId is delayed until after getting the FacesContext
-      // because a resource request could be as a result of an embedded iFrame
-      // i.e. a child scope of the original render -- in this case don't use the render
-      // scope but the correct one contained within it
-      scope = getResourceRequestScope(bCtx, extCtx);
-      
-      if (scope == null)
-      {
-        // don't expect this as we should always have a scope -- but to be safe
-        scope = getNewBridgeRequestScope(bCtx, bCtx.getPortletRequest(), null);
-      }
-
       doFacesRender(bCtx, fCtx, lifecycle, scope);
     }
     catch (Exception e)
@@ -608,7 +559,7 @@ public class BridgeControllerImpl
       BridgeRequestScope scope
       )
     throws BridgeException, BridgeUninitializedException, NullPointerException
-  {
+  {   
     // Note: if the scope wasn't restored then the Faces
     // FACES_VIEW_STATE
     // parameter will not have been carried into this render and hence
@@ -616,10 +567,7 @@ public class BridgeControllerImpl
     // in a postback (isPostback() will return false. This means Faces
     // will create a new Tree instead of restoring one -- the semantics
     // one should get if the Bridge can't access its requestScope.
-    
-    PortletRequest request = bCtx.getPortletRequest();
-    MimeResponse response = (MimeResponse) bCtx.getPortletResponse();
-      
+          
     try
     {
       // add self as PhaseListener to restore Messages and in the case of 
@@ -669,9 +617,11 @@ public class BridgeControllerImpl
       redirectRender(bCtx, fCtx, lifecycle, scope);
       fCtx = FacesContext.getCurrentInstance();
     }
-    
-    // finish up by doing what the bridge needs to do to save end of response state
-    encodeMarkupResponse(bCtx, fCtx, scope);
+    else
+    {
+      // finish up by doing what the bridge needs to do to save end of response state
+      encodeMarkupResponse(bCtx, fCtx, scope);
+    }
   }
   
   private void redirectRender(BridgeContext bCtx,
@@ -691,17 +641,23 @@ public class BridgeControllerImpl
                                                        new HashMap<String, String[]>(bCtx.getPortletRequest().getPublicParameterMap()));
     }
     
-    // Reset the scope
+   
+    // close the FacesContext
+    releaseFacesContext(bCtx, fCtx);
+    
+    // clear the render redirect boolean so that when we render we no longer think we are in a redirect
+    bCtx.setRenderRedirect(false);
+    
+    QueryString cachedQS = updateRequestUsingRenderRedirect(bCtx);
+    
+    // Clear the previous scope since we never really got here (we renderRedirected)
     if (scope != null)
     {
-      scope.clear();
+      bCtx.getBridgeRequestScopeManager().removeRequestScope(bCtx, scope);
     }
-    
-    // close the FacesContext
-    releaseFacesContext(bCtx, fCtx);
           
     // start a new FacesContext
-    fCtx = getFacesContext(bCtx, lifecycle, getCachedRenderRedirectQueryString(bCtx));
+    fCtx = getFacesContext(bCtx, lifecycle);
     
     // Deal with possible recursion by clearing the cache, then calling doFacesRender
     // to render the redirect, and then finally setting the cache, if its hasn't
@@ -710,7 +666,7 @@ public class BridgeControllerImpl
     fCtx.getExternalContext().getSessionMap().remove(BridgeControllerImpl.RENDER_REDIRECT_VIEWPARAMS);
     
     // Run lifecycle.execute again ... then render
-    doFacesRender(bCtx, fCtx, lifecycle, scope);
+    doFacesRender(bCtx, fCtx, lifecycle, null);
     
     // Reacquire the context as it may have changed if a recursive redirect render occurred
     fCtx = FacesContext.getCurrentInstance();
@@ -719,7 +675,7 @@ public class BridgeControllerImpl
     // that occur before an action
     if (fCtx.getExternalContext().getSessionMap().get(BridgeControllerImpl.RENDER_REDIRECT_VIEWPARAMS) == null)
     {
-      fCtx.getExternalContext().getSessionMap().put(BridgeControllerImpl.RENDER_REDIRECT_VIEWPARAMS, getCachedRenderRedirectQueryString(bCtx));
+      fCtx.getExternalContext().getSessionMap().put(BridgeControllerImpl.RENDER_REDIRECT_VIEWPARAMS, cachedQS);
     }
 
   }  
@@ -752,7 +708,7 @@ public class BridgeControllerImpl
     }
   }
   
-  private FacesContext getFacesContext(BridgeContext bCtx, Lifecycle lifecycle, QueryString redirectParams)
+  private FacesContext getFacesContext(BridgeContext bCtx, Lifecycle lifecycle)
     throws FacesException
   {
     FacesContext fCtx = null;
@@ -760,14 +716,7 @@ public class BridgeControllerImpl
     fCtx = 
           getFacesContextFactory().getFacesContext(bCtx.getPortletContext(), bCtx.getPortletRequest(), bCtx.getPortletResponse(), lifecycle);
     
-    if (redirectParams != null)
-    {
-      // render redirect -- wrap the request
       
-      // call ExternalContext.setRequest with wrapped request
-      fCtx.getExternalContext().setRequest(wrapRequestToRedirect((RenderRequest) bCtx.getPortletRequest(), redirectParams));
-    }
-       
     // Send the Post Construct FacesContext system event
     fCtx.getApplication().publishEvent(fCtx, BridgePostConstructFacesContextSystemEvent.class, bCtx);
     
@@ -783,44 +732,32 @@ public class BridgeControllerImpl
     fCtx.release();
   }
   
-  private BridgeRequestScope getRequestScope(BridgeContext bCtx)
+  
+  private BridgeRequestScope getBridgeRequestScope(BridgeContext bCtx)
   {
-    String scopeId = bCtx.getPortletRequest().getParameter(REQUEST_SCOPE_ID_RENDER_PARAM);
+    String ignoreScope = bCtx.getPortletRequest().getParameter(BridgeController.IGNORE_BRIDGE_SCOPE);
+    BridgeRequestScope scope = bCtx.getBridgeScope();
 
-    if (scopeId == null)
-    {
-      PortletSession session = bCtx.getPortletRequest().getPortletSession();
-      if (session != null)
-      {
-        scopeId = (String) session.getAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
-      }
-    }
-    
-    // Only use this scope if it matches the current request mode
-    if (scopeId != null)
+    if (scope != null && Boolean.getBoolean(ignoreScope))
     {
-      // Its possible we didn't detect the mode change but its the wrong scope
-      // as the scope is encoded with the mode -- confirm its right
-      StringBuffer sb = new StringBuffer(10);
-      String modeCheck = sb.append(":").append(bCtx.getPortletRequest().getPortletMode().toString()).append(":").toString();
-      if (scopeId.indexOf(modeCheck) < 0 )
-      {
-        // scope is for a different mode
-        scopeId = null;
-      }
+      bCtx.getBridgeRequestScopeManager().removeRequestScope(bCtx, scope);
+      scope = null;
     }
-        
-    if (scopeId != null)
-    {
-      return getBridgeRequestScopeManager(bCtx).getRequestScopeById(bCtx, scopeId);
-    }
-    else
+    return scope;        
+  }
+  
+  private void clearBridgeRequestScope(BridgeContext bCtx)
+  {
+    BridgeRequestScope scope = bCtx.getBridgeScope();
+    if (scope != null)
     {
-      return null;
+      scope.clear();
     }
-          
   }
   
+  //TODO: unneeded??
+  
+  /*
   private BridgeRequestScope getResourceRequestScope(BridgeContext bCtx, ExternalContext extCtx)
   {
     BridgeRequestScope childScope = null;
@@ -856,7 +793,7 @@ public class BridgeControllerImpl
       
       if (childScopeId == null)
       {
-        childScope = getNewBridgeRequestScope(bCtx, bCtx.getPortletRequest(), null);
+        childScope = getNewBridgeRequestScope(bCtx);
       
         if (childResourceScopeMap == null)
         {
@@ -890,6 +827,7 @@ public class BridgeControllerImpl
     // also ensure that the scopeId is now carried forward as a renderParameter
     bCtx.getPortletRequest().getPortletSession().removeAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
   }
+*/
   
   @SuppressWarnings("unchecked")
   private boolean restoreBridgeRequestScopeData(BridgeContext bCtx, BridgeRequestScope scope)
@@ -978,6 +916,52 @@ public class BridgeControllerImpl
     }   
   }
   
+  private boolean isClientDirectedView(BridgeContext bCtx)
+  {
+    return  bCtx.getPortletRequest().getAttribute(Bridge.VIEW_ID) != null ||
+            bCtx.getPortletRequest().getAttribute(Bridge.VIEW_PATH) != null;
+  }
+  
+  private boolean renderFollowsRenderRedirect(BridgeContext bCtx)
+  {
+    // Is there a cached renderRedirect????
+    QueryString redirectParams = getCachedRenderRedirectQueryString(bCtx);
+    
+    // Can't use renderRedirect with client directed views or if the mode has changed
+    if (redirectParams != null &&
+        !isClientDirectedView(bCtx) &&
+        !hasModeChanged(bCtx, redirectParams))
+    {
+      return true;
+    }
+    else
+    {
+      clearRenderRedirectCache(bCtx);
+      return false;
+    }
+  }
+  
+  private QueryString updateRequestUsingRenderRedirect(BridgeContext bCtx)
+  {
+    QueryString qs = new QueryString(bCtx.getRenderRedirectQueryString(), "UTF-8");
+    bCtx.setPortletRequest(wrapRequestToRedirect((RenderRequest) bCtx.getPortletRequest(), qs));
+    return qs;
+  }
+  
+  private void updateRequestUsingRenderRedirectCache(BridgeContext bCtx)
+  {
+    // Is there a cached renderRedirect????
+    QueryString redirectParams = getCachedRenderRedirectQueryString(bCtx);
+    
+    if (redirectParams != null)
+    {
+      // There is -- so wrap the request to reflect the render redirect state
+      // But first carry forward any changes to the PRPs
+      redirectParams = updatePRPsInRenderRedirectCache(bCtx);
+      bCtx.setPortletRequest(wrapRequestToRedirect((RenderRequest) bCtx.getPortletRequest(), redirectParams));
+    }
+  }
+  
   private QueryString getCachedRenderRedirectQueryString(BridgeContext bCtx)
   {
     return (QueryString) bCtx.getPortletRequest().getPortletSession(true).getAttribute(BridgeControllerImpl.RENDER_REDIRECT_VIEWPARAMS);
@@ -1064,9 +1048,10 @@ public class BridgeControllerImpl
     session.removeAttribute(BridgeControllerImpl.RENDER_REDIRECT_PRPMAP);
   }
   
-  private void encodeStateAwareResponse(BridgeContext bCtx, FacesContext fCtx, BridgeRequestScope scope)
+  private BridgeRequestScope encodeStateAwareResponse(BridgeContext bCtx, FacesContext fCtx)
     throws FacesException, IOException
   {
+    BridgeRequestScope scope = null;
     // Finalize the action response -- key here is the reliance on
     // ExternalContext.encodeActionURL to migrate info encoded
     // in the actionURL constructed from the target of this
@@ -1086,12 +1071,14 @@ public class BridgeControllerImpl
     if (bCtx.getPreserveBridgeRequestScope())
     {
       
+       scope = bCtx.getBridgeScope();
+      
       if (scope == null)
       {
         // Each action starts a new "action lifecycle"
         // The Bridge preserves request scoped data and if so configured
         // Action Parameters for the duration of an action lifecycle
-        scope = getNewBridgeRequestScope(bCtx, bCtx.getPortletRequest(), (StateAwareResponse) bCtx.getPortletResponse());
+        scope = getNewBridgeRequestScope(bCtx);
       }
 
       // managed in the bridge request scope so can restore in other phases
@@ -1102,8 +1089,7 @@ public class BridgeControllerImpl
 
       if (bCtx.getPortletRequestPhase() == Bridge.PortletPhase.ACTION_PHASE)
       {
-        // Spec requires we preserve the FACES_VIEW_STATE parameter
-        // in addition the portlet may be configured to preserve the
+        // Portlet may be configured to preserve the
         // rest of them.
         saveActionParams(fCtx);
       }
@@ -1117,41 +1103,37 @@ public class BridgeControllerImpl
       // Finally set the response render parameter to preserve the scope id
       ((StateAwareResponse) bCtx.getPortletResponse()).setRenderParameter(REQUEST_SCOPE_ID_RENDER_PARAM, scope.getId());
     }
-    else if (scope != null)
-    {
-      // if we aren't saving the scope -- clear it ( -- in case comething goes wrong and its not removed)
-      scope.clear();
-    }
+    
+    return scope;
   }
   
   private void encodeMarkupResponse(BridgeContext bCtx, FacesContext fCtx, BridgeRequestScope scope)
   {
-    
-    // Shouldn't happen but make sure there is always a scope
     if (scope == null) 
     {
-      // TODO:
-      // if (!mDebugLoggingEnabled.booleanValue())
-      // context.getExternalContext().log("WARNING: Unexpected situation -- reached end of internal doFacesRender without a scopeId");
+      if (bCtx.getPortletRequestPhase() == Bridge.PortletPhase.RENDER_PHASE)
+      {
+        // render does no saving until the first scope comes into existence via one of the other calls
+        return;
+      }
+      else
+      {  
+        // TODO:
+        // if (!mDebugLoggingEnabled.booleanValue())
+        // context.getExternalContext().log("WARNING: Unexpected situation -- reached end of internal doFacesRender without a scopeId");
       
-      // Don't expect to get here -- but just create a new scope
-      scope = getNewBridgeRequestScope(bCtx, bCtx.getPortletRequest(), null);
+        scope = getNewBridgeRequestScope(bCtx);
+      }
     }
     
     // Now make sure we cache the ViewState
     saveFacesViewState(scope, fCtx);
     
-    if (bCtx.getPortletRequestPhase() == Bridge.PortletPhase.RENDER_PHASE)
+    if (bCtx.getPortletRequestPhase() == Bridge.PortletPhase.RESOURCE_PHASE)
     {
-      scope.put(SCOPE_VIEW_KEY, getScopeViewKey(fCtx.getExternalContext()));
-    }
-    else if (bCtx.getPortletRequestPhase() == Bridge.PortletPhase.RESOURCE_PHASE)
-    {
-      
       // Resource request then we also update the full scope
       saveFacesMessageState(fCtx);
       scope.putAll(fCtx.getExternalContext().getRequestMap());
-
     }
   }
 
@@ -1387,60 +1369,21 @@ public class BridgeControllerImpl
     }
   }
 
-  private synchronized BridgeRequestScopeManager createBridgeRequestScopeManager(BridgeContext bCtx)
-  {
-    BridgeRequestScopeManager scopeManager = (BridgeRequestScopeManager) bCtx.getPortletContext().getAttribute(BridgeControllerImpl.REQUEST_SCOPE_MANAGER);
-    if (scopeManager == null)
-    {
-      bCtx.getPortletContext().setAttribute(BridgeControllerImpl.REQUEST_SCOPE_MANAGER, new BridgeRequestScopeManagerImpl(bCtx.getBridgeConfig()));
-      // get after put to ensure we get the one that actually stuck
-      scopeManager = (BridgeRequestScopeManager) bCtx.getPortletContext().getAttribute(BridgeControllerImpl.REQUEST_SCOPE_MANAGER);
-    }
-    return scopeManager;
-  }
-
-  private BridgeRequestScopeManager getBridgeRequestScopeManager(BridgeContext bCtx)
-  {
-    BridgeRequestScopeManager scopeManager = (BridgeRequestScopeManager) bCtx.getPortletContext().getAttribute(BridgeControllerImpl.REQUEST_SCOPE_MANAGER);
-
-    if (scopeManager == null)
-    {
-      scopeManager = createBridgeRequestScopeManager(bCtx);
-    }
-    return scopeManager;
-  }
   
-  private BridgeRequestScope getNewBridgeRequestScope(BridgeContext bCtx, PortletRequest request, StateAwareResponse response)
+  private BridgeRequestScope getNewBridgeRequestScope(BridgeContext bCtx)
   {
 
     // TODO:
     // Get the BridgeRequestScopeManager 
 
-    BridgeRequestScopeManager scopeManager = getBridgeRequestScopeManager(bCtx);
+    BridgeRequestScopeManager scopeManager = bCtx.getBridgeRequestScopeManager();
       
     // Ask it to create a BridgeRequestScope
-    BridgeRequestScope requestScope = scopeManager.createRequestScope(bCtx);
+    BridgeRequestScope requestScope = scopeManager.createRequestScope(bCtx, bCtx.getFacesViewId(true));
     
     // Set its excludes
     requestScope.setExcludedEntries(bCtx.getBridgeConfig().getExcludedRequestAttributes());
     requestScope.addExcludedEntries(bCtx.getPreFacesRequestAttrNames());
-    
-    // Now ensure the scopeId can be recovered in the next request
-    if (response != null)
-    {
-      // set in response render parameter so will receive in future calls
-      // however don't store internally until there is specific state to
-      // manage
-      response.setRenderParameter(REQUEST_SCOPE_ID_RENDER_PARAM, requestScope.getId());
-    }
-    else
-    {
-      // Must be a render/resource request before a scope has been established
-      // store in session until next action
-      PortletSession session = request.getPortletSession(true);
-      session.setAttribute(Bridge.BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM, requestScope.getId());
-    }
-
     return requestScope;
   }
 
@@ -1489,6 +1432,8 @@ public class BridgeControllerImpl
   {
     // get the messages from Faces Context
     Iterator<String> clientIds = context.getClientIdsWithMessages();
+    Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
+
     if (clientIds.hasNext())
     {
       FacesMessageState state = new FacesMessageState();
@@ -1501,9 +1446,13 @@ public class BridgeControllerImpl
         }
       }
       // save state in ViewRoot attributes
-      Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
       requestMap.put(FACES_MESSAGES, state);
     }
+    else
+    {
+      // No messages -- be sure not to carry anything forward.
+      requestMap.remove(FACES_MESSAGES);
+    }
   }
   
   private void restoreFacesMessageState(FacesContext context)
@@ -1513,8 +1462,9 @@ public class BridgeControllerImpl
     {
       Map<String, Object> map = context.getExternalContext().getRequestMap();
 
-      // restoring FacesMessages
-      FacesMessageState state = (FacesMessageState) map.get(FACES_MESSAGES);
+      // restoring FacesMessages -- remove cache it from request scope so its not reused if 
+      // this request ends with no messages
+      FacesMessageState state = (FacesMessageState) map.remove(FACES_MESSAGES);
 
       if (state != null)
       {

Modified: myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeImpl.java?rev=1139083&r1=1139082&r2=1139083&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/refactored_3.0.x/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/scope/BridgeRequestScopeImpl.java Thu Jun 23 21:45:13 2011
@@ -66,52 +66,101 @@ public class  BridgeRequestScopeImpl ext
   private static final float DEFAULT_LOAD_FACTOR = .75f;
   private static final int DEFAULT_CONCURRENCY_LEVEL = 4;
   
-  private String mIdPrefix;
+  private String mPortletId;
+  private String mSessionId;
+  private String mViewId;
+  private String mPortletMode;
   private String mId;
   private Vector<String> mExcludedEntries;
   
 // TODO: implement notifyPredestory function as weell as the ServletRequestAttributeListener stuff that used to be in BridgeImpl 
   
-  public BridgeRequestScopeImpl(String prefix)
+  public BridgeRequestScopeImpl(String portletId, String sessionId, String viewId, String portletMode)
   {
-    this(prefix, DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+    super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+    initScope(portletId, sessionId, viewId, portletMode);
   }
   
-  public BridgeRequestScopeImpl(String prefix, int initialCapacity)
+  public BridgeRequestScopeImpl(String portletId, String sessionId, String viewId, String portletMode, int initialCapacity)
   {
-    this(prefix, initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+    super(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
+    initScope(portletId, sessionId, viewId, portletMode);
   }
   
-  public BridgeRequestScopeImpl(String prefix, int initialCapacity, float loadFactor, int concurrencyLevel)
+  public BridgeRequestScopeImpl(String portletId, String sessionId, String viewId, String portletMode, int initialCapacity, float loadFactor, int concurrencyLevel)
   {
     super(initialCapacity, loadFactor, concurrencyLevel);
-    mIdPrefix = prefix;
+    initScope(portletId, sessionId, viewId, portletMode);
   }
   
-  public BridgeRequestScopeImpl(String prefix, Map<String,Object> t)
+  public BridgeRequestScopeImpl(String portletId, String sessionId, String viewId, String portletMode, Map<String,Object> t)
   {
     super(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
-    mIdPrefix = prefix;
+    initScope(portletId, sessionId, viewId, portletMode);
   }
-
+  
+  
+  private void initScope(String portletId, String sessionId, String viewId, String portletMode)
+  {
+    mPortletId = portletId;
+    mSessionId = sessionId;
+    mViewId = viewId;
+    mPortletMode = portletMode;
+  }
+  
  
  /**
    * 
-   * @return unique string id representing this scope.  Its value is prefixed by 
-   *         whatever prefix has been previously set on it.
+   * @return unique string id representing this scope.
    */
  public String getId()
  {
    if (mId == null)
    {
      UID uid = new UID();
-     StringBuffer sb = new StringBuffer(mIdPrefix);
-     mId = sb.append(':').append(uid.toString()).toString();
+     mId = uid.toString();
    }
    
    return mId;
  }
  
+  /**
+    * 
+    * @return unique string id representing the portlet to which this scope pertains.
+    */
+  public String getPortletId()
+  {
+    return mPortletId;
+  }
+  
+  /**
+    * 
+    * @return unique string id representing the sesssion to which this scope pertains.
+    */
+  public String getSessionId()
+  {
+    return mSessionId;
+  }
+  
+  /**
+    * 
+    * @return unique string id representing the Faces viewId to which this scope pertains.
+    */
+  public String getViewId()
+  {
+    return mViewId;
+  }
+  
+  
+  /**
+    * 
+    * @return unique string id representing the Portlet mode to which this scope pertains.
+    */
+  public String getPortletMode()
+  {
+    return mPortletMode;
+  }
+ 
  /**
    * Sets a new List of excluded attribute names.  The names follow the syntax
    * described in the specification.  Any currently set attribute names are



Mime
View raw message