KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > TransactionFactoryImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28
29 //----------------------------------------------------------------------------
30
//
31
// Module: TransactionFactoryImpl.java
32
//
33
// Description: TransactionFactory object implementation.
34
//
35
// Product: com.sun.jts.CosTransactions
36
//
37
// Author: Simon Holdsworth
38
//
39
// Date: March, 1997
40
//
41
// Copyright (c): 1995-1997 IBM Corp.
42
//
43
// The source code for this program is not published or otherwise divested
44
// of its trade secrets, irrespective of what has been deposited with the
45
// U.S. Copyright Office.
46
//
47
// This software contains confidential and proprietary information of
48
// IBM Corp.
49
//----------------------------------------------------------------------------
50

51 package com.sun.jts.CosTransactions;
52
53 import org.omg.CORBA.*;
54 import org.omg.PortableServer.*;
55 import org.omg.CosTransactions.*;
56
57 import org.omg.CosNaming.*;
58 import org.omg.CosNaming.NamingContextPackage.*;
59
60 import com.sun.jts.trace.*;
61
62 import java.util.logging.Logger JavaDoc;
63 import java.util.logging.Level JavaDoc;
64 import com.sun.logging.LogDomains;
65 import com.sun.jts.utils.LogFormatter;
66
67 /**
68  * The TransactionFactoryImpl interface is our implementation of the standard
69  * TransactionFactory interface. It provides operations to create the objects
70  * required to process a transaction.
71  *
72  * @version 0.01
73  *
74  * @author Simon Holdsworth, IBM Corporation
75  *
76  * @see
77  */

78
79 //----------------------------------------------------------------------------
80
// CHANGE HISTORY
81
//
82
// Version By Change Description
83
// 0.01 SAJH Initial implementation.
84
//----------------------------------------------------------------------------
85

86 class TransactionFactoryImpl extends TransactionFactoryPOA implements TransactionFactory {
87
88     private static POA poa = null;
89     private TransactionFactory thisRef = null;
90
91     static boolean active = true;
92
93     /*Logger to log transaction messages*/
94     static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER);
95     /**
96      * Constructor for the TransactionFactoryImpl. Passes through
97      * to the parent constructor.
98      *
99      * @param
100      *
101      * @return
102      *
103      * @see
104      */

105     TransactionFactoryImpl() {
106
107         // Initialise the TimeoutManager and RecoveryManager.
108

109         TimeoutManager.initialise();
110         RecoveryManager.initialise();
111     }
112
113     /**
114      * Creates the Coordinator, Control and Terminator objects for a
115      * new top-level transaction.
116      *
117      * @param timeOut The timeout value for the transaction.
118      *
119      * @return The Control object for the new transaction.
120      *
121      * @exception SystemException An error occurred.
122      *
123      * @see
124      */

125     public Control create(int timeOut) throws SystemException {
126
127         Control result = null;
128     
129         ControlImpl cimpl = localCreate(timeOut);
130
131         if (cimpl == null) {
132             return result;
133         }
134
135         if (Configuration.isLocalFactory()) {
136             result = (Control) cimpl;
137         } else {
138             result = cimpl.object();
139         }
140
141         return result;
142     }
143
144     /**
145      * Creates the Coordinator, Control and Terminator objects for a
146      * new top-level transaction.
147      *
148      * @param timeOut The timeout value for the transaction.
149      *
150      * @return The local Control object for the new transaction.
151      *
152      * @exception SystemException An error occurred.
153      *
154      * @see
155      */

