KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jass > hls > ont > ONT


1 /**
2  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3  -
4  - JASS: Java Advanced tranSaction Support
5  -
6  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7  -
8  - This module was originally developed by
9  -
10  - LSD (Distributed Systems Lab, http://lsd.ls.fi.upm.es/lsd/lsd.htm)
11  - at Universidad Politecnica de Madrid (UPM) as an ObjectWeb Consortium
12  - (http://www.objectweb.org) project.
13  -
14  - This project has been partially funded by the European Commission under
15  - the IST programme of V FP grant IST-2001-37126 and by the Spanish
16  - Ministry of Science & Technology (MCyT) grants TIC2002-10376-E and
17  - TIC2001-1586-C03-02
18  -
19  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20  - The original code and portions created by LSD are
21  - Copyright (c) 2004 LSD (UPM)
22  - All rights reserved.
23  -
24  - Redistribution and use in source and binary forms, with or without
25  - modification, are permitted provided that the following conditions are met:
26  -
27  - -Redistributions of source code must retain the above copyright notice, this
28  - list of conditions and the following disclaimer.
29  -
30  - -Redistributions in binary form must reproduce the above copyright notice,
31  - this list of conditions and the following disclaimer in the documentation
32  - and/or other materials provided with the distribution.
33  -
34  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
35  - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
38  - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39  - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40  - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41  - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42  - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43  - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44  - POSSIBILITY OF SUCH DAMAGE.
45  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
46  -
47  - Author: Francisco Perez Sorrosal (frperezs)
48  -
49  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50 */

51
52 package org.objectweb.jass.hls.ont;
53
54 import org.apache.log4j.Logger;
55
56 import javax.activity.*;
57 import javax.activity.Status JavaDoc;
58 import javax.activity.SystemException JavaDoc;
59 import javax.activity.opennested.*;
60 import javax.naming.*;
61 import javax.transaction.*;
62
63 import java.io.Serializable JavaDoc;
64 import java.util.Stack JavaDoc;
65
66 /**
67  * ONT service main class. It implements the UserOpenNested service
68  * interface offered to applications throught JNDI by the
69  * {@link org.objectweb.jass.hls.ont.jboss.ONTService} class. A singleton ONT
70  * object is created.
71  * @author fran
72  * Date: Feb 11, 2004
73  * org.objectweb.jass.hls.ontONT.java
74  */

