You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2006/09/21 00:42:55 UTC

svn commit: r448388 - /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/

Author: mmarinschek
Date: Wed Sep 20 15:42:54 2006
New Revision: 448388

URL: http://svn.apache.org/viewvc?view=rev&rev=448388
Log:
fix for [MYFACES-1411] :  Lifecycle phase executions repetitions. Thanks to Nikolay Petrov for this excellent cleanup.

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * Apply request values phase (JSF Spec 2.2.2)
+ */
+class ApplyRequestValuesExecutor implements PhaseExecutor {
+	public boolean execute(FacesContext facesContext) {
+		facesContext.getViewRoot().processDecodes(facesContext);
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.APPLY_REQUEST_VALUES;
+	}
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * Invoke application phase (JSF Spec 2.2.5)
+ */
+class InvokeApplicationExecutor implements PhaseExecutor {
+	public boolean execute(FacesContext facesContext) {
+		facesContext.getViewRoot().processApplication(facesContext);
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.INVOKE_APPLICATION;
+	}
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java?view=diff&rev=448388&r1=448387&r2=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java Wed Sep 20 15:42:54 2006
@@ -15,36 +15,32 @@
  */
 package org.apache.myfaces.lifecycle;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.portlet.MyFacesGenericPortlet;
-import org.apache.myfaces.portlet.PortletUtil;
-import org.apache.myfaces.util.DebugUtils;
-import org.apache.myfaces.shared_impl.util.RestoreStateUtils;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.faces.FacesException;
-import javax.faces.application.Application;
-import javax.faces.application.ViewHandler;
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
 import javax.faces.lifecycle.Lifecycle;
-import javax.portlet.PortletRequest;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.util.DebugUtils;
 
 /**
  * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
  * @author Manfred Geiler
+ * @author Nikolay Petrov
  */
 public class LifecycleImpl
         extends Lifecycle
 {
     private static final Log log = LogFactory.getLog(LifecycleImpl.class);
 
+    private PhaseExecutor[] lifecycleExecutors;
+    private PhaseExecutor renderExecutor;
+
     private final List _phaseListenerList = new ArrayList();
 
     /**
@@ -52,462 +48,153 @@
      */
     private PhaseListener[] _phaseListenerArray = null;
 
-    public LifecycleImpl()
-    {
+    public LifecycleImpl() {
         // hide from public access
-    }
+    	lifecycleExecutors = new PhaseExecutor[] {
+    			new RestoreViewExecutor(),
+    			new ApplyRequestValuesExecutor(),
+    			new ProcessValidationsExecutor(),
+    			new UpdateModelValuesExecutor(),
+    			new InvokeApplicationExecutor()
+    	};
 
-    public void execute(FacesContext facesContext)
-        throws FacesException
-    {
-        PhaseListenerManager phaseListenerMgr = new PhaseListenerManager(this, facesContext, getPhaseListeners());
-        
-        if (restoreView(facesContext, phaseListenerMgr))
-        {
-            return;
-        }
-
-        if (applyRequestValues(facesContext, phaseListenerMgr))
-        {
-            return;
-        }
-
-        if (processValidations(facesContext, phaseListenerMgr))
-        {
-            return;
-        }
-
-        if (updateModelValues(facesContext, phaseListenerMgr))
-        {
-            return;
-        }
-
-        invokeApplication(facesContext, phaseListenerMgr);
+    	renderExecutor = new RenderResponseExecutor();
     }
 
-
-    // Phases
-
-    /**
-     * Restore View (JSF.2.2.1)
-     * @return true, if immediate rendering should occur
-     */
-    private boolean restoreView(FacesContext facesContext, PhaseListenerManager phaseListenerMgr)
-        throws FacesException
-    {
-    		boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering restoreView in " + LifecycleImpl.class.getName());
-
-        try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.RESTORE_VIEW);
-
-            if(isResponseComplete(facesContext, "restoreView", true))
-            {
-                            // have to skips this phase
-                            return true;
-            }
-            if (shouldRenderResponse(facesContext, "restoreView", true)) 
-            {
-                            skipFurtherProcessing = true;
-                    }
-
-            // Derive view identifier
-            String viewId = deriveViewId(facesContext);
-
-            if(viewId == null)
-            {
-                ExternalContext externalContext = facesContext.getExternalContext();
-
-                if(!externalContext.getRequestServletPath().endsWith("/"))
-                {
-                    try
-                    {
-                        externalContext.redirect(externalContext.getRequestServletPath()+"/");
-                        facesContext.responseComplete();
-                        return true;
-                    }
-                    catch (IOException e)
-                    {
-                        throw new FacesException("redirect failed",e);
-                    }
-                }
-            }
-
-            Application application = facesContext.getApplication();
-            ViewHandler viewHandler = application.getViewHandler();
-
-            //boolean viewCreated = false;
-            UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewId);
-            if (viewRoot == null)
-            {
-                viewRoot = viewHandler.createView(facesContext, viewId);
-                viewRoot.setViewId(viewId);
-                facesContext.renderResponse();
-                //viewCreated = true;
-            }
-
-            facesContext.setViewRoot(viewRoot);
-
-            /* This section has been disabled because it causes some bug.
-             * Be careful if you need to re-enable it.
-             * Furthermore, for an unknown reason, it seems that by default
-             * it is executed (i.e. log.isTraceEnabled() is true).
-             * Bug example :
-             * This traceView causes DebugUtil.printComponent to print all the attributes
-             * of the view components.
-             * And if you have a data table within an aliasBean, this causes the data table
-             * to initialize it's value attribute while the alias isn't set.
-             * So, the value initializes with an UIData.EMPTY_DATA_MODEL, and not with the aliased one.
-             * But as it's initialized, it will not try to get the value from the ValueBinding next
-             * time it needs to.
-             * I expect this to cause more similar bugs.
-             * TODO : Completely remove or be SURE by default it's not executed, and it has no more side-effects.
-
-            if (log.isTraceEnabled())
-            {
-                //Note: DebugUtils Logger must also be in trace level
-                DebugUtils.traceView(viewCreated ? "Newly created view" : "Restored view");
-            }*/
-
-            if (facesContext.getExternalContext().getRequestParameterMap().isEmpty())
-            {
-                //no POST or query parameters --> set render response flag
-                facesContext.renderResponse();
-            }
-
-            RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(facesContext, viewRoot);
-        } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.RESTORE_VIEW);
-        }
-
-        if (isResponseComplete(facesContext, "restoreView", false)
-				|| shouldRenderResponse(facesContext, "restoreView", false))
-        {
-        		// since this phase is completed we don't need to return right away even if the response is completed
-        		skipFurtherProcessing = true;
+    public void execute(FacesContext facesContext) throws FacesException {
+        PhaseListenerManager phaseListenerMgr = new PhaseListenerManager(this, facesContext, getPhaseListeners());
+        for(int executorIndex = 0;executorIndex < lifecycleExecutors.length;executorIndex++) {
+        	if(executePhase(facesContext, lifecycleExecutors[executorIndex], phaseListenerMgr)) {
+        		return;
+        	}
         }
-
-        if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting restoreView in " + LifecycleImpl.class.getName());
-        return skipFurtherProcessing;
     }
 
 
-    /**
-     * Apply Request Values (JSF.2.2.2)
-     * @return true, if response is complete
-     */
-    private boolean applyRequestValues(FacesContext facesContext, PhaseListenerManager phaseListenerMgr)
-        throws FacesException
-    {
-    		boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering applyRequestValues in " + LifecycleImpl.class.getName());
-
-        try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.APPLY_REQUEST_VALUES);
-
-            if(isResponseComplete(facesContext, "applyRequestValues", true))
-            {
-                            // have to return right away
-                            return true;
-            }
-            if(shouldRenderResponse(facesContext, "applyRequestValues", true))
-            {
-                            skipFurtherProcessing = true;
-            }
-
-            facesContext.getViewRoot().processDecodes(facesContext);
-        } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.APPLY_REQUEST_VALUES);
+    private boolean executePhase(FacesContext facesContext, PhaseExecutor executor,
+    		PhaseListenerManager phaseListenerMgr) throws FacesException {
+		boolean skipFurtherProcessing = false;
+        if (log.isTraceEnabled()) {
+        	log.trace("entering " + executor.getPhase() + " in " + LifecycleImpl.class.getName());
         }
 
-
-        if (isResponseComplete(facesContext, "applyRequestValues", false)
-				|| shouldRenderResponse(facesContext, "applyRequestValues", false))
-        {
-        		// since this phase is completed we don't need to return right away even if the response is completed
-        		skipFurtherProcessing = true;
-        }
-
-        if (!skipFurtherProcessing && log.isTraceEnabled())
-			log.trace("exiting applyRequestValues in "
-					+ LifecycleImpl.class.getName());
-        return skipFurtherProcessing;
-    }
-
-
-    /**
-     * Process Validations (JSF.2.2.3)
-     * @return true, if response is complete
-     */
-    private boolean processValidations(FacesContext facesContext, PhaseListenerManager phaseListenerMgr)
-        throws FacesException
-    {
-        boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering processValidations in " + LifecycleImpl.class.getName());
-
         try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.PROCESS_VALIDATIONS);
