You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/03/13 19:29:51 UTC

svn commit: r1300273 - /myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java

Author: lu4242
Date: Tue Mar 13 18:29:51 2012
New Revision: 1300273

URL: http://svn.apache.org/viewvc?rev=1300273&view=rev
Log:
MYFACES-3199 Handling AbortProcessingException is unconsistent (catch other Exception instance (non APE) ,publish them as ExceptionQueuedEvent and short-circuit broadcast to ensure source component available within exceptionQueuedEventContext.getComponent() ) (Thanks to Martin Koci for provide this patch)

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1300273&r1=1300272&r2=1300273&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Tue Mar 13 18:29:51 2012
@@ -272,14 +272,22 @@ public class UIViewRoot extends UICompon
         do
         {
             // First broadcast events that have been queued for PhaseId.ANY_PHASE.
-            _broadcastAll(context, events.getAnyPhase(), eventsAborted);
+            boolean noUnexpectedException = _broadcastAll(context, events.getAnyPhase(), eventsAborted);
+            if (!noUnexpectedException)
+            {
+                return;
+            }
             List<FacesEvent> eventsOnPhase = events.getOnPhase();
             if (!eventsAborted.isEmpty())
             {
                 eventsOnPhase.removeAll(eventsAborted);
                 eventsAborted.clear();
             }
-            _broadcastAll(context, eventsOnPhase, eventsAborted);
+            noUnexpectedException = _broadcastAll(context, eventsOnPhase, eventsAborted);
+            if (!noUnexpectedException)
+            {
+                return;
+            }
 
             events = _getEvents(phaseId);
             loops++;
@@ -986,10 +994,12 @@ public class UIViewRoot extends UICompon
      *
      * @param context the current JSF context
      * @param events the events to broadcast
+     * @return 
      *
-     * @return <code>true</code> if the broadcast was completed without abortion, <code>false</code> otherwise
+     * @return <code>true</code> if the broadcast was completed without unexpected abortion/exception,
+     *  <code>false</code> otherwise
      */
-    private void _broadcastAll(FacesContext context,
+    private boolean _broadcastAll(FacesContext context,
                                List<? extends FacesEvent> events,
                                Collection<FacesEvent> eventsAborted)
     {
@@ -1012,15 +1022,39 @@ public class UIViewRoot extends UICompon
                 // Actual event broadcasting
                 source.broadcast(event);
             }
-            catch (AbortProcessingException e)
+            catch (Exception e)
             {
+                // for any other exception publish ExceptionQueuedEvent
                 // publish the Exception to be handled by the ExceptionHandler
+                // to publish or to not publish APE? That is the question : MYFACES-3199 
                 ExceptionQueuedEventContext exceptionContext 
                         = new ExceptionQueuedEventContext(context, e, source, context.getCurrentPhaseId());
                 context.getApplication().publishEvent(context, ExceptionQueuedEvent.class, exceptionContext);
+
+                Throwable cause = e;
+                AbortProcessingException ape = null;
+                do
+                {
+                    if (cause != null && cause instanceof AbortProcessingException)
+                    {
+                        ape = (AbortProcessingException) cause;
+                        break;
+                    }
+                    cause = cause.getCause();
+                }
+                while (cause != null);
                 
-                // Abortion
-                eventsAborted.add(event);
+                if (ape != null)
+                {
+                    // APE found,  abortion for this event only
+                    eventsAborted.add(event);
+                    return true;
+                }
+                else
+                {
+                    // We can't continue broadcast processing if other exception is thrown:
+                    return false;
+                }
             }
             finally
             {
@@ -1032,7 +1066,7 @@ public class UIViewRoot extends UICompon
                 }
             }
         }
-
+        return true;
     }
 
     private void clearEvents()