You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shale.apache.org by ma...@apache.org on 2008/01/13 23:30:01 UTC

svn commit: r611661 - in /shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test: base/ jmock/ mock/ mock/lifecycle/

Author: matzew
Date: Sun Jan 13 14:30:00 2008
New Revision: 611661

URL: http://svn.apache.org/viewvc?rev=611661&view=rev
Log:
SHALE-482 - simple lifecycle added;
needs testing...

Added:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ApplyRequestValuesExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/DefaultRestoreViewSupport.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/InvokeApplicationExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycle.java
      - copied, changed from r610605, shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycle.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycleFactory.java
      - copied, changed from r610605, shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycleFactory.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseListenerManager.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ProcessValidationsExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RenderResponseExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewExecutor.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewSupport.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/UpdateModelValuesExecutor.java
Removed:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycle.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycleFactory.java
Modified:
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/base/AbstractJsfTestCase.java
    shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/jmock/AbstractJmockJsfTestCase.java

Modified: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/base/AbstractJsfTestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/base/AbstractJsfTestCase.java?rev=611661&r1=611660&r2=611661&view=diff
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/base/AbstractJsfTestCase.java (original)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/base/AbstractJsfTestCase.java Sun Jan 13 14:30:00 2008
@@ -35,11 +35,11 @@
 import org.apache.shale.test.mock.MockHttpServletRequest;
 import org.apache.shale.test.mock.MockHttpServletResponse;
 import org.apache.shale.test.mock.MockHttpSession;
-import org.apache.shale.test.mock.MockLifecycle;
-import org.apache.shale.test.mock.MockLifecycleFactory;
 import org.apache.shale.test.mock.MockRenderKit;
 import org.apache.shale.test.mock.MockServletConfig;
 import org.apache.shale.test.mock.MockServletContext;
+import org.apache.shale.test.mock.lifecycle.MockLifecycle;
+import org.apache.shale.test.mock.lifecycle.MockLifecycleFactory;
 
 /**
  * <p>Abstract JUnit test case base class, which sets up the JavaServer Faces
@@ -116,7 +116,7 @@
         FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
         "org.apache.shale.test.mock.MockFacesContextFactory");
         FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY,
-        "org.apache.shale.test.mock.MockLifecycleFactory");
+        "org.apache.shale.test.mock.lifecycle.MockLifecycleFactory");
         FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
         "org.apache.shale.test.mock.MockRenderKitFactory");
 

Modified: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/jmock/AbstractJmockJsfTestCase.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/jmock/AbstractJmockJsfTestCase.java?rev=611661&r1=611660&r2=611661&view=diff
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/jmock/AbstractJmockJsfTestCase.java (original)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/jmock/AbstractJmockJsfTestCase.java Sun Jan 13 14:30:00 2008
@@ -33,11 +33,11 @@
 import org.apache.shale.test.mock.MockHttpServletRequest;
 import org.apache.shale.test.mock.MockHttpServletResponse;
 import org.apache.shale.test.mock.MockHttpSession;
-import org.apache.shale.test.mock.MockLifecycle;
-import org.apache.shale.test.mock.MockLifecycleFactory;
 import org.apache.shale.test.mock.MockRenderKit;
 import org.apache.shale.test.mock.MockServletConfig;
 import org.apache.shale.test.mock.MockServletContext;
+import org.apache.shale.test.mock.lifecycle.MockLifecycle;
+import org.apache.shale.test.mock.lifecycle.MockLifecycleFactory;
 import org.jmock.cglib.MockObjectTestCase;
 
 /**
@@ -109,7 +109,7 @@
         FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
         "org.apache.shale.test.mock.MockFacesContextFactory");
         FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY,
-        "org.apache.shale.test.mock.MockLifecycleFactory");
+        "org.apache.shale.test.mock.lifecycle.MockLifecycleFactory");
         FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
         "org.apache.shale.test.mock.MockRenderKitFactory");
         

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ApplyRequestValuesExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ApplyRequestValuesExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ApplyRequestValuesExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ApplyRequestValuesExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,41 @@
+/*
+ * 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.shale.test.mock.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) {
+    
+    System.out.println("\n\n\n\n\n ApplyRequestValuesExecutor \n\n\n\n\n");
+    
+    facesContext.getViewRoot().processDecodes(facesContext);
+    return false;
+  }
+
+  public PhaseId getPhase() {
+    return PhaseId.APPLY_REQUEST_VALUES;
+  }
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/DefaultRestoreViewSupport.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/DefaultRestoreViewSupport.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/DefaultRestoreViewSupport.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/DefaultRestoreViewSupport.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,114 @@
+/*
+ * 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.shale.test.mock.lifecycle;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author: mbr $)
+ * @version $Revision: 517403 $ $Date: 2007-03-12 22:17:00 +0100 (Mo, 12 Mrz 2007) $
+ */
+public class DefaultRestoreViewSupport implements RestoreViewSupport
+{
+    private static final String JAVAX_SERVLET_INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
+
+    private static final String JAVAX_SERVLET_INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
+
+    private final Log log = LogFactory.getLog(DefaultRestoreViewSupport.class);
+
+    public void processComponentBinding(FacesContext facesContext, UIComponent component)
+    {
+        ValueExpression binding = component.getValueExpression("binding");
+        if (binding != null)
+        {
+            binding.setValue(facesContext.getELContext(), component);
+        }
+
+        for (Iterator iter = component.getFacetsAndChildren(); iter.hasNext();)
+        {
+            processComponentBinding(facesContext, (UIComponent) iter.next());
+        }
+    }
+
+    public String calculateViewId(FacesContext facesContext)
+    {
+        //Assert.notNull(facesContext);
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Map requestMap = externalContext.getRequestMap();
+
+        String viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_PATH_INFO);
+        boolean traceEnabled = log.isTraceEnabled();
+        if (viewId != null)
+        {
+            if (traceEnabled)
+            {
+                log.trace("Calculated viewId '" + viewId + "' from request param '" + JAVAX_SERVLET_INCLUDE_PATH_INFO
+                        + "'");
+            }
+        }
+        else
+        {
+            viewId = externalContext.getRequestPathInfo();
+            if (viewId != null && traceEnabled)
+            {
+                log.trace("Calculated viewId '" + viewId + "' from request path info");
+            }
+        }
+
+        if (viewId == null)
+        {
+            viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_SERVLET_PATH);
+            if (viewId != null && traceEnabled)
+            {
+                log.trace("Calculated viewId '" + viewId + "' from request param '"
+                        + JAVAX_SERVLET_INCLUDE_SERVLET_PATH + "'");
+            }
+        }
+
+        if (viewId == null)
+        {
+            viewId = externalContext.getRequestServletPath();
+            if (viewId != null && traceEnabled)
+            {
+                log.trace("Calculated viewId '" + viewId + "' from request servlet path");
+            }
+        }
+
+        if (viewId == null)
+        {
+            throw new FacesException("Could not determine view id.");
+        }
+
+        return viewId;
+    }
+
+    public boolean isPostback(FacesContext facesContext)
+    {
+        return true;
+    }
+}

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/InvokeApplicationExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/InvokeApplicationExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/InvokeApplicationExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/InvokeApplicationExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.shale.test.mock.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;
+  }
+}
\ No newline at end of file

