You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mf...@apache.org on 2009/08/12 19:56:39 UTC

svn commit: r803627 - in /myfaces/portlet-bridge/core/trunk: api/src/main/java/javax/portlet/faces/ examples/assembly/src/main/resources/META-INF/ examples/demo/src/main/resources/META-INF/ impl/src/main/java/org/apache/myfaces/portlet/faces/applicatio...

Author: mfreedman
Date: Wed Aug 12 17:56:39 2009
New Revision: 803627

URL: http://svn.apache.org/viewvc?rev=803627&view=rev
Log:
PORTLETBRIDGE-93: Exception thrown during restore 
PORTLETBRIDGE-92: Refresh under Client saving: ClasscastExc
PORTLETBRIDGE-91: Update HttpUtils to most recent URI spec
PORTLETBRIDGE-89: encodeActionURL encodes invalid mode
PORTLETBRIDGE-88: encodeActionURL incorrectly parse portlet: 
PORTLETBRIDGE-87: getActionURL doesn't encode extra params
PORTLETBRIDGE-86: extraParams on viewId causes restore fail
PORTLETBRIDGE-85: GFP.doDispatch has baad equality check
+ Updated examples NOTICE files to be consistent.

Added:
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/RenderResponseDecorator.java
Modified:
    myfaces/portlet-bridge/core/trunk/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
    myfaces/portlet-bridge/core/trunk/examples/assembly/src/main/resources/META-INF/NOTICE
    myfaces/portlet-bridge/core/trunk/examples/demo/src/main/resources/META-INF/NOTICE
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/ActionResponseDecorator.java
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
    myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/HTTPUtils.java
    myfaces/portlet-bridge/core/trunk/impl/src/main/resources/META-INF/faces-config.xml

Modified: myfaces/portlet-bridge/core/trunk/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java (original)
+++ myfaces/portlet-bridge/core/trunk/api/src/main/java/javax/portlet/faces/GenericFacesPortlet.java Wed Aug 12 17:56:39 2009
@@ -197,7 +197,7 @@
   {
     // Defer to helper methods for standard modes so subclasses can override
     PortletMode mode = request.getPortletMode();
-    if (mode == PortletMode.EDIT || mode == PortletMode.HELP || mode == PortletMode.VIEW)
+    if (mode.equals(PortletMode.EDIT) || mode.equals(PortletMode.HELP) || mode.equals(PortletMode.VIEW))
     {
       super.doDispatch(request, response);
     } else
@@ -260,7 +260,7 @@
     ArrayList<String> list = new ArrayList(attrArray.length);
     for (int i = 0; i < attrArray.length; i++)
     {
-      list.add(attrArray[i]);
+      list.add(attrArray[i].trim());
     }
     return list;
   }

Modified: myfaces/portlet-bridge/core/trunk/examples/assembly/src/main/resources/META-INF/NOTICE
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/examples/assembly/src/main/resources/META-INF/NOTICE?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/examples/assembly/src/main/resources/META-INF/NOTICE (original)
+++ myfaces/portlet-bridge/core/trunk/examples/assembly/src/main/resources/META-INF/NOTICE Wed Aug 12 17:56:39 2009
@@ -1,9 +1,20 @@
 Apache MyFaces Portlet Bridge
 Copyright [2007, 2008, 2009] The Apache Software Foundation
 
+This is an implementation of a public review specification
+developed under the Java Community Process (JCP). This
+implementation may not fully conform to this specification.
+This implementation may differ from the final specification.
+The code is not compatible with any specification of the JCP.
+
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 
+Portions of this software are Copyright (c) 2007, Oracle 
+Corporation, <http://www.oracle.com/> and are licensed to 
+the Apache Software Foundation under the "Software Grant 
+and Corporate Contribution License Agreement"
+
 See the LICENSE.txt file for information on all licenses 
 associated with this software.
 

