KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > transaction > TransactionCurrentImpl


1 /*
2  * JacORB - a free Java ORB
3  *
4  * Copyright (C) 1999-2004 Gerald Brose
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the Free
18  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */

21 package org.jacorb.transaction;
22
23 import org.apache.avalon.framework.logger.Logger;
24
25 import org.omg.CosTransactions.*;
26 import org.omg.CosNaming.*;
27 import org.omg.IOP.*;
28 import org.jacorb.orb.ORB;
29 import org.omg.CORBA.Any JavaDoc;
30 import java.util.*;
31
32 /**
33  * This class represents the transaction current.
34  * It is a very simple implementation wich mostly
35  * maps to the methods in the control.
36  *
37  * @author Nicolas Noffke
38  * @author Vladimir Mencl
39  * @version $Id: TransactionCurrentImpl.java,v 1.16 2004/05/06 12:40:01 nicolas Exp $
40  *
41  * Changes made by Vladimir Mencl <vladimir.mencl@mff.cuni.cz> (2002/07/15)
42  *
43  * * Current.commit() catches and rethrows TRANSACTION_ROLLEDBACK
44  * (and removes the association of the transaction with the current thread)
45  *
46  * Changes made by Vladimir Mencl <vladimir.mencl@mff.cuni.cz> (2002/05/01)
47  *
48  * * implemented suspend() and resume()
49  *
50  * * added setCurrentThreadContext() used by suspend()
51  *
52  * * made slot_id static so that it can be used from getControl
53  *
54  * * extra dependency: suspend() and resume() used by
55  * ServerContextTransferInterceptor to set/rest context
56  */