Copied: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycle.java (from r610605, shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycle.java)
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycle.java?p2=shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycle.java&p1=shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycle.java&r1=610605&r2=611661&rev=611661&view=diff
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycle.java (original)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycle.java Sun Jan 13 14:30:00 2008
@@ -15,12 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.shale.test.mock;
+package org.apache.shale.test.mock.lifecycle;
 
 import java.util.ArrayList;
 import java.util.List;
 import javax.faces.FacesException;
 import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
 import javax.faces.lifecycle.Lifecycle;
 
@@ -42,8 +43,22 @@
     /**
      * <p>List of event listeners for this instance.</p>
      */
-    private List listeners = new ArrayList();
+    private List phaseListenerList = new ArrayList();
+    private PhaseExecutor[] lifecycleExecutors;
+    private PhaseExecutor renderExecutor;
+
+    public MockLifecycle()
+    {
+        lifecycleExecutors = new PhaseExecutor[] {
+            new RestoreViewExecutor(),
+            new ApplyRequestValuesExecutor(),
+            new ProcessValidationsExecutor(),
+            new UpdateModelValuesExecutor(),
+            new InvokeApplicationExecutor()
+        };
 
+        renderExecutor = new RenderResponseExecutor();
+    }
 
     // ------------------------------------------------------- Lifecycle Methods
 
@@ -51,7 +66,7 @@
     /** {@inheritDoc} */
     public void addPhaseListener(PhaseListener listener) {
 
-        listeners.add(listener);
+      phaseListenerList.add(listener);
 
     }
 
