Author: mrdon
Date: Tue Jun 20 19:52:25 2006
New Revision: 415877

URL: http://svn.apache.org/viewvc?rev=415877&view=rev
Log:
Fixing JSF spec compliance, ensuring phase listeners called after every phase, 
minor formatting

WW-1357

Modified:
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
    
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ApplyRequestValuesInterceptor.java
 Tue Jun 20 19:52:25 2006
@@ -26,45 +26,50 @@
  */
 public class ApplyRequestValuesInterceptor extends FacesInterceptor {
 
-       private static final long serialVersionUID = -1471180154211835323L;
+    private static final long serialVersionUID = -1471180154211835323L;
 
-       /**
-        * Apply Request Values (JSF.2.2.2)
-        * 
-        * @param viewId The view id
-        * @param facesContext The faces context
-        * @return true, if response is complete
-        */
-       protected boolean executePhase(String viewId, FacesContext facesContext)
-                       throws FacesException {
-               boolean skipFurtherProcessing = false;
-               if (log.isTraceEnabled())
-                       log.trace("entering applyRequestValues");
-
-               informPhaseListenersBefore(facesContext, 
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);
-
-               informPhaseListenersAfter(facesContext, 
PhaseId.APPLY_REQUEST_VALUES);
-
-               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");
-               return skipFurtherProcessing;
-       }
+    /**
+     * Apply Request Values (JSF.2.2.2)
+     * 
+     * @param viewId
+     *            The view id
+     * @param facesContext
+     *            The faces context
+     * @return true, if response is complete
+     */
+    protected boolean executePhase(String viewId, FacesContext facesContext)
+            throws FacesException {
+        boolean skipFurtherProcessing = false;
+        if (log.isTraceEnabled())
+            log.trace("entering applyRequestValues");
+
+        informPhaseListenersBefore(facesContext, PhaseId.APPLY_REQUEST_VALUES);
+
+        try {
+            if (isResponseComplete(facesContext, "applyRequestValues", true)) {
+                // have to return right away
+                return true;
+            }
+            if (shouldRenderResponse(facesContext, "applyRequestValues", 
true)) {
+                skipFurtherProcessing = true;
+            }
+
+            facesContext.getViewRoot().processDecodes(facesContext);
+        } finally {
+            informPhaseListenersAfter(facesContext,
+                    PhaseId.APPLY_REQUEST_VALUES);
+        }
+
+        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");
+        return skipFurtherProcessing;
+    }
 }

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/FacesResult.java
 Tue Jun 20 19:52:25 2006
@@ -33,53 +33,56 @@
  */
 public class FacesResult extends FacesSupport implements Result {
 
-       private static final long serialVersionUID = -3548970638740937804L;
+    private static final long serialVersionUID = -3548970638740937804L;
 
-       /**
-        * Executes the result
-        */
-       public void execute(ActionInvocation invocation) throws Exception {
-               render(FacesContext.getCurrentInstance());
-       }
+    /**
+     * Executes the result
+     */
+    public void execute(ActionInvocation invocation) throws Exception {
+        render(FacesContext.getCurrentInstance());
+    }
 
-       /**
-        * Executes the render phase, borrowed from MyFaces
-        * 
-        * @param facesContext
-        *            The faces context
-        * @throws FacesException
-        *             If anything goes wrong
-        */
-       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;
-               }
-               if (log.isTraceEnabled())
-                       log.trace("entering renderResponse");
+    /**
+     * Executes the render phase, borrowed from MyFaces
+     * 
+     * @param facesContext
+     *            The faces context
+     * @throws FacesException
+     *             If anything goes wrong
+     */
+    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;
+        }
+        if (log.isTraceEnabled())
+            log.trace("entering renderResponse");
 