75 public class ONT implements UserOpenNested, Serializable JavaDoc {
76
77     private static Logger log = Logger.getLogger(ONT.class);
78
79     // Constants --------------------------------------------------------------
80

81     // Attributes ---------------------------------------------------------------
82

83     private static ONT singleton = new ONT();
84
85     // The ONT service manager
86
private ONTServiceManager serviceManager;
87     // This instance provides access to the AS...
88
private ActivityManager activityManager = null;
89     // ...and this one to JTA.
90
private TransactionManager tm = null;
91     private int defaultTimeout = 0; // It means no timeout
92

93     // Constructors -----------------------------------------------------------
94

95     /**
96      * Default Constructor. Creates the singleton ONT instance, allowing
97      * access to AS and JTA, and registers the ONT service manager
98      * object in the AS.
99      */

100     private ONT() {
101
102         try {
103             Context ctx = new InitialContext();
104
105             log.info(
106                 getThreadName() + " Looking for an ActivityManager instance...");
107             activityManager = (ActivityManager) ctx.lookup("ActivityManager");
108             log.info(getThreadName() + " AM instance found!!!");
109
110             log.info(getThreadName() + " Looking for a TransactionManager...");
111             tm = ((TransactionManager) ctx.lookup("java:/TransactionManager"));
112             log.info(" TM found !!!");
113
114             // The ONT service manager is created and registered in AS instance
115
serviceManager = new ONTServiceManager();
116             activityManager.registerService(serviceManager);
117
118             log.info(
119                 getThreadName()
120                     + " ONT service registered in Activity Service instance");
121         } catch (NamingException e) {
122             log.error("Instance NOT found");
123             e.printStackTrace();
124         } catch (Exception JavaDoc e) {
125             e.printStackTrace();
126         }
127     }
128
129     // Static -----------------------------------------------------------------
130

131     /**
132      * Returns the unique ONT service instance.
133      * @return The unique instance.
134      */

135     public static ONT getSingleton() {
136
137         return singleton;
138     }
139
140     // Public ---------------------------------------------------------------------
141

142     // UserOpenNested implementation ------------------------------------------
143

144     /**
145      * A new Activity is created. If the invoking thread already has an active
146      * Activity associated with it then the newly created Activity will be
147      * nested within it. Regardless of whether or not the Activity is nested, a
148      * top-level transaction is created using the Transaction Service and
149      * associated with the newly created Activity. The invoking thread's notion
150      * of the current Activity will be changed to this Activity.
151      *
152      * @param timeout - is used to control the lifetime of the transactional
153      * Activity. If the Activity has not completed by the time timeout seconds
154      * elapses, then it is subject to being rolled back. The timeout defined by
155      * the Open Nested Current interface is not controlled by the Open
156      * Nested Service which rather relies on the underlying Activity Service
157      * to manage it. Values the timeout can have are those defined by the
158      * Activity Service.
159      */

160     public void activityBegin(int timeout)
161         throws InvalidActivityException, TimeoutRangeException {
162
163         ThreadInfo ti = getThreadInfo();
164
165         log.info(getThreadName() + " BEGINING ONT ACTIVITY...");
166
167         try {
168             // We suspend any possible active transaction
169
if (tm.getTransaction() != null) {
170                 log.info("\t" + tm.getTransaction() + " is suspending...");
171                 ti.suspendedTxs.push(tm.suspend());
172             } else
173                 log.info("\tThere are no transactions to suspend");
174         
175             log.info("\tTransactions in stack: " + ti.suspendedTxs.size());
176             if (timeout == 0) {
177                 activityManager.begin(defaultTimeout);
178             } else {
179                 activityManager.begin(timeout);
180             }
181             
182             // We start the associated transaction
183
tm.begin();
184             log.info("\t" + tm.getTransaction() + " started");
185         } catch (InvalidStateException e) {
186             throw new InvalidActivityException();
187         } catch (TimeoutRangeException e) {
188             throw e;
189         } catch (Exception JavaDoc e) {
190             e.printStackTrace();
191         }
192         log.info(getThreadName() + " ONT ACTIVITY BEGUN");
193         log.info(
194             "\n----------------------------------------------------------------------------------\n");
195     }
196
197     /**
198      * The transactional Activity associated with the client thread is committed;
199      * this implicitly causes the commit of the associated transaction. Only the
200      * Activity originator may call activity_commit().
201      *
202      * @param compensator_object - If the Activity/transaction can commit,
203      * this object will be registered as the compensating action for this
204      * activity/transaction. Failure to register the Compensator will cause the
205      * Activity to rollback.
206      */

207     public void activityCommit(Compensator compensator_object)
208         throws
209             NoActivityException,
210             HeuristicMixedException,
211             HeuristicRollbackException,
212             ActivityPendingException,
213             ContextPendingException,
214             NotOriginatorException,
215             ActivityRolledBackException,
216             HeuristicCompensateException,
217             HeuristicNoCompensateException {
218
219         Outcome out = null;
220         ThreadInfo ti = getThreadInfo();
221
222         log.info(getThreadName() + " COMMITTING ONTs ACTIVITY...");
223
224         try {
225             log.info("\t " + tm.getTransaction() + " is committing...");
226             tm.commit();
227             log.info("\t Transaction committed !!!!!");
228             if (compensator_object != null) {
229                 CompensatingAction action =
230                     new CompensatingAction(compensator_object, 0);
231                 ActivityCoordinator parent = activityManager.getParentCoordinator();
232                 // If it is a nested activity
233
if (parent != null) {
234                     try {
235                         // We try to register the compensator object with the
236
// parent activity
237
parent.addAction(
238                             action,
239                             ONTCompletionSS.COMPLETION_SS_NAME,
240                             0);
241                         log.debug(
242                             "Compensator added sucessfully with parent ("
243                                 + parent.getName()
244                                 + ")");
245                     } catch (Exception JavaDoc e) {
246                         log.info("Action not added to the parent. Compensating...");
247                         compensator_object.compensate();
248                         log.info(
249                             "Triying to complete activity "
250                                 + getActivityName()
251                                 + " with CompletionStatusFail *****");
252                         out =
253                             activityManager.completeWithStatus(
254                                 CompletionStatus.CompletionStatusFail);
255                         throw new ActivityRolledBackException();
256                     }
257                 } else
258                     log.info(
259                         "There is no parent activity to register the compensator!");
260             }
261             log.info(
262                 "Triying to complete activity "
263                     + getActivityName()
264                     + " with CompletionStatusSuccess *****");
265             out =
266                 activityManager.completeWithStatus(
267                     CompletionStatus.CompletionStatusSuccess);
268             if (out != null)
269                 if (out.getName().equals("heuristic_compensate_decision"))
270                     throw new HeuristicCompensateException();
271
272         } catch (RollbackException e) {
273             try {
274                 log.info("\t Transaction Rolledback !!!!!");
275                 log.info(
276                     " Triying to complete activity "
277                         + getActivityName()
278                         + " with CompletionStatusFail *****");
279                 out =
280                     activityManager.completeWithStatus(
281                         CompletionStatus.CompletionStatusFail);
282                 if (out == null) {
283                     throw new ActivityRolledBackException();
284                 } else {
285                     if (out.getName().equals("heuristic_cannot_compensate"))
286                         throw new HeuristicNoCompensateException();
287                 }
288             } catch (Exception JavaDoc e1) {
289                 e1.printStackTrace();
290             }
291         } catch (ActivityRolledBackException e) {
292             throw e;
293         } catch (Exception JavaDoc e) {
294             e.printStackTrace();
295         } finally {
296             log.info(getThreadName() + " ONT ACTIVITY COMPLETED");
297             // If there is a suspended transaction, we must to resume it
298
if (!ti.suspendedTxs.empty()) {
299                 try {
300                     tm.resume((Transaction) ti.suspendedTxs.pop());
301                     log.info("\t" + tm.getTransaction() + " has been resumed");
302                     log.info("\tTransactions in stack: " + ti.suspendedTxs.size());
303                 } catch (Exception JavaDoc e) {
304                     e.printStackTrace();
305                 }
306             }
307             log.info(
308                 "\n----------------------------------------------------------------------------------\n");
309         }
310     }
311
312     /**
313      * The transactional Activity associated with the client thread is rolled
314      * back; this implicitly causes the rollback of the associated transaction.
315      * Any nested transactional activities are also rolled back.
316      */

317     public void activityRollback()
318         throws NoActivityException, HeuristicNoCompensateException {
319
320         Outcome out = null;
321         ThreadInfo ti = getThreadInfo();
322
323         log.info(getThreadName() + " ROLLING-BACK ONT ACTIVITY...");
324
325         try {
326             if (activityManager.getCoordinator() == null)
327                 throw new NoActivityException();
328
329             log.info("\t" + tm.getTransaction() + " is rolling-back...");
330             tm.rollback();
331             log.info("\tTransaction rolled-back !!!!!");
332             log.info(
333                 "Completing activity " + getActivityName() + " with fail *****");
334
335             out = activityManager.completeWithStatus(
336                         CompletionStatus.CompletionStatusFail);
337
338             if (out != null) {
339                 if (out.getName().equals("heuristic_cannot_compensate"))
340                     throw new HeuristicNoCompensateException();
341             }
342         } catch (Exception JavaDoc e) {
343             e.printStackTrace();
344         } finally {
345             log.info(getThreadName() + " ONT ACTIVITY COMPLETED");
346             if (!ti.suspendedTxs.empty()) {
347                 try {
348                     tm.resume((Transaction) ti.suspendedTxs.pop());
349                     log.info("\t" + tm.getTransaction() + " has been resumed");
350                     log.info("\tTransactions in stack: " + ti.suspendedTxs.size());
351                 } catch (Exception JavaDoc e) {
352                     e.printStackTrace();
353                 }
354             }
355             log.info(
356                 "\n----------------------------------------------------------------------------------\n");
357         }
358     }
359
360     /**
361      * The current Activity is modified so that the only possible outcome is
362      * rollback. The associated transaction is also marked as rollback only.
363      */

364     public void activitySetRollbackOnly() throws NoActivityException {
365         try {
366             tm.setRollbackOnly();
367             activityManager.setCompletionStatus(
368                 CompletionStatus.CompletionStatusFailOnly);
369         } catch (NoActivityException e) {
370             e.printStackTrace();
371             throw e;
372         } catch (Exception JavaDoc e) {
373             e.printStackTrace();
374         }
375     }
376
377     /**
378      * This method resets the default timeout value for ONT Activities. The
379      * default timeout value is used for activities that are begun with a
380      * timeout value of 0.
381      */

382     public void activitySetTimeout(int seconds) throws TimeoutRangeException {
383         if (seconds < -1)
384             throw new TimeoutRangeException();
385         defaultTimeout = seconds;
386     }
387
388     /**
389      * This operation returns the default timeout value that is used for
390      * activities that are begun with a timeout value of 0.
391      */

392     public int getActivityTimeout() {
393         return defaultTimeout;
394     }
395
396     /**
397      * This operation returns the ActivityStatus of the activity associated
398      * with the calling thread. If there is no activity associated with the
399      * calling thread, the StatusNoActivity value is returned.
400      */

401     public int activityGetStatus() {
402         int status = Status.StatusNoActivity;
403         try {
404             status = activityManager.getStatus();
405         } catch (Exception JavaDoc e) {
406             e.printStackTrace();
407         }
408         return status;
409     }
410
411     /**
412      * This operation returns a printable string describing the current
413      * activity. If there is no activity associated with the calling thread,
414      * an empty string is returned.
415      */

416     public String JavaDoc getActivityName() {
417         String JavaDoc name = null;
418         try {
419             name = activityManager.getName();
420         } catch (Exception JavaDoc e) {
421             e.printStackTrace();
422         }
423         return name;
424     }
425
426     /**
427      * This operation returns a printable string describing the transaction
428      * associated with the current activity. If there is no current activity a
429      * null string is returned.
430      */

431     public String JavaDoc getTransactionName() {
432         String JavaDoc name = null;
433         try {
434             name = tm.getTransaction().toString();
435         } catch (javax.transaction.SystemException JavaDoc e) {
436             e.printStackTrace();
437         }
438         return name;
439     }
440
441     // My Public --------------------------------------------------------------
442

443     // My Private -------------------------------------------------------------
444

445     // Local thread info
446
private ThreadLocal JavaDoc threadActivityInfo = new ThreadLocal JavaDoc();
447
448     /**
449      * Obtains the information associated with the current thread
450      * @return Information associated with the current thread
451      */

452     private ThreadInfo getThreadInfo() {
453
454         ThreadInfo ret = (ThreadInfo) threadActivityInfo.get();
455
456         if (ret == null) {
457             ret = new ThreadInfo();
458             threadActivityInfo.set(ret);
459         } else
460             log.debug("Thread info != null");
461
462         return ret;
463     }
464
465     /**
466      * Returns the name of current thread.
467      * @return the current thread name.
468      */

469     private String JavaDoc getThreadName() {
470         return Thread.currentThread().getName();
471     }
472
473     // Inner classes --------------------------------------------------------------
474

475     /**
476      * Contains the stack of the thread-associated suspended transactions.
477      * It also has a TEST field "suspendedAct" to test the suspend/resume
478      * methods.
479      */

480     static class ThreadInfo {
481         Stack JavaDoc suspendedTxs = new Stack JavaDoc();
482         Stack JavaDoc suspendedAct = new Stack JavaDoc();
483     }
484
485     // Test -----------------------------------------------------------------------
486

487     /**
488      * This is a TEST method!!!
489      * It allows to suspend the current activity.
490      * @return the ONTActivity suspended.
491      */

492     public ONTActivity suspend() {
493         ActivityToken at = null;
494         Transaction tx = null;
495         ONTActivityImpl activity = null;
496
497         try {
498             tx = tm.suspend();
499             at = activityManager.suspend();
500             activity = new ONTActivityImpl(tx, at);
501         } catch (javax.transaction.SystemException JavaDoc e) {
502             e.printStackTrace();
503         } catch (ServiceNotRegisteredException e) {
504             e.printStackTrace();
505         } catch (SystemException JavaDoc e) {
506             e.printStackTrace();
507         }
508
509         /* ThreadInfo ti = getThreadInfo();
510                 try {
511                     ti.suspendedAct.push(activityManager.suspend());
512                 } catch (ServiceNotRegisteredException e) {
513                     e.printStackTrace();
514                 } catch (SystemException e) {
515                     e.printStackTrace();
516                 } */

517         return activity;
518     }
519
520     /**
521      * This is a TEST method!!!
522      * It allows to resume the last suspended activity.
523      * @param activity the ONTActivity to be resumed.
524      */

525     public void resume(ONTActivity activity) {
526
527         if (activity != null) {
528             try {
529                 tm.resume(activity.getTransaction());
530                 activityManager.resume(activity.getActivityToken());
531             } catch (Exception JavaDoc e) {
532                 e.printStackTrace();
533             }
534         }
535
536         /*ThreadInfo ti = getThreadInfo();
537         try {
538             activityManager.resume((ActivityToken) ti.suspendedAct.pop());
539         } catch (ServiceNotRegisteredException e) {
540             e.printStackTrace();
541         } catch (SystemException e) {
542             e.printStackTrace();
543         } catch (InvalidActivityException e) {
544             e.printStackTrace();
545         } catch (InvalidParentContextException e) {
546             e.printStackTrace();
547         }*/

548     }
549             
550     // End Test ------------------------------------------------------------------
551

552 }
Popular Tags