156     public ControlImpl localCreate(int timeOut) throws SystemException {
157
158         // If the transaction service is not active, throw an exception.
159

160         if (!active) {
161             NO_PERMISSION exc =
162                 new NO_PERMISSION(0, CompletionStatus.COMPLETED_NO);
163             throw exc;
164         }
165
166         // Ensure that resync has completed.
167

168         RecoveryManager.waitForResync();
169
170         // Create a new top-level Coordinator, and initialise it
171
// with the given time-out value. If the operation fails,
172
// return a NULL Control
173
// object, and whatever exception was raised.
174

175         TopCoordinator coordinator = null;
176         TerminatorImpl terminator = null;
177         ControlImpl result = null;
178
179         try {
180             coordinator = new TopCoordinator(timeOut);
181
182             // Create a Terminator object, and initialise it with
183
// the Coordinator reference and a flag
184
// to indicate that it does not represent a
185
// subtransaction. If the operation fails,
186
// return a NULL Control object, and whatever exception was raised.
187

188             terminator = new TerminatorImpl(coordinator,false);
189
190             // Create a Control object, and initialise it with the Terminator,
191
// Coordinator and global OMGtid. If the operation fails,
192
// return a NULL Control object, and whatever exception was raised.
193

194             // result = new ControlImpl(terminator, coordinator,
195
// new GlobalTID(coordinator.getGlobalTID()),
196
// new Long(coordinator.getLocalTID()));
197
result = new ControlImpl(terminator, coordinator,
198                                      coordinator.getGlobalTid(),
199                                      new Long JavaDoc(coordinator.getLocalTID()));
200             if(_logger.isLoggable(Level.FINE))
201             {
202                 _logger.logp(Level.FINE,"TransactionFactoryImpl","localCreate()",
203                         "Control object :" + result +
204                         " corresponding to this transaction has been created"+
205                         "GTID is : "+
206                         ((TopCoordinator)coordinator).superInfo.globalTID.toString());
207             }
208     
209         } catch (Throwable JavaDoc exc) {
210
211             // If an error occurred, free up the objects.
212

213             if (coordinator != null) {
214                 coordinator.finalize();
215             }
216
217             if (terminator != null) {
218                 terminator.finalize();
219             }
220             if (result != null) {
221                 ((ControlImpl) result).finalize();
222             }
223
224             result = null;
225         }
226
227         return result;
228     }
229
230     /**
231      * Creates the Coordinator, Control and Terminator objects
232      * for a transaction based on the context passed in.
233      *
234      * @param context The context for the transaction.
235      *
236      * @return The Control object for the new transaction.
237      *
238      * @exception SystemException An error occurred.
239      *
240      * @see
241      */