57
58 public class TransactionCurrentImpl
59     extends org.omg.CORBA.LocalObject JavaDoc
60     implements Current
61 {
62     private static final int DEFAULT_TIMEOUT = 30;
63   
64     private Hashtable contexts = null;
65     private Hashtable timeouts = null;
66     private ORB orb = null;
67     private static int slot_id = -1; /* used from static getControl */
68
69     /** there will only be ony logger instance for all TX services in a process...*/
70     private static Logger logger;
71
72     private TransactionFactory factory = null;
73   
74     public TransactionCurrentImpl(ORB orb, int slot_id)
75     {
76         this.orb = orb;
77         this.slot_id = slot_id;
78         logger =
79             orb.getConfiguration().getNamedLogger("jacorb.tx_service.current");
80
81         contexts = new Hashtable();
82         timeouts = new Hashtable();
83
84         try
85         {
86             NamingContextExt nc =
87                 NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService"));
88             NameComponent [] name = new NameComponent[1];
89             name[0] = new NameComponent( "TransactionService", "service");
90             factory = TransactionFactoryHelper.narrow(nc.resolve(name));
91         }
92         catch (Exception JavaDoc e)
93         {
94             if (logger.isErrorEnabled())
95                 logger.error("Unable to obtain Transaction Service reference. Giving up.", e );
96             throw new Error JavaDoc(e.getMessage());
97         }
98     }
99
100     /**
101      * Creates a non-functional current.
102      */

103     public TransactionCurrentImpl()
104     {
105         contexts = new Hashtable();
106         timeouts = new Hashtable();
107     }
108
109     /**
110      * This method is a convenience method for the server
111      * programmer the exctract the Control from the
112      * PICurrent.
113      */

114     public static Control getControl(org.omg.CORBA.ORB JavaDoc orb)
115     {
116         try
117         {
118             org.omg.PortableInterceptor.Current JavaDoc pi_current =
119                 (org.omg.PortableInterceptor.Current JavaDoc)orb.resolve_initial_references("PICurrent");
120
121             PropagationContext context = PropagationContextHelper.extract
122                 (pi_current.get_slot(slot_id));
123
124             return ControlHelper.extract(context.implementation_specific_data);
125         }
126         catch(Exception JavaDoc e)
127         {
128             if (logger.isDebugEnabled())
129                 logger.debug("Unable to obtain Transaction Service reference. Giving up.", e );
130         }
131
132         return null;
133     }
134
135     // implementation of org.omg.CosTransactions.CurrentOperations interface
136
/**
137      * Start a new transaction. The propagation context will be transfered
138      * on ALL communication (~1k extra data) from now on, until
139      * the transaction is committed or rolled back. <br>
140      * NOTICE: the PropagationContext might not be set up fully
141      * compliant to the Spec.
142      */

143     public void begin()
144         throws SubtransactionsUnavailable
145     {
146         Thread JavaDoc thread = Thread.currentThread();
147
148         if (contexts.containsKey(thread))
149             throw new SubtransactionsUnavailable();
150
151         int timeout = (timeouts.containsKey(thread))?
152             ((Integer JavaDoc) timeouts.get(thread)).intValue() : DEFAULT_TIMEOUT;
153
154         Control control = factory.create(timeout);
155         contexts.put(thread, control);
156     
157         try
158         {
159             org.omg.PortableInterceptor.Current JavaDoc pi_current =
160                 (org.omg.PortableInterceptor.Current JavaDoc) orb.resolve_initial_references("PICurrent");
161
162             // the info inserted here is actually never needed and mostly a waste of
163
// space/bandwidth, since the control itself is transfered also.
164
TransIdentity id = new TransIdentity(control.get_coordinator(),
165                                                  control.get_terminator(),
166                                                  new otid_t(0, 0, new byte[0]));
167       
168             Any JavaDoc control_any = orb.create_any();
169             ControlHelper.insert(control_any, control);
170
171             PropagationContext context = new PropagationContext(timeout,
172                                                                 id, new TransIdentity[0],
173                                                                 control_any);
174             Any JavaDoc context_any = orb.create_any();
175             PropagationContextHelper.insert(context_any, context);
176
177             pi_current.set_slot(slot_id, context_any);
178         }
179         catch (Exception JavaDoc e)
180         {
181             if (logger.isDebugEnabled())
182                 logger.debug("Exception: ", e);
183         }
184     }
185
186     public void commit(boolean report_heuristics)
187         throws NoTransaction, HeuristicMixed, HeuristicHazard
188     {
189         Thread JavaDoc current = Thread.currentThread();
190
191         if (! contexts.containsKey(current))
192             throw new NoTransaction();
193
194     Control control = null;
195         try
196         {
197             control = (Control) contexts.get(current);
198             control.get_terminator().commit(report_heuristics);
199             control._release();
200
201             removeContext(current);
202     }
203         catch (org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc tr)
204         {
205         // Transaction was rolledback.
206
if (logger.isDebugEnabled())
207                 logger.debug("TRANSACTION_ROLLEDBACK: ", tr);
208
209         control._release();
210         removeContext(current);
211         throw tr; // re-throw the exception
212
}
213         catch (Exception JavaDoc e)
214         {
215             if (logger.isDebugEnabled())
216                 logger.debug("Exception: ", e);
217         }
218     }
219
220     /**
221      * This and the following method should actually throw
222      * NoTransaction, but that is against the spec.
223      */

224     public Control get_control()
225     {
226         return (Control) contexts.get(Thread.currentThread());
227     }
228
229     public Status get_status()
230     {
231         Thread JavaDoc current = Thread.currentThread();
232
233         if (! contexts.containsKey(current))
234             return null;
235
236         try
237         {
238             return ((Control) contexts.get(current)).get_coordinator().get_status();
239         }
240         catch (Exception JavaDoc e)
241         {
242             if (logger.isDebugEnabled())
243                 logger.debug("Exception: ", e);
244         }
245         return null;
246     }
247
248     public String JavaDoc get_transaction_name()
249     {
250         Thread JavaDoc current = Thread.currentThread();
251
252         if (! contexts.containsKey(current))
253             return null;
254
255         try
256         {
257             return ((Control) contexts.get(current)).get_coordinator().get_transaction_name();
258         }
259         catch (Exception JavaDoc e)
260         {
261             if (logger.isDebugEnabled())
262                 logger.debug("Exception: ", e);
263         }
264         return null;
265     }
266
267     public void resume(Control which)
268         throws InvalidControl
269     {
270     setCurrentThreadContext(which);
271     }
272
273     public void rollback()
274         throws NoTransaction
275     {
276         Thread JavaDoc current = Thread.currentThread();
277
278         if (! contexts.containsKey(current))
279             throw new NoTransaction();
280         try
281         {
282             Control control = (Control) contexts.get(current);
283             control.get_terminator().rollback();
284    
285             control._release();
286
287             removeContext(current);
288         }
289         catch (Exception JavaDoc e)
290         {
291             if (logger.isDebugEnabled())
292                 logger.debug("Exception: ", e);
293         }
294     }
295
296     public void rollback_only()
297         throws NoTransaction
298     {
299         Thread JavaDoc current = Thread.currentThread();
300
301         if (! contexts.containsKey(current))
302             throw new NoTransaction();
303         try
304         {
305             Control control = (Control) contexts.get(current);
306             control.get_coordinator().rollback_only();
307             control._release();
308
309             removeContext(current);
310         }
311         catch (Exception JavaDoc e){
312             if (logger.isDebugEnabled())
313                 logger.debug("Exception: ", e);
314         }
315     }
316
317     public void set_timeout(int seconds)
318     {
319         timeouts.put(Thread.currentThread(), new Integer JavaDoc(seconds));
320     }
321
322     public Control suspend()
323     {
324         Control result = get_control();
325         removeContext(Thread.currentThread());
326         return result;
327     }
328
329     public void setCurrentThreadContext(Control control)
330     {
331         Thread JavaDoc thread = Thread.currentThread();
332
333         contexts.put(thread, control);
334     
335         try
336         {
337             org.omg.PortableInterceptor.Current JavaDoc pi_current =
338                 (org.omg.PortableInterceptor.Current JavaDoc)orb.resolve_initial_references("PICurrent");
339
340             // the info inserted here is actually never needed and mostly a waste of
341
// space/bandwidth, since the control itself is transfered also.
342
TransIdentity id =
343                 new TransIdentity(control.get_coordinator(),
344                                   control.get_terminator(),
345                                   new otid_t(0, 0, new byte[0]));
346       
347             Any JavaDoc control_any = orb.create_any();
348             ControlHelper.insert(control_any, control);
349
350             int timeout =
351                 (timeouts.containsKey(thread))?
352                 ((Integer JavaDoc) timeouts.get(thread)).intValue() :
353                 DEFAULT_TIMEOUT;
354
355             PropagationContext context =
356                 new PropagationContext(timeout,
357                                        id,
358                                        new TransIdentity[0],
359                                        control_any);
360
361             Any JavaDoc context_any = orb.create_any();
362             PropagationContextHelper.insert(context_any, context);
363             pi_current.set_slot(slot_id, context_any);
364         }
365         catch (Exception JavaDoc e)
366         {
367             if (logger.isDebugEnabled())
368                 logger.debug("Exception: ", e);
369         }
370     }
371
372     private void removeContext(Thread JavaDoc current)
373     {
374         //remove control from Hashtable
375
contexts.remove(current);
376
377         try
378         {
379             org.omg.PortableInterceptor.Current JavaDoc pi_current =
380                 (org.omg.PortableInterceptor.Current JavaDoc)orb.resolve_initial_references("PICurrent");
381
382             //remove control from PICurrent by overwriting it with
383
//an empty any
384
Any JavaDoc empty = orb.create_any();
385             pi_current.set_slot(slot_id, empty);
386         }
387         catch (Exception JavaDoc e)
388         {
389             if (logger.isDebugEnabled())
390                 logger.debug("Exception: ", e);
391         }
392     }
393 } // TransactionCurrentImpl
394

395
396
397
398
399
400
Popular Tags