Author: ivaynberg
Date: Fri Nov 19 20:31:29 2010
New Revision: 1037011

URL: http://svn.apache.org/viewvc?rev=1037011&view=rev
Log:
allow request cycle listeners to return a request handler from onexception

Modified:
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/DefaultExceptionMapper.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/AbstractRequestCycleListener.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/IRequestCycleListener.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycleListenerCollection.java
    
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/cycle/RequestCycleListenerTest.java

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/DefaultExceptionMapper.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/DefaultExceptionMapper.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/DefaultExceptionMapper.java 
(original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/DefaultExceptionMapper.java 
Fri Nov 19 20:31:29 2010
@@ -28,7 +28,7 @@ import org.apache.wicket.request.handler
 import org.apache.wicket.request.handler.PageProvider;
 import org.apache.wicket.request.handler.RenderPageRequestHandler;
 import org.apache.wicket.request.http.WebRequest;
-import org.apache.wicket.request.http.handler.ErrorCodeResponseHandler;
+import org.apache.wicket.request.http.handler.ErrorCodeRequestHandler;
 import org.apache.wicket.request.mapper.StalePageException;
 import org.apache.wicket.settings.IExceptionSettings;
 import 
org.apache.wicket.settings.IExceptionSettings.UnexpectedExceptionDisplay;
@@ -55,7 +55,7 @@ public class DefaultExceptionMapper impl
                        // hmmm, we were already handling an exception! give up
                        logger.error("unexpected exception when handling 
another exception: " + e.getMessage(),
                                e);
-                       return new ErrorCodeResponseHandler(500);
+                       return new ErrorCodeRequestHandler(500);
                }
        }
 
@@ -69,7 +69,7 @@ public class DefaultExceptionMapper impl
                        switch 
(application.getExceptionSettings().getAjaxErrorHandlingStrategy())
                        {
                                case INVOKE_FAILURE_HANDLER :
-                                       return new 
ErrorCodeResponseHandler(500);
+                                       return new ErrorCodeRequestHandler(500);
                        }
                }
 

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/AbstractRequestCycleListener.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/AbstractRequestCycleListener.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/AbstractRequestCycleListener.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/AbstractRequestCycleListener.java
 Fri Nov 19 20:31:29 2010
@@ -16,6 +16,8 @@
  */
 package org.apache.wicket.request.cycle;
 
+import org.apache.wicket.request.IRequestHandler;
+
 public abstract class AbstractRequestCycleListener implements 
IRequestCycleListener
 {
        public void onBeginRequest(final RequestCycle cycle)
@@ -30,7 +32,8 @@ public abstract class AbstractRequestCyc
        {
        }
 
-       public void onException(final RequestCycle cycle, Exception ex)
+       public IRequestHandler onException(final RequestCycle cycle, Exception 
ex)
        {
+               return null;
        }
 }

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/IRequestCycleListener.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/IRequestCycleListener.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/IRequestCycleListener.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/IRequestCycleListener.java
 Fri Nov 19 20:31:29 2010
@@ -17,6 +17,7 @@
 package org.apache.wicket.request.cycle;
 
 import org.apache.wicket.Application;
+import org.apache.wicket.request.IRequestHandler;
 
 /**
  * A callback interface for various methods in the request cycle. If you are 
creating a framework
@@ -63,9 +64,12 @@ public interface IRequestCycleListener
         * 
         * @param cycle
         * 
+        * @return request handler that will be exectued or {...@code null} if 
none. If a request handler
+        *         is returned, it will override any configured exception mapper
+        * 
         * @param ex
         *            the exception that was passed in to
         *            {...@link RequestCycle#handleException(Exception)}
         */
-       void onException(RequestCycle cycle, Exception ex);
+       IRequestHandler onException(RequestCycle cycle, Exception ex);
 }
\ No newline at end of file

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycle.java
 Fri Nov 19 20:31:29 2010
@@ -290,7 +290,11 @@ public class RequestCycle extends Reques
         */
        protected IRequestHandler handleException(final Exception e)
        {
-               listeners.onException(this, e);
+               IRequestHandler handler = listeners.onException(this, e);
+               if (handler != null)
+               {
+                       return handler;
+               }
                return exceptionMapper.map(e);
        }
 

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycleListenerCollection.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycleListenerCollection.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycleListenerCollection.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/request/cycle/RequestCycleListenerCollection.java
 Fri Nov 19 20:31:29 2010