242     public Control recreate(PropagationContext context)
243             throws SystemException {
244
245         // If the transaction service is not active, throw an exception.
246

247         if (!active) {
248             NO_PERMISSION exc =
249                 new NO_PERMISSION(0,CompletionStatus.COMPLETED_NO);
250             throw exc;
251         }
252
253         // If the transaction identifier in the context is NULL, just return.
254

255         if (context.current == null || context.current.otid.formatID == -1) {
256             return null;
257         }
258
259         // First check whether there is already a local subordinate
260
// for the given transaction.
261

262         GlobalTID globalTID = new GlobalTID(context.current.otid);
263         CoordinatorImpl subordinate =
264             RecoveryManager.getCoordinator(globalTID);
265         Control result = null;
266
267         // If there is no local subordinate, but the Coordinator
268
// in the context represents a local object,
269
// then the Coordinator must have been created by the client using
270
// this TransactionFactory, and the transaction it represents
271
// must have been rolled back - invoking a method on the Coordinator
272
// at this point should throw OBJECT_NOT_EXIST. This means that we
273
// cannot import the transaction, and should throw
274
// TRANSACTION_ROLLEDBACK.
275

276         ProxyChecker checker = Configuration.getProxyChecker();
277         if (subordinate == null &&
278                 !checker.isProxy(context.current.coord)) {
279
280             TRANSACTION_ROLLEDBACK exc =
281                 new TRANSACTION_ROLLEDBACK(0, CompletionStatus.COMPLETED_NO);
282             throw exc;
283         }
284
285         // If there is no subordinate, then we must import the transaction.
286
// We first must make sure that resync is not in progress.
287

288         if (subordinate == null) {
289             RecoveryManager.waitForResync();
290             subordinate = RecoveryManager.getCoordinator(globalTID);
291         }
292
293         // If there is no local subordinate, then for each OMGtid
294
// in the context, make sure there is a local
295
// Coordinator set up in this process - required for
296
// AIX, where we need to ensure every ancestor has a locally created
297
// transaction. When we have threading on AIX this will not
298
// be absolutely necessary, but will still be desirable.
299

300         try {
301
302             if (subordinate == null) {
303
304                 if (context.parents.length > 0) {
305
306                     CoordinatorImpl[] newAncestors =
307                         new CoordinatorImpl[context.parents.length];
308
309                     // If there are indeed ancestors, go through them
310
// starting at the top-level
311
// ancestor, which is the last in the sequence.
312

313                     for (int i = context.parents.length - 1; i >= 0; i--) {
314
315                         // If a subordinate does not exist, create one.
316

317                         GlobalTID subGlobalTID =
318                             new GlobalTID(context.parents[i].otid);
319                         subordinate =
320                             RecoveryManager.getCoordinator(subGlobalTID);
321
322                         if (subordinate == null) {
323
324                             if (i == context.parents.length - 1) {
325
326                                 // If it is the last ancestor, create a
327
// temporary top-level subordinate. Use a
328
// duplicate of the proxy to allow the context
329
// to be fully destroyed.
330

331                                 subordinate = new TopCoordinator(
332                                     context.timeout,
333                                     subGlobalTID,
334                                     (Coordinator) context.parents[i].
335                                         coord._duplicate(),
336                                     true);
337
338                             } else {
339
340                                 // If it is not the last ancestor, create a
341
// temporary child subordinate. Use a duplicate
342
// of the proxy to allow the context to be
343
// fully destroyed.
344

345                                 CoordinatorImpl[] subAncestors =
346                                     new CoordinatorImpl[context.parents.length
347                                                         - i - 1];
348                                 System.arraycopy(newAncestors, i + 1,
349                                                  subAncestors, 0,
350                                                  context.
351                                                     parents.length - i - 1);
352
353                                 subordinate =
354                                     new SubCoordinator(
355                                         subGlobalTID,
356                                         (Coordinator)context.parents[i].
357                                             coord._duplicate(),
358                                         true,
359                                         subAncestors);
360
361                                 // Make sure that the parent knows about
362
// its new child.
363

364                                 newAncestors[i+1].addChild(subordinate);
365                             }
366                          }
367
368                         // Replace the Coordinator reference in the sequence
369
// of ancestors with that of the local subordinate,
370
// first releasing the proxy in the context.
371

372                         context.parents[i].coord._release();
373                         newAncestors[i] = subordinate;
374                     }
375
376                     // Now the ancestors have been 'converted' create a
377
// subordinate of the given subtransaction.
378
// Use a duplicate of the proxy to allow
379
// the context to be fully destroyed.
380

381                     subordinate =
382                         new SubCoordinator(globalTID,
383                                            (Coordinator) context.current.
384                                                 coord._duplicate(),
385                                            true,
386                                            newAncestors);
387
388                     //$ This flag was set to false. Surely this subordinate
389
// is temporary?
390

391                     // Make sure the parent knows about its new child.
392

393                     newAncestors[0].addChild(subordinate);
394                 } else {
395
396                     // If there are no ancestors, but the subordinate
397
// does not already exist, create a top-level subordinate.
398
// Use a duplicate of the proxy to allow the context
399
// to be fully destroyed.
400

401                     subordinate = new TopCoordinator(
402                                     context.timeout,
403                                     globalTID,
404                                     (Coordinator) context.
405                                         current.coord._duplicate(),
406                                     true);
407                 }
408
409                 //$ This flag was set to false.
410
// Surely this subordinate is temporary?
411

412             } else {
413
414                 // If there already is a subordinate, then ensure
415
// that it knows it is not a temporary Coordinator.
416
subordinate.setPermanent();
417
418             }
419
420             // Create a new Control object for the transaction.
421
// We do not create a local Terminator
422

423             if (Configuration.isLocalFactory()) {
424                 result = (Control) new ControlImpl(null, subordinate, globalTID,
425                                      new Long JavaDoc(subordinate.getLocalTID())
426                                     );
427             } else {
428                 result = new ControlImpl(null, subordinate, globalTID,
429                                      new Long JavaDoc(subordinate.getLocalTID())
430                                     ).object();
431             }
432
433         } catch (Throwable JavaDoc exc) {
434
435             // If any exception was thrown during that lot, then we
436
// have failed to create a subordinate. Do something drastic.
437
_logger.log(Level.SEVERE,"jts.unable_to_create_subordinate_coordinator");
438              String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
439                                       "jts.unable_to_create_subordinate_coordinator");
440              throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
441         }
442
443         return result;
444     }
445
446     /**
447      * Creates the Coordinator, Control and Terminator objects
448      * for a transaction based on the Xid object passed in.
449      *
450      * @param xid Xid object containing a transaction context.
451      *
452      * @return The Control object for the new transaction.
453      *
454      * @exception SystemException An error occurred.
455      */