-               informPhaseListenersBefore(facesContext, 
PhaseId.RENDER_RESPONSE);
-               // also possible that one of the listeners completed the 
response
-               if (isResponseComplete(facesContext, "render", 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);
-               }
+        informPhaseListenersBefore(facesContext, PhaseId.RENDER_RESPONSE);
+        try {
+            // also possible that one of the listeners completed the response
+            if (isResponseComplete(facesContext, "render", 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);
+            }
+        } finally {
+            informPhaseListenersAfter(facesContext, PhaseId.RENDER_RESPONSE);
+        }
+        if (log.isTraceEnabled()) {
+            // Note: DebugUtils Logger must also be in trace level
+            // DebugUtils.traceView("View after rendering");
+        }
 
-               informPhaseListenersAfter(facesContext, 
PhaseId.RENDER_RESPONSE);
-               if (log.isTraceEnabled()) {
-                       // Note: DebugUtils Logger must also be in trace level
-                       // DebugUtils.traceView("View after rendering");
-               }
-
-               if (log.isTraceEnabled())
-                       log.trace("exiting renderResponse");
-       }
+        if (log.isTraceEnabled())
+            log.trace("exiting renderResponse");
+    }
 
 }

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/InvokeApplicationInterceptor.java
 Tue Jun 20 19:52:25 2006
@@ -26,48 +26,50 @@
  */
 public class InvokeApplicationInterceptor extends FacesInterceptor {
 
-       private static final long serialVersionUID = -7388153356410171208L;
+    private static final long serialVersionUID = -7388153356410171208L;
 
-       /**
-        * Invoke Application (JSF.2.2.5)
-        * 
-        * @param viewId
-        *            The view id
-        * @param facesContext
-        *            The faces context
-        * @return true, if response is complete
-        */
-       protected boolean executePhase(String viewId, FacesContext facesContext)
-                       throws FacesException {
-               boolean skipFurtherProcessing = false;
-               if (log.isTraceEnabled())
-                       log.trace("entering invokeApplication");
-
-               informPhaseListenersBefore(facesContext, 
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);
-
-               informPhaseListenersAfter(facesContext, 
PhaseId.INVOKE_APPLICATION);
-
-               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;
-               }
+    /**
+     * Invoke Application (JSF.2.2.5)
+     * 
+     * @param viewId
+     *            The view id
+     * @param facesContext
+     *            The faces context
+     * @return true, if response is complete
+     */
+    protected boolean executePhase(String viewId, FacesContext facesContext)
+            throws FacesException {
+        boolean skipFurtherProcessing = false;
+        if (log.isTraceEnabled())
+            log.trace("entering invokeApplication");
+
+        informPhaseListenersBefore(facesContext, PhaseId.INVOKE_APPLICATION);
+
+        try {
+            if (isResponseComplete(facesContext, "invokeApplication", true)) {
+                // have to return right away
+                return true;
+            }
+            if (shouldRenderResponse(facesContext, "invokeApplication", true)) 
{
+                skipFurtherProcessing = true;
+            }
+
+            facesContext.getViewRoot().processApplication(facesContext);
+        } finally {
+            informPhaseListenersAfter(facesContext, 
PhaseId.INVOKE_APPLICATION);
+        }
+
+        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 invokeApplication ");
+        if (!skipFurtherProcessing && log.isTraceEnabled())
+            log.trace("exiting invokeApplication ");
 
-               return skipFurtherProcessing;
-       }
+        return skipFurtherProcessing;
+    }
 }

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/ProcessValidationsInterceptor.java
 Tue Jun 20 19:52:25 2006
@@ -45,17 +45,19 @@
 
                informPhaseListenersBefore(facesContext, 
PhaseId.PROCESS_VALIDATIONS);
 
