View Javadoc

1   /*
2    * $Id: TestExceptionStrategy.java 19396 2010-09-07 16:25:10Z epere4 $
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.SystemExceptionHandler;
15  import org.mule.exception.AbstractMessagingExceptionStrategy;
16  
17  import java.util.ArrayList;
18  import java.util.LinkedList;
19  import java.util.List;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  /**
25   * <code>TestExceptionStrategy</code> is used by the Mule test cases as a direct
26   * replacement of the {@link org.mule.exception.AbstractMessagingExceptionStrategy}.
27   * This is used to test that overriding the default Exception strategy works.
28   */
29  public class TestExceptionStrategy extends AbstractMessagingExceptionStrategy
30      implements SystemExceptionHandler
31  {
32      /**
33       * logger used by this class
34       */
35      protected final Log logger = LogFactory.getLog(getClass());
36  
37      /**
38       * This is the lock that protect both the storage of {@link #callback} and
39       * modifications of {@link #unhandled}.
40       */
41      private Object callbackLock = new Object();
42  
43      // @GuardedBy("callbackLock")
44      private ExceptionCallback callback;
45      // @GuardedBy("callbackLock")
46      private List<Exception> unhandled = new LinkedList<Exception>();
47  
48      private volatile String testProperty;
49  
50      public String getTestProperty()
51      {
52          return testProperty;
53      }
54  
55      public void setTestProperty(String testProperty)
56      {
57          this.testProperty = testProperty;
58      }
59  
60      @Override
61      public MuleEvent handleException(Exception exception, MuleEvent event)
62      {
63          ExceptionCallback callback = null;
64          synchronized (callbackLock)
65          {
66              if (this.callback != null)
67              {
68                  callback = this.callback;
69              }
70              else
71              {
72                  unhandled.add(exception);
73              }
74          }
75          // It is important that the call to the callback is done outside
76          // synchronization since we don't control that code and
77          // we could have liveness problems.
78          logger.info("Handling exception: " + exception.getClass().getName());
79          if (callback != null)
80          {
81              logger.info("Exception caught on TestExceptionStrategy and was sent to callback.", exception);
82              callback.onException(exception);
83          }
84          else
85          {
86              logger.info("Exception caught on TestExceptionStrategy but there was no callback set.", exception);
87          }
88          return event;
89      }
90  
91      public void handleException(Exception exception)
92      {
93          handleException(exception, null);
94      }
95  
96      public interface ExceptionCallback
97      {
98          void onException(Throwable t);
99      }
100 
101     public void setExceptionCallback(ExceptionCallback exceptionCallback)
102     {
103         synchronized (callbackLock)
104         {
105             this.callback = exceptionCallback;
106         }
107         processUnhandled();
108     }
109 
110     protected void processUnhandled()
111     {
112         List<Exception> unhandledCopies = null;
113         ExceptionCallback callback = null;
114         synchronized (callbackLock)
115         {
116             if (this.callback != null)
117             {
118                 callback = this.callback;
119                 unhandledCopies = new ArrayList<Exception>(unhandled);
120                 unhandled.clear();
121             }
122         }
123         // It is important that the call to the callback is done outside
124         // synchronization since we don't control that code and
125         // we could have liveness problems.
126         if (callback != null && unhandledCopies != null)
127         {
128             for (Exception exception : unhandledCopies)
129             {
130                 logger.info("Handling exception after setting the callback.", exception);
131                 callback.onException(exception);
132             }
133         }
134     }
135 }