+            phaseListenerMgr.informPhaseListenersBefore(executor.getPhase());
 
-            if(isResponseComplete(facesContext, "processValidations", true))
-            {
-                            // have to return right away
-                            return true;
+            if(isResponseComplete(facesContext, executor.getPhase(), true)) {
+                // have to return right away
+            	return true;
             }
-            if(shouldRenderResponse(facesContext, "processValidations", true))
-            {
-                            skipFurtherProcessing = true;
+            if(shouldRenderResponse(facesContext, executor.getPhase(), true)) {
+            	skipFurtherProcessing = true;
             }
 
-            facesContext.getViewRoot().processValidators(facesContext);
-        } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.PROCESS_VALIDATIONS);
-        }
-
-		if (isResponseComplete(facesContext, "processValidations", false)
-				|| shouldRenderResponse(facesContext, "processValidations", false))
-        {
-        		// since this phase is completed we don't need to return right away even if the response is completed
-        		skipFurtherProcessing = true;
-        }
-
-        if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting processValidations in " + LifecycleImpl.class.getName());
-        return skipFurtherProcessing;
-    }
-
-
-    /**
-     * Update Model Values (JSF.2.2.4)
-     * @return true, if response is complete
-     */
-    private boolean updateModelValues(FacesContext facesContext, PhaseListenerManager phaseListenerMgr)
-        throws FacesException
-    {
-	    boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering updateModelValues in " + LifecycleImpl.class.getName());
-
-        try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.UPDATE_MODEL_VALUES);
-
-            if(isResponseComplete(facesContext, "updateModelValues", true))
-            {
-                            // have to return right away
-                            return true;
-            }
-            if(shouldRenderResponse(facesContext, "updateModelValues", true))
-            {
-                            skipFurtherProcessing = true;
+            if(executor.execute(facesContext)) {
+            	return true;
             }
-
-            facesContext.getViewRoot().processUpdates(facesContext);
         } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.UPDATE_MODEL_VALUES);