@@ -59,15 +74,51 @@
     /** {@inheritDoc} */
     public void execute(FacesContext context) throws FacesException {
 
-        throw new UnsupportedOperationException();
+        PhaseListenerManager phaseListenerMgr = new PhaseListenerManager(this, context, getPhaseListeners());
+        for(int executorIndex = 0;executorIndex < lifecycleExecutors.length;executorIndex++) {
+            if(executePhase(context, lifecycleExecutors[executorIndex], phaseListenerMgr)) {
+                return;
+            }
+        }
+    }
+
+    private boolean executePhase(FacesContext facesContext, PhaseExecutor executor,
+        PhaseListenerManager phaseListenerMgr) throws FacesException {
+        boolean skipFurtherProcessing = false;
+
+        try {
+            phaseListenerMgr.informPhaseListenersBefore(executor.getPhase());
+
+            if(isResponseComplete(facesContext, executor.getPhase(), true)) {
+                // have to return right away
+              return true;
+            }
+            if(shouldRenderResponse(facesContext, executor.getPhase(), true)) {
+              skipFurtherProcessing = true;
+            }
+
+            if(executor.execute(facesContext)) {
+              return true;
+            }
+        } finally {
+            phaseListenerMgr.informPhaseListenersAfter(executor.getPhase());
+        }
+
+
+        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;
+        }
 
+        return skipFurtherProcessing;
     }
 
 
     /** {@inheritDoc} */
     public PhaseListener[] getPhaseListeners() {
 
-        return (PhaseListener[]) listeners.toArray(new PhaseListener[listeners.size()]);
+        return (PhaseListener[]) phaseListenerList.toArray(new PhaseListener[phaseListenerList.size()]);
 
     }
 
@@ -75,7 +126,7 @@
     /** {@inheritDoc} */
     public void removePhaseListener(PhaseListener listener) {
 
-        listeners.remove(listener);
+      phaseListenerList.remove(listener);
 
     }
 
@@ -83,9 +134,41 @@
     /** {@inheritDoc} */
     public void render(FacesContext context) throws FacesException {
 
-        throw new UnsupportedOperationException();
+      // if the response is complete we should not be invoking the phase listeners
+      if(isResponseComplete(context, renderExecutor.getPhase(), true)) {
+        return;
+      }
+
+      PhaseListenerManager phaseListenerMgr = new PhaseListenerManager(this, context, getPhaseListeners());
+
+      try {
+          phaseListenerMgr.informPhaseListenersBefore(renderExecutor.getPhase());
+          // also possible that one of the listeners completed the response
+          if(isResponseComplete(context, renderExecutor.getPhase(), true)) {
+            return;
+          }
+
+          renderExecutor.execute(context);
+      } finally {
+          phaseListenerMgr.informPhaseListenersAfter(renderExecutor.getPhase());
+      }
 
     }
+    
+    private boolean isResponseComplete(FacesContext facesContext, PhaseId phase, boolean before) {
+      boolean flag = false;
+        if (facesContext.getResponseComplete()) {
+            flag = true;
+        }
+        return flag;
+    }
 
+    private boolean shouldRenderResponse(FacesContext facesContext, PhaseId phase, boolean before) {
+      boolean flag = false;
+      if (facesContext.getRenderResponse()) {
+          flag = true;
+      }
+      return flag;
+  }
 
 }

