KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > tm > iiop > client > IIOPClientUserTransaction


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.iiop.client;
23
24 import java.io.Serializable JavaDoc;
25
26 import javax.naming.NamingException JavaDoc;
27 import javax.naming.Reference JavaDoc;
28 import javax.naming.Referenceable JavaDoc;
29
30 import javax.transaction.HeuristicMixedException JavaDoc;
31 import javax.transaction.HeuristicRollbackException JavaDoc;
32 import javax.transaction.NotSupportedException JavaDoc;
33 import javax.transaction.RollbackException JavaDoc;
34 import javax.transaction.Status JavaDoc;
35 import javax.transaction.SystemException JavaDoc;
36 import javax.transaction.UserTransaction JavaDoc;
37
38 import org.omg.CORBA.BAD_INV_ORDER JavaDoc;
39 import org.omg.CORBA.NO_PERMISSION JavaDoc;
40 import org.omg.CORBA.OBJECT_NOT_EXIST JavaDoc;
41 import org.omg.CORBA.ORB JavaDoc;
42 import org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc;
43 import org.omg.CosNaming.NamingContextExt JavaDoc;
44 import org.omg.CosNaming.NamingContextExtHelper JavaDoc;
45 import org.omg.CosTransactions.Control;
46 import org.omg.CosTransactions.Coordinator;
47 import org.omg.CosTransactions.HeuristicMixed;
48 import org.omg.CosTransactions.HeuristicHazard;
49 import org.omg.CosTransactions.Inactive;
50 import org.omg.CosTransactions.NoTransaction;
51 import org.omg.CosTransactions.PropagationContext;
52 import org.omg.CosTransactions.Terminator;
53
54 import org.jboss.iiop.CorbaORB;
55 import org.jboss.tm.iiop.TransactionDesc;
56 import org.jboss.tm.iiop.TransactionFactoryExt;
57 import org.jboss.tm.iiop.TransactionFactoryExtHelper;
58 import org.jboss.tm.iiop.TxClientInterceptor;
59
60 /**
61  * The client-side UserTransaction implementation for RMI/IIOP clients.
62  * This will delegate all UserTransaction calls to the server.
63  *
64  * <em>Warning:</em> This is only for stand-alone RMI/IIOP clients that
65  * do not have their own transaction service. No local work is done in
66  * the context of transactions started here, only work done in beans
67  * at the server.
68  *
69  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
70  * @version $Revision: 37459 $
71  */

