1 22 package org.jboss.tm.iiop; 23 24 import javax.transaction.HeuristicCommitException ; 25 import javax.transaction.HeuristicMixedException ; 26 import javax.transaction.HeuristicRollbackException ; 27 import javax.transaction.NotSupportedException ; 28 import javax.transaction.RollbackException ; 29 import javax.transaction.SystemException ; 30 import javax.transaction.Transaction ; 31 import javax.transaction.TransactionManager ; 32 import javax.transaction.xa.XAResource ; 33 import javax.transaction.xa.Xid ; 34 35 import org.omg.CORBA.BAD_INV_ORDER ; 36 import org.omg.CORBA.BAD_OPERATION ; 37 import org.omg.CORBA.BAD_PARAM ; 38 import org.omg.CORBA.OBJECT_NOT_EXIST ; 39 import org.omg.CORBA.ORB ; 40 import org.omg.CORBA.TRANSIENT ; 41 import org.omg.CORBA.ORBPackage.InvalidName ; 42 import org.omg.CORBA.NO_PERMISSION ; 43 import org.omg.CORBA.TRANSACTION_ROLLEDBACK ; 44 import org.omg.CORBA.UNKNOWN ; 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 ; 75 import org.omg.PortableServer.Servant ; 76 import org.omg.PortableServer.CurrentPackage.NoContext ; 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 99 public class OTSServant 100 extends TransactionServicePOA 101 implements ResourceFactory, 102 OTSContextFactory, 103 StringRemoteRefConverter 104 { 105 107 private static final Logger log = 108 Logger.getLogger(OTSServant.class); 109 110 112 113 private static final byte CONTROL = 0x43; 114 115 116 private static final byte COORDINATOR = 0x63; 117 118 119 private static final byte TX_FACTORY = 0x46; 120 121 122 private static final byte TERMINATOR = 0x74; 123 124 125 private static final byte RECOVERY_COORDINATOR = 0x76; 126 127 128 private static final byte RESOURCE = 0x72; 129 130 132 133 private static final String [] controlInterfaceIds = { 134 ControlHelper.id() 135 }; 136 137 138 private static final String [] coordinatorInterfaceIds = { 139 CoordinatorExtHelper.id(), 140 CoordinatorHelper.id() 141 }; 142 143 144 private static final String [] txFactoryInterfaceIds = { 145 TransactionFactoryExtHelper.id(), 146 TransactionFactoryHelper.id() 147 }; 148 149 150 private static final String [] terminatorInterfaceIds = { 151 TerminatorHelper.id() 152 }; 153 154 155 private static final String [] recoveryCoordinatorInterfaceIds = { 156 RecoveryCoordinatorHelper.id() 157 }; 158 159 161 private ORB orb; 162 private POA poa; 163 private POA resourcePoa; 164 private ResourceImpl resourceServant; 165 private org.omg.PortableServer.Current poaCurrent; 166 167 169 static byte[] theFactoryId() { return new byte[] { TX_FACTORY }; } 170 171 173 OTSServant(ORB 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 obj = 183 orb.resolve_initial_references("POACurrent"); 184 poaCurrent = org.omg.PortableServer.CurrentHelper.narrow(obj); 185 } 186 catch (InvalidName e) { 188 log.warn("Call to resolve_initial_references failed: ", e); 189 throw new RuntimeException ( 190 "Call to resolve_initial_references failed: ", e); 191 } 192 catch (BAD_PARAM e) { 194 log.warn("Call to narrow failed: ", e); 195 throw new RuntimeException ("Call to narrow failed: ", e); 196 } 197 } 198 199 201 204 public Servant getResourceServant() 205 { 206 return resourceServant; 207 } 208 209 211 public String [] _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 ("Unknown CORBA object id"); 225 } 226 227 229 public TransactionDesc create_transaction(int timeout) 230 { 231 log.trace("TransactionFactoryExt.create_transaction"); 232 checkInvocationTarget(TX_FACTORY); 233 try 234 { 235 TransactionManager tm = TMUtil.getTransactionManager(); 236 237 if (timeout != 0) 239 tm.setTransactionTimeout(timeout); 240 241 tm.begin(); 243 244 TransactionImpl tx = (TransactionImpl)tm.suspend(); 247 XidImpl xid = tx.getXid(); 248 long localId = xid.getLocalIdValue(); 249 250 byte[] oid = new byte[9]; 252 oid[0] = COORDINATOR; 253 LocalId.toByteArray(localId, oid, 1); 254 255 Coordinator coord = CoordinatorHelper.narrow( 257 poa.create_reference_with_id(oid, CoordinatorHelper.id())); 258 259 oid[0] = TERMINATOR; 261 Terminator term = TerminatorHelper.narrow( 262 poa.create_reference_with_id(oid, TerminatorHelper.id())); 263 264 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 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 td; 279 } 280 catch (SystemException e) 281 { 282 if (log.isTraceEnabled()) 283 log.trace("Unexpected exception: ", e); 284 UNKNOWN ex = new UNKNOWN (); 285 ex.initCause(e); 286 throw ex; 287 288 } 289 catch (NotSupportedException e) 290 { 291 if (log.isTraceEnabled()) 292 log.trace("Unexpected exception: ", e); 293 BAD_INV_ORDER ex = new BAD_INV_ORDER (); 294 ex.initCause(e); 295 throw ex; 296 } 297 } 298 299 301 public Control create(int timeout) 302 { 303 log.trace("TransactionFactory.create"); 304 checkInvocationTarget(TX_FACTORY); 305 try 306 { 307 TransactionManager tm = TMUtil.getTransactionManager(); 308 309 if (timeout != 0) 311 tm.setTransactionTimeout(timeout); 312 313 tm.begin(); 315 316 TransactionImpl tx = (TransactionImpl)tm.suspend(); 319 XidImpl xid = tx.getXid(); 320 long localId = xid.getLocalIdValue(); 321 322 byte[] oid = new byte[9]; 324 oid[0] = CONTROL; 325 LocalId.toByteArray(localId, oid, 1); 326 327 return ControlHelper.narrow( 329 poa.create_reference_with_id(oid, ControlHelper.id())); 330 } 331 catch (SystemException e) 332 { 333 if (log.isTraceEnabled()) 334 log.trace("Unexpected exception: ", e); 335 UNKNOWN ex = new UNKNOWN (); 336 ex.initCause(e); 337 throw ex; 338 } 339 catch (NotSupportedException e) 340 { 341 if (log.isTraceEnabled()) 342 log.trace("Unexpected exception: ", e); 343 BAD_INV_ORDER ex = new BAD_INV_ORDER (); 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 ( 356 "recreate: PropagationContext parameter cannot be null"); 357 358 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 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 byte[] oid = new byte[9]; 373 oid[0] = CONTROL; 374 LocalId.toByteArray(tx.getLocalIdValue(), oid, 1); 375 376 return ControlHelper.narrow( 378 poa.create_reference_with_id(oid, ControlHelper.id())); 379 380 } 381 382 384 public Terminator get_terminator() 385 throws Unavailable 386 { 387 byte[] oid = getTargetId(); 388 if (oid[0] != CONTROL) 389 throw new BAD_OPERATION (); 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 (); 421 oid[0] = COORDINATOR; 422 return CoordinatorHelper.narrow( 423 poa.create_reference_with_id(oid, CoordinatorHelper.id())); 424 } 425 426 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 (); 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 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 ("No transaction."); 448 } 449 450 try 451 { 452 tx.commit(); 453 } 454 catch (RollbackException e) 455 { 456 if (log.isTraceEnabled()) 457 log.trace("Exception: ", e); 458 TRANSACTION_ROLLEDBACK ex = new TRANSACTION_ROLLEDBACK (); 459 ex.initCause(e); 460 throw ex; 461 } 462 catch (HeuristicMixedException 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 e) 474 { 475 if (log.isTraceEnabled()) 476 log.trace("Exception: ", e); 477 TRANSACTION_ROLLEDBACK ex = new TRANSACTION_ROLLEDBACK (); 478 ex.initCause(e); 479 throw ex; 480 } 481 catch (SecurityException e) 482 { 483 if (log.isTraceEnabled()) 484 log.trace("Unexpected exception: ", e); 485 NO_PERMISSION ex = new NO_PERMISSION (); 486 ex.initCause(e); 487 throw ex; 488 } 489 catch (IllegalStateException e) 490 { 491 if (log.isTraceEnabled()) 492 log.trace("Unexpected exception: ", e); 493 BAD_INV_ORDER ex = new BAD_INV_ORDER (); 494 ex.initCause(e); 495 throw ex; 496 } 497 catch (SystemException e) 498 { 499 if (log.isTraceEnabled()) 500 log.trace("Unexpected exception: ", e); 501 UNKNOWN ex = new UNKNOWN (); 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 (); 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 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 ("No transaction."); 526 } 527 528 try 529 { 530 tx.rollback(); 531 } 532 catch (IllegalStateException e) 533 { 534 if (log.isTraceEnabled()) 535 log.trace("Unexpected exception: ", e); 536 BAD_INV_ORDER ex = new BAD_INV_ORDER (); 537 ex.initCause(e); 538 throw ex; 539 } 540 catch (SecurityException e) 541 { 542 if (log.isTraceEnabled()) 543 log.trace("Unexpected exception: ", e); 544 NO_PERMISSION ex = new NO_PERMISSION (); 545 ex.initCause(e); 546 throw ex; 547 } 548 catch (SystemException e) 549 { 550 if (log.isTraceEnabled()) 551 log.trace("Unexpected exception: ", e); 552 UNKNOWN ex = new UNKNOWN (); 553 ex.initCause(e); 554 throw ex; 555 } 556 } 557 558 560 public TransactionId get_transaction_id() 561 { 562 byte[] oid = getTargetId(); 563 if (oid[0] != COORDINATOR) 564 throw new BAD_OPERATION (); 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 ("No transaction."); 580 } 581 582 Xid xid = tx.getXid(); 583 return new TransactionId(xid.getFormatId(), 584 xid.getGlobalTransactionId()); 585 } 586 587 589 public Status get_status() 590 { 591 byte[] oid = getTargetId(); 592 if (oid[0] != COORDINATOR) 593 throw new BAD_OPERATION (); 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 tx = TMUtil.getTransaction(localId); 603 604 if (tx == null) 605 { 606 log.trace("RuntimeException in get_status: transaction not found"); 607 throw new OBJECT_NOT_EXIST ("No transaction."); 610 } 612 613 int status; 614 615 try 616 { 617 status = tx.getStatus(); 618 } 619 catch (SystemException e) 620 { 621 if (log.isTraceEnabled()) 622 log.trace("Unexpected exception: ", e); 623 UNKNOWN ex = new UNKNOWN (); 624 ex.initCause(e); 625 throw ex; 626 } 627 return javaxToCosTransactions(status); 628 } 629 630 public Status get_parent_status() 631 { 632 return get_status(); 636 } 637 638 public Status get_top_level_status() 639 { 640 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 (); 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 ("No transaction."); 666 } 667 668 Xid 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 e) 680 { 681 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 ex = new BAD_PARAM (); 696 ex.initCause(e); 697 throw ex; 698 } 699 } 700 } 701 702 public boolean is_ancestor_transaction(Coordinator other) 703 { 704 return is_same_transaction(other); 707 } 708 709 public boolean is_descendant_transaction(Coordinator other) 710 { 711 return is_same_transaction(other); 714 } 715 716 public boolean is_related_transaction(Coordinator other) 717 { 718 return is_same_transaction(other); 721 } 722 723 public boolean is_top_level_transaction() 724 { 725 checkInvocationTarget(COORDINATOR); 726 return true; } 728 729 public int hash_transaction() 730 { 731 byte[] oid = getTargetId(); 732 if (oid[0] != COORDINATOR) 733 throw new BAD_OPERATION (); 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 ("No transaction."); 748 } 749 return tx.getGlobalId().hashCode(); 750 } 751 752 public int hash_top_level_tran() 753 { 754 return hash_transaction(); 757 } 758 759 public RecoveryCoordinator register_resource(Resource r) 760 throws Inactive 761 { 762 byte[] oid = getTargetId(); 763 if (oid[0] != COORDINATOR) 764 throw new BAD_OPERATION (); 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 ("No transaction."); 780 } 781 782 try 783 { 784 tx.enlistRemoteResource(new OTSResourceWrapper(r)); 785 } 786 catch (RollbackException e) 787 { 788 if (log.isTraceEnabled()) 789 log.trace("Exception: ", e); 790 TRANSACTION_ROLLEDBACK ex = new TRANSACTION_ROLLEDBACK (); 791 ex.initCause(e); 792 throw ex; 793 } 794 catch (IllegalStateException 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 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 (); 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 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 ("No transaction."); 831 } 832 833 try 834 { 835 tx.registerSynchronization( 836 new javax.transaction.Synchronization () 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 e) 849 { 850 if (log.isTraceEnabled()) 851 log.trace("Exception: ", e); 852 TRANSACTION_ROLLEDBACK ex = new TRANSACTION_ROLLEDBACK (); 853 ex.initCause(e); 854 throw ex; 855 } 856 catch (IllegalStateException 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 e) 865 { 866 if (log.isTraceEnabled()) 867 log.trace("Unexpected exception: ", e); 868 UNKNOWN ex = new UNKNOWN (); 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 (); 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 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 ("No transaction."); 901 } 902 903 try 904 { 905 tx.setRollbackOnly(); 906 } 907 catch (IllegalStateException 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 e) 916 { 917 if (log.isTraceEnabled()) 918 log.trace("Unexpected exception: ", e); 919 UNKNOWN ex = new UNKNOWN (); 920 ex.initCause(e); 921 throw ex; 922 } 923 } 924 925 public String get_transaction_name() 926 { 927 byte[] oid = getTargetId(); 928 if (oid[0] != COORDINATOR) 929 throw new BAD_OPERATION (); 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 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 ("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 (); 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 ("No transaction."); 976 } 977 Xid xid = tx.getXid(); 978 979 Coordinator coord = CoordinatorHelper.narrow( 981 poa.create_reference_with_id(oid, CoordinatorHelper.id())); 982 983 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 e) 992 { 993 throw new BAD_INV_ORDER ("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 pc; 1001 } 1002 1003 1005 public Status replay_completion(final Resource r) 1006 throws NotPrepared 1007 { 1008 byte[] oid = getTargetId(); 1009 if (oid[0] != RECOVERY_COORDINATOR) 1010 throw new BAD_OPERATION (); 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 ("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 ("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 runnable = new Runnable () 1048 { 1049 public void run() 1050 { 1051 try 1052 { 1053 r.rollback(); 1054 } 1055 catch (Exception ignore) 1056 { 1057 if (log.isTraceEnabled()) 1061 log.trace("Ignoring exception in resource rollback", 1062 ignore); 1063 } 1064 } 1065 }; 1066 Thread t = new Thread (runnable, "resourceRollbackThread"); 1067 1068 t.start(); 1069 } 1070 return javaxToCosTransactions(status); 1071 } 1072 1073 1075 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 (); 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 ("No transaction."); 1103 } 1104 1105 TransactionManager 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 return Vote.VoteReadOnly; 1115 } 1116 catch (RollbackException 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 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 e) 1137 { 1138 if (log.isTraceEnabled()) 1139 log.trace("Exception: ", e); 1140 return Vote.VoteRollback; 1141 } 1142 catch (Exception e) 1143 { 1144 if (log.isTraceEnabled()) 1145 log.trace("Unexpected exception: ", e); 1146 UNKNOWN ex = new UNKNOWN (); 1147 ex.initCause(e); 1148 throw ex; 1149 } 1150 finally 1151 { 1152 try 1153 { 1154 tm.suspend(); 1155 } 1156 catch (SystemException e) 1157 { 1158 if (log.isTraceEnabled()) 1159 log.trace("Unexpected exception: ", e); 1160 UNKNOWN ex = new UNKNOWN (); 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 (); 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 ("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 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 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 e) 1217 { 1218 if (log.isTraceEnabled()) 1219 log.trace("Unexpected exception: ", e); 1220 BAD_INV_ORDER ex = new BAD_INV_ORDER (); 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 (); 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 ("No transaction."); 1246 } 1247 1248 try 1249 { 1250 tx.commit(false); 1251 } 1252 catch (IllegalStateException 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 e) 1261 { 1262 if (log.isTraceEnabled()) 1263 log.trace("Exception: ", e); 1264 TRANSACTION_ROLLEDBACK ex = 1265 new TRANSACTION_ROLLEDBACK (); 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 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 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 e) 1294 { 1295 if (log.isTraceEnabled()) 1296 log.trace("Unexpected exception: ", e); 1297 UNKNOWN ex = new UNKNOWN (); 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 (); 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 ("No transaction."); 1323 } 1324 1325 try 1326 { 1327 tx.commit(true); 1328 } 1329 catch (RollbackException e) 1330 { 1331 if (log.isTraceEnabled()) 1332 log.trace("Exception: ", e); 1333 TRANSACTION_ROLLEDBACK ex = 1334 new TRANSACTION_ROLLEDBACK (); 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 e) 1347 { 1348 if (log.isTraceEnabled()) 1349 log.trace("Unexpected exception: ", e); 1350 UNKNOWN ex = new UNKNOWN (); 1351 ex.initCause(e); 1352 throw ex; 1353 } 1354 catch (HeuristicRollbackException e) 1355 { 1356 if (log.isTraceEnabled()) 1357 log.trace("Unexpected exception: ", e); 1358 UNKNOWN ex = new UNKNOWN (); 1359 ex.initCause(e); 1360 throw ex; 1361 } 1362 catch (SystemException e) 1363 { 1364 if (log.isTraceEnabled()) 1365 log.trace("Unexpected exception: ", e); 1366 UNKNOWN ex = new UNKNOWN (); 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 (); 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 ("No transaction."); 1391 } 1392 1393 tx.forget(); 1394 } 1395 } 1396 1397 1399 1404 public org.jboss.tm.remoting.interfaces.Resource createResource(long localId) 1405 { 1406 byte[] oid = new byte[9]; 1408 oid[0] = RESOURCE; 1409 LocalId.toByteArray(localId, oid, 1); 1410 1411 Resource r = ResourceHelper.narrow( 1413 resourcePoa.create_reference_with_id(oid, ResourceHelper.id())); 1414 1415 return new OTSResourceWrapper(r); 1417 } 1418 1419 1421 1440 public Object createOTSContext(int formatId, byte[] globalId, 1441 org.jboss.tm.remoting.interfaces.Coordinator coordinator) 1442 { 1443 if (!(coordinator instanceof OTSCoordinatorWrapper)) 1444 throw new IllegalArgumentException ("createOTSContext: " + 1445 "coordinator parameter must be an OTSCoordinatorWrapper"); 1446 1447 Coordinator coord = ((OTSCoordinatorWrapper) coordinator).getWrappedCoordinator(); 1448 1449 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 1476 public Object createOTSContext(int formatId, byte[] globalId, long coordinatorLocalId) 1477 { 1478 byte[] oid = new byte[9]; 1480 oid[0] = COORDINATOR; 1481 LocalId.toByteArray(coordinatorLocalId, oid, 1); 1482 1483 Coordinator coord = CoordinatorHelper.narrow( 1485 poa.create_reference_with_id(oid, CoordinatorHelper.id())); 1486 1487 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 1503 public void setTimeout(Object otsContext, int timeout) 1504 { 1505 if (!(otsContext instanceof PropagationContext)) 1506 throw new IllegalArgumentException ("setTimeout: " + 1507 "otsContext parameter must be a PropagationContext"); 1508 1509 PropagationContext pc = (PropagationContext) otsContext; 1510 pc.timeout = timeout; 1511 } 1512 1513 1515 1522 public org.jboss.tm.remoting.interfaces.Resource 1523 stringToResource(String strResource) 1524 { 1525 return OTSResourceWrapper.fromString(strResource); 1526 } 1527 1528 1536 public org.jboss.tm.remoting.interfaces.RecoveryCoordinator 1537 stringToRecoveryCoordinator(String strRecCoordinator) 1538 { 1539 return OTSRecoveryCoordinatorWrapper.fromString(strRecCoordinator); 1540 } 1541 1542 1548 public String resourceToString(org.jboss.tm.remoting.interfaces.Resource res) 1549 { 1550 if (res instanceof OTSResourceWrapper) 1551 return res.toString(); 1552 else 1553 throw new IllegalArgumentException (); 1554 1555 } 1556 1557 1564 public String 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 (); 1571 } 1572 1573 1575 private byte[] getTargetId() 1576 { 1577 byte[] id = null; 1578 try 1579 { 1580 id = poaCurrent.get_object_id(); 1581 } 1582 catch (NoContext e) 1583 { 1584 if (log.isTraceEnabled()) 1585 log.trace("Unexpected exception: " + e); 1586 throw new RuntimeException ("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 (); 1595 } 1596 1597 1600 private static TransIdentity createTransIdentity(Xid xid, 1601 Coordinator coord, 1602 Terminator term) 1603 { 1604 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 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 1622 private static TransIdentity createTransIdentity(int formatId, 1623 byte[] globalId, 1624 Coordinator coord) 1625 { 1626 byte[] trid = new byte[globalId.length + 1]; 1630 System.arraycopy(globalId, 0, trid, 0, globalId.length); 1634 1635 TransIdentity ti = new TransIdentity(); 1637 ti.coord = coord; 1638 ti.term = null; 1639 ti.otid = new otid_t(formatId, 1640 1, 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 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 |