myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lu4...@apache.org
Subject svn commit: r891426 - in /myfaces/core/trunk: api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java
Date Wed, 16 Dec 2009 21:12:09 GMT
Author: lu4242
Date: Wed Dec 16 21:12:08 2009
New Revision: 891426

URL: http://svn.apache.org/viewvc?rev=891426&view=rev
Log:
MYFACES-2459 PreJsf2ExceptionHandlerImpl not correct (thanks to Jakob Korherr for this patch)

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java?rev=891426&r1=891425&r2=891426&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java
(original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/webapp/PreJsf2ExceptionHandlerFactory.java
Wed Dec 16 21:12:08 2009
@@ -26,6 +26,9 @@
 
 import javax.el.ELException;
 import javax.faces.FacesException;
+import javax.faces.application.FacesMessage;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UpdateModelException;
 import javax.faces.context.ExceptionHandler;
 import javax.faces.context.ExceptionHandlerFactory;
 import javax.faces.event.AbortProcessingException;
@@ -63,26 +66,37 @@
         return exceptionHandler;
     }
     
-    /*
-     * Here we're copying org.apache.myfaces.context.ExceptionHandlerImpl and tweaking the
handle() method.
-     * This is really ugly, but I think we have to do this due to the fact that PreJsf2ExceptionHandlerFactory
-     * can be declared directly as an exception handler factory, so it's not as if we can
make the methods
-     * in the factory abstract and have a concrete impl in the impl project (and therefore
be able to
-     * extend ExceptionHandlerImpl).  If this is not the case, please change accordingly.
-     */
-    
     private static class PreJsf2ExceptionHandlerImpl extends ExceptionHandler
     {
+        /*
+         * PLEASE NOTE!!!
+         * This is a copy of the ExceptionHandler implementation of myfaces-impl
+         * (org.apache.myfaces.context.ExceptionHandlerImpl), only handle() differs a bit.
+         * Any changes made here should also be applied to ExceptionHandlerImpl in the right
way.
+         * 
+         * This is really ugly, but I think we have to do this due to the fact that PreJsf2ExceptionHandlerFactory
+         * can be declared directly as an exception handler factory, so it's not as if we
can make the methods
+         * in the factory abstract and have a concrete impl in the impl project (and therefore
be able to
+         * extend ExceptionHandlerImpl).  If this is not the case, please change accordingly.
+         */
+        
+        private static final Logger log = Logger.getLogger(PreJsf2ExceptionHandlerImpl.class.getName());
+        
         private Queue<ExceptionQueuedEvent> handled;
         private Queue<ExceptionQueuedEvent> unhandled;
+        private ExceptionQueuedEvent handledAndThrown;
 
+        public PreJsf2ExceptionHandlerImpl()
+        {
+        }
+        
         /**
          * {@inheritDoc}
          */
         @Override
         public ExceptionQueuedEvent getHandledExceptionQueuedEvent()
         {
-            return handled == null ? null : handled.poll();
+            return handledAndThrown;
         }
 
         /**
@@ -130,6 +144,12 @@
 
         /**
          * {@inheritDoc}
+         * 
+         * Differs from ExceptionHandlerImpl.handle() in two points:
+         *  - Any exceptions thrown before or after phase execution will be logged and swallowed.
+         *  - If the Exception is an instance of UpdateModelException, extract the FacesMessage
from the UpdateModelException.
+         *    Log a SEVERE message to the log and queue the FacesMessage on the FacesContext,
using the clientId of the source
+         *    component in a call to FacesContext.addMessage(java.lang.String, javax.faces.application.FacesMessage).
          */
         @Override
         public void handle() throws FacesException
@@ -141,37 +161,85 @@
                     handled = new LinkedList<ExceptionQueuedEvent>();
                 }
                 