-               if (isResponseComplete(facesContext, "processValidations", 
true)) {
-                       // have to return right away
-                       return true;
-               }
-               if (shouldRenderResponse(facesContext, "processValidations", 
true)) {
-                       skipFurtherProcessing = true;
-               }
-
-               facesContext.getViewRoot().processValidators(facesContext);
-
-               informPhaseListenersAfter(facesContext, 
PhaseId.PROCESS_VALIDATIONS);
+        try {
+                       if (isResponseComplete(facesContext, 
"processValidations", true)) {
+                               // have to return right away
+                               return true;
+                       }
+                       if (shouldRenderResponse(facesContext, 
"processValidations", true)) {
+                               skipFurtherProcessing = true;
+                       }
+        
+                       
facesContext.getViewRoot().processValidators(facesContext);
+        } finally {
+            informPhaseListenersAfter(facesContext, 
PhaseId.PROCESS_VALIDATIONS);
+        }
 
                if (isResponseComplete(facesContext, "processValidations", 
false)
                                || shouldRenderResponse(facesContext, 
"processValidations",

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/RestoreViewInterceptor.java
 Tue Jun 20 19:52:25 2006
@@ -37,185 +37,189 @@
  */
 public class RestoreViewInterceptor extends FacesInterceptor {
 
-       private static final long serialVersionUID = -1500785113037140668L;
+    private static final long serialVersionUID = -1500785113037140668L;
 
-       /**
-        * Restore View (JSF.2.2.1)
-        * 
-        * @param viewId
-        *            The view id
-        * @param facesContext
-        *            The faces context
-        * @return true, if immediate rendering should occur
-        */
-       protected boolean executePhase(String viewId, FacesContext 
facesContext) {
-               boolean skipFurtherProcessing = false;
-               if (log.isTraceEnabled())
-                       log.trace("entering restoreView");
-
-               informPhaseListenersBefore(facesContext, PhaseId.RESTORE_VIEW);
-
-               if (isResponseComplete(facesContext, "restoreView", true)) {
-                       // have to skips this phase
-                       return true;
-               }
-               if (shouldRenderResponse(facesContext, "restoreView", true)) {
-                       skipFurtherProcessing = true;
-               }
-
-               ExternalContext externalContext = 
facesContext.getExternalContext();
-               String defaultSuffix = externalContext
-                               
.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
-               String suffix = defaultSuffix != null ? defaultSuffix
-                               : ViewHandler.DEFAULT_SUFFIX;
-               if (viewId != null) {
-                       viewId += suffix;
-               }
-
-               if (viewId == null) {
-                       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();
-               }
-
-               recursivelyHandleComponentReferencesAndSetValid(facesContext, 
viewRoot);
-
-               informPhaseListenersAfter(facesContext, 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;
-               }
-
-               if (!skipFurtherProcessing && log.isTraceEnabled())
-                       log.trace("exiting restoreView ");
-               return skipFurtherProcessing;
-       }
-
-       /**
-        * Walk the component tree, executing any component-bindings to reattach
-        * components to their backing beans. Also, any UIInput component is 
marked
-        * as Valid.
-        * <p>
-        * Note that this method effectively breaks encapsulation; instead of 
asking
-        * each component to update itself and its children, this method just
-        * reaches into each component. That makes it impossible for any 
component
-        * to customise its behaviour at this point.
-        * <p>
-        * This has been filed as an issue against the spec. Until this issue is
-        * resolved, we'll add a new marker-interface for components to allow 
them
-        * to define their interest in handling children bindings themselves.
-        */
-       protected void recursivelyHandleComponentReferencesAndSetValid(
-                       FacesContext facesContext, UIComponent parent) {
-               recursivelyHandleComponentReferencesAndSetValid(facesContext, 
parent,
-                               false);
-       }
-
-       protected void recursivelyHandleComponentReferencesAndSetValid(
-                       FacesContext facesContext, UIComponent parent, boolean 
forceHandle) {
-               Method handleBindingsMethod = getBindingMethod(parent);
-
-               if (handleBindingsMethod != null && !forceHandle) {
-                       try {
-                               handleBindingsMethod.invoke(parent, new 
Object[] {});
-                       } catch (Throwable th) {
-                               log.error(
-                                               "Exception while invoking 
handleBindings on component with client-id:"
-                                                               + 
parent.getClientId(facesContext), th);
-                       }
-               } else {
-                       for (Iterator it = parent.getFacetsAndChildren(); 
it.hasNext();) {
-                               UIComponent component = (UIComponent) it.next();
-
-                               ValueBinding binding = 
component.getValueBinding("binding"); // TODO:
-                                                                               
                                                                                
// constant
-                               if (binding != null && 
!binding.isReadOnly(facesContext)) {
-                                       binding.setValue(facesContext, 
component);
-                               }
-
-                               if (component instanceof UIInput) {
-                                       ((UIInput) component).setValid(true);
-                               }
-
-                               
recursivelyHandleComponentReferencesAndSetValid(facesContext,
-                                               component);
-                       }
-               }
-       }
-
-       /**
-        * This is all a hack to work around a spec-bug which will be fixed in
-        * JSF2.0
-        * 
-        * @param parent
-        * @return true if this component is bindingAware (e.g. aliasBean)
-        */
-       private static Method getBindingMethod(UIComponent parent) {
-               Class[] clazzes = parent.getClass().getInterfaces();
-
-               for (int i = 0; i < clazzes.length; i++) {
-                       Class clazz = clazzes[i];
-
-                       if (clazz.getName().indexOf("BindingAware") != -1) {
-                               try {
-                                       return 
parent.getClass().getMethod("handleBindings",
-                                                       new Class[] {});
-                               } catch (NoSuchMethodException e) {
-                                       // return
-                               }
-                       }
-               }
+    /**
+     * Restore View (JSF.2.2.1)
+     * 
+     * @param viewId
+     *            The view id
+     * @param facesContext
+     *            The faces context
+     * @return true, if immediate rendering should occur
+     */
+    protected boolean executePhase(String viewId, FacesContext facesContext) {
+        boolean skipFurtherProcessing = false;
+        if (log.isTraceEnabled())
+            log.trace("entering restoreView");
+
+        informPhaseListenersBefore(facesContext, PhaseId.RESTORE_VIEW);
+
+        try {
+            if (isResponseComplete(facesContext, "restoreView", true)) {
+                // have to skips this phase
+                return true;
+            }
+            if (shouldRenderResponse(facesContext, "restoreView", true)) {
+                skipFurtherProcessing = true;
+            }
+
+            ExternalContext externalContext = 
facesContext.getExternalContext();
+            String defaultSuffix = externalContext
+                    .getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+            String suffix = defaultSuffix != null ? defaultSuffix
+                    : ViewHandler.DEFAULT_SUFFIX;
+            if (viewId != null) {
+                viewId += suffix;
+            }
+
+            if (viewId == null) {
+                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();
+            }
+
+            recursivelyHandleComponentReferencesAndSetValid(facesContext,
+                    viewRoot);
+        } finally {
+            informPhaseListenersAfter(facesContext, 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;
+        }
+
+        if (!skipFurtherProcessing && log.isTraceEnabled())
+            log.trace("exiting restoreView ");
+        return skipFurtherProcessing;
+    }
+
+    /**
+     * Walk the component tree, executing any component-bindings to reattach
+     * components to their backing beans. Also, any UIInput component is marked
+     * as Valid.
+     * <p>
+     * Note that this method effectively breaks encapsulation; instead of 
asking
+     * each component to update itself and its children, this method just
+     * reaches into each component. That makes it impossible for any component
+     * to customise its behaviour at this point.
+     * <p>
+     * This has been filed as an issue against the spec. Until this issue is
+     * resolved, we'll add a new marker-interface for components to allow them
+     * to define their interest in handling children bindings themselves.
+     */
+    protected void recursivelyHandleComponentReferencesAndSetValid(
+            FacesContext facesContext, UIComponent parent) {
+        recursivelyHandleComponentReferencesAndSetValid(facesContext, parent,
+                false);
+    }
+
+    protected void recursivelyHandleComponentReferencesAndSetValid(
+            FacesContext facesContext, UIComponent parent, boolean 
forceHandle) {
+        Method handleBindingsMethod = getBindingMethod(parent);
+
+        if (handleBindingsMethod != null && !forceHandle) {
+            try {
+                handleBindingsMethod.invoke(parent, new Object[] {});
+            } catch (Throwable th) {
+                log.error(
+                        "Exception while invoking handleBindings on component 
with client-id:"
+                                + parent.getClientId(facesContext), th);
+            }
+        } else {
+            for (Iterator it = parent.getFacetsAndChildren(); it.hasNext();) {
+                UIComponent component = (UIComponent) it.next();
+
+                ValueBinding binding = component.getValueBinding("binding"); 
// TODO:
+                // constant
+                if (binding != null && !binding.isReadOnly(facesContext)) {
+                    binding.setValue(facesContext, component);
+                }
+
+                if (component instanceof UIInput) {
+                    ((UIInput) component).setValid(true);
+                }
+
+                recursivelyHandleComponentReferencesAndSetValid(facesContext,
+                        component);
+            }
+        }
+    }
+
+    /**
+     * This is all a hack to work around a spec-bug which will be fixed in
+     * JSF2.0
+     * 
+     * @param parent
+     * @return true if this component is bindingAware (e.g. aliasBean)
+     */
+    private static Method getBindingMethod(UIComponent parent) {
+        Class[] clazzes = parent.getClass().getInterfaces();
+
+        for (int i = 0; i < clazzes.length; i++) {
+            Class clazz = clazzes[i];
+
+            if (clazz.getName().indexOf("BindingAware") != -1) {
+                try {
+                    return parent.getClass().getMethod("handleBindings",
+                            new Class[] {});
+                } catch (NoSuchMethodException e) {
+                    // return
+                }
+            }
+        }
 
-               return null;
-       }
+        return null;
+    }
 }

Modified: 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java
URL: 
http://svn.apache.org/viewvc/struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java?rev=415877&r1=415876&r2=415877&view=diff
==============================================================================
--- 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java
 (original)
+++ 
struts/action2/trunk/core/src/main/java/org/apache/struts/action2/jsf/UpdateModelValuesInterceptor.java
 Tue Jun 20 19:52:25 2006
@@ -25,45 +25,50 @@
  * Updates the model values from the component tree
  */
 public class UpdateModelValuesInterceptor extends FacesInterceptor {
-       
-       private static final long serialVersionUID = 4011504235094251077L;
 
-       /**
+    private static final long serialVersionUID = 4011504235094251077L;
+
+    /**
      * Update Model Values (JSF.2.2.4)
      * 
-     * @param viewId The view id
-     * @param facesContext The faces context
+     * @param viewId
+     *            The view id
+     * @param facesContext
+     *            The faces context
      * @return true, if response is complete
      */
-       protected boolean executePhase(String viewId, FacesContext 
facesContext) throws FacesException
-    {
-           boolean skipFurtherProcessing = false;
-        if (log.isTraceEnabled()) log.trace("entering updateModelValues");
+    protected boolean executePhase(String viewId, FacesContext facesContext)
+            throws FacesException {
+        boolean skipFurtherProcessing = false;
+        if (log.isTraceEnabled())
+            log.trace("entering updateModelValues");
 
         informPhaseListenersBefore(facesContext, PhaseId.UPDATE_MODEL_VALUES);
 
-        if(isResponseComplete(facesContext, "updateModelValues", true))
-        {
-                       // have to return right away
-                       return true;
-        }
-        if(shouldRenderResponse(facesContext, "updateModelValues", true))
-        {
-                       skipFurtherProcessing = true;
+        try {
+            if (isResponseComplete(facesContext, "updateModelValues", true)) {
+                // have to return right away
+                return true;
+            }
+            if (shouldRenderResponse(facesContext, "updateModelValues", true)) 
{
+                skipFurtherProcessing = true;
+            }
+
+            facesContext.getViewRoot().processUpdates(facesContext);
+        } finally {
+            informPhaseListenersAfter(facesContext, 
PhaseId.UPDATE_MODEL_VALUES);
         }
 
-        facesContext.getViewRoot().processUpdates(facesContext);
-
-        informPhaseListenersAfter(facesContext, 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;
+        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;
         }
 
-        if (!skipFurtherProcessing && log.isTraceEnabled()) log.trace("exiting 
updateModelValues");
+        if (!skipFurtherProcessing && log.isTraceEnabled())
+            log.trace("exiting updateModelValues");
 
         return skipFurtherProcessing;
     }


Reply via email to