Copied: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycleFactory.java (from r610605, shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycleFactory.java)
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycleFactory.java?p2=shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycleFactory.java&p1=shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycleFactory.java&r1=610605&r2=611661&rev=611661&view=diff
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/MockLifecycleFactory.java (original)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/MockLifecycleFactory.java Sun Jan 13 14:30:00 2008
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shale.test.mock;
+package org.apache.shale.test.mock.lifecycle;
 
 import java.util.HashMap;
 import java.util.Iterator;

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.shale.test.mock.lifecycle;
+
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+/**
+ * Implements the PhaseExecutor for a lifecycle
+ *
+ * @author Nikolay Petrov
+ *
+ */
+interface PhaseExecutor {
+  
+  /**
+   * Executes a phase of the JavaServer(tm) Faces lifecycle, like UpdateModelValues.
+   * The <code>execute</code> method is called by the lifecylce implementation's private
+   * <code>executePhase</code>.
+   * @param facesContext The <code>FacesContext</code> for the current request we are processing 
+   * @return <code>true</code> if execution should be stopped
+   */
+  boolean execute(FacesContext facesContext);
+  
+  /**
+   * Returns the <code>PhaseId</code> for which the implemented executor is invoked 
+   * @return
+   */
+  PhaseId getPhase();
+}
\ No newline at end of file

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseListenerManager.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseListenerManager.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseListenerManager.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/PhaseListenerManager.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,100 @@
+/*
+ * 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.shale.test.mock.lifecycle;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class encapsulates the logic used to call PhaseListeners.  It was 
+ * needed because of issue 9 of the JSF 1.2 spec.  See section 11.3 for more
+ * details.
+ *
+ * @author Stan Silvert
+ */
+class PhaseListenerManager {
+    
+    private static final Log log = LogFactory.getLog(PhaseListenerManager.class);
+    
+    private Lifecycle lifecycle;
+    private FacesContext facesContext;
+    private PhaseListener[] phaseListeners;
+    
+    // Tracks success in the beforePhase.  Listeners that throw an exception
+    // in beforePhase or were never called because a previous listener threw
+    // an exception should not have its afterPhase called
+    //private Map<PhaseId, boolean[]> listenerSuccessMap = new HashMap<PhaseId, boolean[]>();
+    private Map listenerSuccessMap = new HashMap();
+    
+    /** Creates a new instance of PhaseListenerManager */
+    PhaseListenerManager(Lifecycle lifecycle, FacesContext facesContext, PhaseListener[] phaseListeners) {
+        this.lifecycle = lifecycle;
+        this.facesContext = facesContext;
+        this.phaseListeners = phaseListeners;
+    }
+    
+    private boolean isListenerForThisPhase(PhaseListener phaseListener, PhaseId phaseId) {
+        int listenerPhaseId = phaseListener.getPhaseId().getOrdinal();
+        return (listenerPhaseId == PhaseId.ANY_PHASE.getOrdinal() ||
+                listenerPhaseId == phaseId.getOrdinal());
+    }
+    
+    void informPhaseListenersBefore(PhaseId phaseId) {
+        boolean[] beforePhaseSuccess = new boolean[phaseListeners.length];
+        listenerSuccessMap.put(phaseId, beforePhaseSuccess);
+        
+        for (int i = 0; i < phaseListeners.length; i++) {
+            PhaseListener phaseListener = phaseListeners[i];
+            if (isListenerForThisPhase(phaseListener, phaseId)) {
+                try {
+                    phaseListener.beforePhase(new PhaseEvent(facesContext, phaseId, lifecycle));
+                    beforePhaseSuccess[i] = true;
+                } catch (Exception e) {
+                    beforePhaseSuccess[i] = false; // redundant - for clarity
+                    log.error("Exception in PhaseListener " + phaseId.toString() + " beforePhase.", e);
+                    return;
+                }
+            }
+        }
+    }
+
+    void informPhaseListenersAfter(PhaseId phaseId) {
+        //boolean[] beforePhaseSuccess = listenerSuccessMap.get(phaseId);
+        boolean[] beforePhaseSuccess = (boolean[]) listenerSuccessMap.get(phaseId);
+        
+        for (int i = phaseListeners.length - 1; i >= 0; i--)  {
+            PhaseListener phaseListener = phaseListeners[i];
+            if (isListenerForThisPhase(phaseListener, phaseId) 
+                && beforePhaseSuccess[i]) {
+                try {
+                    phaseListener.afterPhase(new PhaseEvent(facesContext, phaseId, lifecycle));
+                } catch (Exception e) {
+                    log.error("Exception in PhaseListener " + phaseId.toString() + " afterPhase", e);
+                }
+            }
+        }
+
+    }
+}
\ No newline at end of file

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ProcessValidationsExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ProcessValidationsExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ProcessValidationsExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/ProcessValidationsExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,38 @@
+/*
+ * 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.shale.test.mock.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;
+  }
+}
\ No newline at end of file

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RenderResponseExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RenderResponseExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RenderResponseExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RenderResponseExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,50 @@
+/*
+ * 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.shale.test.mock.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;
+  }
+}
\ No newline at end of file

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,168 @@
+/*
+ * 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.shale.test.mock.lifecycle;
+
+import javax.faces.FacesException;
+import javax.faces.application.Application;
+import javax.faces.application.ViewExpiredException;
+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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implements the Restore View Phase (JSF Spec 2.2.1)
+ * 
+ * @author Nikolay Petrov
+ * @author Bruno Aranda (JSF 1.2)
+ * @version $Revision: 517403 $ $Date: 2007-03-12 22:17:00 +0100 (Mo, 12 Mrz 2007) $
+ * 
+ */
+class RestoreViewExecutor implements PhaseExecutor
+{
+
+    private static final Log log = LogFactory.getLog(RestoreViewExecutor.class);
+    private RestoreViewSupport _restoreViewSupport;
+
+    public boolean execute(FacesContext facesContext)
+    {
+        if (facesContext == null)
+        {
+            throw new FacesException("FacesContext is null");
+        }
+
+        // init the View
+        Application application = facesContext.getApplication();
+        ViewHandler viewHandler = application.getViewHandler();
+        viewHandler.initView(facesContext);
+
+        UIViewRoot viewRoot = facesContext.getViewRoot();
+
+        RestoreViewSupport restoreViewSupport = getRestoreViewSupport();
+        
+        if (viewRoot != null)
+        {
+            if (log.isTraceEnabled())
+                log.trace("View already exists in the FacesContext");
+
+            viewRoot.setLocale(facesContext.getExternalContext().getRequestLocale());
+            restoreViewSupport.processComponentBinding(facesContext, viewRoot);
+            return false;
+        }
+
+        String viewId = restoreViewSupport.calculateViewId(facesContext);
+
+        // Determine if this request is a postback or initial request
+        if (restoreViewSupport.isPostback(facesContext))
+        {
+            if (log.isTraceEnabled())
+                log.trace("Request is a postback");
+
+            viewRoot = viewHandler.restoreView(facesContext, viewId);
+            if (viewRoot == null)
+            {
+                throw new ViewExpiredException("The expected view was not returned " + "for the view identifier: "
+                        + viewId, viewId);
+            }
+            restoreViewSupport.processComponentBinding(facesContext, viewRoot);
+        }
+        else
+        {
+            if (log.isTraceEnabled())
+                log.trace("Request is not a postback. New UIViewRoot will be created");
+
+            viewRoot = viewHandler.createView(facesContext, viewId);
+            facesContext.renderResponse();
+        }
+
+        facesContext.setViewRoot(viewRoot);
+
+        return false;
+    }
+
+    protected RestoreViewSupport getRestoreViewSupport()
+    {
+        if (_restoreViewSupport == null)
+        {
+            _restoreViewSupport = new DefaultRestoreViewSupport();
+        }
+        return _restoreViewSupport;
+    }
+
+    /**
+     * @param restoreViewSupport
+     *            the restoreViewSupport to set
+     */
+    public void setRestoreViewSupport(RestoreViewSupport restoreViewSupport)
+    {
+        _restoreViewSupport = restoreViewSupport;
+    }
+
+    public PhaseId getPhase()
+    {
+        return PhaseId.RESTORE_VIEW;
+    }
+
+    /**
+     * TODO place that stuff into the default view handler implementation.
+     */
+    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: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewSupport.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewSupport.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewSupport.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/RestoreViewSupport.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,72 @@
+/*
+ * 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.shale.test.mock.lifecycle;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * Support class for restore view phase
+ * 
+ * @author Mathias Broekelmann (latest modification by $Author: mbr $)
+ * @version $Revision: 517403 $ $Date: 2007-03-12 22:17:00 +0100 (Mo, 12 Mrz 2007) $
+ */
+public interface RestoreViewSupport
+{
+    /**
+     * <p>
+     * Calculates the view id from the given faces context by the following algorithm
+     * </p>
+     * <ul>
+     * <li>lookup the viewid from the request attribute "javax.servlet.include.path_info"
+     * <li>if null lookup the value for viewid by {@link ExternalContext#getRequestPathInfo()}
+     * <li>if null lookup the value for viewid from the request attribute "javax.servlet.include.servlet_path"
+     * <li>if null lookup the value for viewid by {@link ExternalContext#getRequestServletPath()}
+     * <li>if null throw a {@link FacesException}
+     * </ul>
+     */
+    String calculateViewId(FacesContext facesContext);
+
+    /**
+     * Processes the component tree. For each component (including the given one) in the tree determine if a value
+     * expression for the attribute "binding" is defined. If the expression is not null set the component instance to
+     * the value of this expression
+     * 
+     * @param facesContext
+     * @param component
+     *            the root component
+     */
+    void processComponentBinding(FacesContext facesContext, UIComponent component);
+
+    /**
+     * <p>
+     * Determine if the current request is a post back by the following algorithm.
+     * </p>
+     * <p>
+     * Find the render-kit-id for the current request by calling calculateRenderKitId() on the Application’s
+     * ViewHandler. Get that RenderKit’s ResponseStateManager and call its isPostback() method, passing the given
+     * FacesContext.
+     * </p>
+     * 
+     * @param facesContext
+     * @return
+     */
+    boolean isPostback(FacesContext facesContext);
+}
\ No newline at end of file

Added: shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/UpdateModelValuesExecutor.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/UpdateModelValuesExecutor.java?rev=611661&view=auto
==============================================================================
--- shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/UpdateModelValuesExecutor.java (added)
+++ shale/framework/trunk/shale-test/src/main/java/org/apache/shale/test/mock/lifecycle/UpdateModelValuesExecutor.java Sun Jan 13 14:30:00 2008
@@ -0,0 +1,39 @@
+/*
+ * 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.shale.test.mock.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;
+  }
+}
\ No newline at end of file