KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > tm > iiop > OTSServant


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;
23
24 import javax.transaction.HeuristicCommitException JavaDoc;
25 import javax.transaction.HeuristicMixedException JavaDoc;
26 import javax.transaction.HeuristicRollbackException JavaDoc;
27 import javax.transaction.NotSupportedException JavaDoc;
28 import javax.transaction.RollbackException JavaDoc;
29 import javax.transaction.SystemException JavaDoc;
30 import javax.transaction.Transaction JavaDoc;
31 import javax.transaction.TransactionManager JavaDoc;
32 import javax.transaction.xa.XAResource JavaDoc;
33 import javax.transaction.xa.Xid JavaDoc;
34
35 import org.omg.CORBA.BAD_INV_ORDER JavaDoc;
36 import org.omg.CORBA.BAD_OPERATION JavaDoc;
37 import org.omg.CORBA.BAD_PARAM JavaDoc;
38 import org.omg.CORBA.OBJECT_NOT_EXIST JavaDoc;
39 import org.omg.CORBA.ORB JavaDoc;
40 import org.omg.CORBA.TRANSIENT JavaDoc;
41 import org.omg.CORBA.ORBPackage.InvalidName JavaDoc;
42 import org.omg.CORBA.NO_PERMISSION JavaDoc;
43 import org.omg.CORBA.TRANSACTION_ROLLEDBACK JavaDoc;
44 import org.omg.CORBA.UNKNOWN JavaDoc;
45 import org.omg.CosTransactions.Control;
46 import org.omg.CosTransactions.ControlHelper;
47 import org.omg.CosTransactions.Coordinator;
48 import org.omg.CosTransactions.CoordinatorHelper;
49 import org.omg.CosTransactions.HeuristicCommit;
50 import org.omg.CosTransactions.HeuristicHazard;
51 import org.omg.CosTransactions.HeuristicMixed;
52 import org.omg.CosTransactions.HeuristicRollback;
53 import org.omg.CosTransactions.Inactive;
54 import org.omg.CosTransactions.NotPrepared;
55 import org.omg.CosTransactions.NotSubtransaction;
56 import org.omg.CosTransactions.PropagationContext;
57 import org.omg.CosTransactions.RecoveryCoordinator;
58 import org.omg.CosTransactions.RecoveryCoordinatorHelper;
59 import org.omg.CosTransactions.Resource;
60 import org.omg.CosTransactions.ResourceHelper;
61 import org.omg.CosTransactions.ResourcePOA;
62 import org.omg.CosTransactions.Status;
63 import org.omg.CosTransactions.SubtransactionAwareResource;
64 import org.omg.CosTransactions.SubtransactionsUnavailable;
65 import org.omg.CosTransactions.Synchronization;
66 import org.omg.CosTransactions.SynchronizationUnavailable;
67 import org.omg.CosTransactions.Terminator;
68 import org.omg.CosTransactions.TerminatorHelper;
69 import org.omg.CosTransactions.TransactionFactoryHelper;
70 import org.omg.CosTransactions.TransIdentity;
71 import org.omg.CosTransactions.Unavailable;
72 import org.omg.CosTransactions.Vote;
73 import org.omg.CosTransactions.otid_t;
74 import org.omg.PortableServer.POA JavaDoc;
75 import org.omg.PortableServer.Servant JavaDoc;
76 import org.omg.PortableServer.CurrentPackage.NoContext JavaDoc;
77
78 import org.jboss.logging.Logger;
79 import org.jboss.tm.LocalId;
80 import org.jboss.tm.OTSContextFactory;
81 import org.jboss.tm.ResourceFactory;
82 import org.jboss.tm.StringRemoteRefConverter;
83 import org.jboss.tm.TransactionImpl;
84 import org.jboss.tm.TMUtil;
85 import org.jboss.tm.TxManager;
86 import org.jboss.tm.XidImpl;
87 import org.jboss.tm.iiop.wrapper.OTSCoordinatorWrapper;
88 import org.jboss.tm.iiop.wrapper.OTSRecoveryCoordinatorWrapper;
89 import org.jboss.tm.iiop.wrapper.OTSResourceWrapper;
90 import org.jboss.tm.remoting.interfaces.HeuristicHazardException;
91 import org.jboss.util.UnreachableStatementException;
92
93 /**
94  * CORBA servant for the JBoss Transaction Service.
95  *
96  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
97  * @version $Revision: 42303 $
98  */