Modified: myfaces/portlet-bridge/core/trunk/examples/demo/src/main/resources/META-INF/NOTICE
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/examples/demo/src/main/resources/META-INF/NOTICE?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/examples/demo/src/main/resources/META-INF/NOTICE (original)
+++ myfaces/portlet-bridge/core/trunk/examples/demo/src/main/resources/META-INF/NOTICE Wed Aug 12 17:56:39 2009
@@ -1,9 +1,20 @@
 Apache MyFaces Portlet Bridge
 Copyright [2007, 2008, 2009] The Apache Software Foundation
 
+This is an implementation of a public review specification
+developed under the Java Community Process (JCP). This
+implementation may not fully conform to this specification.
+This implementation may differ from the final specification.
+The code is not compatible with any specification of the JCP.
+
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 
+Portions of this software are Copyright (c) 2007, Oracle 
+Corporation, <http://www.oracle.com/> and are licensed to 
+the Apache Software Foundation under the "Software Grant 
+and Corporate Contribution License Agreement"
+
 See the LICENSE.txt file for information on all licenses 
 associated with this software.
 

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/application/PortletViewHandlerImpl.java Wed Aug 12 17:56:39 2009
@@ -114,8 +114,20 @@
     if (qsLoc < 0) qsLoc = viewId.length();
     
     String actionURL = super.getActionURL(context, viewId.substring(0, qsLoc));
+    
+    // Now add the parameters back on (if needed)
     if (qsLoc < viewId.length())
-      actionURL = actionURL.concat(viewId.substring(qsLoc));
+    {
+      int aLoc = actionURL.indexOf('?');
+      if (aLoc < 0)
+      {
+        actionURL = actionURL.concat(viewId.substring(qsLoc));
+      }
+      else if (viewId.length() > (qsLoc + 1))
+      {
+        actionURL = actionURL + "&" + viewId.substring(qsLoc + 1);
+      }
+    }
     
     return actionURL;
     
@@ -188,7 +200,12 @@
     
     if (qsLoc < viewId.length())
     {
-      viewRoot.setViewId(viewRoot.getViewId().concat(viewId.substring(qsLoc)));
+      // Add the QueryString as an additional attribute to the UIViewRoot.
+      // Note:  only expected situation is when a NavigationHandler returns a viewId with a QS
+      // as we support this in the faces-config.xml to introduce modes, etc.
+      // The Bridge (ActionHandler) will pull this when it constructs the target
+      // of the actionResponse based on this current ViewId.
+      viewRoot.getAttributes().put(BridgeImpl.VIEWID_QUERYSTRING_ATTRIBUTE, viewId.substring(qsLoc));
     }
        
     return viewRoot;

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/BridgeImpl.java Wed Aug 12 17:56:39 2009
@@ -108,10 +108,12 @@
 
   // 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";
+  public static final String VIEWID_QUERYSTRING_ATTRIBUTE = "org.apache.myfaces.portlet.faces.viewIdQueryString";
 
   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 REQUEST_SCOPE_LISTENER = "org.apache.myfaces.portlet.faces.requestScopeWatch";
+  private static final String REQUEST_SCOPE_ACTIVE = "org.apache.myfaces.portlet.faces.includeInScope.requestScopeActive";
   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";
@@ -550,12 +552,6 @@
     {
       // get context as it may have been reacquired if exception occurred during redirect during render.
       context = FacesContext.getCurrentInstance();
-      // When exception occurs remove stored scope so don't
-      // get stuck replaying the error when/if user refreshes
-      if (scopeId != null)
-      {
-        removeRequestScopes(scopeId);
-      }
 
       mPortletConfig.getPortletContext().log("Exception thrown in doFacesRequest:render: " + e.getMessage() + " : " + e.toString());
       if (!(e instanceof BridgeException))
@@ -640,19 +636,13 @@
       lifecycle.execute(context);
     }
     catch (Exception e)