456     public Control recreate(GlobalTID tid, int timeout)
457             throws SystemException {
458
459         // If the transaction service is not active, throw an exception.
460
if (!active) {
461             NO_PERMISSION exc =
462                 new NO_PERMISSION(0, CompletionStatus.COMPLETED_NO);
463             throw exc;
464         }
465
466         // First check whether there is already a local subordinate
467
// for the given transaction.
468
CoordinatorImpl subordinate = RecoveryManager.getCoordinator(tid);
469         Control result = null;
470
471         // If there is no subordinate, then we must import the transaction.
472
// We first must make sure that resync is not in progress.
473
if (subordinate == null) {
474             RecoveryManager.waitForResync();
475             subordinate = RecoveryManager.getCoordinator(tid);
476         }
477
478         // If there is no local subordinate, then for each OMGtid
479
// in the context, make sure there is a local
480
// Coordinator set up in this process - required for
481
// AIX, where we need to ensure every ancestor has a locally created
482
// transaction. When we have threading on AIX this will not
483
// be absolutely necessary, but will still be desirable.
484

485         try {
486             if (subordinate == null) {
487                 // If there are no ancestors, but the subordinate
488
// does not already exist, create a top-level subordinate.
489
// Use a duplicate of the proxy to allow the context
490
// to be fully destroyed.
491
subordinate = new TopCoordinator(
492                                 timeout, tid, new TxInflowCoordinator(),
493                                 true);
494             } else {
495                 Status status = subordinate.get_status();
496                 if ((status != Status.StatusMarkedRollback) &&
497                         (status != Status.StatusActive)) {
498                     throw new INVALID_TRANSACTION("tx completion in-progress");
499                 }
500                 // If there already is a subordinate, then ensure
501
// that it knows it is not a temporary Coordinator.
502
subordinate.setPermanent();
503             }
504
505             // Create a new Control object for the transaction.
506
// We do not create a local Terminator.
507
if (Configuration.isLocalFactory()) {
508                 result = (Control) new ControlImpl(null, subordinate, tid,
509                                      new Long JavaDoc(subordinate.getLocalTID())
510                                     );
511             } else {
512                 result = new ControlImpl(null, subordinate, tid,
513                                      new Long JavaDoc(subordinate.getLocalTID())
514                                     ).object();
515             }
516         } catch (Throwable JavaDoc exc) {
517             // If any exception was thrown during that lot, then we
518
// have failed to create a subordinate.
519
_logger.log(Level.WARNING,"jts.unable_to_create_subordinate_coordinator");
520              String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
521                                         "jts.unable_to_create_subordinate_coordinator");
522             // ErrorLog.error(Messages.SUBORDINATE_CREATE_FAILED, null, true);
523
INTERNAL intExc = new INTERNAL(msg);
524             //INTERNAL intExc = new INTERNAL("tx recreate failed");
525
intExc.initCause(exc);
526             throw intExc;
527         }
528
529         return result;
530     }
531
532     /**
533      * Prevents any further transactional activity in the process.
534      *
535      * @param
536      *
537      * @return
538      *
539      * @see
540      */

541     static void deactivate() {
542
543         active = false;
544
545         // Shut down the TimeoutManager and RecoveryManager.
546

547         TimeoutManager.shutdown(false);
548         RecoveryManager.shutdown(false);
549         DelegatedRecoveryManager.shutdown(false);
550     }
551
552     /**Returns the CORBA Object which represents this object.
553      *
554      * @param
555      *
556      * @return The CORBA object.
557      *
558      * @see
559      */