-        }
-
-		if (isResponseComplete(facesContext, "updateModelValues", false)
-				|| shouldRenderResponse(facesContext, "updateModelValues", false))
-        {
-        		// since this phase is completed we don't need to return right away even if the response is completed
-        		skipFurtherProcessing = true;
+            phaseListenerMgr.informPhaseListenersAfter(executor.getPhase());
         }
 
-        if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting updateModelValues in " + LifecycleImpl.class.getName());
 
-        return skipFurtherProcessing;
-    }
-
-
-    /**
-     * Invoke Application (JSF.2.2.5)
-     * @return true, if response is complete
-     */
-    private boolean invokeApplication(FacesContext facesContext, PhaseListenerManager phaseListenerMgr)
-        throws FacesException
-    {
-	    boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering invokeApplication in " + LifecycleImpl.class.getName());
-
-        try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.INVOKE_APPLICATION);
-
-            if(isResponseComplete(facesContext, "invokeApplication", true))
-            {
-                            // have to return right away
-                            return true;
-            }
-            if(shouldRenderResponse(facesContext, "invokeApplication", true))
-            {
-                            skipFurtherProcessing = true;
-            }
-
-            facesContext.getViewRoot().processApplication(facesContext);
-        } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.INVOKE_APPLICATION);
+        if (isResponseComplete(facesContext, executor.getPhase(), false)
+        		|| shouldRenderResponse(facesContext, executor.getPhase(), false)) {
+        	// since this phase is completed we don't need to return right away even if the response is completed
+        	skipFurtherProcessing = true;
         }
 
