You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by so...@apache.org on 2010/03/17 10:58:59 UTC

svn commit: r924204 - in /myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0: ./ api/src/main/java/javax/portlet/faces/ api/src/main/java/javax/portlet/faces/component/ api/src/main/resources/META-INF/ assembly/src/main/resources/META-IN...

Author: sobryan
Date: Wed Mar 17 09:58:58 2010
New Revision: 924204

URL: http://svn.apache.org/viewvc?rev=924204&view=rev
Log:
Upmerge to 912019

Modified:
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/   (props changed)
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/Bridge.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/BridgeUtil.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/component/PortletNamingContainerUIViewRoot.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/resources/META-INF/NOTICE   (props changed)
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/assembly/src/main/resources/META-INF/NOTICE   (props changed)
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/pom.xml
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/BridgeRenderRequestWrapper.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletFacesContextFactoryImpl.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/preference/PreferenceValuesList.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletAbstractMap.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestHeaderValuesMap.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestParameterValuesMap.java
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/resources/META-INF/NOTICE   (props changed)
    myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/pom.xml

Propchange: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/
------------------------------------------------------------------------------
    svn:mergeinfo = /myfaces/portlet-bridge/core/trunk_2.0.x:888894-923981

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/Bridge.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/Bridge.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/Bridge.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/Bridge.java Wed Mar 17 09:58:58 2010
@@ -337,6 +337,15 @@ Bridge
    * BRIDGE_PACKAGE_PREFIX + context.getPortletName() + bridgeEventHandler
    */
   public static final String BRIDGE_PUBLIC_RENDER_PARAMETER_HANDLER = "bridgePublicRenderParameterHandler";
+  
+  /** Special value recognized during <code>encodeActionURL</code> of a portlet: url containing either
+   * the <code>_jsfBridgeViewId</code> or <code>_jsfBridgeViewPath</code> parameter. 
+   * <code>encodeActionURL</code> recognizes this value as indicating it needs to generate and
+   * encode an URL to the current JSF including its current state.  I.e. It not only
+   * encodes the link reference but also the existing render parameters so they can be carried forward
+   * to reestablish the state.
+   */
+  public static final String FACES_USE_CURRENT_VIEW_PARAMETER = "_jsfBridgeCurrentView";
 
 
   /** Enumeration whose values describe the current portlet phase the bridge

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/BridgeUtil.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/BridgeUtil.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/BridgeUtil.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/BridgeUtil.java Wed Mar 17 09:58:58 2010
@@ -29,7 +29,14 @@ public class BridgeUtil
    */
   public static boolean isPortletRequest() 
   {
-    Map<String, Object> m = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
+    FacesContext ctx = FacesContext.getCurrentInstance();
+    
+    // This method might be called during App startup (via a context listener) and hence no FacesContext
+    // For example a renderkit might createComponents during such time -- as the bridge overrides faces Application
+    // which implements createComponent and calls this method (to see if we need to wrap/replace with the NamingContainer
+    if (ctx == null)  return false;
+    
+    Map<String, Object> m = ctx.getExternalContext().getRequestMap();
     Bridge.PortletPhase phase = (Bridge.PortletPhase) m.get(Bridge.PORTLET_LIFECYCLE_PHASE);
     return phase != null;
   }

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java Wed Mar 17 09:58:58 2010
@@ -90,7 +90,7 @@ public class GenericFacesPortlet extends
    * by this application.  Typically not used unless more then 1 bridge is configured
    * in an environment as its more usual to rely on the self detection.
    */
-  public static final String BRIDGE_CLASS = Bridge.BRIDGE_PACKAGE_PREFIX + "BridgeImplClass";
+  public static final String BRIDGE_CLASS = Bridge.BRIDGE_PACKAGE_PREFIX + "BridgeClassName";
 
   /** Portlet init parameter that defines the default ViewId that should be used
    * when the request doesn't otherwise convery the target.  There must be one 
@@ -424,7 +424,7 @@ public class GenericFacesPortlet extends
 
   /**
    * Returns the default content type for this portlet request. Subclasses override to
-   * alter the default behavior. Default implementation returns value of the portlet context init
+   * alter the default behavior. Default implementation returns value of the portlet init
    * parameter: javax.portlet.faces.DefaultContentType. If it doesn't exist the portlet
    * request's preferred response content type is returned.
    * 
@@ -436,7 +436,7 @@ public class GenericFacesPortlet extends
   public String getResponseContentType(PortletRequest request)
   {
     String contentType = 
-      getPortletConfig().getPortletContext().getInitParameter(DEFAULT_CONTENT_TYPE);
+      getPortletConfig().getInitParameter(DEFAULT_CONTENT_TYPE);
 
     if (contentType == null || !isInRequestedContentTypes(request, contentType))
     {
@@ -460,7 +460,7 @@ public class GenericFacesPortlet extends
 
   /**
    * Returns the character set encoding used for this portlet response. Subclasses override to
-   * alter the default behavior. Default implementation returns value of the portlet context init
+   * alter the default behavior. Default implementation returns value of the portlet init
    * parameter: javax.portlet.faces.DefaultCharacterSetEncoding. If it doesn't exist null
    * is returned.
    * 
@@ -471,7 +471,7 @@ public class GenericFacesPortlet extends
    */
   public String getResponseCharacterSetEncoding(PortletRequest request)
   {
-    return getPortletConfig().getPortletContext().getInitParameter(DEFAULT_CHARACTERSET_ENCODING);
+    return getPortletConfig().getInitParameter(DEFAULT_CHARACTERSET_ENCODING);
   }
 
 