+                FacesException toThrow = null;
+                
                 do
                 {
                     // For each ExceptionEvent in the list
                     
-                    // The implementation must also ensure that subsequent calls to getUnhandledExceptionEvents()

-                    // do not include that ExceptionEvent instance
-                    ExceptionQueuedEvent event = unhandled.remove();
-                    
-                    // call its getContext() method
-                    ExceptionQueuedEventContext context = event.getContext();
-                    
-                    // and call getException() on the returned result
-                    Throwable exception = context.getException();
-                    
-                    // Upon encountering the first such Exception that is not an instance
of
-                    // javax.faces.event.AbortProcessingException
-                    if (!shouldSkip(exception))
+                    // get the event to handle
+                    ExceptionQueuedEvent event = unhandled.peek();
+                    try
                     {
-                        // the corresponding ExceptionEvent must be set so that a subsequent
call to 
-                        // getHandledExceptionEvent() or getHandledExceptionEvents() returns
that 
-                        // ExceptionEvent instance. 
-                        // Should be ok to clear since this if never executed more than once
per handle() calls
-                        handled.clear();
-                        handled.add(event);
+                        // call its getContext() method
+                        ExceptionQueuedEventContext context = event.getContext();
                         
-                        // According to the spec, just need to log and swallow the exceptions.
-                        // TODO: better message?
-                        
-                        log.log(Level.SEVERE, "Exception encountered", exception);
+                        // and call getException() on the returned result
+                        Throwable exception = context.getException();
+
+                        // UpdateModelException needs special treatment here
+                        if (exception instanceof UpdateModelException)
+                        {
+                            FacesMessage message = ((UpdateModelException) exception).getFacesMessage();
+                            // Log a SEVERE message to the log
+                            log.log(Level.SEVERE, message.getSummary(), exception.getCause());
+                            // queue the FacesMessage on the FacesContext
+                            UIComponent component = context.getComponent();
+                            String clientId = null;
+                            if (component != null)
+                            {
+                                clientId = component.getClientId(context.getContext());
+                            }
+                            context.getContext().addMessage(clientId, message);
+                        }
+                        else if (!shouldSkip(exception) && !context.inBeforePhase()
&& !context.inAfterPhase())
+                        {
+                            // set handledAndThrown so that getHandledExceptionQueuedEvent()
returns this event
+                            handledAndThrown = event;
+                            
+                            // Re-wrap toThrow in a ServletException or (PortletException,
if in a portlet environment) 
+                            // and throw it
+                            // FIXME: The spec says to NOT use a FacesException to propagate
the exception, but I see
+                            //        no other way as ServletException is not a RuntimeException
+                            toThrow = wrap(getRethrownException(exception));
+                            break;
+                        }
+                        else
+                        {
+                            // Testing mojarra it logs a message and the exception
+                            // however, this behaviour is not mentioned in the spec
+                            log.log(Level.SEVERE, exception.getClass().getName() + " occured
while processing " +
+                                    (context.inBeforePhase() ? "beforePhase() of " : 
+                                            (context.inAfterPhase() ? "afterPhase() of "
: "")) + 
+                                    "phase " + context.getPhaseId() + ": " +
+                                    "UIComponent-ClientId=" + 
+                                    (context.getComponent() != null ? 
+                                            context.getComponent().getClientId(context.getContext())
: "") + ", " +
+                                    "Message=" + exception.getMessage());
+                            
+                            log.log(Level.SEVERE, exception.getMessage(), exception);
+                        }
+                    }
+                    catch (Throwable t)
+                    {
+                        // A FacesException must be thrown if a problem occurs while performing
+                        // the algorithm to handle the exception
+                        throw new FacesException("Could not perform the algorithm to handle
the Exception", t);
+                    }
+                    finally
+                    {
+                        // if we will throw the Exception or if we just logged it,
+                        // we handled it in either way --> add to handled
+                        handled.add(event);
+                        unhandled.remove(event);
                     }
                 } while (!unhandled.isEmpty());
+                
+                // do we have to throw an Exception?
+                if (toThrow != null)
+                {
+                    throw toThrow;
+                }
             }
         }
 
@@ -211,11 +279,13 @@
             return toRethrow;
         }
         
-        protected Throwable wrap(Throwable exception)
+        protected FacesException wrap(Throwable exception)
         {
-            // TODO: REPORT This method should be abstract and implemented by a Portlet or
Servlet version 
-            //       instance wrapping to either ServletException or PortletException
-            return exception;
+            if (exception instanceof FacesException)
+            {
+                return (FacesException) exception;
+            }
+            return new FacesException(exception);
         }
         
         protected boolean shouldSkip(Throwable exception)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java?rev=891426&r1=891425&r2=891426&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java
(original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/ExceptionHandlerImpl.java
Wed Dec 16 21:12:08 2009
@@ -42,6 +42,13 @@
  */
 public class ExceptionHandlerImpl extends ExceptionHandler
 {
+    /*
+     * PLEASE NOTE!!!
+     * javax.faces.webapp.PreJsf2ExceptionHandlerFactory uses most parts of this implementation
+     * for its private static inner class, only the handle method differs a bit.
+     * Thus, any changes made here should also be applied to PreJsf2ExceptionHandlerFactory
+     * in the right way (you can copy everything except handle(), this method needs special
treatment).
+     */
     
     private static final Logger log = Logger.getLogger(ExceptionHandlerImpl.class.getName());
     
@@ -159,7 +166,7 @@
                                 "phase " + context.getPhaseId() + ": " +
                                 "UIComponent-ClientId=" + 
                                 (context.getComponent() != null ? 
-                                        context.getComponent().getClientId() : "") + ", "
+
+                                        context.getComponent().getClientId(context.getContext())
: "") + ", " +
                                 "Message=" + exception.getMessage());
                         
                         log.log(Level.SEVERE, exception.getMessage(), exception);
@@ -181,7 +188,7 @@
                 }
             } while (!unhandled.isEmpty());
             
-            // do we have to throw a Exception?
+            // do we have to throw an Exception?
             if (toThrow != null)
             {
                 throw toThrow;



Mime
View raw message