KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > tm > TransactionLocal


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.tm;
23
24 import javax.naming.InitialContext JavaDoc;
25 import javax.naming.NamingException JavaDoc;
26 import javax.transaction.SystemException JavaDoc;
27 import javax.transaction.Transaction JavaDoc;
28 import javax.transaction.TransactionManager JavaDoc;
29
30 /**
31  * A TransactionLocal is similar to ThreadLocal except it is keyed on the
32  * Transactions. A transaction local variable is cleared after the transaction
33  * completes.
34  *
35  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
36  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
37  * @version $Revision: 37459 $
38  */

39 public class TransactionLocal
40 {
41
42    /**
43     * To simplify null values handling in the preloaded data pool we use
44     * this value instead of 'null'
45     */

46    private static final Object JavaDoc NULL_VALUE = new Object JavaDoc();
47
48    /**
49     * The transaction manager is maintained by the system and
50     * manges the assocation of transaction to threads.
51     */

52    protected final TransactionManager JavaDoc transactionManager;
53
54    /**
55     * The delegate
56     */

57    protected TransactionLocalDelegate delegate;
58
59    /**
60     * Creates a thread local variable.
61     * @throws IllegalStateException if there is no system transaction manager
62     */

63    public TransactionLocal()
64    {
65       try
66       {
67          InitialContext JavaDoc context = new InitialContext JavaDoc();
68          transactionManager = (TransactionManager JavaDoc) context.lookup("java:/TransactionManager");
69       }
70       catch(NamingException JavaDoc e)
71       {
72          throw new IllegalStateException JavaDoc(
73             "An error occured while looking up the transaction manager: " + e
74          );
75       }
76       initDelegate();
77    }
78
79    /**
80     * Creates a transaction local variable. Using the given transaction manager
81     *
82     * @param tm the transaction manager
83     */

84    public TransactionLocal(TransactionManager JavaDoc tm)
85    {
86       if (tm == null)
87          throw new IllegalArgumentException JavaDoc("Null transaction manager");
88       this.transactionManager = tm;
89       initDelegate();
90    }
91
92    /**
93     * Lock the TransactionLocal using the current transaction<p>
94     *
95     * WARN: The current implemention just "locks the transactions"
96     *
97     * @throws IllegalStateException if the transaction is not active
98     * @throws InterruptedException if the thread is interrupted
99     */

100    public void lock() throws InterruptedException JavaDoc
101    {
102       lock(getTransaction());
103    }
104       
105    /**
106     * Lock the TransactionLocal using the provided transaction<p>
107     *
108     * WARN: The current implemention just "locks the transactions"
109     *
110     * @param transaction the transaction
111     * @throws IllegalStateException if the transaction is not active
112     * @throws InterruptedException if the thread is interrupted
113     */

114    public void lock(Transaction JavaDoc transaction) throws InterruptedException JavaDoc
115    {
116       // ignore when there is no transaction
117
if (transaction == null)
118          return;
119       
120       delegate.lock(this, transaction);
121    }
122
123    /**
124     * Unlock the TransactionLocal using the current transaction
125     */

126    public void unlock()
127    {
128       unlock(getTransaction());
129    }
130    
131    /**
132     * Unlock the ThreadLocal using the provided transaction
133     *
134     * @param transaction the transaction
135     */

136    public void unlock(Transaction JavaDoc transaction)
137    {
138       // ignore when there is no transaction
139
if (transaction == null)
140          return;
141
142       delegate.unlock(this, transaction);
143    }
144
145    /**
146     * Returns the initial value for this thransaction local. This method
147     * will be called once per accessing transaction for each TransactionLocal,
148     * the first time each transaction accesses the variable with get or set.
149     * If the programmer desires TransactionLocal variables to be initialized to
150     * some value other than null, TransactionLocal must be subclassed, and this
151     * method overridden. Typically, an anonymous inner class will be used.
152     * Typical implementations of initialValue will call an appropriate
153     * constructor and return the newly constructed object.
154     *
155     * @return the initial value for this TransactionLocal
156     */

157    protected Object JavaDoc initialValue()
158    {
159       return null;
160    }
161
162
163    /**
164     * get the transaction local value.
165     */

166    protected Object JavaDoc getValue(Transaction JavaDoc tx)
167    {
168       return delegate.getValue(this, tx);
169    }
170
171    /**
172     * put the value in the TransactionImpl map
173     */

174    protected void storeValue(Transaction JavaDoc tx, Object JavaDoc value)
175    {
176       delegate.storeValue(this, tx, value);
177    }
178
179    /**
180     * does Transaction contain object?
181     */

182    protected boolean containsValue(Transaction JavaDoc tx)
183    {
184       return delegate.containsValue(this, tx);
185    }
186
187    /**
188     * Returns the value of this TransactionLocal variable associated with the
189     * thread context transaction. Creates and initializes the copy if this is
190     * the first time the method is called in a transaction.
191     *
192     * @return the value of this TransactionLocal
193     */

194    public Object JavaDoc get()
195    {
196       return get(getTransaction());
197    }
198
199
200    /**
201     * Returns the value of this TransactionLocal variable associated with the
202     * specified transaction. Creates and initializes the copy if this is the
203     * first time the method is called in a transaction.
204     *
205     * @param transaction the transaction for which the variable it to
206     * be retrieved
207     * @return the value of this TransactionLocal
208     * @throws IllegalStateException if an error occures while registering
209     * a synchronization callback with the transaction
210     */

211    public Object JavaDoc get(Transaction JavaDoc transaction)
212    {
213       if (transaction == null) return initialValue();
214
215       Object JavaDoc value = getValue(transaction);
216
217       // is we didn't get a value initalize this object with initialValue()
218
if(value == null)
219       {
220          // get the initial value
221
value = initialValue();
222          
223          // if value is null replace it with the null value standin
224
if(value == null)
225          {
226             value = NULL_VALUE;
227          }
228
229          // store the value
230
storeValue(transaction, value);
231       }
232
233       // if the value is the null standin return null
234
if(value == NULL_VALUE)
235       {
236          return null;
237       }
238
239       // finall return the value
240
return value;
241    }
242
243    /**
244     * Sets the value of this TransactionLocal variable associtated with the
245     * thread context transaction. This is only used to change the value from
246     * the one assigned by the initialValue method, and many applications will
247     * have no need for this functionality.
248     *
249     * @param value the value to be associated with the thread context
250     * transactions's TransactionLocal
251     */

252    public void set(Object JavaDoc value)
253    {
254       set(getTransaction(), value);
255    }
256
257    /**
258     * Sets the value of this TransactionLocal variable associtated with the
259     * specified transaction. This is only used to change the value from
260     * the one assigned by the initialValue method, and many applications will
261     * have no need for this functionality.
262     *
263     * @param transaction the transaction for which the value will be set
264     * @param value the value to be associated with the thread context
265     * transactions's TransactionLocal
266     */

267    public void set(Transaction JavaDoc transaction, Object JavaDoc value)
268    {
269       if (transaction == null) throw new IllegalStateException JavaDoc("there is no transaction");
270       // If this transaction is unknown, register for synchroniztion callback,
271
// and call initialValue to give subclasses a chance to do some
272
// initialization.
273
if(!containsValue(transaction))
274       {
275          initialValue();
276       }
277
278       // if value is null replace it with the null value standin
279
if(value == null)
280       {
281          value = NULL_VALUE;
282       }
283
284       // finally store the value
285
storeValue(transaction, value);
286    }
287    
288    public Transaction JavaDoc getTransaction()
289    {
290       try
291       {
292          return transactionManager.getTransaction();
293       }
294       catch(SystemException JavaDoc e)
295       {
296          throw new IllegalStateException JavaDoc("An error occured while getting the " +
297                "transaction associated with the current thread: " + e);
298       }
299    }
300
301    /**
302     * Initialise the delegate
303     */

304    protected void initDelegate()
305    {
306       if (transactionManager instanceof TransactionLocalDelegate)
307          delegate = (TransactionLocalDelegate) transactionManager;
308       else
309          delegate = new TransactionLocalDelegateImpl(transactionManager);
310    }
311 }
312
Popular Tags