72 public class IIOPClientUserTransaction
73       implements UserTransaction JavaDoc,
74                  Referenceable JavaDoc,
75                  Serializable JavaDoc
76 {
77    // Static --------------------------------------------------------
78
static final long serialVersionUID = 6653800687253055416L;
79
80    /** Our singleton instance. */
81    private static IIOPClientUserTransaction singleton = null;
82
83    /** CORBA reference to the server's transaction factory. */
84    private static TransactionFactoryExt txFactory;
85
86    /** Transaction information associated with the current thread. */
87    private static ThreadLocal JavaDoc threadLocalData = new ThreadLocal JavaDoc() {
88          protected synchronized Object JavaDoc initialValue()
89          {
90             return new TransactionInfo(); // see nested class below
91
}
92       };
93  
94    // Nested class -------------------------------------------------
95

96    /**
97     * The <code>TransactionInfo</code> class holds transaction information
98     * associated with the current thread. The <code>threadLocalData</code>
99     * field contains an instance of this class. The field timeout applies
100     * to new transactions started by the current thread; its value is not
101     * necessarily equal to the time out of the currrent transaction. The
102     * three remaining fields refer to the currrent transaction.
103     */

104    private static class TransactionInfo
105    {
106       int timeout = 0; // for new transactions started by the current thread
107
Control control; // null if no current transaction
108
Coordinator coord; // null if no current transaction
109
Terminator JavaDoc term; // null if no current transaction
110
}
111
112    // Static accessors to thread-local data -------------------------
113

114    private static void setThreadLocalTimeout(int timeout)
115    {
116       ((TransactionInfo)threadLocalData.get()).timeout = timeout;
117    }
118
119    private static int getThreadLocalTimeout()
120    {
121       return ((TransactionInfo)threadLocalData.get()).timeout;
122    }
123    
124    private static void setThreadLocalControl(Control control)
125    {
126       ((TransactionInfo)threadLocalData.get()).control = control;
127    }
128
129    private static Control getThreadLocalControl()
130    {
131       return ((TransactionInfo)threadLocalData.get()).control;
132    }
133    
134    private static void setThreadLocalCoordinator(Coordinator coord)
135    {
136       ((TransactionInfo)threadLocalData.get()).coord = coord;
137    }
138
139    private static Coordinator getThreadLocalCoordinator()
140    {
141       return ((TransactionInfo)threadLocalData.get()).coord;
142    }
143    
144    private static void setThreadLocalTerminator(Terminator JavaDoc term)
145    {
146       ((TransactionInfo)threadLocalData.get()).term = term;
147    }
148
149    private static Terminator JavaDoc getThreadLocalTerminator()
150       throws NoTransaction
151    {
152       Terminator JavaDoc term = ((TransactionInfo)threadLocalData.get()).term;
153
154       if (term == null)
155          throw new NoTransaction();
156
157       return term;
158    }
159    
160    // Management of the transaction-thread association --------------
161

162    /**
163     * Auxiliary method that sets the current transaction.
164     */

165    private static void setCurrentTransaction(Control control,
166                                              PropagationContext pc)
167    {
168       setThreadLocalControl(control);
169       setThreadLocalCoordinator(pc.current.coord);
170       setThreadLocalTerminator(pc.current.term);
171       TxClientInterceptor.setOutgoingPropagationContext(pc);
172    }
173
174    /**
175     * Auxiliary method that unsets the current transaction.
176     */

177    private static void unsetCurrentTransaction()
178    {
179       setThreadLocalControl(null);
180       setThreadLocalCoordinator(null);
181       setThreadLocalTerminator(null);
182       TxClientInterceptor.unsetOutgoingPropagationContext();
183    }
184
185    // Other auxiliary (and static) methods -------------------------
186

187    /**
188     * Returns a CORBA reference to the TransactionFactory implemented by
189     * the JBoss server.
190     */

191    private static TransactionFactoryExt getTxFactory()
192    {
193       if (txFactory == null)
194       {
195          try
196          {
197             ORB JavaDoc orb = CorbaORB.getInstance();
198             org.omg.CORBA.Object JavaDoc obj =
199                orb.resolve_initial_references("NameService");
200             NamingContextExt JavaDoc rootContext = NamingContextExtHelper.narrow(obj);
201             org.omg.CORBA.Object JavaDoc txFactoryObj =
202                rootContext.resolve_str("TransactionService");
203             txFactory = TransactionFactoryExtHelper.narrow(txFactoryObj);
204          }
205          catch (Exception JavaDoc e)
206          {
207             throw new RuntimeException JavaDoc("Could not get transaction factory: "
208                                        + e);
209          }
210       }
211       return txFactory;
212    }
213
214    /**
215     * Converts transaction status from org.omg.CosTransactions format
216     * to javax.transaction format.
217     */

218    private static int cosTransactionsToJavax(
219                                        org.omg.CosTransactions.Status status)
220    {
221       switch (status.value())
222       {
223       case org.omg.CosTransactions.Status._StatusActive:
224          return javax.transaction.Status.STATUS_ACTIVE;
225       case org.omg.CosTransactions.Status._StatusCommitted:
226          return javax.transaction.Status.STATUS_COMMITTED;
227       case org.omg.CosTransactions.Status._StatusCommitting:
228          return javax.transaction.Status.STATUS_COMMITTING;
229       case org.omg.CosTransactions.Status._StatusMarkedRollback:
230          return javax.transaction.Status.STATUS_MARKED_ROLLBACK;
231       case org.omg.CosTransactions.Status._StatusNoTransaction:
232          return javax.transaction.Status.STATUS_NO_TRANSACTION;
233       case org.omg.CosTransactions.Status._StatusPrepared:
234          return javax.transaction.Status.STATUS_PREPARED;
235       case org.omg.CosTransactions.Status._StatusPreparing:
236          return javax.transaction.Status.STATUS_PREPARING;
237       case org.omg.CosTransactions.Status._StatusRolledBack:
238          return javax.transaction.Status.STATUS_ROLLEDBACK;
239       case org.omg.CosTransactions.Status._StatusRollingBack:
240          return javax.transaction.Status.STATUS_ROLLING_BACK;
241       case org.omg.CosTransactions.Status._StatusUnknown:
242          return javax.transaction.Status.STATUS_UNKNOWN;
243       default:
244          return javax.transaction.Status.STATUS_UNKNOWN;
245       }
246    }
247
248    // Constructors --------------------------------------------------
249

250    /**
251     * Create a new instance.
252     */

253    private IIOPClientUserTransaction()
254    {
255    }
256
257    // Public --------------------------------------------------------
258

259    /**
260     * Returns a reference to the singleton instance.
261     */

262    public static IIOPClientUserTransaction getSingleton()
263    {
264       if (singleton == null)
265          singleton = new IIOPClientUserTransaction();
266       return singleton;
267    }
268
269    //
270
// Implementation of interface UserTransaction
271
//
272

273    public void begin()
274       throws NotSupportedException JavaDoc, SystemException JavaDoc
275    {
276       if (getThreadLocalControl() != null)
277          throw new NotSupportedException JavaDoc();
278       try
279       {
280          TransactionDesc td =
281             getTxFactory().create_transaction(getThreadLocalTimeout());
282          setCurrentTransaction(td.control, td.propagationContext);
283       }
284       catch (RuntimeException JavaDoc e)
285       {
286          SystemException JavaDoc se = new SystemException JavaDoc("Failed to create tx");
287          se.initCause(e);
288          throw se;
289       }
290    }
291
292    public void commit()
293       throws RollbackException JavaDoc,
294              HeuristicMixedException JavaDoc,
295              HeuristicRollbackException JavaDoc,
296              SecurityException JavaDoc,
297              IllegalStateException JavaDoc,
298              SystemException JavaDoc
299    {
300       try
301       {
302          getThreadLocalTerminator().commit(true /* reportHeuristics */);
303       }
304       catch (NoTransaction e)
305       {
306          IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc();
307          ex.initCause(e);
308          throw ex;
309       }
310       catch (HeuristicMixed e)
311       {
312          HeuristicMixedException JavaDoc ex = new HeuristicMixedException JavaDoc();
313          ex.initCause(e);
314          throw ex;
315       }
316       catch (HeuristicHazard e)
317       {
318          HeuristicRollbackException JavaDoc ex = new HeuristicRollbackException JavaDoc();
319          ex.initCause(e);
320          throw ex;
321       }
322       catch (TRANSACTION_ROLLEDBACK JavaDoc e)
323       {
324          RollbackException JavaDoc ex = new RollbackException JavaDoc();
325          ex.initCause(e);
326          throw ex;
327       }
328       catch (BAD_INV_ORDER JavaDoc e)
329       {
330          IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc();
331          ex.initCause(e);
332          throw ex;
333       }
334       catch (NO_PERMISSION JavaDoc e)
335       {
336          SecurityException JavaDoc ex = new SecurityException JavaDoc();
337          ex.initCause(e);
338          throw ex;
339       }
340       catch (RuntimeException JavaDoc e)
341       {
342          SystemException JavaDoc ex = new SystemException JavaDoc();
343          ex.initCause(e);
344          throw ex;
345       }
346       finally
347       {
348          unsetCurrentTransaction();
349       }
350    }
351
352    public void rollback()
353       throws SecurityException JavaDoc,
354              IllegalStateException JavaDoc,
355              SystemException JavaDoc
356    {
357       try
358       {
359          getThreadLocalTerminator().rollback();
360       }
361       catch (NoTransaction e)
362       {
363          IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc();
364          ex.initCause(e);
365          throw ex;
366       }
367       catch (BAD_INV_ORDER JavaDoc e)
368       {
369          IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc();
370          ex.initCause(e);
371          throw ex;
372       }
373       catch (NO_PERMISSION JavaDoc e)
374       {
375          SecurityException JavaDoc ex = new SecurityException JavaDoc();
376          ex.initCause(e);
377          throw ex;
378       }
379       catch (RuntimeException JavaDoc e)
380       {
381          SystemException JavaDoc ex = new SystemException JavaDoc();
382          ex.initCause(e);
383          throw ex;
384       }
385       finally
386       {
387          unsetCurrentTransaction();
388       }
389    }
390
391    public void setRollbackOnly()
392       throws IllegalStateException JavaDoc,
393              SystemException JavaDoc
394    {
395       Coordinator coord = getThreadLocalCoordinator();
396       
397       if (coord == null)
398          throw new IllegalStateException JavaDoc();
399       
400       try
401       {
402          coord.rollback_only();
403       }
404       catch (Inactive e)
405       {
406          SystemException JavaDoc ex = new SystemException JavaDoc();
407          ex.initCause(e);
408          throw ex;
409       }
410       catch (BAD_INV_ORDER JavaDoc e)
411       {
412          IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc();
413          ex.initCause(e);
414          throw ex;
415       }
416       catch (RuntimeException JavaDoc e)
417       {
418          SystemException JavaDoc ex = new SystemException JavaDoc();
419          ex.initCause(e);
420          throw ex;
421       }
422    }
423
424    public int getStatus()
425       throws SystemException JavaDoc
426    {
427       try
428       {
429          Coordinator coord = getThreadLocalCoordinator();
430          if (coord == null)
431             return Status.STATUS_NO_TRANSACTION;
432          else
433             return cosTransactionsToJavax(coord.get_status());
434       }
435       catch (OBJECT_NOT_EXIST JavaDoc e)
436       {
437          return Status.STATUS_NO_TRANSACTION;
438       }
439       catch (RuntimeException JavaDoc e)
440       {
441          SystemException JavaDoc ex = new SystemException JavaDoc();
442          ex.initCause(e);
443          throw ex;
444       }
445    }
446
447    public void setTransactionTimeout(int seconds)
448       throws SystemException JavaDoc
449    {
450       setThreadLocalTimeout(seconds);
451    }
452    
453    //
454
// Implementation of interface Referenceable
455
//
456

457    public Reference JavaDoc getReference()
458       throws NamingException JavaDoc
459    {
460       Reference JavaDoc ref = new Reference JavaDoc(
461             "org.jboss.tm.iiop.client.IIOPClientUserTransaction",
462             "org.jboss.tm.iiop.client.IIOPClientUserTransactionObjectFactory",
463             null);
464       return ref;
465    }
466
467 }
468
Popular Tags