@@ -500,6 +500,10 @@ public class GenericFacesPortlet extends
         if (s.startsWith(DEFAULT_VIEWID) && s.length() > DEFAULT_VIEWID.length())
         {
           String viewId = config.getInitParameter(s);
+          
+          // Don't add if there isn't a view
+          if (viewId == null || viewId.length() == 0) continue;
+          
           // extract the mode
           s = s.substring(len + 1);
           mDefaultViewIdMap.put(s, viewId);

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/component/PortletNamingContainerUIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/component/PortletNamingContainerUIViewRoot.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/component/PortletNamingContainerUIViewRoot.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/java/javax/portlet/faces/component/PortletNamingContainerUIViewRoot.java Wed Mar 17 09:58:58 2010
@@ -52,8 +52,13 @@ public class PortletNamingContainerUIVie
   @Override
   public String getContainerClientId(FacesContext context)
   {
-    if (BridgeUtil.isPortletRequest() && ((Boolean) this.getAttributes().get(PORTLET_ENCODED_NAMESPACE_ID)).equals(Boolean.TRUE))
+    if (BridgeUtil.isPortletRequest())
     {
+      // Some impls (Facelets don't set an id on the UIViewRoot)  -- so do so now
+      if (((Boolean) this.getAttributes().get(PORTLET_ENCODED_NAMESPACE_ID)).equals(Boolean.FALSE))
+      {
+        setId(null); // setId has a default for this
+      }
       return super.getContainerClientId(context);
     }
     else
@@ -68,6 +73,13 @@ public class PortletNamingContainerUIVie
   {
     if (BridgeUtil.isPortletRequest()) 
     {
+      // Turns out that in Facelets the UIViewRoot doesn't seem to have its id set -- i.e. its null
+      // So recognize null and change to ""
+      if (id == null)
+      {
+        id = "";
+      }
+      
       // Turns out some Faces impls (the RI) , on restoreView, manually sets the id from 
       // the extracted state prior to telling the component to restore itself from this state.
       // (At which point the self restore overwrites any id set prior.).  As this manual

Propchange: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/api/src/main/resources/META-INF/NOTICE
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Mar 17 09:58:58 2010
@@ -0,0 +1,2 @@
+/myfaces/portlet-bridge/core/trunk_2.0.x/api/src/main/resources/META-INF/NOTICE:888894-923981
+/myfaces/portlet-bridge/trunk/api/src/main/resources/META-INF/NOTICE:588229-629933

Propchange: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/assembly/src/main/resources/META-INF/NOTICE
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Mar 17 09:58:58 2010
@@ -0,0 +1,2 @@
+/myfaces/portlet-bridge/core/trunk_2.0.x/assembly/src/main/resources/META-INF/NOTICE:888894-923981
+/myfaces/portlet-bridge/trunk/assembly/src/main/resources/META-INF/NOTICE:588229-629933

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/pom.xml?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/pom.xml (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/pom.xml Wed Mar 17 09:58:58 2010
@@ -81,6 +81,9 @@
   <build>
     <resources>
       <resource>
+        <directory>src/main/resources</directory>
+      </resource>
+      <resource>
         <!-- because adding an additional resourceRoot not possible with antrun yet -->
         <directory>target/refactored-shared-sources/main/resources</directory>
       </resource>

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java Wed Mar 17 09:58:58 2010
@@ -28,6 +28,7 @@ import java.net.URL;
 
 import java.rmi.server.UID;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -35,6 +36,7 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -120,6 +122,7 @@ public class BridgeImpl
   public static final String UPDATED_VIEW_STATE_PARAM = "org.apache.myfaces.portlet.faces.updatedViewStateParam";
   public static final String REDIRECT_VIEWPARAMS = "org.apache.myfaces.portlet.faces.redirectViewParams";
   public static final String RENDER_REDIRECT_VIEWPARAMS = "org.apache.myfaces.portlet.faces.renderRedirectViewParams";
+  public static final String RENDER_REDIRECT_PRPMAP = "org.apache.myfaces.portlet.faces.renderRedirectPRPMap";
 
   // public so other parts of the impl can access the portletName to access portlet specific context attrs
   public static final String PORTLET_NAME_ATTRIBUTE = "org.apache.myfaces.portlet.faces.portletName";
@@ -131,9 +134,10 @@ public class BridgeImpl
   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";
   private static final String REQUEST_PARAMETERS = "org.apache.myfaces.portlet.faces.includeInScope.requestParameters";
-  private static final String PREEXISTING_ATTRIBUTE_NAMES = "org.apache.myfaces.portlet.faces.preExistingAttributeNames";
+  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";
   private static final int DEFAULT_MAX_MANAGED_REQUEST_SCOPES = 100;
 
@@ -295,28 +299,24 @@ public class BridgeImpl
     // the application has inserted itself in this process and sets up
     // needed request attributes.
     List<String> preExistingAttributes = getRequestAttributes(request);
-    // place on the request for use here and in the servletRequestAttributeListener
-    if (preExistingAttributes != null)
-    {
-      request.setAttribute(PREEXISTING_ATTRIBUTE_NAMES, preExistingAttributes);
-    }
 
     FacesContext context = null;
+    Lifecycle lifecycle = null;
     String scopeId = null;
     try
     {
       // Get the FacesContext instance for this request
-      context = getFacesContext(request, response, getLifecycle(), null);
+      lifecycle = getLifecycle();
+      context = getFacesContext(request, response, lifecycle, null);
    
       // in case a prior scope was managed temporarily on the session -- remove it
       request.getPortletSession().removeAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
       
-      // process public render parameters -- note pass in the portlet request as this
-      // exposes the PPR where the one in the ExternalContext doesn't
-      processIncomingPublicRenderParameters(context, request);
-
       // For actions we only execute the lifecycle phase
-      getLifecycle().execute(context);
+
+      lifecycle.addPhaseListener(this);
+      
+      lifecycle.execute(context);
 
       // If responseComplete don't save any state as we aren't falling through to render
       // Usual occurs because of a redirect
@@ -385,6 +385,11 @@ public class BridgeImpl
     finally
     {
       dumpScopeId(scopeId, "ACTION_PHASE");
+      
+      if (lifecycle != null)
+      {
+        lifecycle.removePhaseListener(this);
+      }
 
       if (context != null)
       {
@@ -396,6 +401,8 @@ public class BridgeImpl
         // so it can be used in subsequent renders that occur before the action.
         context.getExternalContext().getRequestMap().remove(BridgeImpl.REDIRECT_VIEWPARAMS);
         context.getExternalContext().getSessionMap().remove(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS);
+        context.getExternalContext().getSessionMap().remove(BridgeImpl.RENDER_REDIRECT_PRPMAP);
+
         context.release();
       }
       
@@ -456,7 +463,7 @@ public class BridgeImpl
     if (mEventHandler == null)
     {
       // make sure the render parameters are carried forward into the next request
-      response.setRenderParameters(request);
+      response.setRenderParameters(request.getParameterMap());
       // TODO: maybe log something here?
       return;
     }
@@ -500,16 +507,12 @@ public class BridgeImpl
     // the application has inserted itself in this process and sets up
     // needed request attributes.
     List<String> preExistingAttributes = getRequestAttributes(request);
-    // place on the request for use here and in the servletRequestAttributeListener
-    if (preExistingAttributes != null)
-    {
-      request.setAttribute(PREEXISTING_ATTRIBUTE_NAMES, preExistingAttributes);
-    }
     
     // Make sure that at a minimum the current render parameters are carried forward
-    response.setRenderParameters(request);
+    response.setRenderParameters(request.getParameterMap());
 
     FacesContext context = null;
+    Lifecycle lifecycle = null;
     String scopeId = request.getParameter(REQUEST_SCOPE_ID_RENDER_PARAM);
     if (scopeId != null)
     {
@@ -529,8 +532,9 @@ public class BridgeImpl
     
     try
     {
+      lifecycle = getLifecycle();
       // Get the FacesContext instance for this request
-      context = getFacesContext(request, response, getLifecycle(), null);
+      context = getFacesContext(request, response, lifecycle, null);
       
       if (restoredScope)
       {
@@ -542,12 +546,7 @@ public class BridgeImpl
       // in case a prior scope was managed temporarily on the session -- remove it
       request.getPortletSession().removeAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
       
-      // process public render parameters -- note pass in the portlet request as this
-      // exposes the PPR where the one in the ExternalContext doesn't
-      processIncomingPublicRenderParameters(context, request);
-      
       // add self as PhaseListener to prevent action phase from executing (after restoreView)
-      Lifecycle lifecycle = getLifecycle();
       lifecycle.addPhaseListener(this);
 
       // For actions we only execute the lifecycle phase
@@ -608,7 +607,11 @@ public class BridgeImpl
     }
     finally
     {
-      dumpScopeId(scopeId, "ACTION_PHASE");
+      dumpScopeId(scopeId, "EVENT_PHASE");
+      if (lifecycle != null)
+      {
+        lifecycle.removePhaseListener(this);
+      }
 
       if (context != null)
       {
@@ -620,6 +623,7 @@ public class BridgeImpl
         // so it can be used in subsequent renders that occur before the action.
         context.getExternalContext().getRequestMap().remove(BridgeImpl.REDIRECT_VIEWPARAMS);
         context.getExternalContext().getSessionMap().remove(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS);
+        context.getExternalContext().getSessionMap().remove(BridgeImpl.RENDER_REDIRECT_PRPMAP);
         context.release();
       }
       
@@ -689,23 +693,31 @@ public class BridgeImpl
 
     // 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.
+    // for the request. 
     QueryString redirectParams = (QueryString)
               request.getPortletSession(true).getAttribute(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS);
     
     boolean modeChanged = hasModeChanged(request, redirectParams);
 
-    if (redirectParams != null && (clientDirectedView || modeChanged))  
+    if (redirectParams != null)
     {
-      // if we are too 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
-      redirectParams = null;
-      request.getPortletSession().removeAttribute(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS);
-      
+      if (clientDirectedView || modeChanged)  
+      {
+        // if we are too 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
+        redirectParams = null;
+        request.getPortletSession().removeAttribute(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS);
+        request.getPortletSession().removeAttribute(BridgeImpl.RENDER_REDIRECT_PRPMAP);
+      }
+      else
+      {
+        // Incoming request may contain new PRP values -- if they do we need to update the RENDER_REDIRECT_VIEWPARAMS
+        updatePublicRedirectParams(request, redirectParams, (Map<String, String[]>)request.getPortletSession(true).getAttribute(BridgeImpl.RENDER_REDIRECT_PRPMAP));
+      }
     }
     
     
@@ -831,16 +843,6 @@ public class BridgeImpl
     throws BridgeException, BridgeUninitializedException, NullPointerException
   {
     boolean redirectedDuringRender = false;
-    boolean mappedPublicParams = false;
-    
-    // Only process PublicRenderParameters once
-    if (request.getAttribute(PROCESSED_PUBLIC_PARAMS) == null)
-    {
-      // process public render parameters -- note pass in the portlet request as this
-      // exposes the PPR where the one in the ExternalContext doesn't
-      mappedPublicParams = processIncomingPublicRenderParameters(context, request);
-      request.setAttribute(PROCESSED_PUBLIC_PARAMS, Boolean.TRUE);
-    }
 
     // Note: if the scope wasn't restored then the Faces
     // FACES_VIEW_STATE
@@ -849,18 +851,13 @@ public class BridgeImpl
     // 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.
-
-    // add self as PhaseListener to restore Messages and in the case of 
-    // the render phase, prevent excuting beyond restoreView
-    if (BridgeUtil.getPortletRequestPhase() ==  Bridge.PortletPhase.RENDER_PHASE
-        && !mappedPublicParams)
-        // if public params mapped then run whole lifecycle so values are pushed into view
-    {
-      lifecycle.addPhaseListener(this);
-    }
       
     try
     {
+      // add self as PhaseListener to restore Messages and in the case of 
+      // the render phase, prevent excuting beyond restoreView
+      lifecycle.addPhaseListener(this);
+      
       lifecycle.execute(context);
     }
     catch (Exception e)
@@ -874,10 +871,7 @@ public class BridgeImpl
     }
     finally
     {
-      if (BridgeUtil.getPortletRequestPhase() ==  Bridge.PortletPhase.RENDER_PHASE)
-      {
-        lifecycle.removePhaseListener(this);
-      }
+      lifecycle.removePhaseListener(this);
     }
 
     // check here to see if a redirect occurred -- if so rerun doFacesRequest
@@ -891,7 +885,7 @@ public class BridgeImpl
       // May have been set -- so don't ignore it
       if (!context.getResponseComplete())
       {
-        getLifecycle().render(context);
+        lifecycle.render(context);
       }
     }
     else
@@ -1009,11 +1003,6 @@ public class BridgeImpl
     // the application has inserted itself in this process and sets up
     // needed request attributes.
     List<String> preExistingAttributes = getRequestAttributes(request);
-    // place on the request for use here and in the servletRequestAttributeListener
-    if (preExistingAttributes != null)
-    {
-      request.setAttribute(PREEXISTING_ATTRIBUTE_NAMES, preExistingAttributes);
-    }
 
     String scopeId = getRequestScopeId(request);
     if (scopeId == null)
@@ -1076,6 +1065,10 @@ public class BridgeImpl
       return;
 
     mInitialized = false;
+    
+    // Remove the context listener
+    ((ApplicationFactory)FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
+        .getApplication().removeELContextListener(this);
 
     // remove any scopes being managed for this portlet
     // Each scope has a per portlet prefix -- pass in the prefix
@@ -1213,7 +1206,11 @@ public class BridgeImpl
     while (i.hasNext())
     {
       String mode = i.next();
-      String defaultViewId = encodeMode(mode, viewIdDefaultMap.get(mode));
+      String modeView = viewIdDefaultMap.get(mode);
+      
+      if (modeView == null || modeView.length() == 0) continue;
+      
+      String defaultViewId = encodeMode(mode, modeView);
       StringBuffer key = new StringBuffer(100);
       session.setAttribute(
           key.append(Bridge.VIEWID_HISTORY).append('.').append(mode).toString(),
@@ -1244,6 +1241,21 @@ public class BridgeImpl
       return sb.append(viewId.substring(0, queryStart + 1)).append(qs.toString()).toString();
     }
   }
+  
+  private ArrayList<String> getPublicParameterNamesList()
+  {
+    Enumeration<String> e = mPortletConfig.getPublicRenderParameterNames();
+    if (!e.hasMoreElements()) return (ArrayList<String>) Collections.EMPTY_LIST;
+    ArrayList<String>  l = new ArrayList<String>(10);
+      
+    while (e.hasMoreElements())
+    {
+      l.add(e.nextElement());
+    }
+    // sort so we can use binary search to compare
+    Collections.sort(l);
+    return l;
+  }
 
   private RenderRequest wrapRequestToRedirect(RenderRequest request,
                               QueryString redirectParams)
@@ -1256,7 +1268,9 @@ public class BridgeImpl
     redirectParams.removeParameter(Bridge.PORTLET_SECURE_PARAMETER);
 
     // Now turn the QueryString into a parameter map
-    Map<String, String[]> paramMap = new LinkedHashMap(redirectParams.numParameters());
+    Map<String, String[]> publicParamMap = new LinkedHashMap(redirectParams.numParameters());
+    Map<String, String[]> privateParamMap = new LinkedHashMap(redirectParams.numParameters());
+    ArrayList<String> publicParamNamesList = getPublicParameterNamesList();
     Enumeration<String> nameEnum = redirectParams.getParameterNames();
     while (nameEnum != null && nameEnum.hasMoreElements())
     {
@@ -1267,12 +1281,77 @@ public class BridgeImpl
       {
         values.add(valuesEnum.nextElement());
       }
-
-      paramMap.put(name, values.toArray(new String[values.size()]));
+      
+      if (Collections.binarySearch(publicParamNamesList, name) >= 0)
+      {
+        publicParamMap.put(name, values.toArray(new String[values.size()]));
+      }
+      else
+      {
+        privateParamMap.put(name, values.toArray(new String[values.size()]));
+      }
     }
 
     // now wrap the request object to expose only those params as are in QS
-    return (RenderRequest) new BridgeRenderRequestWrapper(request, paramMap, false);
+    return (RenderRequest) new BridgeRenderRequestWrapper(request, privateParamMap, publicParamMap, false);
+  }
+  
+  private void updatePublicRedirectParams(PortletRequest request, QueryString redirectParams, Map<String, String[]> cachedPRPs)
+  {
+    Map<String, String[]> prps = request.getPublicParameterMap();
+    boolean modified = false;
+    
+    if (cachedPRPs == null)
+    {
+      cachedPRPs = Collections.EMPTY_MAP;
+    }
+    
+    // For each cachedPRP check to see if the prp exists in the current request and has the same value
+    // If any change -- remove/update in the QS
+    for (Map.Entry<String, String[]> entry : cachedPRPs.entrySet())
+    {
+      String key = entry.getKey();
+      if (prps.containsKey(key))
+      {
+        if (!Arrays.equals(prps.get(key), cachedPRPs.get(key)))
+        {
+          modified = true;
+          redirectParams.removeParameter(key);
+          for (String param : prps.get(key))
+          {
+            redirectParams.addParameter(key, param);
+          }
+        }
+      }
+      else
+      {
+        // Its in the cachedPRP but not the current request -- so its been cleared
+        modified = true;
+        redirectParams.removeParameter(key);
+      }
+    }
+    
+    // Now check the reverse -- add those that are in the current request but not the cache
+    for (Map.Entry<String, String[]> entry : prps.entrySet())
+    {
+      String key = entry.getKey();
+      if (!cachedPRPs.containsKey(key))
+      {
+        for (String param : prps.get(key))
+        {
+          modified = true;
+          redirectParams.addParameter(key, param);
+        }
+
+      }
+    }
+    
+    // Update the Map/redirectParams in the cache to the current values
+    if (modified)
+    {
+      request.getPortletSession().setAttribute(BridgeImpl.RENDER_REDIRECT_VIEWPARAMS, redirectParams);
+      request.getPortletSession().setAttribute(BridgeImpl.RENDER_REDIRECT_PRPMAP, new HashMap<String, String[]>(prps));
+    }
   }
 
   private void redirectRender(FacesContext context,
@@ -1283,28 +1362,23 @@ public class BridgeImpl
                               List<String> preExistingAttrs)
   {
     
-    // close the FacesContext
-    context.release();
-    
-    // Now reset attributes to those that existed before we were called
-    // reset request attributes to those that existed before we were called.
-    String[] names = new String[400];
-    int count = 0;
-    Enumeration<String> e = request.getAttributeNames();
-    while (e.hasMoreElements())
+    if (context.getExternalContext().getSessionMap().get(BridgeImpl.RENDER_REDIRECT_PRPMAP) == null)
     {
-      String name = e.nextElement();
-      if (!preExistingAttrs.contains(name))
-      {
-        names[count++] = name;
-      }
+      // Grab the current public parameter map so we can cache it so we can fix up render redisplays
+      // where the incoming request changes a PRP. Do it before redirect to make sure we don't
+      // perturb the result. This also ensures its done on the first redirect in this render -- which is what we want
+      // as this is the original PRPs of this request (unchanged by any other redirect)
+
+      context.getExternalContext().getSessionMap().put(BridgeImpl.RENDER_REDIRECT_PRPMAP,
+                                                       new HashMap<String, String[]>(request.getPublicParameterMap()));
     }
     
-    for (int j = 0; j < count; j++)
-    {
-      request.removeAttribute(names[j]);
-    }
+    // close the FacesContext
+    context.release();
     
+    // This removed the cache of preexisting request attributes -- so acquire again
+    getRequestAttributes(request);
+       
     // start a new FacesContext
     context = getFacesContext(request, response, lifecycle, redirectParams);
     
@@ -1741,7 +1815,13 @@ public class BridgeImpl
   @SuppressWarnings("unchecked")
   private List<String> getRequestAttributes(PortletRequest request)
   {
-    return Collections.list((Enumeration<String>) request.getAttributeNames());
+    List<String> requestAttributeNames =  Collections.list((Enumeration<String>) request.getAttributeNames());
+    // place on the request for use here and in the servletRequestAttributeListener
+    if (requestAttributeNames != null)
+    {
+      request.setAttribute(PREEXISTING_ATTRIBUTE_NAMES, requestAttributeNames);
+    }
+    return requestAttributeNames;
   }
 
   private boolean isExcludedFromBridgeRequestScope(String key, Object value, List<String> preExistingList)
@@ -1994,20 +2074,23 @@ public class BridgeImpl
           // now evaluate the expression
           ValueExpression valExpr = app.getExpressionFactory().createValueExpression(context.getELContext(),
             expr, String.class);
-          String curVal = (String) valExpr.getValue(context.getELContext());
-          // Only update if new value
-          // In EL can't distinguish between null and empty string
-          if (curVal != null && curVal.length() > 0)
+          
+          try
           {
-            try
+            String curVal = (String) valExpr.getValue(context.getELContext());
+            // Only update if new value
+            // In EL can't distinguish between null and empty string
+            if (curVal != null && curVal.length() > 0)
             {
               valExpr.setValue(context.getELContext(), null);
+              paramsMapped = true;
             }
-            catch (Exception ex)
-            {
-              ex.printStackTrace();
-            }
-            paramsMapped = true;
+          }
+          catch (Exception ex)
+          {
+            // Note:  expression may not evaluate because PRP mappings are in face-config.xml and multiple portlets
+            // may be sharing -- hence this portlet may not have an expression mapping
+            ;
           }
         }
       }
@@ -2041,23 +2124,31 @@ public class BridgeImpl
       // now evaluate the expression
       ValueExpression valExpr = app.getExpressionFactory().createValueExpression(context.getELContext(),
         expr, String.class);
-      String value = (String) valExpr.getValue(context.getELContext());
-      
-      // only set in response if the value has changed
-      Map<String, String[]> m = request.getPublicParameterMap();
-      if (value != null)
+      try
       {
-        String[] requestVals = m.get(s);
-        // only set if the values are different
-        if (requestVals == null || !requestVals[0].equals(value))
+        String value = (String) valExpr.getValue(context.getELContext());
+        
+        // only set in response if the value has changed
+        Map<String, String[]> m = request.getPublicParameterMap();
+        if (value != null)
+        {
+          String[] requestVals = m.get(s);
+          // only set if the values are different
+          if (requestVals == null || !requestVals[0].equals(value))
+          {
+            response.setRenderParameter(s, value);
+          }
+        }
+        // see if we need to remove it
+        else if (m.containsKey(s))
         {
-          response.setRenderParameter(s, value);
+          response.removePublicRenderParameter(s);
         }
       }
-      // see if we need to remove it
-      else if (m.containsKey(s))
+      catch (Exception exception)
       {
-        response.removePublicRenderParameter(s);
+        // Do nothing
+        ;
       }
     }
   }
@@ -2207,25 +2298,97 @@ public class BridgeImpl
 
   public void beforePhase(PhaseEvent event)
   {
-    // do nothing
+    FacesContext context = event.getFacesContext();
+    
+    // There is only one lifecycle instance within a webapp -- and lifecycles aren't thread safe
+    // This means we may have multiple listeners registered and/or multiple simulataneous requests
+    // So only do the work if the FacesContext of the event is equal to the one in the current thread
+    if (context != FacesContext.getCurrentInstance())
+    {
+      return;
+    }
+    
+    // only set renderresponse if in RESTORE_VIEW phase (and we are the listener for the targeted portlet)
+    String pName = (String) context.getExternalContext().getRequestMap().get(PORTLET_NAME_ATTRIBUTE);
+    
+    if (event.getPhaseId() == PhaseId.RESTORE_VIEW)
+    {
+      // If the viewRoot has been preset before the lifecycle is run then Faces
+      // uses it but only after reseting its locale to the one requested in the request.
+      // Since the bridge relies on this presetting ability to transfer the view from the
+      // action to the render phase we run into a problem if the action changes the views locale.
+      // This because the view that results/created in from the action's navigation acquires 
+      // the locale of the action's viewRoots locale.  This action causes ViewRoot A to change its
+      // locale to DE -- the navigation causes us to create a new ViewRoot B which Faces sets to
+      // have/use the DE locale.  The render hits this preset code which causes the locale of the
+      // ViewRoot to reset to the requests preferred locale.  Ie.. we lose the locale.  This is why the
+      // CarDemo's locale mechanism wasn't working.  To fix:  check if we are using the preset
+      // ability here -- and if so cache the locale in the request.  On the afterPhase -- reset the locale
+      // back to the what it originally was.
+
+      UIViewRoot viewRoot = context.getViewRoot();
+      if (viewRoot != null)
+      {
+        Locale l = viewRoot.getLocale();
+        if (l != null)
+        {
+          context.getExternalContext().getRequestMap().put(CACHED_VIEWROOT_LOCALE, l);
+        }
+      }
+    }
     return;
   }
 
   public void afterPhase(PhaseEvent event)
   {
     // only set renderresponse if in RESTORE_VIEW phase
-    if (event.getPhaseId() == PhaseId.RESTORE_VIEW)
+    FacesContext context = event.getFacesContext();
+    
+    // There is only one lifecycle instance within a webapp -- and lifecycles aren't thread safe
+    // This means we may have multiple listeners registered and/or multiple simulataneous requests
+    // So only do the work if the FacesContext of the event is equal to the one in the current thread
+    if (context != FacesContext.getCurrentInstance())
     {
-      FacesContext context = event.getFacesContext();
+      return;
+    }
+    
+    // only set renderresponse if in RESTORE_VIEW phase (and we are the listener for the targeted portlet)
+    String pName = (String) context.getExternalContext().getRequestMap().get(PORTLET_NAME_ATTRIBUTE);
+    
+    if (event.getPhaseId() == PhaseId.RESTORE_VIEW)
+    {     
+      // restore ViewRoot locale (see comment in beforePhase)
+      Locale l = (Locale) context.getExternalContext().getRequestMap().get(CACHED_VIEWROOT_LOCALE);
+      if (l != null)
+      {
+        UIViewRoot viewRoot = context.getViewRoot();
+        if (viewRoot != null)
+        {
+          viewRoot.setLocale(l);
+        }
+      }
+      
       // Now restore the Faces Messages
       restoreFacesMessageState(context);
       
+      // Now process any PublicRenderRarameter mappings
+      boolean mappedPublicParams = false;
+      
+      // Only process PublicRenderParameters once
+      if (context.getExternalContext().getRequestMap().get(PROCESSED_PUBLIC_PARAMS) == null)
+      {
+        // process public render parameters -- note pass in the portlet request as this
+        // exposes the PPR where the one in the ExternalContext doesn't
+        mappedPublicParams = processIncomingPublicRenderParameters(context, (PortletRequest) context.getExternalContext().getRequest());
+        context.getExternalContext().getRequestMap().put(PROCESSED_PUBLIC_PARAMS, Boolean.TRUE);
+      }
+      
       switch (BridgeUtil.getPortletRequestPhase())
       {
       case RENDER_PHASE:
       case EVENT_PHASE:
-        // skip rest of action processing                    
-        context.renderResponse();
+        // skip rest of action processing if no PRPs were mapped                  
+        if (!mappedPublicParams) context.renderResponse();
       }
     }
   }

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/BridgeRenderRequestWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/BridgeRenderRequestWrapper.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/BridgeRenderRequestWrapper.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/BridgeRenderRequestWrapper.java Wed Mar 17 09:58:58 2010
@@ -29,25 +29,34 @@ import javax.portlet.filter.RenderReques
 
 public class BridgeRenderRequestWrapper extends RenderRequestWrapper
 {
-  private Map<String, String[]> mActionParams     = null;
+  private Map<String, String[]> mPublicParamMap     = null;
+  private Map<String, String[]> mPrivateParamMap     = null;
   private Map<String, String[]> mCombinedParamMap = null;
   private boolean mCombineParams = true;
+  private boolean mPublicParamMapFixed = false; // if true contains all values and is unmodifyable
+  private boolean mPrivateParamMapFixed = false; // if true contains all values and is unmodifyable
+  private boolean mCombinedParamMapFixed = false; // if true contains all values and is unmodifyable
+
 
   public BridgeRenderRequestWrapper(RenderRequest request, 
-                                    Map<String, String[]> actionParams)
+                                    Map<String, String[]> privateParams)
                                       throws IllegalArgumentException
   {
-    this(request, actionParams, true);
+    this(request, privateParams, null, true);
   }
   
   public BridgeRenderRequestWrapper(RenderRequest request, 
-                                    Map<String, String[]> actionParams,
+                                    Map<String, String[]> privateParams,
+                                    Map<String, String[]> publicParams,
                                     boolean combineParams)
                                       throws IllegalArgumentException
   {
     super(request);
 
-    mActionParams = actionParams;
+    mPrivateParamMap = privateParams;
+    mPublicParamMap = publicParams;
+    mCombinedParamMap = new LinkedHashMap<String, String[]>((mPublicParamMap != null) ? mPublicParamMap : Collections.EMPTY_MAP);
+    mCombinedParamMap.putAll((mPrivateParamMap != null) ?  mPrivateParamMap : Collections.EMPTY_MAP);
     mCombineParams = combineParams;
   }
 
@@ -159,35 +168,28 @@ public class BridgeRenderRequestWrapper 
   @Override
   public Map<String, String[]> getParameterMap()
   {
-    if (!mCombineParams)
+    if (mCombinedParamMapFixed)
     {
-      return mActionParams;
+      return mCombinedParamMap;
     }
-    else if (mActionParams == null || mActionParams.isEmpty())
+    else if (!mCombineParams)
     {
-      return super.getParameterMap();
+      // now make this an immutable Map
+      mCombinedParamMapFixed = true;
+      mCombinedParamMap = Collections.unmodifiableMap(mCombinedParamMap);
+      return mCombinedParamMap;
     }
-    else if (mCombinedParamMap != null)
+    else if ((mCombinedParamMap == null || mCombinedParamMap.isEmpty()))
     {
-      return mCombinedParamMap;
+      return super.getParameterMap();
     }
     else 
     {
       // Combine the two Maps
-      mCombinedParamMap = new LinkedHashMap<String, String[]>(super.getParameterMap());
-
-      // now walk through the actionParams adding those that aren't
-      // already in the ParameterMap
-      for (Map.Entry<String, String[]> entry : mActionParams.entrySet())
-      {
-        String key = entry.getKey();
-        if (!mCombinedParamMap.containsKey(key))
-        {
-          mCombinedParamMap.put(key, entry.getValue());
-        }
-      }
-      
+      mCombinedParamMap.putAll(super.getParameterMap());
+     
       // now make this an immutable Map
+      mCombinedParamMapFixed = true;
       mCombinedParamMap = Collections.unmodifiableMap(mCombinedParamMap);
       
       return mCombinedParamMap;
@@ -211,38 +213,64 @@ public class BridgeRenderRequestWrapper 
   @Override
   public Map<String, String[]> getPrivateParameterMap()
   {
-    if (!mCombineParams)
+    if (mPrivateParamMapFixed)
     {
-      return mActionParams;
+      return mPrivateParamMap;
     }
-    else if (mActionParams == null || mActionParams.isEmpty())
+    else if (!mCombineParams)
     {
-      return super.getPrivateParameterMap();
+      // now make this an immutable Map
+      mPrivateParamMapFixed = true;
+      mPrivateParamMap = Collections.unmodifiableMap(mPrivateParamMap);
+      return mPrivateParamMap;
     }
-    else if (mCombinedParamMap != null)
+    else if ((mPrivateParamMap == null || mPrivateParamMap.isEmpty()))
     {
-      return mCombinedParamMap;
+      return super.getPrivateParameterMap();
     }
     else 
     {
       // Combine the two Maps
-      mCombinedParamMap = new LinkedHashMap<String, String[]>(super.getPrivateParameterMap());
-
-      // now walk through the actionParams adding those that aren't
-      // already in the ParameterMap
-      for (Map.Entry<String, String[]> entry : mActionParams.entrySet())
-      {
-        String key = entry.getKey();
-        if (!mCombinedParamMap.containsKey(key))
-        {
-          mCombinedParamMap.put(key, entry.getValue());
-        }
-      }
+      mPrivateParamMap.putAll(super.getPrivateParameterMap());
+     
+      // now make this an immutable Map
+      mPrivateParamMapFixed = true;
+      mPrivateParamMap = Collections.unmodifiableMap(mPrivateParamMap);
       
+      return mPrivateParamMap;
+    }
+  }
+  
+  @SuppressWarnings("unchecked")
+  @Override
+  public Map<String, String[]> getPublicParameterMap()
+  {
+    if (mPublicParamMapFixed)
+    {
+      return mPublicParamMap;
+    }
+    else if (!mCombineParams)
+    {
       // now make this an immutable Map
-      mCombinedParamMap = Collections.unmodifiableMap(mCombinedParamMap);
+      mPublicParamMapFixed = true;
+      mPublicParamMap = Collections.unmodifiableMap(mPublicParamMap);
+      return mPublicParamMap;
+    }
+    else if ((mPublicParamMap == null || mPublicParamMap.isEmpty()))
+    {
+      return super.getPublicParameterMap();
+    }
+    else 
+    {
+      // Combine the two Maps
+      mPublicParamMap.putAll(super.getPublicParameterMap());
+     
+      // now make this an immutable Map
+      mPublicParamMapFixed = true;
+      mPublicParamMap = Collections.unmodifiableMap(mPublicParamMap);
       
-      return mCombinedParamMap;
+      return mPublicParamMap;
     }
   }
+
 }

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletFacesContextFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletFacesContextFactoryImpl.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletFacesContextFactoryImpl.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletFacesContextFactoryImpl.java Wed Mar 17 09:58:58 2010
@@ -1,29 +1,40 @@
 package org.apache.myfaces.portlet.faces.context;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.faces.FacesException;
 import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.FacesContextFactory;
 import javax.faces.context.FacesContextWrapper;
 import javax.faces.lifecycle.Lifecycle;
-
-import javax.portlet.PortletConfig;
 import javax.portlet.PortletResponse;
 import javax.portlet.faces.Bridge;
 import javax.portlet.faces.annotation.PortletNamingContainer;
 
+import org.apache.myfaces.portlet.faces.bridge.BridgeImpl;
+import org.apache.myfaces.shared_portlet.util.ExternalContextUtils;
+
 public class PortletFacesContextFactoryImpl
   extends FacesContextFactory
 {
-  private FacesContextFactory mWrapped;
   private static final Logger sLOG= Logger.getLogger(PortletFacesContextFactoryImpl.class.getName());
+  private FacesContextFactory mFactory;
+  
+  public PortletFacesContextFactoryImpl(FacesContextFactory factory)
+  {
+    mFactory = factory;
+  }
   
-  public PortletFacesContextFactoryImpl(FacesContextFactory wrapped)
+  @Override
+  public FacesContextFactory getWrapped()
   {
-    mWrapped = wrapped;
+    return mFactory;
   }
 
   public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
@@ -35,7 +46,7 @@ public class PortletFacesContextFactoryI
     // method as that call requires the facesContext to exist.
     FacesContext fc = getWrapped().getFacesContext(context, request, response, lifecycle);
       
-    if(fc.getExternalContext().getContext() instanceof PortletConfig)
+    if(ExternalContextUtils.isPortlet(fc.getExternalContext()))
     {
       fc = new FacesContextImpl(fc);
     }
@@ -79,5 +90,32 @@ public class PortletFacesContextFactoryI
         }
       }
     }
+
+    @Override
+    public void release()
+    {
+      ExternalContext ec = getWrapped().getExternalContext();
+      Map<String,Object> reqAttrs = ec.getRequestMap();
+      
+      @SuppressWarnings("unchecked")
+      List<String> preExistingAttrs = (List<String>)reqAttrs.get(BridgeImpl.PREEXISTING_ATTRIBUTE_NAMES);
+
+      Set<String> keys= reqAttrs.keySet();
+      
+      for(String key:keys)
+      {
+        if (!preExistingAttrs.contains(key))
+        {
+          reqAttrs.remove(key);
+        }
+      }
+      
+      if(ec instanceof PortletExternalContextImpl)
+      {
+        ((PortletExternalContextImpl)ec).release();
+      }
+
+      super.release();
+    }
   }
 }

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/el/PortletELResolver.java Wed Mar 17 09:58:58 2010
@@ -89,7 +89,13 @@ public class PortletELResolver extends E
 
   @Override
   public Object getValue(ELContext context, Object base, Object property) throws ELException
-  {
+  {    
+    // only process if running in a portlet request
+    if (!BridgeUtil.isPortletRequest() || base != null)
+    {
+      return null;
+    }
+    
     // variable resolution is a special case of property resolution
     // where the base is null.
     if (property == null)
@@ -97,12 +103,6 @@ public class PortletELResolver extends E
       throw new PropertyNotFoundException("Null property");
     }
     
-    // only process if running in a portlet request
-    if (!BridgeUtil.isPortletRequest() || base != null)
-    {
-      return null;
-    }
-    
     // Recognize whether we are resolving in a Faces context or JSP context 
     // as the resolution differs.  I.e. in the JSP context we defer to
     // its implicit object resolver to resolve the <portlet:defineObjects> objects.
@@ -372,17 +372,17 @@ public class PortletELResolver extends E
 
   @Override
   public Class<?> getType(ELContext context, Object base, Object property) throws ELException
-  {
-    if (property == null)
-    {
-      throw new PropertyNotFoundException("Null property");
-    }
-    
+  {   
     // only process if running in a portlet request
     if (!BridgeUtil.isPortletRequest() || base != null)
     {
       return null;
     }
+    
+    if (property == null)
+    {
+      throw new PropertyNotFoundException("Null property");
+    }
 
     int index = -1;
     // As these properties aren't writable in either the Faces or JSP resolver

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/preference/PreferenceValuesList.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/preference/PreferenceValuesList.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/preference/PreferenceValuesList.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/preference/PreferenceValuesList.java Wed Mar 17 09:58:58 2010
@@ -30,7 +30,7 @@ public class PreferenceValuesList<String
   {
     this(preference, Arrays.asList(preference, preferences.getValues(preference.getName(), null)));
     
-    mPreference = preference;
+    mPreference = preference; 
   }
   
   public PreferenceValuesList(PortletPreferences preferences, Preference preference, int initialCapacity)

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/QueryString.java Wed Mar 17 09:58:58 2010
@@ -44,7 +44,8 @@ public final class QueryString
    */
   public QueryString(String queryString, String characterEncoding)
   {
-    mQueryString = queryString;
+    // We only work on regular QueryStrings not strictXhtml QueryStrings
+    mQueryString = queryString.replaceAll("\\&amp\\;", "&");
     mCharacterEncoding = characterEncoding;
   }
 

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletAbstractMap.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletAbstractMap.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletAbstractMap.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletAbstractMap.java Wed Mar 17 09:58:58 2010
@@ -18,6 +18,7 @@
 
 package org.apache.myfaces.portlet.faces.util.map;
 
+import java.util.AbstractMap;
 import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -31,7 +32,7 @@ import java.util.Set;
 /**
  * Helper class for different portlet external context maps
  */
-public abstract class PortletAbstractMap<V> implements Map<String, V>
+public abstract class PortletAbstractMap<V> extends AbstractMap<String, V>
 {
   static final String ILLEGAL_ARGUMENT = "Only supported in a portlet environment";
 

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestHeaderValuesMap.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestHeaderValuesMap.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestHeaderValuesMap.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestHeaderValuesMap.java Wed Mar 17 09:58:58 2010
@@ -19,8 +19,10 @@
 package org.apache.myfaces.portlet.faces.util.map;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -36,6 +38,40 @@ public class PortletRequestHeaderValuesM
   {
     mPortletRequestHeaders = portletRequestHeaders;
   }
+  
+  @Override
+  public boolean equals(Object o) {
+      if (o == this)
+          return true;
+
+      if (!(o instanceof Map))
+          return false;
+      Map<String,String[]> t = (Map<String,String[]>) o;
+      if (t.size() != size())
+          return false;
+
+      try {
+          Iterator<Entry<String,String[]>> i = entrySet().iterator();
+          while (i.hasNext()) {
+              Entry<String,String[]> e = i.next();
+              String key = e.getKey();
+              String[] value = e.getValue();
+              if (value == null) {
+                  if (!(t.get(key)==null && t.containsKey(key)))
+                      return false;
+              } else {
+                  if (!Arrays.equals(value, t.get(key)))
+                      return false;
+              }
+          }
+      } catch(ClassCastException unused) {
+          return false;
+      } catch(NullPointerException unused) {
+          return false;
+      }
+
+      return true;
+  }
 
   @Override
   protected String[] getAttribute(String key)

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestParameterValuesMap.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestParameterValuesMap.java?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestParameterValuesMap.java (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/java/org/apache/myfaces/portlet/faces/util/map/PortletRequestParameterValuesMap.java Wed Mar 17 09:58:58 2010
@@ -19,9 +19,11 @@
 package org.apache.myfaces.portlet.faces.util.map;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -55,6 +57,40 @@ public class PortletRequestParameterValu
       throw new IllegalArgumentException(ILLEGAL_ARGUMENT);
     }
   }
+  
+  @Override
+  public boolean equals(Object o) {
+      if (o == this)
+          return true;
+
+      if (!(o instanceof Map))
+          return false;
+      Map<String,String[]> t = (Map<String,String[]>) o;
+      if (t.size() != size())
+          return false;
+
+      try {
+          Iterator<Entry<String,String[]>> i = entrySet().iterator();
+          while (i.hasNext()) {
+              Entry<String,String[]> e = i.next();
+              String key = e.getKey();
+              String[] value = e.getValue();
+              if (value == null) {
+                  if (!(t.get(key)==null && t.containsKey(key)))
+                      return false;
+              } else {
+                  if (!Arrays.equals(value, t.get(key)))
+                      return false;
+              }
+          }
+      } catch(ClassCastException unused) {
+          return false;
+      } catch(NullPointerException unused) {
+          return false;
+      }
+
+      return true;
+  }
 
   @Override
   public String[] getAttribute(String key)

Propchange: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/impl/src/main/resources/META-INF/NOTICE
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Mar 17 09:58:58 2010
@@ -0,0 +1,2 @@
+/myfaces/portlet-bridge/core/trunk_2.0.x/impl/src/main/resources/META-INF/NOTICE:888894-923981
+/myfaces/portlet-bridge/trunk/impl/src/main/resources/META-INF/NOTICE:588229-629933

Modified: myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/pom.xml?rev=924204&r1=924203&r2=924204&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/pom.xml (original)
+++ myfaces/portlet-bridge/core/branches/sobryan_portlet-bridge-3.0.0/pom.xml Wed Mar 17 09:58:58 2010
@@ -76,6 +76,7 @@
 
   <modules>
     <module>api</module>
+    <module>shared</module>
     <module>impl</module>
     <module>examples</module>
   </modules>
@@ -95,7 +96,7 @@
         <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>servlet-api</artifactId>
-          <version>2.4</version>
+          <version>2.5</version>
           <scope>provided</scope>
         </dependency>