You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/07/13 21:40:18 UTC

svn commit: r963832 - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/UIViewRoot.java impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java

Author: jakobk
Date: Tue Jul 13 19:40:18 2010
New Revision: 963832

URL: http://svn.apache.org/viewvc?rev=963832&view=rev
Log:
MYFACES-2374 UIViewRoot.getBeforePhaseListener() and UIViewRoot.getAfterPhaseListener() could be called on PhaseId.RESTORE_VIEW

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=963832&r1=963831&r2=963832&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Tue Jul 13 19:40:18 2010
@@ -34,9 +34,6 @@ import java.util.logging.Logger;
 import javax.el.MethodExpression;
 import javax.el.ValueExpression;
 import javax.faces.FactoryFinder;
-import javax.faces.component.visit.VisitCallback;
-import javax.faces.component.visit.VisitContext;
-import javax.faces.component.visit.VisitResult;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.PartialViewContext;
@@ -48,7 +45,6 @@ import javax.faces.event.PhaseEvent;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
 import javax.faces.event.PostConstructViewMapEvent;
-import javax.faces.event.PostRestoreStateEvent;
 import javax.faces.event.PreDestroyViewMapEvent;
 import javax.faces.event.SystemEvent;
 import javax.faces.event.SystemEventListener;
@@ -655,11 +651,6 @@ public class UIViewRoot extends UICompon
             // The try block must have a finally block that ensures that no FacesEvents remain in the event queue
             broadcastEvents(context, PhaseId.RESTORE_VIEW);
 
-            // invoke afterPhase MethodExpression
-            // Note: In this phase it is not possible to invoke the beforePhase method, because we
-            // first have to restore the view to get its attributes.
-            //notifyListeners(context, PhaseId.RESTORE_VIEW, getAfterPhaseListener(), false);
-            
             //visitTree(VisitContext.createVisitContext(context), new RestoreStateCallback());
         }
     }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java?rev=963832&r1=963831&r2=963832&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java Tue Jul 13 19:40:18 2010
@@ -22,7 +22,9 @@ import java.util.Collection;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.el.MethodExpression;
 import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
 import javax.faces.application.Application;
 import javax.faces.application.ProjectStage;
 import javax.faces.application.ViewExpiredException;
@@ -30,10 +32,14 @@ import javax.faces.application.ViewHandl
 import javax.faces.component.UIViewParameter;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PostAddToViewEvent;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.view.ViewMetadata;
+import javax.faces.webapp.FacesServlet;
 
 import org.apache.myfaces.renderkit.ErrorPageWriter;
 
@@ -86,6 +92,10 @@ class RestoreViewExecutor extends PhaseE
             viewRoot.setLocale(facesContext.getExternalContext().getRequestLocale());
             
             restoreViewSupport.processComponentBinding(facesContext, viewRoot);
+            
+            // invoke the afterPhase MethodExpression of UIViewRoot
+            _invokeViewRootAfterPhaseListener(facesContext);
+            
             return false;
         }
         
@@ -152,7 +162,7 @@ class RestoreViewExecutor extends PhaseE
                     
                     if (viewRoot != null)
                     {
-                        viewParameters = metadata.getViewParameters(viewRoot);
+                        viewParameters = ViewMetadata.getViewParameters(viewRoot);
                     }
                     else if(facesContext.getResponseComplete())
                     {
@@ -207,9 +217,57 @@ class RestoreViewExecutor extends PhaseE
                     .put(ErrorPageWriter.ERROR_PAGE_BEAN_KEY, new ErrorPageWriter.ErrorPageBean());
         }
         
+        // invoke the afterPhase MethodExpression of UIViewRoot
+        _invokeViewRootAfterPhaseListener(facesContext);
+        
         return false;
     }
     
+    /**
+     * Invoke afterPhase MethodExpression of UIViewRoot.
+     * Note: In this phase it is not possible to invoke the beforePhase method, because we
+     * first have to restore the view to get its attributes. Also it is not really possible
+     * to call the afterPhase method inside of UIViewRoot for this phase, thus it was decided
+     * in the JSF 2.0 spec rev A to put this here.
+     * @param facesContext
+     */
+    private void _invokeViewRootAfterPhaseListener(FacesContext facesContext)
+    {
+        // get the UIViewRoot (note that it must not be null at this point)
+        UIViewRoot root = facesContext.getViewRoot();
+        MethodExpression afterPhaseExpression = root.getAfterPhaseListener();
+        if (afterPhaseExpression != null)
+        {
+            PhaseEvent event = new PhaseEvent(facesContext, getPhase(), _getLifecycle(facesContext));
+            try
+            {
+                afterPhaseExpression.invoke(facesContext.getELContext(), new Object[] { event });
+            }
+            catch (Throwable t) 
+            {
+                log.log(Level.SEVERE, "An Exception occured while processing " +
+                        afterPhaseExpression.getExpressionString() + 
+                        " in Phase " + getPhase(), t);
+            }
+        }
+    }
+    
+    /**
+     * Gets the current Lifecycle instance from the LifecycleFactory
+     * @param facesContext
+     * @return
+     */
+    private Lifecycle _getLifecycle(FacesContext facesContext)
+    {
+        LifecycleFactory factory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+        String id = facesContext.getExternalContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
+        if (id == null)
+        {
+            id = LifecycleFactory.DEFAULT_LIFECYCLE;
+        }
+        return factory.getLifecycle(id);  
+    }
+    
     protected RestoreViewSupport getRestoreViewSupport()
     {
         if (_restoreViewSupport == null)

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java?rev=963832&r1=963831&r2=963832&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java Tue Jul 13 19:40:18 2010
@@ -66,11 +66,12 @@ public class RestoreViewExecutorTest ext
         expect(_application.getViewHandler()).andReturn(_viewHandler).anyTimes();
         _viewHandler.initView(eq(_facesContext));
         UIViewRoot viewRoot = _mocksControl.createMock(UIViewRoot.class);
-        expect(_facesContext.getViewRoot()).andReturn(viewRoot);
+        expect(_facesContext.getViewRoot()).andReturn(viewRoot).times(2);
         Locale expectedLocale = new Locale("xxx");
         expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
         expect(_externalContext.getRequestLocale()).andReturn(expectedLocale);
         viewRoot.setLocale(eq(expectedLocale));
+        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
         _restoreViewSupport.processComponentBinding(same(_facesContext), same(viewRoot));
 
         _mocksControl.replay();
@@ -104,6 +105,8 @@ public class RestoreViewExecutorTest ext
 
         _application.publishEvent(same(_facesContext), same(PostAddToViewEvent.class), same(viewRoot));
         _facesContext.setViewRoot(same(viewRoot));
+        expect(_facesContext.getViewRoot()).andReturn(viewRoot);
+        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
 
         _mocksControl.replay();
         _testimpl.doPrePhaseActions(_facesContext);
@@ -127,6 +130,8 @@ public class RestoreViewExecutorTest ext
         _restoreViewSupport.processComponentBinding(same(_facesContext), same(viewRoot));
         _facesContext.setViewRoot(same(viewRoot));
         _facesContext.setProcessingEvents(eq(false));
+        expect(_facesContext.getViewRoot()).andReturn(viewRoot);
+        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
 
         _mocksControl.replay();
         _testimpl.doPrePhaseActions(_facesContext);