-    {
-      // When exception occurs remove stored scope so don't
-      // get stuck replaying the error when/if user refreshes
-      if (scopeId != null)
-      {
-        removeRequestScopes(scopeId);
-      }
-      
+    {    
       // now rethrow the exception as a BridgeException
       if (!(e instanceof BridgeException))
       {
-        throw new BridgeException(e);
+        e = new BridgeException(e);
       }
+      throw (BridgeException) e;
     }
     finally
     {
@@ -777,44 +767,8 @@
    * ServletRequestAttributeListener implementation
    */
   public void attributeAdded(ServletRequestAttributeEvent srae)
-  {
-    // use this phase attribute as an indicator of whether 
-    // we are actively working on a request
-    PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
-    
-    // do nothing if before/after bridge processing or in the render phase.
-    // Don't care about render phase because we don't update/change the managed
-    // scope based on changes during render.
-    // ALSO: do nothing if not in the Bridge's managed request scope
-    if (phase == null || phase == PortletPhase.RENDER_PHASE ||
-        isExcludedFromBridgeRequestScope(srae.getName(),
-                                         srae.getValue(),
-                                         (List<String>) srae.getServletRequest()
-                                            .getAttribute(PREEXISTING_ATTRIBUTE_NAMES)))
-    {
-      return;
-    }
-
-    // Otherwise -- see if the added attribute implements the bridge's 
-    // BridgeRequestScopeAdded annotation -- call each method so annotated
-    Object o = srae.getValue();
-    Method[] methods = o.getClass().getMethods();
-    for (int i = 0; i < methods.length; i++)
-    {
-      if (methods[i].isAnnotationPresent(BridgeRequestScopeAttributeAdded.class))
-      {
-        try
-        {
-          methods[i].invoke(o, null);
-        }
-        catch (Exception e)
-        {
-          // TODO: log problem
-          // do nothing and forge ahead
-          ;
-        }
-      }
-    }
+  { 
+    // do nothing and forge ahead
   }
 
   public void attributeRemoved(ServletRequestAttributeEvent srae)
@@ -823,11 +777,10 @@
     // we are actively working on a request
     PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
     
-    // If in an action this means the attribute has been removed before we have
-    // saved the action scope -- since the managed bean has been informed we are
-    // running in a portlet environment it should have ignored the PreDestroy.
-    // To make up for this we call its BridgePredestroy
-    if (phase != null && phase == PortletPhase.ACTION_PHASE)
+    // Only notify if in an Action but only if the bridge request scope has been created/saved.
+    // Otherwise the regular PreDestroy will be called/run/work as normal as the managedBean hasn't yet
+    // been notified its in the bridge request scope.
+    if (phase != null && phase == PortletPhase.ACTION_PHASE && srae.getServletRequest().getAttribute(REQUEST_SCOPE_ACTIVE) != null)
     {
       notifyPreDestroy(srae.getValue()); // in outerclass (BridgeImpl)
     }
@@ -839,11 +792,10 @@
     // we are actively working on a request
     PortletPhase phase = (PortletPhase) srae.getServletRequest().getAttribute(Bridge.PORTLET_LIFECYCLE_PHASE);
     
-    // If in an action this means the attribute has been replaced before we have
-    // saved the action scope -- since the managed bean has been informed we are
-    // running in a portlet environment it should have ignored the PreDestroy.
-    // To make up for this we call its BridgePredestroy
-    if (phase != null && phase == PortletPhase.ACTION_PHASE)
+    // Only notify if in an Action but only if the bridge request scope has been created/saved.
+    // Otherwise the regular PreDestroy will be called/run/work as normal as the managedBean hasn't yet
+    // been notified its in the bridge request scope.
+    if (phase != null && phase == PortletPhase.ACTION_PHASE && srae.getServletRequest().getAttribute(REQUEST_SCOPE_ACTIVE) != null)
     {
       notifyPreDestroy(srae.getValue()); // in outerclass (BridgeImpl)
     }
@@ -1054,10 +1006,12 @@
     if (viewRoot != null)
     {
       context.setViewRoot(viewRoot);
-      // remove from current Request Scope and the saved Bridge Request
-      // Scope
+      // remove from current Request Scope
       requestMap.remove(FACES_VIEWROOT);
-      removeFromBridgeRequestScopeData(context, scopeId, FACES_VIEWROOT);
+      
+      // Delay removing from the bridge request scope until after we are sure that 
+      // render completes okay and the state is saved by Faces -- otherwise
+      // we won't be able to reply/retry,
     }
     
     // Messages get restored in a phase listener
@@ -1254,9 +1208,16 @@
   private void saveBridgeRequestScopeData(FacesContext context, String scopeId, 
                                           List<String> preExistingList)
   {
+    Map <String, Object> m = context.getExternalContext().getRequestMap();
+    
+    // mark as an actively managed scope -- by putting it into the request it
+    // will also get into the bridge request scope -- so future restores will
+    // also automatically be marked.
+    m.put(REQUEST_SCOPE_ACTIVE, Boolean.TRUE);
+    
     // Store the RequestMap @ the bridge's request scope
     putBridgeRequestScopeData(scopeId, 
-                              copyRequestMap(context.getExternalContext().getRequestMap(), preExistingList));
+                              copyRequestMap(m, preExistingList));
 
     // flag the data so can remove it if the session terminates
     // as its unlikely useful if the session disappears
@@ -1298,6 +1259,7 @@
       if (!isExcludedFromBridgeRequestScope(key, value, preExistingList))
       {
         copy.put(key, value);
+        notifyAttributeAdded(value);
       }
     }
     return copy;
@@ -1319,12 +1281,15 @@
 
   private boolean isPreDefinedExcludedObject(String s, Object o)
   {
-    return o instanceof PortletConfig || o instanceof PortletContext || 
+    if (o != null && (o instanceof PortletConfig || o instanceof PortletContext || 
       o instanceof PortletRequest || o instanceof PortletResponse || o instanceof PortletSession || 
       o instanceof PortletPreferences || o instanceof PortalContext || o instanceof FacesContext || 
       o instanceof ExternalContext || o instanceof ServletConfig || o instanceof ServletContext || 
-      o instanceof ServletRequest || o instanceof ServletResponse || o instanceof HttpSession || 
-      isInNamespace(s, "javax.portlet.") ||
+      o instanceof ServletRequest || o instanceof ServletResponse || o instanceof HttpSession))
+      return true;
+    else
+    {
+      return isInNamespace(s, "javax.portlet.") ||
       isInNamespace(s, "javax.portlet.faces.") ||
       isInNamespace(s, "javax.faces.") ||
       isInNamespace(s, "javax.servlet.") ||
@@ -1333,6 +1298,7 @@
       // our ExternalContext uses this prefix internally to append to url which might
       // contain another '.' -- so exclude all that are prefixed with this
       s.startsWith("org.apache.myfaces.portlet.faces.context.");
+    }
   }
 
   private boolean isConfiguredExcludedAttribute(String s)
@@ -1526,10 +1492,26 @@
     // in the subsequent render request(s).
 
     String viewId = context.getViewRoot().getViewId();
+    // Get and remove any querystring params we stashed that were part of the target viewId
+    // We support viewId targets in faces-config.xml so can set things like modes
+    String qs = (String) context.getViewRoot().getAttributes().remove(VIEWID_QUERYSTRING_ATTRIBUTE);
 
     // don't care about the return as it means nothing
     ViewHandler viewHandler = context.getApplication().getViewHandler();
     String viewURL = viewHandler.getActionURL(context, viewId);
+    if (qs != null && qs.length() > 1)
+    {
+      // see whether the viewURL contains any params
+      // Now add the parameters back on (if needed)
+      if (viewURL.indexOf('?') < 0)
+      {
+        viewURL = viewURL.concat(qs);
+      }
+      else
+      {
+        viewURL = viewURL + "&" + qs.substring(1);
+      }
+    }
     context.getExternalContext().encodeActionURL(viewURL);
 
   }
@@ -1544,6 +1526,27 @@
       notifyPreDestroy(i.next().getValue());
     }
   }
