View Javadoc

1   /*
2    * $Id: MuleTransactionConfig.java 23054 2011-10-02 05:31:18Z dirk.olmes $
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.transaction;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.MuleRuntimeException;
15  import org.mule.api.context.MuleContextAware;
16  import org.mule.api.transaction.Transaction;
17  import org.mule.api.transaction.TransactionConfig;
18  import org.mule.api.transaction.TransactionFactory;
19  import org.mule.config.i18n.CoreMessages;
20  import org.mule.transaction.constraints.ConstraintFilter;
21  import org.mule.util.ClassUtils;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  /**
27   * <p/> <code>MuleTransactionConfig</code> defines transaction configuration for a
28   * transactional endpoint.
29   */
30  public class MuleTransactionConfig implements TransactionConfig, MuleContextAware
31  {
32      /**
33       * logger used by this class
34       */
35      protected static final Log logger = LogFactory.getLog(MuleTransactionConfig.class);
36  
37      public static final String ACTION_NONE_STRING = "NONE";
38      public static final String ACTION_ALWAYS_BEGIN_STRING = "ALWAYS_BEGIN";
39      public static final String ACTION_BEGIN_OR_JOIN_STRING = "BEGIN_OR_JOIN";
40      public static final String ACTION_ALWAYS_JOIN_STRING = "ALWAYS_JOIN";
41      public static final String ACTION_JOIN_IF_POSSIBLE_STRING = "JOIN_IF_POSSIBLE";
42      public static final String ACTION_NEVER_STRING = "NEVER";
43      public static final String ACTION_INDIFFERENT_STRING = "INDIFFERENT";
44  
45      private TransactionFactory factory;
46  
47      private byte action = ACTION_DEFAULT;
48  
49      private ConstraintFilter constraint = null;
50  
51      private Integer timeout;
52  
53      private boolean interactWithExternal = false;
54  
55      public MuleTransactionConfig()
56      {
57      }
58  
59      public MuleTransactionConfig(byte action)
60      {
61          this.action = action;
62      }
63  
64      public void setMuleContext(MuleContext context)
65      {
66          // override only if not set in config
67          if (this.timeout == null)
68          {
69              this.timeout = context.getConfiguration().getDefaultTransactionTimeout();
70          }
71      }
72  
73      public TransactionFactory getFactory()
74      {
75          return factory;
76      }
77  
78      public void setFactory(TransactionFactory factory)
79      {
80          if (factory == null)
81          {
82              throw new IllegalArgumentException("Transaction Factory cannot be null");
83          }
84          this.factory = factory;
85      }
86  
87      public byte getAction()
88      {
89          return action;
90      }
91  
92      public void setAction(byte action)
93      {
94          this.action = action;
95  
96      }
97  
98      public boolean isInteractWithExternal()
99      {
100         return interactWithExternal;
101     }
102 
103     public void setInteractWithExternal(boolean interactWithExternal)
104     {
105         this.interactWithExternal = interactWithExternal;
106     }
107 
108     public void setActionAsString(String action)
109     {
110         if (ACTION_ALWAYS_BEGIN_STRING.equals(action))
111         {
112             this.action = ACTION_ALWAYS_BEGIN;
113         }
114         else if (ACTION_BEGIN_OR_JOIN_STRING.equals(action))
115         {
116             this.action = ACTION_BEGIN_OR_JOIN;
117         }
118         else if (ACTION_ALWAYS_JOIN_STRING.equals(action))
119         {
120             this.action = ACTION_ALWAYS_JOIN;
121         }
122         else if (ACTION_JOIN_IF_POSSIBLE_STRING.equals(action))
123         {
124             this.action = ACTION_JOIN_IF_POSSIBLE;
125         }
126         else if (ACTION_NONE_STRING.equals(action))
127         {
128             this.action = ACTION_NONE;
129         }
130         else if (ACTION_NEVER_STRING.equals(action))
131         {
132             this.action = ACTION_NEVER;
133         }
134         else if (ACTION_INDIFFERENT_STRING.equals(action))
135         {
136             this.action = ACTION_INDIFFERENT;
137         }
138         else
139         {
140             throw new IllegalArgumentException("Action " + action + " is not recognised as a begin action.");
141         }
142     }
143 
144     public String getActionAsString()
145     {
146         switch (action)
147         {
148             case ACTION_ALWAYS_BEGIN:
149                 return ACTION_ALWAYS_BEGIN_STRING;
150             case ACTION_BEGIN_OR_JOIN:
151                 return ACTION_BEGIN_OR_JOIN_STRING; 
152             case ACTION_ALWAYS_JOIN:
153                 return ACTION_ALWAYS_JOIN_STRING;
154             case ACTION_JOIN_IF_POSSIBLE:
155                 return ACTION_JOIN_IF_POSSIBLE_STRING;
156             case ACTION_NONE:
157                 return ACTION_NONE_STRING;
158             case ACTION_INDIFFERENT:
159                 return ACTION_INDIFFERENT_STRING;
160             default :
161                 return ACTION_NEVER_STRING;
162         }
163     }
164 
165     /**
166      * Will the result, at the end of running the transaction template, be an active transaction?
167      */
168     public boolean isTransacted()
169     {
170         if (action == ACTION_NEVER || action == ACTION_NONE)
171         {
172             return false;
173         }
174         if (factory == null)
175         {
176             if (action != ACTION_INDIFFERENT)
177             {
178                 // TODO use TransactionException here? This causes API changes as TE is a checked exception ...
179                 throw new MuleRuntimeException(CoreMessages.transactionFactoryIsMandatory(getActionAsString()));
180             }
181 
182         }
183         else if (!factory.isTransacted())
184         {
185             return false;
186         }
187 
188         switch (action)
189         {
190             case ACTION_ALWAYS_BEGIN:
191             case ACTION_ALWAYS_JOIN:
192             case ACTION_BEGIN_OR_JOIN:
193                 return true;
194 
195             case ACTION_JOIN_IF_POSSIBLE:
196             case ACTION_INDIFFERENT:
197                 return TransactionCoordination.getInstance().getTransaction() != null;
198 
199             default:
200                 // should not happen
201                 return false;
202 
203         }
204     }
205     
206     public boolean isConfigured()
207     {
208         return factory != null;
209     }
210 
211     public ConstraintFilter getConstraint()
212     {
213         if (constraint == null)
214         {
215             return null;
216         }
217         try
218         {
219             return (ConstraintFilter) constraint.clone();
220         }
221         catch (CloneNotSupportedException e)
222         {
223             logger.fatal("Failed to clone ConstraintFilter: " + e.getMessage(), e);
224             return constraint;
225         }
226     }
227 
228     public void setConstraint(ConstraintFilter constraint)
229     {
230         this.constraint = constraint;
231     }
232 
233     public int getTimeout()
234     {
235         return timeout == null ? 0 : timeout;
236     }
237 
238     public void setTimeout(int timeout)
239     {
240         this.timeout = timeout;
241     }
242 
243     public String toString()
244     {
245         StringBuffer buf = new StringBuffer();
246         buf.append("Transaction{factory=")
247             .append(factory)
248             .append(", action=")
249             .append(getActionAsString())
250             .append(", timeout=")
251             .append(timeout == null ? 0 : timeout)
252             .append("}");
253         return buf.toString();
254     }
255     
256     public int hashCode()
257     {
258         return ClassUtils.hash(new Object[]{factory, action, constraint, timeout == null ? 0 : timeout});
259     }
260 
261     public boolean equals(Object obj)
262     {
263         if (this == obj) return true;
264         if (obj == null || getClass() != obj.getClass()) return false;
265 
266         final MuleTransactionConfig other = (MuleTransactionConfig) obj;
267         return ClassUtils.equal(factory, other.factory)
268                && ClassUtils.equal(action, other.action)
269                && ClassUtils.equal(constraint, other.constraint)
270                && ClassUtils.equal(timeout, other.timeout);
271 
272     }
273     
274 }