KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > tm > remoting > client > ClientUserTransaction


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.remoting.client;
23
24 import java.io.Serializable JavaDoc;
25 import java.rmi.AccessException JavaDoc;
26 import java.rmi.NoSuchObjectException JavaDoc;
27 import java.rmi.RemoteException JavaDoc;
28
29 import javax.naming.Context JavaDoc;
30 import javax.naming.InitialContext JavaDoc;
31 import javax.naming.NamingException JavaDoc;
32 import javax.naming.Reference JavaDoc;
33 import javax.naming.Referenceable JavaDoc;
34 import javax.transaction.HeuristicMixedException JavaDoc;
35 import javax.transaction.HeuristicRollbackException JavaDoc;
36 import javax.transaction.NotSupportedException JavaDoc;
37 import javax.transaction.RollbackException JavaDoc;
38 import javax.transaction.SystemException JavaDoc;
39 import javax.transaction.Transaction JavaDoc;
40 import javax.transaction.TransactionRolledbackException JavaDoc;
41 import javax.transaction.UserTransaction JavaDoc;
42
43 import org.jboss.tm.TransactionPropagationContextFactory;
44 import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
45 import org.jboss.tm.remoting.interfaces.Status;
46 import org.jboss.tm.remoting.interfaces.TransactionFactory;
47 import org.jboss.tm.remoting.interfaces.TransactionInactiveException;
48 import org.jboss.tm.remoting.interfaces.TxPropagationContext;
49
50
51 /**
52  * The client-side UserTransaction implementation for JBoss remoting clients.
53  * This will delegate all UserTransaction calls to the DTM in the server.
54  *
55  * <em>Warning:</em> This is only for stand-alone JBoss remoting clients that
56  * do not have their own transaction service. No local work is done in
57  * the context of transactions started here, only work done in beans
58  * at the server.
59  *
60  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
61  * @version $Revision: 37459 $
62  */