+  
+  private void notifyAttributeAdded(Object o)
+  {
+    Method[] methods = o.getClass().getMethods();
+    for (int i = 0; i < methods.length; i++)
+    {
+      if (methods[i].isAnnotationPresent(BridgeRequestScopeAttributeAdded.class))
+      {
+        try
+        {
+          methods[i].invoke(o, null);
+        }
+        catch (Exception e)
+        {
+          // TODO: log problem
+          // do nothing and forge ahead
+          ;
+        }
+      }
+    }
+  }
 
   // notify this scope's attributes that they are being removed
   private void notifyPreDestroy(Object o)

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/ActionResponseDecorator.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/ActionResponseDecorator.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/ActionResponseDecorator.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/ActionResponseDecorator.java Wed Aug 12 17:56:39 2009
@@ -74,7 +74,7 @@
   public void setWindowState(WindowState windowState) throws WindowStateException
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).setWindowState(windowState);
+    ((ActionResponse) getParent()).setWindowState(windowState);
   }
 
   /**
@@ -106,7 +106,7 @@
   public void setPortletMode(PortletMode portletMode) throws PortletModeException
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).setPortletMode(portletMode);
+    ((ActionResponse) getParent()).setPortletMode(portletMode);
   }
 
   /**
@@ -141,7 +141,7 @@
   public void sendRedirect(String location) throws java.io.IOException
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).sendRedirect(location);
+    ((ActionResponse) getParent()).sendRedirect(location);
   }
 
   /**
@@ -171,7 +171,7 @@
 	public void setRenderParameters(Map parameters)
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).setRenderParameters(parameters);
+    ((ActionResponse) getParent()).setRenderParameters(parameters);
   }
 
   /**
@@ -197,7 +197,7 @@
   public void setRenderParameter(String key, String value)
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).setRenderParameter(key, value);
+    ((ActionResponse) getParent()).setRenderParameter(key, value);
   }
 
   /**
@@ -223,7 +223,7 @@
   public void setRenderParameter(String key, String[] values)
   {
     // mResponse is a protected memeber of PortletResponseDecorator
-    ((ActionResponse) mResponse).setRenderParameter(key, values);
+    ((ActionResponse) getParent()).setRenderParameter(key, values);
   }
 
 }

Added: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/RenderResponseDecorator.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/RenderResponseDecorator.java?rev=803627&view=auto
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/RenderResponseDecorator.java (added)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/bridge/wrapper/RenderResponseDecorator.java Wed Aug 12 17:56:39 2009
@@ -0,0 +1,369 @@
+/* Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.myfaces.portlet.faces.bridge.wrapper;
+
+import javax.portlet.PortletResponse;
+import javax.portlet.PortletURL;
+import javax.portlet.RenderResponse;
+
+public class RenderResponseDecorator extends PortletResponseDecorator implements RenderResponse
+{
+  protected PortletResponse mResponse = null;
+
+  public RenderResponseDecorator(PortletResponse response) throws IllegalArgumentException
+  {
+    super(response);
+  }
+
+  /**
+   * Returns the MIME type that can be used to contribute
+   * markup to the render response.
+   * <p>
+   * If no content type was set previously using the {@link #setContentType} method
+   * this method retuns <code>null</code>.
+   *
+   * @see #setContentType
+   *
+   * @return   the MIME type of the response, or <code>null</code>
+   *           if no content type is set
+   */
+  
+  public String getContentType ()
+  {
+    return ((RenderResponse) getParent()).getContentType();
+  }
+
+
+  /**
+   * Creates a portlet URL targeting the portlet. If no portlet mode, 
+   * window state or security modifier is set in the PortletURL the
+   * current values are preserved. If a request is triggered by the
+   * PortletURL, it results in a render request.
+   * <p>
+   * The returned URL can be further extended by adding
+   * portlet-specific parameters and portlet modes and window states. 
+   * <p>
+   * The created URL will per default not contain any parameters
+   * of the current render request.
+   *
+   * @return a portlet render URL
+   */
+  public PortletURL createRenderURL ()
+  {
+    return ((RenderResponse) getParent()).createRenderURL();
+  }
+
+
+  /**
+   * Creates a portlet URL targeting the portlet. If no portlet mode, 
+   * window state or security modifier is set in the PortletURL the
+   * current values are preserved. If a request is triggered by the
+   * PortletURL, it results in an action request.
+   * <p>
+   * The returned URL can be further extended by adding
+   * portlet-specific parameters and portlet modes and window states. 
+   * <p>
+   * The created URL will per default not contain any parameters
+   * of the current render request.
+   *
+   * @return a portlet action URL
+   */
+  public PortletURL createActionURL ()
+  {
+    return ((RenderResponse) getParent()).createActionURL();
+  }
+
+
+
+  /**
+   * The value returned by this method should be prefixed or appended to 
+   * elements, such as JavaScript variables or function names, to ensure 
+   * they are unique in the context of the portal page.
+   *
+   * @return   the namespace
+   */
+  
+  public String getNamespace ()
+  {
+    return ((RenderResponse) getParent()).getNamespace();
+  }
+
+
+
+  /**
+   * This method sets the title of the portlet.
+   * <p>
+   * The value can be a text String
+   *
+   * @param  title    portlet title as text String or resource URI
+   */
+
+  public void setTitle(String title)
+  {
+    ((RenderResponse) getParent()).setTitle(title);
+  }
+
+
+
+
+  /**
+   * Sets the MIME type for the render response. The portlet must
+   * set the content type before calling {@link #getWriter} or
+   * {@link #getPortletOutputStream}.
+   * <p>
+   * Calling <code>setContentType</code> after <code>getWriter</code>
+   * or <code>getOutputStream</code> does not change the content type.
+   *
+   * @param   type  the content MIME type
+   *
+   * @throws  java.lang.IllegalArgumentException
+   *              if the given type is not in the list returned
+   *              by <code>PortletRequest.getResponseContentTypes</code>
+   *
+   * @see  RenderRequest#getResponseContentTypes
+   * @see  #getContentType
+   */
+  
+  public void setContentType(String type)
+  {
+    ((RenderResponse) getParent()).setContentType(type);
+  }
+
+
+  /**
+   * Returns the name of the charset used for
+   * the MIME body sent in this response.
+   *
+   * <p>See <a href="http://ds.internic.net/rfc/rfc2045.txt">RFC 2047</a>
+   * for more information about character encoding and MIME.
+   *
+   * @return            a <code>String</code> specifying the
+   *                    name of the charset, for
+   *                    example, <code>ISO-8859-1</code>
+   *
+   */
+  
+  public String getCharacterEncoding()
+  {
+    return ((RenderResponse) getParent()).getCharacterEncoding();
+  }
+
+
+  /**
+   * Returns a PrintWriter object that can send character 
+   * text to the portal.
+   * <p>
+   * Before calling this method the content type of the
+   * render response must be set using the {@link #setContentType}
+   * method.
+   * <p>
+   * Either this method or {@link #getPortletOutputStream} may be 
+   * called to write the body, not both.
+   *
+   * @return    a <code>PrintWriter</code> object that 
+   *            can return character data to the portal
+   *
+   * @exception  java.io.IOException
+   *                 if an input or output exception occurred
+   * @exception  java.lang.IllegalStateException
+   *                 if the <code>getPortletOutputStream</code> method
+   *                 has been called on this response, 
+   *                 or if no content type was set using the
+   *                 <code>setContentType</code> method.
+   *
+   * @see #setContentType
+   * @see #getPortletOutputStream
+   */
+
+  public java.io.PrintWriter getWriter() throws java.io.IOException
+  {
+    return ((RenderResponse) getParent()).getWriter();
+  }
+
+    
+  /**
+   * Returns the locale assigned to the response.
+   * 
+   * @return  Locale of this response
+   */
+
+  public java.util.Locale getLocale()
+  {
+    return ((RenderResponse) getParent()).getLocale();
+  }
+    
+
+  /**
+   * Sets the preferred buffer size for the body of the response.  
+   * The portlet container will use a buffer at least as large as 
+   * the size requested.
+   * <p>
+   * This method must be called before any response body content is
+   * written; if content has been written, or the portlet container
+   * does not support buffering, this method may throw an 
+   * <code>IllegalStateException</code>.
+   *
+   * @param size        the preferred buffer size
+   *
+   * @exception  java.lang.IllegalStateException        
+   *                    if this method is called after
+   *                    content has been written, or the
+   *                    portlet container does not support buffering
+   *
+   * @see               #getBufferSize
+   * @see               #flushBuffer
+   * @see               #isCommitted
+   * @see               #reset
+   */
+
+  public void setBufferSize(int size)
+  {
+    ((RenderResponse) getParent()).setBufferSize(size);
+  }
+    
+
+  /**
+   * Returns the actual buffer size used for the response.  If no buffering
+   * is used, this method returns 0.
+   *
+   * @return            the actual buffer size used
+   *
+   * @see               #setBufferSize
+   * @see               #flushBuffer
+   * @see               #isCommitted
+   * @see               #reset
+   */
+
+  public int getBufferSize()
+  {
+    return ((RenderResponse) getParent()).getBufferSize();
+  }
+    
+    
+  
+  /**
+   * Forces any content in the buffer to be written to the client.  A call
+   * to this method automatically commits the response.
+   *
+   * @exception  java.io.IOException  if an error occured when writing the output
+   *
+   * @see               #setBufferSize
+   * @see               #getBufferSize
+   * @see               #isCommitted
+   * @see               #reset
+   */
+
+  public void flushBuffer() throws java.io.IOException
+  {
+    ((RenderResponse) getParent()).flushBuffer();
+  }
+    
+    
+  /**
+   * Clears the content of the underlying buffer in the response without
+   * clearing properties set. If the response has been committed, 
+   * this method throws an <code>IllegalStateException</code>.
+   *
+   * @exception  IllegalStateException  if this method is called after
+   *                                    response is comitted
+   *
+   * @see               #setBufferSize
+   * @see               #getBufferSize
+   * @see               #isCommitted
+   * @see               #reset
+   */
+
+  public void resetBuffer()
+  {
+    ((RenderResponse) getParent()).resetBuffer();
+  }
+    
+
+  /**
+   * Returns a boolean indicating if the response has been
+   * committed.
+   *
+   * @return            a boolean indicating if the response has been
+   *            committed
+   *
+   * @see               #setBufferSize
+   * @see               #getBufferSize
+   * @see               #flushBuffer
+   * @see               #reset
+   */
+
+  public boolean isCommitted()
+  {
+    return ((RenderResponse) getParent()).isCommitted();
+  }
+    
+    
+  /**
+   * Clears any data that exists in the buffer as well as the properties set.
+   * If the response has been committed, this method throws an 
+   * <code>IllegalStateException</code>.
+   *
+   * @exception java.lang.IllegalStateException  if the response has already been
+   *                                   committed
+   *
+   * @see               #setBufferSize
+   * @see               #getBufferSize
+   * @see               #flushBuffer
+   * @see               #isCommitted
+   */
+
+  public void reset()
+  {
+    ((RenderResponse) getParent()).reset();
+  }
+    
+
+  /**
+   * Returns a <code>OutputStream</code> suitable for writing binary 
+   * data in the response. The portlet container does not encode the
+   * binary data.  
+   * <p>
+   * Before calling this method the content type of the
+   * render response must be set using the {@link #setContentType}
+   * method.
+   * <p>
+   * Calling <code>flush()</code> on the OutputStream commits the response.
+   * <p>
+   * Either this method or {@link #getWriter} may be called to write the body, not both.
+   *
+   * @return    a <code>OutputStream</code> for writing binary data     
+   *
+   * @exception java.lang.IllegalStateException   if the <code>getWriter</code> method
+   *                                    has been called on this response, or
+   *                                    if no content type was set using the
+   *                                    <code>setContentType</code> method.
+   *
+   * @exception java.io.IOException     if an input or output exception occurred
+   *
+   * @see #setContentType
+   * @see #getWriter
+   */
+
+  public java.io.OutputStream getPortletOutputStream() throws java.io.IOException
+  {
+    return ((RenderResponse) getParent()).getPortletOutputStream();
+  }
+
+}

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/context/PortletExternalContextImpl.java Wed Aug 12 17:56:39 2009
@@ -287,7 +287,7 @@
       //URL is of the form scheme:urlType?queryString
       // remove the scheme
       path = url.substring(url.indexOf(":")+ 1);