-		if (isResponseComplete(facesContext, "invokeApplication", false)
-				|| shouldRenderResponse(facesContext, "invokeApplication", false))
-        {
-        		// since this phase is completed we don't need to return right away even if the response is completed
-        		skipFurtherProcessing = true;
+        if (!skipFurtherProcessing && log.isTraceEnabled()) {
+			log.trace("exiting " + executor.getPhase() + " in " + LifecycleImpl.class.getName());
         }
 
-        if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting invokeApplication in " + LifecycleImpl.class.getName());
-
         return skipFurtherProcessing;
     }
 
-
-    public void render(FacesContext facesContext) throws FacesException
-    {
-    		// if the response is complete we should not be invoking the phase listeners
-        if(isResponseComplete(facesContext, "render", true))
-        {
-        		return;
+    public void render(FacesContext facesContext) throws FacesException {
+    	// if the response is complete we should not be invoking the phase listeners
+        if(isResponseComplete(facesContext, renderExecutor.getPhase(), true)) {
+        	return;
         }
-        if (log.isTraceEnabled()) log.trace("entering renderResponse in " + LifecycleImpl.class.getName());
+        if (log.isTraceEnabled()) log.trace("entering " + renderExecutor.getPhase() + " in " + LifecycleImpl.class.getName());
 
         PhaseListenerManager phaseListenerMgr = new PhaseListenerManager(this, facesContext, getPhaseListeners());
-     
+
         try {
-            phaseListenerMgr.informPhaseListenersBefore(PhaseId.RENDER_RESPONSE);
+            phaseListenerMgr.informPhaseListenersBefore(renderExecutor.getPhase());
             // also possible that one of the listeners completed the response
-            if(isResponseComplete(facesContext, "render", true))
-            {
-                            return;
+            if(isResponseComplete(facesContext, renderExecutor.getPhase(), true)) {
+            	return;
             }
-            Application application = facesContext.getApplication();
-            ViewHandler viewHandler = application.getViewHandler();
 
-            try
-            {
-                viewHandler.renderView(facesContext, facesContext.getViewRoot());
-            }
-            catch (IOException e)
-            {
-                throw new FacesException(e.getMessage(), e);
-            }
+            renderExecutor.execute(facesContext);
         } finally {
-            phaseListenerMgr.informPhaseListenersAfter(PhaseId.RENDER_RESPONSE);
+            phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase());
         }
-        
-        if (log.isTraceEnabled())
-        {
+
+        if (log.isTraceEnabled()) {
             //Note: DebugUtils Logger must also be in trace level
             DebugUtils.traceView("View after rendering");
         }
 
-        if (log.isTraceEnabled()) log.trace("exiting renderResponse in " + LifecycleImpl.class.getName());
+        if (log.isTraceEnabled()) {
+        	log.trace("exiting " + renderExecutor.getPhase() + " in " + LifecycleImpl.class.getName());
+        }
     }
 
-
-    private boolean isResponseComplete(FacesContext facesContext, String phase, boolean before) {
-    		boolean flag = false;
-        if (facesContext.getResponseComplete())
-        {
-            if (log.isDebugEnabled())
+    private boolean isResponseComplete(FacesContext facesContext, PhaseId phase, boolean before) {
+		boolean flag = false;
+	    if (facesContext.getResponseComplete()) {
+	        if (log.isDebugEnabled()) {
 				log.debug("exiting from lifecycle.execute in " + phase
 						+ " because getResponseComplete is true from one of the " +
 						(before ? "before" : "after") + " listeners");
-            flag = true;
-        }
-        return flag;
-    }
+	        }
+	        flag = true;
+	    }
+	    return flag;
+	}
 
-    private boolean shouldRenderResponse(FacesContext facesContext, String phase, boolean before) {
-    		boolean flag = false;
-        if (facesContext.getRenderResponse())
-        {
-            if (log.isDebugEnabled())
+	private boolean shouldRenderResponse(FacesContext facesContext, PhaseId phase, boolean before) {
+			boolean flag = false;
+	    if (facesContext.getRenderResponse()) {
+	        if (log.isDebugEnabled()) {
 				log.debug("exiting from lifecycle.execute in " + phase
-						+ " because getRenderResponse is true from one of the " + 
+						+ " because getRenderResponse is true from one of the " +
 						(before ? "before" : "after") + " listeners");
-            flag = true;
-        }
-        return flag;
+	        }
+	        flag = true;
+	    }
+	    return flag;
 	}
 
-    private static String deriveViewId(FacesContext facesContext)
-    {
-        ExternalContext externalContext = facesContext.getExternalContext();
-
-        if (PortletUtil.isPortletRequest(facesContext))
-        {
-            PortletRequest request = (PortletRequest)externalContext.getRequest();
-            return request.getParameter(MyFacesGenericPortlet.VIEW_ID);
-        }
-
-        String viewId = externalContext.getRequestPathInfo();  //getPathInfo
-        if (viewId == null)
-        {
-            //No extra path info found, so it is propably extension mapping
-            viewId = externalContext.getRequestServletPath();  //getServletPath
-            DebugUtils.assertError(viewId != null,
-                                   log, "RequestServletPath is null, cannot determine viewId of current page.");
-            if(viewId==null)
-                return null;
-
-            //TODO: JSF Spec 2.2.1 - what do they mean by "if the default ViewHandler implementation is used..." ?
-            String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
-            String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
-            DebugUtils.assertError(suffix.charAt(0) == '.',
-                                   log, "Default suffix must start with a dot!");
-
-            int dot = viewId.lastIndexOf('.');
-            if (dot == -1)
-            {
-                log.error("Assumed extension mapping, but there is no extension in " + viewId);
-                viewId=null;
-            }
-            else
-            {
-                viewId = viewId.substring(0, dot) + suffix;
-            }
-        }
-
-        return viewId;
-    }
-
-
-    public void addPhaseListener(PhaseListener phaseListener)
-    {
-        if(phaseListener == null)
-        {
-            throw new NullPointerException("PhaseListener must not be null.");
-        }
-        synchronized(_phaseListenerList)
-        {
-            _phaseListenerList.add(phaseListener);
-            _phaseListenerArray = null; // reset lazy cache array
-        }
-    }
-
-    public void removePhaseListener(PhaseListener phaseListener)
-    {
-        if(phaseListener == null)
-        {
-            throw new NullPointerException("PhaseListener must not be null.");
-        }
-        synchronized(_phaseListenerList)
-        {
-            _phaseListenerList.remove(phaseListener);
-            _phaseListenerArray = null; // reset lazy cache array
-        }
-    }
-
-    public PhaseListener[] getPhaseListeners()
-    {
-        synchronized(_phaseListenerList)
-        {
-            // (re)build lazy cache array if necessary
-            if (_phaseListenerArray == null)
-            {
-                _phaseListenerArray = (PhaseListener[])_phaseListenerList.toArray(new PhaseListener[_phaseListenerList.size()]);
-            }
-            return _phaseListenerArray;
-        }
-    }
-
+    public void addPhaseListener(PhaseListener phaseListener) {
+		if (phaseListener == null) {
+			throw new NullPointerException("PhaseListener must not be null.");
+		}
+		synchronized (_phaseListenerList) {
+			_phaseListenerList.add(phaseListener);
+			_phaseListenerArray = null; // reset lazy cache array
+		}
+	}
 
-    
+	public void removePhaseListener(PhaseListener phaseListener) {
+		if (phaseListener == null) {
+			throw new NullPointerException("PhaseListener must not be null.");
+		}
+		synchronized (_phaseListenerList) {
+			_phaseListenerList.remove(phaseListener);
+			_phaseListenerArray = null; // reset lazy cache array
+		}
+	}
 
+	public PhaseListener[] getPhaseListeners() {
+		synchronized (_phaseListenerList) {
+			// (re)build lazy cache array if necessary
+			if (_phaseListenerArray == null) {
+				_phaseListenerArray = (PhaseListener[]) _phaseListenerList.toArray(new PhaseListener[_phaseListenerList
+						.size()]);
+			}
+			return _phaseListenerArray;
+		}
+	}
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the PhaseExecutor for a lifecycle
+ *
+ * @author Nikolay Petrov
+ *
+ */
+interface PhaseExecutor {
+	public boolean execute(FacesContext facesContext);
+	public PhaseId getPhase();
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * Process validations phase (JSF Spec 2.2.3)
+ */
+class ProcessValidationsExecutor implements PhaseExecutor {
+	public boolean execute(FacesContext facesContext) {
+		facesContext.getViewRoot().processValidators(facesContext);
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.PROCESS_VALIDATIONS;
+	}
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import java.io.IOException;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * render response phase (JSF Spec 2.2.6)
+ */
+class RenderResponseExecutor implements PhaseExecutor {
+	public boolean execute(FacesContext facesContext) {
+		Application application = facesContext.getApplication();
+		ViewHandler viewHandler = application.getViewHandler();
+
+		try {
+			viewHandler.renderView(facesContext, facesContext.getViewRoot());
+		} catch (IOException e) {
+			throw new FacesException(e.getMessage(), e);
+		}
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.RENDER_RESPONSE;
+	}
+}

Added: 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?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import java.io.IOException;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+import javax.portlet.PortletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.portlet.MyFacesGenericPortlet;
+import org.apache.myfaces.portlet.PortletUtil;
+import org.apache.myfaces.shared_impl.util.RestoreStateUtils;
+import org.apache.myfaces.util.DebugUtils;
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * Restore view phase (JSF Spec 2.2.1)
+ */
+class RestoreViewExecutor implements PhaseExecutor {
+
+	private static final Log log = LogFactory.getLog(LifecycleImpl.class);
+
+	public boolean execute(FacesContext facesContext) {
+		// Derive view identifier
+		String viewId = deriveViewId(facesContext);
+
+		if (viewId == null) {
+			ExternalContext externalContext = facesContext.getExternalContext();
+
+			if (!externalContext.getRequestServletPath().endsWith("/")) {
+				try {
+					externalContext.redirect(externalContext.getRequestServletPath() + "/");
+					facesContext.responseComplete();
+					return true;
+				} catch (IOException e) {
+					throw new FacesException("redirect failed", e);
+				}
+			}
+		}
+
+		Application application = facesContext.getApplication();
+		ViewHandler viewHandler = application.getViewHandler();
+
+		// boolean viewCreated = false;
+		UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewId);
+		if (viewRoot == null) {
+			viewRoot = viewHandler.createView(facesContext, viewId);
+			viewRoot.setViewId(viewId);
+			facesContext.renderResponse();
+			// viewCreated = true;
+		}
+
+		facesContext.setViewRoot(viewRoot);
+
+		if (facesContext.getExternalContext().getRequestParameterMap().isEmpty()) {
+			// no POST or query parameters --> set render response flag
+			facesContext.renderResponse();
+		}
+
+		RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(facesContext, viewRoot);
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.RESTORE_VIEW;
+	}
+
+	private static String deriveViewId(FacesContext facesContext) {
+		ExternalContext externalContext = facesContext.getExternalContext();
+
+		if (PortletUtil.isPortletRequest(facesContext)) {
+			PortletRequest request = (PortletRequest) externalContext.getRequest();
+			return request.getParameter(MyFacesGenericPortlet.VIEW_ID);
+		}
+
+		String viewId = externalContext.getRequestPathInfo(); // getPathInfo
+		if (viewId == null) {
+			// No extra path info found, so it is propably extension mapping
+			viewId = externalContext.getRequestServletPath(); // getServletPath
+			DebugUtils.assertError(viewId != null, log,
+					"RequestServletPath is null, cannot determine viewId of current page.");
+			if (viewId == null)
+				return null;
+
+			// TODO: JSF Spec 2.2.1 - what do they mean by "if the default
+			// ViewHandler implementation is used..." ?
+			String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+			String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
+			DebugUtils.assertError(suffix.charAt(0) == '.', log, "Default suffix must start with a dot!");
+
+			int dot = viewId.lastIndexOf('.');
+			if (dot == -1) {
+				log.error("Assumed extension mapping, but there is no extension in " + viewId);
+				viewId = null;
+			} else {
+				viewId = viewId.substring(0, dot) + suffix;
+			}
+		}
+
+		return viewId;
+	}
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java?view=auto&rev=448388
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java Wed Sep 20 15:42:54 2006
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+
+/**
+ * Implements the lifecycle as described in Spec. 1.0 PFD Chapter 2
+ * @author Nikolay Petrov
+ *
+ * Update model values phase (JSF Spec 2.2.4)
+ */
+class UpdateModelValuesExecutor implements PhaseExecutor {
+	public boolean execute(FacesContext facesContext) {
+		facesContext.getViewRoot().processUpdates(facesContext);
+		return false;
+	}
+
+	public PhaseId getPhase() {
+		return PhaseId.UPDATE_MODEL_VALUES;
+	}
+}



Re: svn commit: r448388 - /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/

Posted by Martin Marinschek <ma...@gmail.com>.
As I wrote in my response to your comment on the issue, he has faxed
in an ICLA already - it hasn't been processed so far, but it will
definitely be very soon.

In cleaning up an older issue, I have found Ernst Fastls name there
now - so that seems to be settled now.

regards,

Martin

On 9/21/06, Wendy Smoak <ws...@gmail.com> wrote:
> Especially given the comment on the issue that these did not come in
> with the licence header, I think we need an iCLA for this.  I'm
> uncomfortable with having @author tags for someone who hasn't signed
> an agreement.  (At least, I don't see this name on Jim's page [1].)
>
> Is there a reason the copyright date on the new files is 2004 ?
>
> [1] http://people.apache.org/~jim/committers.html
>
> Thanks,
> --
> Wendy
>
> On 9/20/06, mmarinschek@apache.org <mm...@apache.org> wrote:
> > Author: mmarinschek
> > Date: Wed Sep 20 15:42:54 2006
> > New Revision: 448388
> >
> > URL: http://svn.apache.org/viewvc?view=rev&rev=448388
> > Log:
> > fix for [MYFACES-1411] :  Lifecycle phase executions repetitions. Thanks to Nikolay Petrov for this excellent cleanup.
> >
> > Added:
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java
> > Modified:
> >     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
>


-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces

Re: svn commit: r448388 - /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/

Posted by Wendy Smoak <ws...@gmail.com>.
Especially given the comment on the issue that these did not come in
with the licence header, I think we need an iCLA for this.  I'm
uncomfortable with having @author tags for someone who hasn't signed
an agreement.  (At least, I don't see this name on Jim's page [1].)

Is there a reason the copyright date on the new files is 2004 ?

[1] http://people.apache.org/~jim/committers.html

Thanks,
-- 
Wendy

On 9/20/06, mmarinschek@apache.org <mm...@apache.org> wrote:
> Author: mmarinschek
> Date: Wed Sep 20 15:42:54 2006
> New Revision: 448388
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=448388
> Log:
> fix for [MYFACES-1411] :  Lifecycle phase executions repetitions. Thanks to Nikolay Petrov for this excellent cleanup.
>
> Added:
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/PhaseExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ProcessValidationsExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/UpdateModelValuesExecutor.java
> Modified:
>     myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java