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 2009/01/05 23:51:53 UTC

svn commit: r731755 - in /myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal: application/ context/external/ webapp/

Author: sobryan
Date: Mon Jan  5 14:51:52 2009
New Revision: 731755

URL: http://svn.apache.org/viewvc?rev=731755&view=rev
Log:
TRINIDAD-1203:  DATE SELECTION IN INPUTDATE ON BLACKBERRY THROWS VIEWEXPIREDEXCEPTION

* Changed StateManagerImpl and ViewHandlerImpl to move the logic to restore
  the UIViewRoot into the StateManagerImpl so that we are able to call
  through the Mojarra ViewHandler so that the state can be set up correctly.

* Modified the ServletExternalContext to properly allow a redirect even when
  a FacesContext is not present.  This is important because this object is
  often used as a wrapper object in filters, where a FacesContext may not
  be available.

* Modified the TrinidadFilterImpl to handle re-running of the lifecycle through
  a redirect rather then through simply re-running the lifecycle.

Modified:
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/ViewHandlerImpl.java
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/external/ServletExternalContext.java
    myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java?rev=731755&r1=731754&r2=731755&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java Mon Jan  5 14:51:52 2009
@@ -52,6 +52,8 @@
 import java.io.ObjectOutputStream;
 
 import org.apache.myfaces.trinidad.bean.util.StateUtils;