560     synchronized TransactionFactory object() {
561         if (thisRef == null) {
562             if (poa == null) {
563                 poa = Configuration.getPOA("transient"/*#Frozen*/);
564             }
565
566             try {
567                 poa.activate_object(this);
568                 thisRef = TransactionFactoryHelper.
569                             narrow(poa.servant_to_reference(this));
570                 //thisRef = (TransactionFactory)this;
571

572                 /*
573                  * ADDED(Ram J) Whenever a TransactionFactory corba object is
574                  * created, put it in the cosnaming service.
575                  */

576
577                 NamingContext namingContext = null;
578                 try {
579                     namingContext = NamingContextHelper.narrow(
580                         Configuration.getORB().resolve_initial_references("NameService"/*#Frozen*/));
581                 } catch (Exception JavaDoc exc) {
582                     _logger.log(Level.WARNING,"jts.orb_not_running");
583                 }
584
585                 try {
586                     NameComponent nc = new NameComponent(TransactionFactoryHelper.id(), "");
587                     NameComponent path[] = { nc };
588                     namingContext.rebind(path, thisRef);
589                 } catch (Exception JavaDoc exc) {
590                     _logger.log(Level.WARNING,"jts.cannot_register_with_orb",
591                             "TransactionFactory");
592                 }
593             } catch (Exception JavaDoc exc) {
594                 _logger.log(Level.SEVERE,"jts.create_transactionfactory_object_error");
595                  String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
596                                         "jts.create_transactionfactory_object_error");
597                  throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
598             }
599         }
600
601         return thisRef;
602     }
603
604     /**Returns the TransactionFactoryImpl which serves the given object.
605      *
606      * @param The CORBA Object.
607      *
608      * @return The TransactionFactoryImpl object which serves it.
609      *
610      * @see
611      */

612     synchronized static final TransactionFactoryImpl servant(TransactionFactory factory) {
613         TransactionFactoryImpl result = null;
614
615         // we will not be able to obtain the
616
// servant from our local POA for a proxy factory object.
617
// so return null
618
if (factory != null && Configuration.getProxyChecker().isProxy(factory)) {
619             return result;
620         }
621
622         if (factory instanceof TransactionFactoryImpl ) {
623             result = (TransactionFactoryImpl) factory;
624         } else if (poa != null) {
625             try {
626                 result = (TransactionFactoryImpl) poa.reference_to_servant(factory);
627                 if( result.thisRef == null )
628                     result.thisRef = factory;
629             } catch( Exception JavaDoc exc ) {
630                 _logger.log(Level.WARNING,"jts.cannot_locate_servant",
631                         "TransactionFactory");
632             }
633         }
634
635         return result;
636     }
637
638     /*
639      * These methods are there to satisy the compiler. At some point
640      * when we move towards a tie based model, the org.omg.Corba.Object
641      * interface method implementation below shall be discarded.
642      */

643
644     public org.omg.CORBA.Object JavaDoc _duplicate() {
645         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
646     }
647
648     public void _release() {
649         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
650     }
651
652     public boolean _is_a(String JavaDoc repository_id) {
653         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
654     }
655
656     public boolean _is_equivalent(org.omg.CORBA.Object JavaDoc that) {
657         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
658     }
659
660     public boolean _non_existent() {
661         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
662     }
663
664     public int _hash(int maximum) {
665         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
666     }
667
668     public Request _request(String JavaDoc operation) {
669         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
670     }
671
672     public Request _create_request(Context ctx,
673                    String JavaDoc operation,
674                    NVList arg_list,
675                    NamedValue result) {
676         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
677     }
678
679     public Request _create_request(Context ctx,
680                    String JavaDoc operation,
681                    NVList arg_list,
682                    NamedValue result,
683                    ExceptionList exceptions,
684                    ContextList contexts) {
685         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
686     }
687
688     public org.omg.CORBA.Object JavaDoc _get_interface_def() {
689         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
690     }
691
692     public org.omg.CORBA.Policy JavaDoc _get_policy(int policy_type) {
693         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
694     }
695
696     public org.omg.CORBA.DomainManager JavaDoc[] _get_domain_managers() {
697         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
698     }
699
700     public org.omg.CORBA.Object JavaDoc _set_policy_override(
701             org.omg.CORBA.Policy JavaDoc[] policies,
702             org.omg.CORBA.SetOverrideType JavaDoc set_add) {
703         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc("This is a locally constrained object.");
704     }
705 }
706
Popular Tags