@@ -16,6 +16,11 @@
  */
 package org.apache.wicket.request.cycle;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.IRequestHandler;
 import org.apache.wicket.util.listener.ListenerCollection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,16 +53,35 @@ public class RequestCycleListenerCollect
                });
        }
 
-       public void onException(final RequestCycle cycle, final Exception ex)
+       public IRequestHandler onException(final RequestCycle cycle, final 
Exception ex)
        {
+               final List<IRequestHandler> handlers = new 
ArrayList<IRequestHandler>();
+
                notify(new INotifier<IRequestCycleListener>()
                {
                        public void notify(IRequestCycleListener listener)
                        {
-                               listener.onException(cycle, ex);
+                               IRequestHandler handler = 
listener.onException(cycle, ex);
+                               if (handler != null)
+                               {
+                                       handlers.add(handler);
+                               }
                        }
                });
 
+               if (handlers.isEmpty())
+               {
+                       return null;
+               }
+
+               if (handlers.size() > 1)
+               {
+                       throw new WicketRuntimeException(
+                               "More than one request cycle listener returned 
a request handler while handling the exception.",
+                               ex);
+               }
+
+               return handlers.get(0);
        }
 
        public void onDetach(final RequestCycle cycle)

Modified: 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/cycle/RequestCycleListenerTest.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/test/java/org/apache/wicket/request/cycle/RequestCycleListenerTest.java?rev=1037011&r1=1037010&r2=1037011&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/cycle/RequestCycleListenerTest.java
 (original)
+++ 
wicket/trunk/wicket/src/test/java/org/apache/wicket/request/cycle/RequestCycleListenerTest.java
 Fri Nov 19 20:31:29 2010
@@ -18,6 +18,7 @@ package org.apache.wicket.request.cycle;
 
 import org.apache.wicket.Application;
 import org.apache.wicket.ThreadContext;
+import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.mock.MockWebRequest;
 import org.apache.wicket.request.IExceptionMapper;
 import org.apache.wicket.request.IRequestCycle;
@@ -40,11 +41,14 @@ public class RequestCycleListenerTest ex
 
        private IRequestHandler handler;
 
+       private int errorCode;
+
        @Override
        protected void setUp() throws Exception
        {
                super.setUp();
                ThreadContext.setApplication(new DummyApplication());
+               errorCode = 0;
        }
 
        @Override
@@ -167,6 +171,32 @@ public class RequestCycleListenerTest ex
        /**
         * @throws Exception
         */
+       public void testExceptionRequestHandlers() throws Exception
+       {
+               Application.get().getRequestCycleListeners().add(new 
ErrorCodeListener(401));
+
+               RequestCycle cycle = newRequestCycle(true);
+               cycle.processRequestAndDetach();
+
+               assertEquals(401, errorCode);
+
+               // two listeners that return a request handler should cause an 
exception
+               Application.get().getRequestCycleListeners().add(new 
ErrorCodeListener(401));
+               cycle = newRequestCycle(true);
+               try
+               {
+                       cycle.processRequestAndDetach();
+                       fail("expected an exception because two request cycle 
listeners returned a request handler");
+               }
+               catch (WicketRuntimeException e)
+               {
+                       // expected
+               }
+       }
+
+       /**
+        * @throws Exception
+        */
        public void testExceptionHandingInOnDetach() throws Exception
        {
                // this test is a little flaky because it depends on the 
ordering of listeners which is not
@@ -200,11 +230,40 @@ public class RequestCycleListenerTest ex
                assertEquals(detachesnotified, this.detachesnotified);
        }
 
+       private class ErrorCodeListener extends AbstractRequestCycleListener
+       {
+               private final int code;
+
+               public ErrorCodeListener(int code)
+               {
+                       this.code = code;
+               }
+
+               @Override
+               public IRequestHandler onException(final RequestCycle cycle, 
Exception ex)
+               {
+                       return new IRequestHandler()
+                       {
+                               public void respond(IRequestCycle requestCycle)
+                               {
+                                       errorCode = code;
+                               }
+
+                               public void detach(IRequestCycle requestCycle)
+                               {
+                               }
+
+                       };
+               }
+       }
+
+
        private class IncrementingListener implements IRequestCycleListener
        {
-               public void onException(final RequestCycle cycle, Exception ex)
+               public IRequestHandler onException(final RequestCycle cycle, 
Exception ex)
                {
                        exceptions++;
+                       return null;
                }
 
                public void onEndRequest(final RequestCycle cycle)


Reply via email to