99 public class OTSServant
100       extends TransactionServicePOA
101       implements ResourceFactory,
102                  OTSContextFactory,
103                  StringRemoteRefConverter
104 {
105    // Constants ----------------------------------------------------
106

107    private static final Logger log =
108       Logger.getLogger(OTSServant.class);
109
110    // The first byte of our CORBA oids tells the type of the object:
111

112    /** Value in position 0 of the oid within a Control reference. */
113    private static final byte CONTROL = 0x43;
114
115    /** Value in position 0 of the oid within a Coordinator reference. */
116    private static final byte COORDINATOR = 0x63;
117
118    /** Value in position 0 of the oid within a TransactionFactory reference. */
119    private static final byte TX_FACTORY = 0x46;
120
121    /** Value in position 0 of the oid within a Terminator reference. */
122    private static final byte TERMINATOR = 0x74;
123
124    /** Value in position 0 of the oid within a RecoveryCoordinator reference. */
125    private static final byte RECOVERY_COORDINATOR = 0x76;
126
127    /** Value in position 0 of the oid within a Resource reference. */
128    private static final byte RESOURCE = 0x72;
129
130    // String arrays returned by _all_interfaces:
131

132    /** Interface ids of Control and its superinterfaces. */
133    private static final String JavaDoc[] controlInterfaceIds = {
134       ControlHelper.id()
135    };
136
137    /** Interface ids of CoordinatorExt and its superinterfaces. */
138    private static final String JavaDoc[] coordinatorInterfaceIds = {
139       CoordinatorExtHelper.id(),
140       CoordinatorHelper.id()
141    };
142
143    /** Interface ids of TransactionFactoryExt and its superinterfaces. */
144    private static final String JavaDoc[] txFactoryInterfaceIds = {
145       TransactionFactoryExtHelper.id(),
146       TransactionFactoryHelper.id()
147    };
148
149    /** Interface ids of Terminator and its superinterfaces. */
150    private static final String JavaDoc[] terminatorInterfaceIds = {
151       TerminatorHelper.id()
152    };
153
154    /** Interface ids of RecoveryCoordinator and its superinterfaces. */
155    private static final String JavaDoc[] recoveryCoordinatorInterfaceIds = {
156       RecoveryCoordinatorHelper.id()
157    };
158
159    // Attributes ----------------------------------------------------
160

161    private ORB JavaDoc orb;
162    private POA poa;
163    private POA resourcePoa;
164    private ResourceImpl resourceServant;
165    private org.omg.PortableServer.Current JavaDoc poaCurrent;
166
167    // Package -------------------------------------------------------
168

169    static byte[] theFactoryId() { return new byte[] { TX_FACTORY }; }
170
171    // Constructor ---------------------------------------------------
172

173    OTSServant(ORB JavaDoc orb, POA poa, POA resourcePoa)
174    {
175       this.orb = orb;
176       this.poa = poa;
177       this.resourcePoa = resourcePoa;
178       this.resourceServant = new ResourceImpl();
179
180       try
181       {
182          org.omg.CORBA.Object JavaDoc obj =
183             orb.resolve_initial_references("POACurrent");
184          poaCurrent = org.omg.PortableServer.CurrentHelper.narrow(obj);
185       }
186       catch (InvalidName JavaDoc e) // thrown by resolve_initial_references
187
{
188          log.warn("Call to resolve_initial_references failed: ", e);
189          throw new RuntimeException JavaDoc(
190                            "Call to resolve_initial_references failed: ", e);
191       }
192       catch (BAD_PARAM JavaDoc e) // thrown by narrow
193
{
194          log.warn("Call to narrow failed: ", e);
195          throw new RuntimeException JavaDoc("Call to narrow failed: ", e);
196       }
197    }
198
199    // Attribute -----------------------------------------------------
200

201    /**
202     * Returns the default servant for OTS <code>Resource</code>s.
203     */

204    public Servant JavaDoc getResourceServant()
205    {
206       return resourceServant;
207    }
208
209    // org.omg.PortableServer.Servant override -----------------------
210

211    public String JavaDoc[] _all_interfaces(POA poa, byte[] oid)
212    {
213       if (oid[0] == TX_FACTORY)
214          return txFactoryInterfaceIds;
215       else if (oid[0] == CONTROL)
216          return controlInterfaceIds;
217       else if (oid[0] == COORDINATOR)
218          return coordinatorInterfaceIds;
219       else if (oid[0] == TERMINATOR)
220          return terminatorInterfaceIds;
221       else if (oid[0] == RECOVERY_COORDINATOR)
222          return recoveryCoordinatorInterfaceIds;
223       else
224          throw new BAD_PARAM JavaDoc("Unknown CORBA object id");
225    }
226
227    // TransactionFactoryExt operation -------------------------------
228

229    public TransactionDesc create_transaction(int timeout)
230    {
231       log.trace("TransactionFactoryExt.create_transaction");
232       checkInvocationTarget(TX_FACTORY);
233       try
234       {
235          TransactionManager JavaDoc tm = TMUtil.getTransactionManager();
236
237          // Set timeout value
238
if (timeout != 0)
239             tm.setTransactionTimeout(timeout);
240
241          // Start tx
242
tm.begin();
243
244          // Suspend thread association
245
// and get the xid and the local id the transaction
246
TransactionImpl tx = (TransactionImpl)tm.suspend();
247          XidImpl xid = tx.getXid();
248          long localId = xid.getLocalIdValue();
249
250          // Set up oid byte array to create CORBA reference to the Coordinator
251
byte[] oid = new byte[9];
252          oid[0] = COORDINATOR;
253          LocalId.toByteArray(localId, oid, 1);
254
255          // Create CORBA reference to the Coordinator
256
Coordinator coord = CoordinatorHelper.narrow(
257                poa.create_reference_with_id(oid, CoordinatorHelper.id()));
258
259          // Reuse the oid array to create CORBA reference to the Terminnator
260
oid[0] = TERMINATOR;
261          Terminator JavaDoc term = TerminatorHelper.narrow(
262                poa.create_reference_with_id(oid, TerminatorHelper.id()));
263
264          // Create and initialize PropagationContext object
265
PropagationContext pc = new PropagationContext();
266          pc.current = createTransIdentity(xid, coord, term);
267          pc.timeout = timeout;
268          pc.parents = new TransIdentity[0];
269          pc.implementation_specific_data = orb.create_any();
270
271          // Create and initialize TransactionDesc object
272
TransactionDesc td = new TransactionDesc();
273          td.control = ControlHelper.narrow(
274                      poa.create_reference_with_id(oid, ControlHelper.id()));
275          td.propagationContext = pc;
276
277          // Return TransactionDesc
278
return td;
279       }
280       catch (SystemException JavaDoc e)
281       {
282          if (log.isTraceEnabled())
283             log.trace("Unexpected exception: ", e);
284          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
285          ex.initCause(e);
286          throw ex;
287
288       }
289       catch (NotSupportedException JavaDoc e)
290       {
291          if (log.isTraceEnabled())
292             log.trace("Unexpected exception: ", e);
293          BAD_INV_ORDER JavaDoc ex = new BAD_INV_ORDER JavaDoc();
294          ex.initCause(e);
295          throw ex;
296       }
297    }
298
299    // CosTransactions::TransactionFactory operations ----------------
300

301    public Control create(int timeout)
302    {
303       log.trace("TransactionFactory.create");
304       checkInvocationTarget(TX_FACTORY);
305       try
306       {
307          TransactionManager JavaDoc tm = TMUtil.getTransactionManager();
308
309          // Set timeout value
310
if (timeout != 0)
311             tm.setTransactionTimeout(timeout);
312
313          // Start tx
314
tm.begin();
315
316          // Suspend thread association
317
// and get the xid and the local id the transaction
318
TransactionImpl tx = (TransactionImpl)tm.suspend();
319          XidImpl xid = tx.getXid();
320          long localId = xid.getLocalIdValue();
321
322          // Set up oid byte array to create CORBA reference to the Control
323
byte[] oid = new byte[9];
324          oid[0] = CONTROL;
325          LocalId.toByteArray(localId, oid, 1);
326
327          // Return CORBA reference to the control
328
return ControlHelper.narrow(
329                      poa.create_reference_with_id(oid, ControlHelper.id()));
330       }
331       catch (SystemException JavaDoc e)
332       {
333          if (log.isTraceEnabled())
334             log.trace("Unexpected exception: ", e);
335          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
336          ex.initCause(e);
337          throw ex;
338       }
339       catch (NotSupportedException JavaDoc e)
340       {
341          if (log.isTraceEnabled())
342             log.trace("Unexpected exception: ", e);
343          BAD_INV_ORDER JavaDoc ex = new BAD_INV_ORDER JavaDoc();
344          ex.initCause(e);
345          throw ex;
346       }
347    }
348
349    public Control recreate(PropagationContext pc)
350    {
351       log.trace("TransactionFactory.recreate");
352       checkInvocationTarget(TX_FACTORY);
353
354       if (pc == null)
355          throw new BAD_PARAM JavaDoc(
356                "recreate: PropagationContext parameter cannot be null");
357       
358       // prune the branch qualifier part of the OTS tid
359
byte[] globalId =
360          new byte[pc.current.otid.tid.length - pc.current.otid.bqual_length];
361       System.arraycopy(pc.current.otid.tid, 0, globalId, 0, globalId.length);
362       
363       // import the transaction
364
TxManager tm = (TxManager) TMUtil.getTransactionManager();
365       TransactionImpl tx =
366          tm.importExternalTransaction(pc.current.otid.formatID,
367                                       globalId,
368                                       new OTSCoordinatorWrapper(pc.current.coord),
369                                       pc.timeout * 1000);
370
371       // Set up oid byte array to create CORBA reference to the Control
372
byte[] oid = new byte[9];
373       oid[0] = CONTROL;
374       LocalId.toByteArray(tx.getLocalIdValue(), oid, 1);
375
376       // Return CORBA reference to the control
377
return ControlHelper.narrow(
378                   poa.create_reference_with_id(oid, ControlHelper.id()));
379       
380    }
381
382    // CosTransactions::Control operations ---------------------------
383

384    public Terminator JavaDoc get_terminator()
385       throws Unavailable
386    {
387       byte[] oid = getTargetId();
388       if (oid[0] != CONTROL)
389          throw new BAD_OPERATION JavaDoc();
390       
391       long localIdValue = LocalId.fromByteArray(oid, 1);
392
393       if (log.isTraceEnabled())
394          log.trace("Control.get_terminator, targetId=" +
395                    Long.toHexString(localIdValue));
396
397       LocalId localId = new LocalId(localIdValue);
398       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
399       if (tx.isImported())
400             throw new Unavailable("Terminator not available " +
401                                   "for imported transactions");
402       oid[0] = TERMINATOR;
403       return TerminatorHelper.narrow(
404                   poa.create_reference_with_id(oid, TerminatorHelper.id()));
405    }
406
407    public Coordinator get_coordinator()
408       throws Unavailable
409    {
410       byte[] oid = getTargetId();
411
412       if (log.isTraceEnabled())
413       {
414          long localIdValue = LocalId.fromByteArray(oid, 1);
415          log.trace("Control.get_coordinator, targetId=" +
416                    Long.toHexString(localIdValue));
417       }
418
419       if (oid[0] != CONTROL)
420          throw new BAD_OPERATION JavaDoc();
421       oid[0] = COORDINATOR;
422       return CoordinatorHelper.narrow(
423                   poa.create_reference_with_id(oid, CoordinatorHelper.id()));
424    }
425
426    // CosTransactions::Terminator operations ------------------------
427

428    public void commit(boolean reportHeuristics)
429       throws HeuristicHazard, HeuristicMixed
430    {
431       byte[] oid = getTargetId();
432       if (oid[0] != TERMINATOR)
433          throw new BAD_OPERATION JavaDoc();
434
435       long localIdValue = LocalId.fromByteArray(oid, 1);
436
437       if (log.isTraceEnabled())
438          log.trace("Terminator.commit, targetId=" +
439                    Long.toHexString(localIdValue));
440
441       LocalId localId = new LocalId(localIdValue);
442       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
443
444       if (tx == null)
445       {
446          log.trace("RuntimeException in commit: transaction not found");
447          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
448       }
449
450       try
451       {
452          tx.commit();
453       }
454       catch (RollbackException JavaDoc e)
455       {
456          if (log.isTraceEnabled())
457             log.trace("Exception: ", e);
458          TRANSACTION_ROLLEDBACK JavaDoc ex = new TRANSACTION_ROLLEDBACK JavaDoc();
459          ex.initCause(e);
460          throw ex;
461       }
462       catch (HeuristicMixedException JavaDoc e)
463       {
464          if (log.isTraceEnabled())
465             log.trace("Exception: ", e);
466          if (reportHeuristics)
467          {
468             HeuristicMixed ex = new HeuristicMixed();
469             ex.initCause(e);
470             throw ex;
471          }
472       }
473       catch (HeuristicRollbackException JavaDoc e)
474       {
475          if (log.isTraceEnabled())
476             log.trace("Exception: ", e);
477          TRANSACTION_ROLLEDBACK JavaDoc ex = new TRANSACTION_ROLLEDBACK JavaDoc();
478          ex.initCause(e);
479          throw ex;
480       }
481       catch (SecurityException JavaDoc e)
482       {
483          if (log.isTraceEnabled())
484             log.trace("Unexpected exception: ", e);
485          NO_PERMISSION JavaDoc ex = new NO_PERMISSION JavaDoc();
486          ex.initCause(e);
487          throw ex;
488       }
489       catch (IllegalStateException JavaDoc e)
490       {
491          if (log.isTraceEnabled())
492             log.trace("Unexpected exception: ", e);
493          BAD_INV_ORDER JavaDoc ex = new BAD_INV_ORDER JavaDoc();
494          ex.initCause(e);
495          throw ex;
496       }
497       catch (SystemException JavaDoc e)
498       {
499          if (log.isTraceEnabled())
500             log.trace("Unexpected exception: ", e);
501          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
502          ex.initCause(e);
503          throw ex;
504       }
505    }
506
507    public void rollback()
508    {
509       byte[] oid = getTargetId();
510       if (oid[0] != TERMINATOR)
511          throw new BAD_OPERATION JavaDoc();
512
513       long localIdValue = LocalId.fromByteArray(oid, 1);
514
515       if (log.isTraceEnabled())
516          log.trace("Terminator.rollback, targetId=" +
517                    Long.toHexString(localIdValue));
518
519       LocalId localId = new LocalId(localIdValue);
520       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
521
522       if (tx == null)
523       {
524          log.trace("RuntimeException in rollback: transaction not found");
525          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
526       }
527
528       try
529       {
530          tx.rollback();
531       }
532       catch (IllegalStateException JavaDoc e)
533       {
534          if (log.isTraceEnabled())
535             log.trace("Unexpected exception: ", e);
536          BAD_INV_ORDER JavaDoc ex = new BAD_INV_ORDER JavaDoc();
537          ex.initCause(e);
538          throw ex;
539       }
540       catch (SecurityException JavaDoc e)
541       {
542          if (log.isTraceEnabled())
543             log.trace("Unexpected exception: ", e);
544          NO_PERMISSION JavaDoc ex = new NO_PERMISSION JavaDoc();
545          ex.initCause(e);
546          throw ex;
547       }
548       catch (SystemException JavaDoc e)
549       {
550          if (log.isTraceEnabled())
551             log.trace("Unexpected exception: ", e);
552          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
553          ex.initCause(e);
554          throw ex;
555       }
556    }
557
558    // CoordinatorExt operation --------------------------------------
559

560    public TransactionId get_transaction_id()
561    {
562       byte[] oid = getTargetId();
563       if (oid[0] != COORDINATOR)
564          throw new BAD_OPERATION JavaDoc();
565
566       long localIdValue = LocalId.fromByteArray(oid, 1);
567
568       if (log.isTraceEnabled())
569          log.trace("CoordinatorExt.get_transaction_id, targetId=" +
570                    Long.toHexString(localIdValue));
571
572       LocalId localId = new LocalId(localIdValue);
573       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
574
575       if (tx == null)
576       {
577          log.trace("RuntimeException in get_transaction_id: " +
578                    "transaction not found");
579          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
580       }
581       
582       Xid JavaDoc xid = tx.getXid();
583       return new TransactionId(xid.getFormatId(),
584                                xid.getGlobalTransactionId());
585    }
586
587    // CosTransactions::Coordinator operations -----------------------
588

589    public Status get_status()
590    {
591       byte[] oid = getTargetId();
592       if (oid[0] != COORDINATOR)
593          throw new BAD_OPERATION JavaDoc();
594
595       long localIdValue = LocalId.fromByteArray(oid, 1);
596
597       if (log.isTraceEnabled())
598          log.trace("Coordinator.get_status, targetId=" +
599                    Long.toHexString(localIdValue));
600
601       LocalId localId = new LocalId(localIdValue);
602       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
603
604       if (tx == null)
605       {
606          log.trace("RuntimeException in get_status: transaction not found");
607          // Not sure if here I should return StatusNoTransaction
608
// instead of throwing OBJECT_NOT_EXIST... (Francisco)
609
throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
610          // return org.omg.CosTransactions.Status.StatusNoTransaction; // ?
611
}
612       
613       int status;
614
615       try
616       {
617          status = tx.getStatus();
618       }
619       catch (SystemException JavaDoc e)
620       {
621          if (log.isTraceEnabled())
622             log.trace("Unexpected exception: ", e);
623          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
624          ex.initCause(e);
625          throw ex;
626       }
627       return javaxToCosTransactions(status);
628    }
629
630    public Status get_parent_status()
631    {
632       // The target coordinator is associated with a top-level
633
// transaction, because we do not support nested transactions.
634
// Therefore get_parent_status() is equivalent to get_status().
635
return get_status();
636    }
637
638    public Status get_top_level_status()
639    {
640       // The target coordinator is associated with a top-level
641
// transaction, because we do not support nested transactions.
642
// Therefore get_top_level_status() is equivalent to get_status().
643
return get_status();
644    }
645
646    public boolean is_same_transaction(Coordinator other)
647    {
648       byte[] oid = getTargetId();
649       if (oid[0] != COORDINATOR)
650          throw new BAD_OPERATION JavaDoc();
651
652       long localIdValue = LocalId.fromByteArray(oid, 1);
653
654       if (log.isTraceEnabled())
655          log.trace("Coordinator.is_same_transaction, targetId=" +
656                    Long.toHexString(localIdValue));
657
658       LocalId localId = new LocalId(localIdValue);
659       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
660
661       if (tx == null)
662       {
663          log.trace("RuntimeException in is_same_transaction: " +
664                    "transaction not found");
665          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
666       }
667       
668       Xid JavaDoc xid = tx.getXid();
669
670       try
671       {
672          CoordinatorExt otherExt = CoordinatorExtHelper.narrow(other);
673          TransactionId otherId = otherExt.get_transaction_id();
674          return compare(xid,
675                         otherId.formatId,
676                         otherId.globalId,
677                         otherId.globalId.length);
678       }
679       catch (BAD_PARAM JavaDoc e)
680       {
681           // narrow failed: foreign transaction case
682
try
683          {
684             otid_t otherOtid = other.get_txcontext().current.otid;
685             return compare(xid,
686                            otherOtid.formatID,
687                            otherOtid.tid,
688                            otherOtid.tid.length - otherOtid.bqual_length);
689          }
690          catch (Unavailable u)
691          {
692             if (log.isTraceEnabled())
693                log.trace(
694                   "Foreign Coordinator do not support get_txcontext(): ", e);
695             BAD_PARAM JavaDoc ex = new BAD_PARAM JavaDoc();
696             ex.initCause(e);
697             throw ex;
698          }
699       }
700    }
701
702    public boolean is_ancestor_transaction(Coordinator other)
703    {
704       // We do not support nested transactions. In this case
705
// is_ancestor_transaction() is equivalent to is_same_transaction().
706
return is_same_transaction(other);
707    }
708
709    public boolean is_descendant_transaction(Coordinator other)
710    {
711       // We do not support nested transactions. In this case
712
// is_descendant_transaction() is equivalent to is_same_transaction().
713
return is_same_transaction(other);
714    }
715
716    public boolean is_related_transaction(Coordinator other)
717    {
718       // We do not support nested transactions. In this case
719
// is_descendant_transaction() is equivalent to is_same_transaction().
720
return is_same_transaction(other);
721    }
722
723    public boolean is_top_level_transaction()
724    {
725       checkInvocationTarget(COORDINATOR);
726       return true; // because we do not support nested transactions.
727
}
728
729    public int hash_transaction()
730    {
731       byte[] oid = getTargetId();
732       if (oid[0] != COORDINATOR)
733          throw new BAD_OPERATION JavaDoc();
734
735       long localIdValue = LocalId.fromByteArray(oid, 1);
736
737       if (log.isTraceEnabled())
738          log.trace("Coordinator.hash_transaction, targetId=" +
739                    Long.toHexString(localIdValue));
740
741       LocalId localId = new LocalId(localIdValue);
742       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
743       if (tx == null)
744       {
745          log.trace("RuntimeException in is_same_transaction: " +
746                    "transaction not found");
747          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
748       }
749       return tx.getGlobalId().hashCode();
750    }
751
752    public int hash_top_level_tran()
753    {
754       // We do not support nested transactions. In this case
755
// hash_top_level_transaction() is equivalent to hash_transaction().
756
return hash_transaction();
757    }
758
759    public RecoveryCoordinator register_resource(Resource JavaDoc r)
760       throws Inactive
761    {
762       byte[] oid = getTargetId();
763       if (oid[0] != COORDINATOR)
764          throw new BAD_OPERATION JavaDoc();
765
766       long localIdValue = LocalId.fromByteArray(oid, 1);
767
768       if (log.isTraceEnabled())
769          log.trace("Coordinator.register_resource, targetId=" +
770                    Long.toHexString(localIdValue));
771
772       LocalId localId = new LocalId(localIdValue);
773       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
774
775       if (tx == null)
776       {
777          log.trace("RuntimeException in register_resource: " +
778                    "transaction not found");
779          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
780       }
781
782       try
783       {
784          tx.enlistRemoteResource(new OTSResourceWrapper(r));
785       }
786       catch (RollbackException JavaDoc e)
787       {
788          if (log.isTraceEnabled())
789             log.trace("Exception: ", e);
790          TRANSACTION_ROLLEDBACK JavaDoc ex = new TRANSACTION_ROLLEDBACK JavaDoc();
791          ex.initCause(e);
792          throw ex;
793       }
794       catch (IllegalStateException JavaDoc e)
795       {
796          if (log.isTraceEnabled())
797             log.trace("Exception: ", e);
798          Inactive ex = new Inactive();
799          ex.initCause(e);
800          throw ex;
801       }
802
803       // Create and return a RecoveryCoordinator reference
804
oid[0] = RECOVERY_COORDINATOR;
805       return RecoveryCoordinatorHelper.narrow(
806                   poa.create_reference_with_id(oid,
807                                                RecoveryCoordinatorHelper.id()));
808    }
809
810    public void register_synchronization(final Synchronization sync)
811       throws SynchronizationUnavailable, Inactive
812    {
813       byte[] oid = getTargetId();
814       if (oid[0] != COORDINATOR)
815          throw new BAD_OPERATION JavaDoc();
816
817       long localIdValue = LocalId.fromByteArray(oid, 1);
818
819       if (log.isTraceEnabled())
820          log.trace("Coordinator.register_synchronization, targetId=" +
821                    Long.toHexString(localIdValue));
822
823       LocalId localId = new LocalId(localIdValue);
824       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
825
826       if (tx == null)
827       {
828          log.trace("RuntimeException in register_synchronization: " +
829                    "transaction not found");
830          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
831       }
832       
833       try
834       {
835          tx.registerSynchronization(
836             new javax.transaction.Synchronization JavaDoc()
837             {
838                public void beforeCompletion()
839                {
840                   sync.before_completion();
841                }
842                public void afterCompletion(int status)
843                {
844                   sync.after_completion(javaxToCosTransactions(status));
845                }
846             });
847       }
848       catch (RollbackException JavaDoc e)
849       {
850          if (log.isTraceEnabled())
851             log.trace("Exception: ", e);
852          TRANSACTION_ROLLEDBACK JavaDoc ex = new TRANSACTION_ROLLEDBACK JavaDoc();
853          ex.initCause(e);
854          throw ex;
855       }
856       catch (IllegalStateException JavaDoc e)
857       {
858          if (log.isTraceEnabled())
859             log.trace("Unexpected exception: ", e);
860          Inactive ex = new Inactive();
861          ex.initCause(e);
862          throw ex;
863       }
864       catch (SystemException JavaDoc e)
865       {
866          if (log.isTraceEnabled())
867             log.trace("Unexpected exception: ", e);
868          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
869          ex.initCause(e);
870          throw ex;
871       }
872    }
873
874    public void register_subtran_aware(SubtransactionAwareResource r)
875       throws NotSubtransaction, Inactive
876    {
877       checkInvocationTarget(COORDINATOR);
878       throw new NotSubtransaction("Nested transactions are not supported");
879    }
880
881    public void rollback_only()
882       throws Inactive
883    {
884       byte[] oid = getTargetId();
885       if (oid[0] != COORDINATOR)
886          throw new BAD_OPERATION JavaDoc();
887
888       long localIdValue = LocalId.fromByteArray(oid, 1);
889
890       if (log.isTraceEnabled())
891          log.trace("Coordinator.rollback_only, targetId=" +
892                    Long.toHexString(localIdValue));
893
894       LocalId localId = new LocalId(localIdValue);
895       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
896
897       if (tx == null)
898       {
899          log.trace("RuntimeException in rollback_only: transaction not found");
900          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
901       }
902
903       try
904       {
905          tx.setRollbackOnly();
906       }
907       catch (IllegalStateException JavaDoc e)
908       {
909          if (log.isTraceEnabled())
910             log.trace("Unexpected exception: ", e);
911          Inactive ex = new Inactive();
912          ex.initCause(e);
913          throw ex;
914       }
915       catch (SystemException JavaDoc e)
916       {
917          if (log.isTraceEnabled())
918             log.trace("Unexpected exception: ", e);
919          UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
920          ex.initCause(e);
921          throw ex;
922       }
923    }
924
925    public String JavaDoc get_transaction_name()
926    {
927       byte[] oid = getTargetId();
928       if (oid[0] != COORDINATOR)
929          throw new BAD_OPERATION JavaDoc();
930
931       long localIdValue = LocalId.fromByteArray(oid, 1);
932
933       if (log.isTraceEnabled())
934          log.trace("Coordinator.get_transaction_name, targetId=" +
935                    Long.toHexString(localIdValue));
936
937       LocalId localId = new LocalId(localIdValue);
938       Transaction JavaDoc tx = TMUtil.getTransaction(localId);
939
940       if (tx == null)
941       {
942          log.trace("RuntimeException in get_transaction_name: " +
943                    "transaction not found");
944          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
945       }
946       return tx.toString();
947    }
948
949    public Control create_subtransaction()
950       throws SubtransactionsUnavailable, Inactive
951    {
952       checkInvocationTarget(COORDINATOR);
953       throw new SubtransactionsUnavailable(
954                               "Nested transactions are not supported");
955    }
956
957    public PropagationContext get_txcontext()
958       throws Unavailable
959    {
960       byte[] oid = getTargetId();
961       if (oid[0] != COORDINATOR)
962          throw new BAD_OPERATION JavaDoc();
963       
964       long localIdValue = LocalId.fromByteArray(oid, 1);
965
966       if (log.isTraceEnabled())
967          log.trace("Coordinator.get_txcontext, targetId=" +
968                    Long.toHexString(localIdValue));
969
970       LocalId localId = new LocalId(localIdValue);
971       TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
972       if (tx == null)
973       {
974          log.trace("RuntimeException in get_txcontext: transaction not found");
975          throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
976       }
977       Xid JavaDoc xid = tx.getXid();
978
979       // Create CORBA reference to the Coordinator (the target of this call)
980
Coordinator coord = CoordinatorHelper.narrow(
981             poa.create_reference_with_id(oid, CoordinatorHelper.id()));
982
983       // Create and initialize PropagationContext object
984
PropagationContext pc = new PropagationContext();
985       pc.current = createTransIdentity(xid, coord, null);
986       try
987       {
988          pc.timeout =
989             TMUtil.divideAndRoundUp(tx.getTimeLeftBeforeTimeout(true), 1000);
990       }
991       catch (RollbackException JavaDoc e)
992       {
993          throw new BAD_INV_ORDER JavaDoc("get_txcontext(), but the transaction is " +
994                                  "not in the active state.");
995       }
996       pc.parents = new TransIdentity[0];
997       pc.implementation_specific_data = orb.create_any();
998       
999       // Return PropagationContext
1000
return pc;
1001   }
1002
1003   // CosTransactions::RecoveryCoordinator operation ----------------
1004

1005   public Status replay_completion(final Resource JavaDoc r)
1006      throws NotPrepared
1007   {
1008         byte[] oid = getTargetId();
1009         if (oid[0] != RECOVERY_COORDINATOR)
1010            throw new BAD_OPERATION JavaDoc();
1011         
1012         long localIdValue = LocalId.fromByteArray(oid, 1);
1013
1014         if (log.isTraceEnabled())
1015            log.trace("RecoveryCoordinator.replay_completion, targetId=" +
1016                      Long.toHexString(localIdValue));
1017
1018         TxManager tm = (TxManager) TMUtil.getTransactionManager();
1019         if (tm.isRecoveryPending())
1020         {
1021            if (log.isTraceEnabled())
1022               log.trace("RecoveryCoordinator.replay_completion called on" +
1023                         " targetId=" + Long.toHexString(localIdValue) +
1024                         " before recovery is complete.\n" +
1025                         " Throwing TRANSIENT exception.");
1026            
1027            throw new TRANSIENT JavaDoc("Transaction manager not ready.");
1028         }
1029         
1030         LocalId localId = new LocalId(localIdValue);
1031         TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
1032         
1033         if (tx == null)
1034         {
1035            log.trace("RuntimeException in replay_completion: " +
1036                      "transaction not found");
1037            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1038         }
1039
1040         int status = tx.replayCompletion(new OTSResourceWrapper(r));
1041         
1042         if (status == javax.transaction.Status.STATUS_MARKED_ROLLBACK ||
1043               status == javax.transaction.Status.STATUS_NO_TRANSACTION ||
1044               status == javax.transaction.Status.STATUS_ROLLEDBACK ||
1045               status == javax.transaction.Status.STATUS_ROLLING_BACK)
1046         {
1047            Runnable JavaDoc runnable = new Runnable JavaDoc()
1048            {
1049               public void run()
1050               {
1051                  try
1052                  {
1053                     r.rollback();
1054                  }
1055                  catch (Exception JavaDoc ignore)
1056                  {
1057                     // We can ignore this exception. If the resource
1058
// didn't get the rollback then it will eventually
1059
// call replay_completion again.
1060
if (log.isTraceEnabled())
1061                        log.trace("Ignoring exception in resource rollback",
1062                                  ignore);
1063                  }
1064               }
1065            };
1066            Thread JavaDoc t = new Thread JavaDoc(runnable, "resourceRollbackThread");
1067            
1068            t.start();
1069         }
1070         return javaxToCosTransactions(status);
1071   }
1072
1073   // CosTransactions::Resource operations in inner class below -----
1074

1075   /**
1076    * Default servant class for OTS <code>Resource</code> objects.
1077    * OTS <code>Resource</code>s cannot share a default servant with all other
1078    * OTS objects, because there is a name clash between
1079    * <code>Terminator::rollback</code> and <code>Resource::rollback</code>.
1080    */

1081   public class ResourceImpl
1082      extends ResourcePOA
1083   {
1084      public Vote prepare()
1085         throws HeuristicHazard, HeuristicMixed
1086      {
1087         byte[] oid = getTargetId();
1088         if (oid[0] != RESOURCE)
1089            throw new BAD_OPERATION JavaDoc();
1090         
1091         long localIdValue = LocalId.fromByteArray(oid, 1);
1092
1093         if (log.isTraceEnabled())
1094            log.trace("Resource.prepare, targetId=" +
1095                      Long.toHexString(localIdValue));
1096
1097         LocalId localId = new LocalId(localIdValue);
1098         TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
1099         if (tx == null)
1100         {
1101            log.trace("RuntimeException in prepare: transaction not found");
1102            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1103         }
1104         
1105         TransactionManager JavaDoc tm = TMUtil.getTransactionManager();
1106         try
1107         {
1108            tm.resume(tx);
1109            int vote = tx.prepare(null);
1110            
1111            if (vote == XAResource.XA_OK)
1112               return Vote.VoteCommit;
1113            else // (vote == XAResource.XA_RDONLY)
1114
return Vote.VoteReadOnly;
1115         }
1116         catch (RollbackException JavaDoc e)
1117         {
1118            return Vote.VoteRollback;
1119         }
1120         catch (HeuristicHazardException e)
1121         {
1122            if (log.isTraceEnabled())
1123               log.trace("Exception: ", e);
1124            HeuristicHazard ex = new HeuristicHazard();
1125            ex.initCause(e);
1126            throw ex;
1127         }
1128         catch (HeuristicMixedException JavaDoc e)
1129         {
1130            if (log.isTraceEnabled())
1131               log.trace("Exception: ", e);
1132            HeuristicMixed ex = new HeuristicMixed();
1133            ex.initCause(e);
1134            throw ex;
1135         }
1136         catch (HeuristicRollbackException JavaDoc e)
1137         {
1138            if (log.isTraceEnabled())
1139               log.trace("Exception: ", e);
1140            return Vote.VoteRollback;
1141         }
1142         catch (Exception JavaDoc e)
1143         {
1144            if (log.isTraceEnabled())
1145               log.trace("Unexpected exception: ", e);
1146            UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1147            ex.initCause(e);
1148            throw ex;
1149         }
1150         finally
1151         {
1152            try
1153            {
1154               tm.suspend();
1155            }
1156            catch (SystemException JavaDoc e)
1157            {
1158               if (log.isTraceEnabled())
1159                  log.trace("Unexpected exception: ", e);
1160               UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1161               ex.initCause(e);
1162               throw ex;
1163            }
1164         }
1165      }
1166
1167      public void rollback()
1168         throws HeuristicHazard, HeuristicMixed, HeuristicCommit
1169      {
1170         byte[] oid = getTargetId();
1171         if (oid[0] != RESOURCE)
1172            throw new BAD_OPERATION JavaDoc();
1173            
1174         long localIdValue = LocalId.fromByteArray(oid, 1);
1175
1176         if (log.isTraceEnabled())
1177            log.trace("Resource.rollback, targetId=" +
1178                      Long.toHexString(localIdValue));
1179
1180         LocalId localId = new LocalId(localIdValue);
1181         TransactionImpl tx = (TransactionImpl)TMUtil.getTransaction(localId);
1182         if (tx == null)
1183         {
1184            log.trace("RuntimeException in rollback: transaction not found");
1185            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1186         }
1187            
1188         try
1189         {
1190            tx.rollbackBranch();
1191         }
1192         catch (HeuristicHazardException e)
1193         {
1194            if (log.isTraceEnabled())
1195               log.trace("Exception: ", e);
1196            HeuristicHazard ex = new HeuristicHazard();
1197            ex.initCause(e);
1198            throw ex;
1199         }
1200         catch (HeuristicMixedException JavaDoc e)
1201         {
1202            if (log.isTraceEnabled())
1203               log.trace("Exception: ", e);
1204            HeuristicMixed ex = new HeuristicMixed();
1205            ex.initCause(e);
1206            throw ex;
1207         }
1208         catch (HeuristicCommitException JavaDoc e)
1209         {
1210            if (log.isTraceEnabled())
1211               log.trace("Exception: ", e);
1212            HeuristicCommit ex = new HeuristicCommit();
1213            ex.initCause(e);
1214            throw ex;
1215         }
1216         catch (IllegalStateException JavaDoc e)
1217         {
1218            if (log.isTraceEnabled())
1219               log.trace("Unexpected exception: ", e);
1220            BAD_INV_ORDER JavaDoc ex = new BAD_INV_ORDER JavaDoc();
1221            ex.initCause(e);
1222            throw ex;
1223         }
1224      }
1225
1226      public void commit()
1227         throws NotPrepared, HeuristicHazard, HeuristicMixed, HeuristicRollback
1228      {
1229         byte[] oid = getTargetId();
1230         if (oid[0] != RESOURCE)
1231            throw new BAD_OPERATION JavaDoc();
1232            
1233         long localIdValue = LocalId.fromByteArray(oid, 1);
1234
1235         if (log.isTraceEnabled())
1236            log.trace("Resource.commit, targetId=" +
1237                      Long.toHexString(localIdValue));
1238
1239         LocalId localId = new LocalId(localIdValue);
1240         TransactionImpl tx =
1241            (TransactionImpl)TMUtil.getTransaction(localId);
1242         if (tx == null)
1243         {
1244            log.trace("RuntimeException in commit: transaction not found");
1245            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1246         }
1247
1248         try
1249         {
1250            tx.commit(false);
1251         }
1252         catch (IllegalStateException JavaDoc e)
1253         {
1254            if (log.isTraceEnabled())
1255               log.trace("Exception: ", e);
1256            NotPrepared ex = new NotPrepared();
1257            ex.initCause(e);
1258            throw ex;
1259         }
1260         catch (RollbackException JavaDoc e)
1261         {
1262            if (log.isTraceEnabled())
1263               log.trace("Exception: ", e);
1264            TRANSACTION_ROLLEDBACK JavaDoc ex =
1265               new TRANSACTION_ROLLEDBACK JavaDoc();
1266            ex.initCause(e);
1267            throw ex;
1268         }
1269         catch (HeuristicHazardException e)
1270         {
1271            if (log.isTraceEnabled())
1272               log.trace("Exception: ", e);
1273            HeuristicHazard ex = new HeuristicHazard();
1274            ex.initCause(e);
1275            throw ex;
1276         }
1277         catch (HeuristicMixedException JavaDoc e)
1278         {
1279            if (log.isTraceEnabled())
1280               log.trace("Exception: ", e);
1281            HeuristicMixed ex = new HeuristicMixed();
1282            ex.initCause(e);
1283            throw ex;
1284         }
1285         catch (HeuristicRollbackException JavaDoc e)
1286         {
1287            if (log.isTraceEnabled())
1288               log.trace("Exception: ", e);
1289            HeuristicRollback ex = new HeuristicRollback();
1290            ex.initCause(e);
1291            throw ex;
1292         }
1293         catch (SystemException JavaDoc e)
1294         {
1295            if (log.isTraceEnabled())
1296               log.trace("Unexpected exception: ", e);
1297            UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1298            ex.initCause(e);
1299            throw ex;
1300         }
1301      }
1302
1303      public void commit_one_phase()
1304         throws HeuristicHazard
1305      {
1306         byte[] oid = getTargetId();
1307         if (oid[0] != RESOURCE)
1308            throw new BAD_OPERATION JavaDoc();
1309            
1310         long localIdValue = LocalId.fromByteArray(oid, 1);
1311
1312         if (log.isTraceEnabled())
1313            log.trace("Resource.commit_one_phase, targetId=" +
1314                      Long.toHexString(localIdValue));
1315
1316         LocalId localId = new LocalId(localIdValue);
1317         TransactionImpl tx =
1318            (TransactionImpl)TMUtil.getTransaction(localId);
1319         if (tx == null)
1320         {
1321            log.trace("RuntimeException in commit: transaction not found");
1322            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1323         }
1324
1325         try
1326         {
1327            tx.commit(true);
1328         }
1329         catch (RollbackException JavaDoc e)
1330         {
1331            if (log.isTraceEnabled())
1332               log.trace("Exception: ", e);
1333            TRANSACTION_ROLLEDBACK JavaDoc ex =
1334               new TRANSACTION_ROLLEDBACK JavaDoc();
1335            ex.initCause(e);
1336            throw ex;
1337         }
1338         catch (HeuristicHazardException e)
1339         {
1340            if (log.isTraceEnabled())
1341               log.trace("Exception: ", e);
1342            HeuristicHazard ex = new HeuristicHazard();
1343            ex.initCause(e);
1344            throw ex;
1345         }
1346         catch (HeuristicMixedException JavaDoc e)
1347         {
1348            if (log.isTraceEnabled())
1349               log.trace("Unexpected exception: ", e);
1350            UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1351            ex.initCause(e);
1352            throw ex;
1353         }
1354         catch (HeuristicRollbackException JavaDoc e)
1355         {
1356            if (log.isTraceEnabled())
1357               log.trace("Unexpected exception: ", e);
1358            UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1359            ex.initCause(e);
1360            throw ex;
1361         }
1362         catch (SystemException JavaDoc e)
1363         {
1364            if (log.isTraceEnabled())
1365               log.trace("Unexpected exception: ", e);
1366            UNKNOWN JavaDoc ex = new UNKNOWN JavaDoc();
1367            ex.initCause(e);
1368            throw ex;
1369         }
1370      }
1371
1372      public void forget()
1373      {
1374         byte[] oid = getTargetId();
1375         if (oid[0] != RESOURCE)
1376            throw new BAD_OPERATION JavaDoc();
1377            
1378         long localIdValue = LocalId.fromByteArray(oid, 1);
1379
1380         if (log.isTraceEnabled())
1381            log.trace("Resource.forget, targetId=" +
1382                      Long.toHexString(localIdValue));
1383
1384         LocalId localId = new LocalId(localIdValue);
1385         TransactionImpl tx =
1386            (TransactionImpl)TMUtil.getTransaction(localId);
1387         if (tx == null)
1388         {
1389            log.trace("RuntimeException in forget: transaction not found");
1390            throw new OBJECT_NOT_EXIST JavaDoc("No transaction.");
1391         }
1392         
1393         tx.forget();
1394      }
1395   }
1396
1397   // ResourceFactory implementation --------------------------------
1398

1399   /**
1400    * Creates a wrapped reference for the OTS resource with the given
1401    * <code>localId</code>.
1402    * @see org.jboss.tm.ResourceFactory#createResource(long)
1403    */

1404   public org.jboss.tm.remoting.interfaces.Resource createResource(long localId)
1405   {
1406      // Set up oid byte array to create CORBA reference to the Resource
1407
byte[] oid = new byte[9];
1408      oid[0] = RESOURCE;
1409      LocalId.toByteArray(localId, oid, 1);
1410
1411      // Create CORBA reference to the Resource
1412
Resource JavaDoc r = ResourceHelper.narrow(
1413            resourcePoa.create_reference_with_id(oid, ResourceHelper.id()));
1414      
1415      // Return an OTSResourceWrapper containing the CORBA reference
1416
return new OTSResourceWrapper(r);
1417   }
1418   
1419   // OTSContextFactory implementation ------------------------------
1420

1421   /**
1422    * Creates an OTS context with the specified <code>formatId</code>,
1423    * <code>globalId</code>, and <code>coordinator</code>. The OTS context
1424    * will contain a null <code>Terminator</code> reference and an
1425    * <code>org.omg.CosTransactions.Coordinator</code> reference extracted from
1426    * the <code>coordinator</code> parameter, which must be an instance of
1427    * <code>org.jboss.tm.iiop.wrapper.OTSCoordinatorWrapper</code>.
1428    * It will contain zero in its timeout field. The caller should use the
1429    * method <code>setTimeout</code> to set the timeout field of the newly
1430    * created OTS context.
1431    *
1432    * @param formatId the format id to be stored in the OTS context
1433    * @param globalId the global id to be stored in the OTS context
1434    * @param coordinator an <code>org.jboss.tm.iiop.wrapper.OTSCoordinatorWrapper</code>
1435    * containing the <code>org.omg.CosTransactions.Coordinator</code>
1436    * reference to be stored in the OTS context
1437    * @return an instance of <code>org.omg.CosTransactions.PropagationContext</code>.
1438    * @see org.jboss.tm.OTSContextFactory#createOTSContext(int, byte[], org.jboss.tm.remoting.interfaces.Coordinator)
1439    */

1440   public Object JavaDoc createOTSContext(int formatId, byte[] globalId,
1441                                  org.jboss.tm.remoting.interfaces.Coordinator coordinator)
1442   {
1443      if (!(coordinator instanceof OTSCoordinatorWrapper))
1444         throw new IllegalArgumentException JavaDoc("createOTSContext: " +
1445                     "coordinator parameter must be an OTSCoordinatorWrapper");
1446         
1447      Coordinator coord = ((OTSCoordinatorWrapper) coordinator).getWrappedCoordinator();
1448      
1449      // Create and initialize PropagationContext object
1450
PropagationContext pc = new PropagationContext();
1451      pc.current = createTransIdentity(formatId, globalId, coord);
1452      pc.timeout = 0;
1453      pc.parents = new TransIdentity[0];
1454      pc.implementation_specific_data = orb.create_any();
1455
1456      return pc;
1457   }
1458
1459   /**
1460    * Creates an OTS context with the specified <code>formatId</code> and
1461    * <code>globalId</code>, and with an
1462    * <code>org.omg.CosTransactions.Coordinator</code> reference that
1463    * corresponds to the local transaction whose local id is
1464    * <code>coordinatorLocalId</code>. The OTS context will contain a null
1465    * <code>Terminator</code> reference and zero in its timeout field.
1466    * The caller should use the method <code>setTimeout</code> to set the
1467    * timeout field of the newly created OTS context.
1468    *
1469    * @param formatId the format id to be stored in the OTS context
1470    * @param globalId the global id to be stored in the OTS context
1471    * @param coordinatorLocalId the local id of the transaction associated with
1472    * the coordinator reference to be stored in the OTS context
1473    * @return an instance of <code>org.omg.CosTransactions.PropagationContext</code>.
1474    * @see org.jboss.tm.OTSContextFactory#createOTSContext(int, byte[], long)
1475    */

1476   public Object JavaDoc createOTSContext(int formatId, byte[] globalId, long coordinatorLocalId)
1477   {
1478      // Set up oid byte array to create CORBA reference to the Coordinator
1479
byte[] oid = new byte[9];
1480      oid[0] = COORDINATOR;
1481      LocalId.toByteArray(coordinatorLocalId, oid, 1);
1482
1483      // Create CORBA reference to the Coordinator
1484
Coordinator coord = CoordinatorHelper.narrow(
1485            poa.create_reference_with_id(oid, CoordinatorHelper.id()));
1486
1487      // Create and initialize PropagationContext object
1488
PropagationContext pc = new PropagationContext();
1489      pc.current = createTransIdentity(formatId, globalId, coord);
1490      pc.timeout = 0;
1491      pc.parents = new TransIdentity[0];
1492      pc.implementation_specific_data = orb.create_any();
1493
1494      return pc;
1495   }
1496
1497   /**
1498    * Sets the timeout field of the specified OTS context.
1499    * @param otsContext an instance of <code>org.omg.CosTransactions.PropagationContext</code>
1500    * @param timeout the timeout value to be stored in the OTS context.
1501    * @see org.jboss.tm.OTSContextFactory#setTimeout(java.lang.Object, long)
1502    */

1503   public void setTimeout(Object JavaDoc otsContext, int timeout)
1504   {
1505      if (!(otsContext instanceof PropagationContext))
1506         throw new IllegalArgumentException JavaDoc("setTimeout: " +
1507                     "otsContext parameter must be a PropagationContext");
1508      
1509      PropagationContext pc = (PropagationContext) otsContext;
1510      pc.timeout = timeout;
1511   }
1512
1513   // StringRemoteRefConverter implementation ---------------
1514

1515   /**
1516    * Converts a stringfied reference to a remote resource back to a remote
1517    * reference.
1518    *
1519    * @param strResource a stringfied reference to a remote resource
1520    * @return a remote reference to the resource.
1521    */

1522   public org.jboss.tm.remoting.interfaces.Resource
1523   stringToResource(String JavaDoc strResource)
1524   {
1525      return OTSResourceWrapper.fromString(strResource);
1526   }
1527
1528   /**
1529    * Converts a stringfied reference to a remote recovery coordinator back
1530    * to a remote reference.
1531    *
1532    * @param strRecCoordinator a stringfied reference to a remote recovery
1533    * coordinator
1534    * @return a remote reference to the recovery coordinator.
1535    */

1536   public org.jboss.tm.remoting.interfaces.RecoveryCoordinator
1537   stringToRecoveryCoordinator(String JavaDoc strRecCoordinator)
1538   {
1539      return OTSRecoveryCoordinatorWrapper.fromString(strRecCoordinator);
1540   }
1541
1542   /**
1543    * Takes a remote reference to a resource and converts it to a string.
1544    *
1545    * @param res a remote reference to a resource
1546    * @return a string that represents the remote resource.
1547    */

1548   public String JavaDoc resourceToString(org.jboss.tm.remoting.interfaces.Resource res)
1549   {
1550      if (res instanceof OTSResourceWrapper)
1551         return res.toString();
1552      else
1553         throw new IllegalArgumentException JavaDoc();
1554
1555   }
1556   
1557   /**
1558    * Takes a remote reference to recovery coordinator and converts it to a
1559    * string.
1560    *
1561    * @param recoveryCoord a remote reference to a recovery coordinator
1562    * @return a string that represents the remote recovery coordinator.
1563    */

1564   public String JavaDoc recoveryCoordinatorToString(
1565         org.jboss.tm.remoting.interfaces.RecoveryCoordinator recoveryCoord)
1566   {
1567      if (recoveryCoord instanceof OTSRecoveryCoordinatorWrapper)
1568         return recoveryCoord.toString();
1569      else
1570         throw new IllegalArgumentException JavaDoc();
1571   }
1572
1573   // Private -------------------------------------------------------
1574

1575   private byte[] getTargetId()
1576   {
1577      byte[] id = null;
1578      try
1579      {
1580         id = poaCurrent.get_object_id();
1581      }
1582      catch (NoContext JavaDoc e)
1583      {
1584         if (log.isTraceEnabled())
1585            log.trace("Unexpected exception: " + e);
1586         throw new RuntimeException JavaDoc("Unexpected exception: ", e);
1587      }
1588      return id;
1589   }
1590
1591   private void checkInvocationTarget(int targetType)
1592   {
1593      if (getTargetId()[0] != targetType)
1594         throw new BAD_OPERATION JavaDoc();
1595   }
1596
1597   /**
1598    * Create and initialize TransIdentity object.
1599    */

1600   private static TransIdentity createTransIdentity(Xid JavaDoc xid,
1601                                                    Coordinator coord,
1602                                                    Terminator JavaDoc term)
1603   {
1604      // Concatenate global transaction id and branch qualifier
1605
byte gtrid[] = xid.getGlobalTransactionId();
1606      byte bqual[] = xid.getBranchQualifier();
1607      byte[] trid = new byte[gtrid.length + bqual.length];
1608      System.arraycopy(gtrid, 0, trid, 0, gtrid.length);
1609      System.arraycopy(bqual, 0, trid, gtrid.length, bqual.length);
1610
1611      // Create TransIdentity instance and set its fields
1612
TransIdentity ti = new TransIdentity();
1613      ti.coord = coord;
1614      ti.term = term;
1615      ti.otid = new otid_t(xid.getFormatId(), bqual.length, trid);
1616      return ti;
1617   }
1618
1619   /**
1620    * Create and initialize TransIdentity object.
1621    */

1622   private static TransIdentity createTransIdentity(int formatId,
1623                                                    byte[] globalId,
1624                                                    Coordinator coord)
1625   {
1626      // Concatenate the globalId and a zero-valued branch qualifier of length
1627
// 1, just because the OTS and XA specs insist that the branch qualifier
1628
// cannot have lenght zero.
1629
byte[] trid = new byte[globalId.length + 1];
1630      // The branch qualifier part of the trid is trid[globalId.length], which
1631
// already contains 0. We only need to fill the global transaction id
1632
// part.
1633
System.arraycopy(globalId, 0, trid, 0, globalId.length);
1634
1635      // Create TransIdentity instance and set its fields
1636
TransIdentity ti = new TransIdentity();
1637      ti.coord = coord;
1638      ti.term = null;
1639      ti.otid = new otid_t(formatId,
1640                           1, /* bqual length */
1641                           trid);
1642      return ti;
1643   }
1644
1645   private static Status javaxToCosTransactions(int status)
1646   {
1647      switch (status)
1648      {
1649      case javax.transaction.Status.STATUS_ACTIVE:
1650         return org.omg.CosTransactions.Status.StatusActive;
1651      case javax.transaction.Status.STATUS_COMMITTED:
1652         return org.omg.CosTransactions.Status.StatusCommitted;
1653      case javax.transaction.Status.STATUS_COMMITTING:
1654         return org.omg.CosTransactions.Status.StatusCommitting;
1655      case javax.transaction.Status.STATUS_MARKED_ROLLBACK:
1656         return org.omg.CosTransactions.Status.StatusMarkedRollback;
1657      case javax.transaction.Status.STATUS_NO_TRANSACTION:
1658         return org.omg.CosTransactions.Status.StatusNoTransaction;
1659      case javax.transaction.Status.STATUS_PREPARED:
1660         return org.omg.CosTransactions.Status.StatusPrepared;
1661      case javax.transaction.Status.STATUS_PREPARING:
1662         return org.omg.CosTransactions.Status.StatusPreparing;
1663      case javax.transaction.Status.STATUS_ROLLEDBACK:
1664         return org.omg.CosTransactions.Status.StatusRolledBack;
1665      case javax.transaction.Status.STATUS_ROLLING_BACK:
1666         return org.omg.CosTransactions.Status.StatusRollingBack;
1667      case javax.transaction.Status.STATUS_UNKNOWN:
1668         return org.omg.CosTransactions.Status.StatusUnknown;
1669      default:
1670         log.trace("Invalid transaction status.");
1671         return org.omg.CosTransactions.Status.StatusUnknown;
1672      }
1673   }
1674
1675    private static boolean compare(Xid JavaDoc xid,
1676                                   int otherFormatId,
1677                                   byte[] otherGlobalId,
1678                                   int otherLength)
1679    {
1680        if (xid.getFormatId() != otherFormatId)
1681            return false;
1682
1683        byte[] globalId = xid.getGlobalTransactionId();
1684        int len = globalId.length;
1685
1686        if (len != otherLength)
1687            return false;
1688
1689        for (int i = 0; i < len; ++i)
1690            if (globalId[i] != otherGlobalId[i])
1691                return false;
1692
1693        return true;
1694    }
1695
1696}
1697
Popular Tags