View Javadoc

1   /*
2    * $Id: TestExceptionStrategy.java 22772 2011-08-27 15:20:15Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.tck.testmodels.mule;
12  
13  import org.mule.api.MuleEvent;
14  import org.mule.api.exception.MessagingExceptionHandler;
15  import org.mule.api.exception.RollbackSourceCallback;
16  import org.mule.api.exception.SystemExceptionHandler;
17  import org.mule.exception.AbstractExceptionStrategy;
18  
19  import java.util.ArrayList;
20  import java.util.LinkedList;
21  import java.util.List;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  /**
27   * <code>TestExceptionStrategy</code> is used by the Mule test cases as a direct
28   * replacement of the {@link org.mule.exception.AbstractMessagingExceptionStrategy}.
29   * This is used to test that overriding the default Exception strategy works.
30   */
31  public class TestExceptionStrategy extends AbstractExceptionStrategy implements MessagingExceptionHandler, SystemExceptionHandler
32  {
33      /**
34       * logger used by this class
35       */
36      protected final Log logger = LogFactory.getLog(getClass());
37  
38      /**
39       * This is the lock that protect both the storage of {@link #callback} and
40       * modifications of {@link #unhandled}.
41       */
42      private Object callbackLock = new Object();
43  
44      // @GuardedBy("callbackLock")
45      private ExceptionCallback callback;
46      // @GuardedBy("callbackLock")
47      private List<Exception> unhandled = new LinkedList<Exception>();
48  
49      private volatile String testProperty;
50  
51      public TestExceptionStrategy()
52      {
53          super(null);
54      }
55      
56      public String getTestProperty()
57      {
58          return testProperty;
59      }
60  
61      public void setTestProperty(String testProperty)
62      {
63          this.testProperty = testProperty;
64      }
65  
66      public MuleEvent handleException(Exception exception, MuleEvent event, RollbackSourceCallback rollbackMethod)
67      {
68          ExceptionCallback callback = null;
69          synchronized (callbackLock)
70          {
71              if (this.callback != null)
72              {
73                  callback = this.callback;
74              }
75              else
76              {
77                  unhandled.add(exception);
78              }
79          }
80          // It is important that the call to the callback is done outside
81          // synchronization since we don't control that code and
82          // we could have liveness problems.
83          logger.info("Handling exception: " + exception.getClass().getName());
84          if (callback != null)
85          {
86              logger.info("Exception caught on TestExceptionStrategy and was sent to callback.", exception);
87              callback.onException(exception);
88          }
89          else
90          {
91              logger.info("Exception caught on TestExceptionStrategy but there was no callback set.", exception);
92          }
93          return event;
94      }
95  
96      public MuleEvent handleException(Exception exception, MuleEvent event)
97      {
98          return handleException(exception, event, null);
99      }
100 
101     public void handleException(Exception exception, RollbackSourceCallback rollbackMethod)
102     {
103         handleException(exception, null, rollbackMethod);
104     }
105 
106     public void handleException(Exception exception)
107     {
108         handleException(exception, null, null);
109     }
110 
111     public interface ExceptionCallback
112     {
113         void onException(Throwable t);
114     }
115 
116     public void setExceptionCallback(ExceptionCallback exceptionCallback)
117     {
118         synchronized (callbackLock)
119         {
120             this.callback = exceptionCallback;
121         }
122         processUnhandled();
123     }
124 
125     protected void processUnhandled()
126     {
127         List<Exception> unhandledCopies = null;
128         ExceptionCallback callback = null;
129         synchronized (callbackLock)
130         {
131             if (this.callback != null)
132             {
133                 callback = this.callback;
134                 unhandledCopies = new ArrayList<Exception>(unhandled);
135                 unhandled.clear();
136             }
137         }
138         // It is important that the call to the callback is done outside
139         // synchronization since we don't control that code and
140         // we could have liveness problems.
141         if (callback != null && unhandledCopies != null)
142         {
143             for (Exception exception : unhandledCopies)
144             {
145                 logger.info("Handling exception after setting the callback.", exception);
146                 callback.onException(exception);
147             }
148         }
149     }
150 }