63 public class ClientUserTransaction
64       implements UserTransaction JavaDoc,
65                  TransactionPropagationContextFactory,
66                  Referenceable JavaDoc,
67                  Serializable JavaDoc
68 {
69    // Static --------------------------------------------------------
70

71    static final long serialVersionUID = -3704980350844202097L;
72
73    /** Our singleton instance. */
74    private static ClientUserTransaction singleton = null;
75
76    /** The JNDI name to which the server's transaction factory proxy is bound */
77    public static final String JavaDoc TX_FACTORY_JNDI_NAME = "DTMTransactionFactory";
78    
79    /** Remote proxy to the server's transaction factory. */
80    private static TransactionFactory txFactory;
81
82    /** Transaction information associated with the current thread. */
83    private static ThreadLocal JavaDoc threadLocalData = new ThreadLocal JavaDoc() {
84          protected synchronized Object JavaDoc initialValue()
85          {
86             return new TransactionInfo(); // see nested class below
87
}
88       };
89  
90    // Nested class -------------------------------------------------
91

92    /**
93     * The <code>TransactionInfo</code> class holds transaction information
94     * associated with the current thread. The <code>threadLocalData</code>
95     * field contains an instance of this class. The field timeout applies
96     * to new transactions started by the current thread; its value is not
97     * necessarily equal to the time out of the currrent transaction. The
98     * <code>TxPropagationContext</code> field refers to the currrent
99     * transaction.
100     */

101    private static class TransactionInfo
102    {
103       int timeout = 0; // for new transactions started by the current thread
104
TxPropagationContext tpc; // null if no current transaction
105
}
106
107    // Static accessors to thread-local data -------------------------
108

109    private static void setThreadLocalTimeout(int timeout)
110    {
111       ((TransactionInfo)threadLocalData.get()).timeout = timeout;
112    }
113
114    private static int getThreadLocalTimeout()
115    {
116       return ((TransactionInfo)threadLocalData.get()).timeout;
117    }
118    
119    private static void setThreadLocalTPC(TxPropagationContext tpc)
120    {
121       ((TransactionInfo)threadLocalData.get()).tpc = tpc;
122    }
123
124    private static TxPropagationContext getThreadLocalTPC()
125       throws IllegalStateException JavaDoc
126    {
127       return ((TransactionInfo)threadLocalData.get()).tpc;
128    }
129    
130    // Other auxiliary (and static) methods -------------------------
131

132    /**
133     * Returns a CORBA reference to the TransactionFactory implemented by
134     * the JBoss server.
135     */

136    private static TransactionFactory getTxFactory()
137    {
138       if (txFactory == null)
139       {
140          try
141          {
142             Context JavaDoc ctx = new InitialContext JavaDoc();
143             txFactory = (TransactionFactory) ctx.lookup(TX_FACTORY_JNDI_NAME);
144          }
145          catch (Exception JavaDoc e)
146          {
147             throw new RuntimeException JavaDoc("Could not get transaction factory: ", e);
148          }
149       }
150       return txFactory;
151    }
152
153    /**
154     * Converts transaction status from org.omg.CosTransactions format
155     * to javax.transaction format.
156     */

157    private static int jbossToJavax(Status status)
158    {
159       return status.toInteger();
160    }
161
162    // Constructors --------------------------------------------------
163

164    /**
165     * Create a new instance.
166     */

167    private ClientUserTransaction()
168    {
169    }
170
171    // Public --------------------------------------------------------
172

173    /**
174     * Returns a reference to the singleton instance.
175     */

176    public static ClientUserTransaction getSingleton()
177    {
178       if (singleton == null)
179          singleton = new ClientUserTransaction();
180       return singleton;
181    }
182
183    //
184
// Implementation of interface UserTransaction
185
//
186

187    public void begin()
188       throws NotSupportedException JavaDoc, SystemException JavaDoc
189    {
190       if (getThreadLocalTPC() != null)
191          throw new NotSupportedException JavaDoc();
192       try
193       {
194          TxPropagationContext tpc =
195             getTxFactory().create(getThreadLocalTimeout());
196          setThreadLocalTPC(tpc);
197       }
198       catch (RemoteException JavaDoc e)
199       {
200          SystemException JavaDoc e2 = new SystemException JavaDoc("Unable to begin transaction");
201          e2.initCause(e);
202          throw e2;
203       }
204    }
205
206    public void commit()
207       throws RollbackException JavaDoc,
208              HeuristicMixedException JavaDoc,
209              HeuristicRollbackException JavaDoc,
210              SecurityException JavaDoc,
211              IllegalStateException JavaDoc,
212              SystemException JavaDoc
213    {
214       try
215       {
216          TxPropagationContext tpc = getThreadLocalTPC();
217
218          if (tpc == null)
219             throw new IllegalStateException JavaDoc();
220
221          tpc.terminator.commit(true /* reportHeuristics */);
222       }
223       catch (TransactionRolledbackException JavaDoc e)
224       {
225          RollbackException JavaDoc e2 = new RollbackException JavaDoc("Transaction rolled back");
226          e2.initCause(e);
227          throw e2;
228       }
229       catch (HeuristicHazardException e)
230       {
231          HeuristicRollbackException JavaDoc e2 = new HeuristicRollbackException JavaDoc("Heuristic hazard");
232          e2.initCause(e);
233          throw e2;
234       }
235       catch (AccessException JavaDoc e)
236       {
237          SecurityException JavaDoc e2 = new SecurityException JavaDoc("Access denied");
238          e2.initCause(e);
239          throw e2;
240       }
241       catch (RemoteException JavaDoc e)
242       {
243          SystemException JavaDoc e2 = new SystemException JavaDoc("Error during commit");
244          e2.initCause(e);
245          throw e2;
246       }
247       finally
248       {
249          setThreadLocalTPC(null);
250       }
251    }
252
253    public void rollback()
254       throws SecurityException JavaDoc,
255              IllegalStateException JavaDoc,
256              SystemException JavaDoc
257    {
258       try
259       {
260          TxPropagationContext tpc = getThreadLocalTPC();
261          
262          if (tpc == null)
263             throw new IllegalStateException JavaDoc();
264          
265          tpc.terminator.rollback();
266       }
267       catch (AccessException JavaDoc e)
268       {
269          SecurityException JavaDoc e2 = new SecurityException JavaDoc("Access denied");
270          e2.initCause(e);
271          throw e2;
272       }
273       catch (RemoteException JavaDoc e)
274       {
275          SystemException JavaDoc e2 = new SystemException JavaDoc("Error during rollback");
276          e2.initCause(e);
277          throw e2;
278       }
279       finally
280       {
281          setThreadLocalTPC(null);
282       }
283    }
284
285    public void setRollbackOnly()
286       throws IllegalStateException JavaDoc,
287              SystemException JavaDoc
288    {
289       try
290       {
291          TxPropagationContext tpc = getThreadLocalTPC();
292          
293          if (tpc == null)
294             throw new IllegalStateException JavaDoc();
295
296          tpc.coordinator.rollbackOnly();
297       }
298       catch (TransactionInactiveException e)
299       {
300          IllegalStateException JavaDoc e2 = new IllegalStateException JavaDoc("Transaction is not active");
301          e2.initCause(e);
302          throw e2;
303       }
304       catch (RemoteException JavaDoc e)
305       {
306          SystemException JavaDoc e2 = new SystemException JavaDoc("Error during rollback");
307          e2.initCause(e);
308          throw e2;
309       }
310    }
311
312    public int getStatus()
313       throws SystemException JavaDoc
314    {
315       try
316       {
317          TxPropagationContext tpc = getThreadLocalTPC();
318          
319          if (tpc == null)
320             return javax.transaction.Status.STATUS_NO_TRANSACTION;
321          else
322             return jbossToJavax(tpc.coordinator.getStatus());
323       }
324       catch (NoSuchObjectException JavaDoc e)
325       {
326          return javax.transaction.Status.STATUS_NO_TRANSACTION;
327       }
328       catch (RemoteException JavaDoc e)
329       {
330          SystemException JavaDoc e2 = new SystemException JavaDoc("Error getting status");
331          e2.initCause(e);
332          throw e2;
333       }
334    }
335
336    public void setTransactionTimeout(int seconds)
337       throws SystemException JavaDoc
338    {
339       setThreadLocalTimeout(seconds);
340    }
341    
342    //
343
// implements interface TransactionPropagationContextFactory
344
//
345

346    public Object JavaDoc getTransactionPropagationContext()
347    {
348       return getThreadLocalTPC();
349    }
350
351    public Object JavaDoc getTransactionPropagationContext(Transaction JavaDoc tx)
352    {
353       // No need to implement in a stand-alone client.
354
throw new InternalError JavaDoc("Should not have been used.");
355    }
356
357    //
358
// Implementation of interface Referenceable
359
//
360

361    public Reference JavaDoc getReference()
362       throws NamingException JavaDoc
363    {
364       Reference JavaDoc ref = new Reference JavaDoc(
365             "org.jboss.tm.remoting.client.ClientUserTransaction",
366             "org.jboss.tm.remoting.client.ClientUserTransactionObjectFactory",
367             null);
368       return ref;
369    }
370
371 }
372
Popular Tags