+import org.apache.myfaces.trinidadinternal.context.RequestContextImpl;
+import org.apache.myfaces.trinidadinternal.context.TrinidadPhaseListener;
 
 /**
  * StateManager that handles a hybrid client/server strategy:  a
@@ -495,6 +497,16 @@
   public UIViewRoot restoreView(FacesContext context, String viewId,
                                 String renderKitId)
   {
+    // If we're being asked to execute a "return" event from, say, a dialog, always 
+    // restore the "launch view", which was set over in the TrinidadFilter.
+    UIViewRoot launchView = (UIViewRoot)
+      context.getExternalContext().getRequestMap().remove(RequestContextImpl.LAUNCH_VIEW);
+    if (launchView != null)
+    {
+      TrinidadPhaseListener.markPostback(context);
+      return launchView;
+    }
+    
     if (!isSavingStateInClient(context))
       return _delegate.restoreView(context, viewId, renderKitId);
 

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/ViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/ViewHandlerImpl.java?rev=731755&r1=731754&r2=731755&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/ViewHandlerImpl.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/ViewHandlerImpl.java Mon Jan  5 14:51:52 2009
@@ -206,22 +206,19 @@
   public UIViewRoot restoreView(
     FacesContext context,
     String       viewId)
-  {
-    // If we're being asked to re-run the lifecycle for a "return"
-    // event, always restore the "launch view", which was set
-    // over in RequestContextImpl
-    UIViewRoot launchView = (UIViewRoot)
-      context.getExternalContext().getRequestMap().get(
-        RequestContextImpl.LAUNCH_VIEW);
-
-    if (launchView != null)
+  {    
+    //This code processes a "return" event.  Most of this logic was moved to 
+    //StateManagerImpl because we ran into a problem with JSF where it didn't 
+    //set up the JSF mapping properly if we didn't delegate to the default 
+    //ViewHandler.  There may be other logic associated with the internalView
+    //which might need to be moved to the StateManager as well.  This might also
+    //be able to be further optimized if all the other logic in this method passes
+    //through.
+    if(context.getExternalContext().getRequestMap().get(RequestContextImpl.LAUNCH_VIEW) != null)
     {
-      context.getExternalContext().getRequestMap().remove(
-        RequestContextImpl.LAUNCH_VIEW);
-      TrinidadPhaseListener.markPostback(context);
-      return launchView;
+      return super.restoreView(context, viewId);
     }
-
+    
     InternalView internal = _getInternalView(context, viewId);
     if (internal != null)
     {

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/external/ServletExternalContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/external/ServletExternalContext.java?rev=731755&r1=731754&r2=731755&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/external/ServletExternalContext.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/external/ServletExternalContext.java Mon Jan  5 14:51:52 2009
@@ -462,7 +462,12 @@
     if (_servletResponse instanceof HttpServletResponse)
     {
       _httpServletResponse.sendRedirect(url);
-      FacesContext.getCurrentInstance().responseComplete();
+      
+      FacesContext fc = FacesContext.getCurrentInstance();
+      if(fc != null)
+      {
+        fc.responseComplete();
+      }
     }
     else
     {

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java?rev=731755&r1=731754&r2=731755&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java Mon Jan  5 14:51:52 2009
@@ -19,9 +19,14 @@
 package org.apache.myfaces.trinidadinternal.webapp;
 
 import java.io.IOException;
+import java.io.Serializable;
+
 import java.util.List;
 import java.util.Map;
 
+import java.util.UUID;
+
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.servlet.Filter;
@@ -36,6 +41,7 @@
 
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidad.util.ExternalContextUtils;
 import org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl;
 import org.apache.myfaces.trinidadinternal.config.dispatch.DispatchResponseConfiguratorImpl;
 import org.apache.myfaces.trinidadinternal.config.dispatch.DispatchServletResponse;
@@ -145,7 +151,6 @@
 
     try
     {
-      
       _doFilterImpl(request, response, chain);
     }
     // For PPR errors, handle the request specially
@@ -200,60 +205,155 @@
     // -= Scott O'Bryan =-
     // Added for backward compatibility
     ExternalContext ec = new ServletExternalContext(_servletContext, request, response);
-    HttpServletResponse dispatch = new DispatchServletResponse(ec);
-    DispatchResponseConfiguratorImpl.apply(ec);
-
-    _invokeDoFilter(request, dispatch, chain);
-
-    // If there are existing "launchParameters", then that means
-    // we've returned from a "launch", and we need to re-execute the
-    // faces lifecycle.  ViewHandlerImpl will be responsible for ensuring
-    // that we re-execute the lifecycle on the correct page.
-    // -= Simon Lessard =-
-    // FIXME: Using <String, String[]> for now to accomodate ReplaceParametersRequestWrapper.
-    //        However, the Servlet specification suggest <String, Object> so this 
-    //        could lead to some nasty problems one day. Especially if JEE spec includes 
-    //        generics for its Servlet API soon.
-    //
-    // -= Scott O'Bryan =- 
-    // TODO: The following should be made available to the Portal.  This is not trivial 
-    //       because this just re-invokes the filter chain with a new set of parameters.
-    //       In the portal environment, this must rerun the portlet without the use of 
-    //       filters until Portlet 2.0.
-    Map<String, String[]> launchParameters = (Map<String, String[]>)
-      request.getAttribute(RequestContextImpl.LAUNCH_PARAMETERS);
-    if (launchParameters != null)
-    {
-      request.removeAttribute(RequestContextImpl.LAUNCH_PARAMETERS);
-      request.setAttribute(_IS_RETURNING_KEY, Boolean.TRUE);
-      request = new ReplaceParametersRequestWrapper(
-               (HttpServletRequest) request, launchParameters);
-      _invokeDoFilter(request, dispatch, chain);
-      request.removeAttribute(_IS_RETURNING_KEY);
+    boolean isHttpReq = ExternalContextUtils.isHttpServletRequest(ec);
+    
+    if(isHttpReq)
+    {
+      response = _getResponse(ec);
+      ec.setResponse(response);
     }
-  }
-
-  private void _invokeDoFilter(
-    ServletRequest  request,
-    ServletResponse response,
-    FilterChain     chain) throws IOException, ServletException
-  {
+     
     // Set up a PseudoFacesContext with the actual request and response
     // so that RequestContext can be more functional in the interval
     // between now and when the FacesServlet starts.
-    PseudoFacesContext pfc = new PseudoFacesContext(
-      new ServletExternalContext(_servletContext, request, response));
+    PseudoFacesContext pfc = new PseudoFacesContext(ec);
     _PSEUDO_FACES_CONTEXT.set(pfc);
     try
     {
+      if(isHttpReq)
+      {
+        // If there are existing "launchParameters", then that means
+        // we've returned from a "launch", and we need to re-execute the
+        // faces lifecycle.  ViewHandlerImpl will be responsible for ensuring
+        // that we re-execute the lifecycle on the correct page.
+        // -= Simon Lessard =-
+        // FIXME: Using <String, String[]> for now to accomodate ReplaceParametersRequestWrapper.
+        //        However, the Servlet specification suggest <String, Object> so this 
+        //        could lead to some nasty problems one day. Especially if JEE spec includes 
+        //        generics for its Servlet API soon.
+        //
+        // -= Scott O'Bryan =- 
+        // TODO: The following should be made available to the Portal.  This is not trivial 
+        //       because this just re-invokes the filter chain with a new set of parameters.
+        //       In the portal environment, this must rerun the portlet without the use of 
+        //       filters until Portlet 2.0.
+        request = _getRequest(ec);
+        ec.setRequest(request);
+      }
+      
       chain.doFilter(request, response);
+
+      if(isHttpReq)
+      {
+        _handleDialogReturn(ec);
+      }
     }
     finally
     {
       _PSEUDO_FACES_CONTEXT.remove();
     }
   }
+  
+  private String _getKey(String uid)
+  {
+    return _LAUNCH_KEY+"_"+uid;
+  }
+  
+  private ServletResponse _getResponse(ExternalContext ec)
+  {
+    HttpServletResponse dispatch = new DispatchServletResponse(ec);
+    DispatchResponseConfiguratorImpl.apply(ec);
+    return dispatch;
+  }
+  
+  private ServletRequest _getRequest(ExternalContext ec)
+  {
+    String uid = ec.getRequestParameterMap().get(_LAUNCH_KEY);
+    if(uid != null)
+    {
+      /**
+       * We use pageflow scope so that if something fails on the redirect, we
+       * have a chance of getting cleaned up early.  This will not always happen
+       * so the object may stick around for a while.
+       */
+      Map<String, Object> sessionMap = ec.getSessionMap();
+      
+      LaunchData data = (LaunchData)sessionMap.remove(_getKey(uid));
+      
+      if(data != null)
+      {
+        Map<String, Object> requestMap = ec.getRequestMap();
+        requestMap.put(_IS_RETURNING_KEY, Boolean.TRUE);
+        requestMap.put(RequestContextImpl.LAUNCH_VIEW, data.getLaunchView());
+        
+        return new ReplaceParametersRequestWrapper(
+             (HttpServletRequest) ec.getRequest(), 
+             data.getLaunchParam());
+      }
+    }
+    
+    return (ServletRequest)ec.getRequest();
+  }
+  
+  private void _handleDialogReturn(ExternalContext ec)
+    throws IOException
+  {
+    Map<String, Object> reqMap = ec.getRequestMap();
+    Map<String, String[]> launchParameters = (Map<String, String[]>)reqMap.get(RequestContextImpl.LAUNCH_PARAMETERS);
+    if(launchParameters != null && !Boolean.TRUE.equals(reqMap.get(_IS_RETURNING_KEY)))
+    {
+      /**
+       * We use pageflow scope so that if something fails on the redirect, we
+       * have a chance of getting cleaned up early.  This will not always happen
+       * so the object may stick around for a while.
+       */
+      Map<String, Object> sessionMap = ec.getSessionMap();
+      String uid = UUID.randomUUID().toString();
+      LaunchData data = new LaunchData((UIViewRoot)reqMap.get(RequestContextImpl.LAUNCH_VIEW), launchParameters);
+      sessionMap.put(_getKey(uid), data);
+      
+      //Construct URL
+      //TODO: sobryan I believe some of this can be added to the RequestContextUtils to allow
+      //      this url to be constructed for both portlet and servlet environments.  We'll want to research.
+      HttpServletRequest req = (HttpServletRequest) ec.getRequest();
+      StringBuffer url = req.getRequestURL().append("?");
+      String queryStr = req.getQueryString();
+      if((queryStr != null) && (queryStr.trim().length() >0))
+      {
+        url.append(queryStr)
+           .append("&");
+      }
+      
+      url.append(_LAUNCH_KEY)
+         .append("=")
+         .append(uid);
+      
+      ec.redirect(url.toString());
+    }
+  }
+  
+  private static final class LaunchData implements Serializable
+  {
+    private UIViewRoot _launchView;
+    private Map<String, String[]> _launchParam;
+    
+    
+    public LaunchData(UIViewRoot launchView, Map<String, String[]> launchParam)
+    {
+      _launchView = launchView;
+      _launchParam = launchParam;
+    }
 
+    private UIViewRoot getLaunchView()
+    {
+      return _launchView;
+    }
+
+    private Map<String, String[]> getLaunchParam()
+    {
+      return _launchParam;
+    }
+  }
 
   private static final class FilterListChain implements FilterChain
   {
@@ -293,6 +393,7 @@
   private ServletContext _servletContext;
   private List<Filter> _filters = null;
 
+  private static final String _LAUNCH_KEY = "_dlgDta";
   private static final String _IS_RETURNING_KEY =
     "org.apache.myfaces.trinidadinternal.webapp.AdfacesFilterImpl.IS_RETURNING";
   private static final String _FILTER_EXECUTED_KEY =