-      queryStart = url.indexOf('?');
+      queryStart = path.indexOf('?');
 
       if (queryStart != -1)
       {
@@ -1424,35 +1424,17 @@
 
     queryStr = new QueryString(s.substring(queryStart + 1), "UTF8");
     path = s.substring(0, queryStart);
-
-    if (hasBackLink)
+  
+    try
     {
-      Enumeration<String> list = queryStr.getParameterNames();
-      while (list.hasMoreElements())
+      // If there is a backlink -- remove and convert it
+      String backLinkValue = queryStr.removeParameter(Bridge.BACK_LINK);
+      if (backLinkValue!= null)
       {
-        String param = list.nextElement().toString();
-        if (hasBackLink && param.equals(Bridge.BACK_LINK))
-        {
-          try
-          {
-            // Set backlink as parameter using value as param name
-            queryStr.setParameter(queryStr.getParameter(param), 
-                                encodeActionURL(context.getApplication().getViewHandler().getActionURL(context, 
-                                                                                                       context.getViewRoot().getViewId())));
-            ;
-          }
-          catch (Exception e)
-          {
-            ; // do nothing -- just ignore
-          }
-        }
+        queryStr.setParameter(backLinkValue, encodeActionURL(context.getApplication().getViewHandler().getActionURL(context, 
+                                context.getViewRoot().getViewId())), false);
       }
-    }
-    
-    // Now make sure the parameters are removed
-    try
-    {
-      queryStr.removeParameter(Bridge.BACK_LINK);
+      // just remove the viewLink param
       queryStr.removeParameter(Bridge.VIEW_LINK);
     }
     catch (Exception e)
@@ -1836,7 +1818,7 @@
   {
     // determine mode that we need to encode with this viewId
     String mode = queryStr.getParameter(Bridge.PORTLET_MODE_PARAMETER);
-    if (mode == null)
+    if (mode == null || !mPortletRequest.isPortletModeAllowed(new PortletMode(mode)))
     {
       mode = mPortletRequest.getPortletMode().toString();
     }

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/HTTPUtils.java
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/HTTPUtils.java?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/HTTPUtils.java (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/java/org/apache/myfaces/portlet/faces/util/HTTPUtils.java Wed Aug 12 17:56:39 2009
@@ -87,12 +87,9 @@
     sValidChar['-'] = true;
     sValidChar['_'] = true;
     sValidChar['.'] = true;
-    sValidChar['!'] = true;
     sValidChar['~'] = true;
-    sValidChar['*'] = true;
     sValidChar['\''] = true;
-    sValidChar['('] = true;
-    sValidChar[')'] = true;
+ 
 
     // Also initialize the sHexLookup table
     for (byte b = 0; b < 16; b++)

Modified: myfaces/portlet-bridge/core/trunk/impl/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/portlet-bridge/core/trunk/impl/src/main/resources/META-INF/faces-config.xml?rev=803627&r1=803626&r2=803627&view=diff
==============================================================================
--- myfaces/portlet-bridge/core/trunk/impl/src/main/resources/META-INF/faces-config.xml (original)
+++ myfaces/portlet-bridge/core/trunk/impl/src/main/resources/META-INF/faces-config.xml Wed Aug 12 17:56:39 2009
@@ -29,6 +29,7 @@
         <application-extension>
           <bridge:excluded-attributes>
             <bridge:excluded-attribute>com.sun.faces.*</bridge:excluded-attribute>
+		<bridge:excluded-attribute>com.sun.faces.util.*</bridge:excluded-attribute>
             <bridge:excluded-attribute>org.apache.myfaces.application.jsp.JspStateManagerImpl.*</bridge:excluded-attribute>
             <bridge:excluded-attribute>org.apache.myfaces.el.unified.resolver.managedbean.*</bridge:excluded-attribute>
             <bridge:excluded-attribute>org.apache.myfaces.shared_impl.renderkit.RendererUtils.*</bridge:excluded-attribute>