1 43 package org.objectweb.jotm; 44 45 import java.io.Serializable ; 46 import java.nio.ByteBuffer ; 47 import java.security.SecureRandom ; 48 49 import org.objectweb.howl.log.xa.XACommittingTx; 50 51 70 public class XidImpl implements Xid, Serializable { 71 72 public static final int JOTM_FORMAT_ID = 0xBB14; 73 74 private static SecureRandom rand = null; private final byte internalVersId = 1; 77 private static int count = 1; 78 private static long uuid0; 79 private static long uuid1; 80 private static boolean uuidsRecovered = false; 81 private static byte[] gtrid_base = null; private static String host, server; 83 84 private String fullString = ""; 85 private String shortString = ""; 86 87 private boolean hashcodevalid = false; 88 private int myhashcode; 89 90 static String HexDigits[] = { 91 "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", 92 "0a", "0b", "0c", "0d", "0e", "0f", 93 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", 94 "1a", "1b", "1c", "1d", "1e", "1f", 95 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", 96 "2a", "2b", "2c", "2d", "2e", "2f", 97 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", 98 "3a", "3b", "3c", "3d", "3e", "3f", 99 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", 100 "4a", "4b", "4c", "4d", "4e", "4f", 101 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", 102 "5a", "5b", "5c", "5d", "5e", "5f", 103 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", 104 "6a", "6b", "6c", "6d", "6e", "6f", 105 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", 106 "7a", "7b", "7c", "7d", "7e", "7f", 107 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", 108 "8a", "8b", "8c", "8d", "8e", "8f", 109 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", 110 "9a", "9b", "9c", "9d", "9e", "9f", 111 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", 112 "aa", "ab", "ac", "ad", "ae", "af", 113 "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", 114 "ba", "bb", "bc", "bd", "be", "bf", 115 "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", 116 "ca", "cb", "cc", "cd", "ce", "cf", 117 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", 118 "da", "db", "dc", "dd", "de", "df", 119 "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", 120 "ea", "eb", "ec", "ed", "ee", "ef", 121 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", 122 "fa", "fb", "fc", "fd", "fe", "ff" 123 }; 124 125 129 private int formatId; 130 131 135 private int gtrid_length; 136 137 141 private int bqual_length; 142 143 147 private byte[] gtrid; 148 149 153 private byte[] bqual; 154 155 159 162 public XidImpl( String serverName, int ipAddr ) { 163 164 if (TraceTm.jotm.isDebugEnabled()) { 165 TraceTm.jotm.debug("serverName=" + serverName + ", ipAddr=" + ipAddr); 166 } 167 168 formatId = JOTM_FORMAT_ID; 169 byte local_vers = 0; 170 long uuid; 171 long myipaddr; 172 173 synchronized (getClass()) { 174 uuid = System.currentTimeMillis() * 1024 + count; 175 count++; 176 } 177 178 String s = 181 Long.toHexString(local_vers) 182 + Long.toHexString(uuid) 183 + "_" 184 + Long.toHexString(ipAddr) 185 + "_" 186 + serverName; 187 188 if (s.length() > Xid.MAXBQUALSIZE) { 189 s = s.substring(0, Xid.MAXBQUALSIZE); 190 } 191 192 gtrid = s.getBytes(); 193 gtrid_length = gtrid.length; 194 195 bqual = s.getBytes(); 197 bqual_length = bqual.length; 198 199 if (TraceTm.jotm.isDebugEnabled()) { 200 TraceTm.jotm.debug("Xid (uuid= " + Long.toHexString(uuid) + ")"); 201 } 202 } 203 204 207 public XidImpl( int fid, int bqualsz, byte[] tid ) { 208 if (TraceTm.jotm.isDebugEnabled()) { 209 TraceTm.jotm.debug("constructor from otid_t"); 210 } 211 212 formatId = fid; 214 215 int gtridsz = tid.length - bqualsz; 217 gtrid = new byte[gtridsz]; 218 System.arraycopy(tid, bqualsz, gtrid, 0, gtridsz); 219 220 bqual = new byte[bqualsz]; 222 System.arraycopy(tid, 0, bqual, 0, bqualsz); 223 224 gtrid_length = gtridsz; 226 227 bqual_length = bqualsz; 229 } 230 231 235 public XidImpl( int formatId, byte[] gtrid, byte[] bqual ) { 236 237 this.formatId = formatId; 238 this.gtrid = gtrid; 239 this.bqual = bqual; 240 this.gtrid_length = gtrid.length; 241 this.bqual_length = bqual.length; 242 } 243 244 247 public XidImpl() { 248 formatId = JOTM_FORMAT_ID; 249 250 gtrid = makeGtrid(); 251 gtrid_length = gtrid.length; 252 bqual = new byte[0]; 253 bqual_length = bqual.length; 254 } 255 256 262 public XidImpl( Xid oldXid, int index ) { 263 264 if (TraceTm.jotm.isDebugEnabled()) { 265 TraceTm.jotm.debug("old XID= " + oldXid); 266 TraceTm.jotm.debug("index= " + index); 267 } 268 269 formatId = oldXid.getFormatId(); 270 271 gtrid = oldXid.getGlobalTransactionId(); 272 makeGtridBase(); 273 gtrid_length = gtrid.length; 274 275 bqual = new byte[MAXBQUALSIZE]; 276 ByteBuffer bb = ByteBuffer.wrap(bqual); 277 bb.put(gtrid_base); 278 bb.putLong(0L); bb.putLong(index+0L); bqual_length = bqual.length; 281 } 282 283 294 295 public XidImpl( ByteBuffer XidByteBuffer){ 296 byte tempByte; 297 298 tempByte = XidByteBuffer.get(); 299 300 while ( tempByte != ':' ){ 301 formatId = (formatId * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 302 tempByte = XidByteBuffer.get(); 303 } 304 305 tempByte = XidByteBuffer.get(); 306 307 while ( tempByte != ':' ){ 308 gtrid_length = (gtrid_length * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 309 tempByte = XidByteBuffer.get(); 310 } 311 tempByte = XidByteBuffer.get(); 312 313 while ( tempByte != ':' ){ 314 bqual_length = (bqual_length * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 315 tempByte = XidByteBuffer.get(); 316 } 317 318 gtrid = new byte[gtrid_length]; 319 bqual = new byte[bqual_length]; 320 321 int tempInt; 322 323 for ( int i = 0 ; i <= (gtrid_length - 1) ; i++ ) { 324 byte tempByteUpper = XidByteBuffer.get(); 325 byte tempByteLower = XidByteBuffer.get(); 326 gtrid[i] = (byte)((16 * ((int)tempByteUpper -((int)tempByteUpper > 96 ? 87 : 48 ))) 327 + ((int)tempByteLower -((int)tempByteLower > 96 ? 87 : 48 ))); 328 } 329 330 if( XidByteBuffer.get() != ':') { 331 if (TraceTm.recovery.isDebugEnabled()) { 332 TraceTm.recovery.debug(" XXXX XidByteArray alignment is bad! XXX "); 333 } 334 } 335 336 for ( int i = 0 ; i <= (bqual_length - 1) ; i++ ) { 337 byte tempByteUpper = XidByteBuffer.get(); 338 byte tempByteLower = XidByteBuffer.get(); 339 bqual[i] = (byte)((16 * ((int)tempByteUpper -((int)tempByteUpper > 96 ? 87 : 48 ))) 340 + ((int)tempByteLower -((int)tempByteLower > 96 ? 87 : 48 ))); 341 } 342 343 if (TraceTm.recovery.isDebugEnabled()) { 344 TraceTm.recovery.debug("Rebuilt Xid: " + this.toString(true)); 345 } 346 } 347 348 356 357 public XidImpl( byte[] XidByteArray){ 358 byte tempByte; 359 int tempIndex = 0; 360 361 tempByte = XidByteArray[tempIndex]; 362 363 while ( tempByte != ':' ){ 364 formatId = (formatId * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 365 tempIndex++; 366 tempByte = XidByteArray[tempIndex]; 367 } 368 369 tempIndex++; 370 tempByte = XidByteArray[tempIndex]; 371 372 while ( tempByte != ':' ){ 373 gtrid_length = (gtrid_length * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 374 tempIndex++; 375 tempByte = XidByteArray[tempIndex]; 376 } 377 378 tempIndex++; 379 tempByte = XidByteArray[tempIndex]; 380 381 while ( tempByte != ':' ){ 382 bqual_length = (bqual_length * 16) + ((int)tempByte-((int)tempByte>96? 87 : 48 )); 383 tempIndex++; 384 tempByte = XidByteArray[tempIndex]; 385 } 386 387 gtrid = new byte[gtrid_length]; 388 bqual = new byte[bqual_length]; 389 390 int tempInt; 391 392 for ( int i = 0 ; i <= (gtrid_length - 1) ; i++ ) { 393 tempIndex++; 394 byte tempByteUpper = XidByteArray[tempIndex]; 395 tempIndex++; 396 byte tempByteLower = XidByteArray[tempIndex]; 397 gtrid[i] = (byte)((16 * ((int)tempByteUpper -((int)tempByteUpper > 96 ? 87 : 48 ))) 398 + ((int)tempByteLower -((int)tempByteLower > 96 ? 87 : 48 ))); 399 } 400 401 tempIndex++; 402 tempByte = XidByteArray[tempIndex]; 403 404 if( tempByte != ':') { 405 if (TraceTm.recovery.isDebugEnabled()) { 406 TraceTm.recovery.debug(" XXXX XidByteArray alignment is bad! XXX "); 407 } 408 } 409 410 for ( int i = 0 ; i <= (bqual_length - 1) ; i++ ) { 411 tempIndex++; 412 byte tempByteUpper = XidByteArray[tempIndex]; 413 tempIndex++; 414 byte tempByteLower = XidByteArray[tempIndex]; 415 bqual[i] = (byte)((16 * ((int)tempByteUpper -((int)tempByteUpper > 96 ? 87 : 48 ))) 416 + ((int)tempByteLower -((int)tempByteLower > 96 ? 87 : 48 ))); 417 } 418 419 if (TraceTm.recovery.isDebugEnabled()) { 420 TraceTm.recovery.debug("Rebuilt Xid: " + this.toString(true)); 421 } 422 } 423 424 429 430 public XidImpl( javax.transaction.xa.Xid passedXid) { 431 if (TraceTm.jotm.isDebugEnabled()) { 432 TraceTm.jotm.debug("passed XID= " + passedXid); 433 } 434 435 formatId = passedXid.getFormatId(); 436 gtrid = passedXid.getGlobalTransactionId(); 437 gtrid_length = gtrid.length; 438 bqual = passedXid.getBranchQualifier(); 439 bqual_length = bqual.length; 440 } 441 442 446 450 public static void setUuids( long passedUuid0, long passedUuid1) { 451 uuid0 = passedUuid0; 452 uuid1 = passedUuid1; 453 uuidsRecovered = true; 454 455 if (TraceTm.recovery.isDebugEnabled()) { 456 TraceTm.recovery.debug("uuids recovered; uuid0:" + uuid0 + " uuid1:" + uuid1); 457 } 458 } 459 460 463 public int getFormatId() { 464 return formatId; 465 } 466 467 470 public byte[] getGlobalTransactionId() { 471 return gtrid; 472 } 473 474 477 public byte[] getBranchQualifier() { 478 return bqual; 479 } 480 481 485 488 static final void byteToHex( byte inbyte, StringBuffer str_buff ) { 489 490 int myByte = 0xFF & inbyte; 491 492 str_buff.append( HexDigits[myByte] ); 493 return; 494 } 495 496 500 public String toString() { 501 return this.toString( false ); 502 } 503 504 public String toString( boolean Full ) { 505 506 byte[] gtrid_local = null; 507 byte[] bqual_local = null; 508 509 if (Full && (fullString.length() != 0) ) { 510 return fullString; 511 } else if (!Full && (shortString.length() != 0) ) { 512 return shortString; 513 } 514 515 StringBuffer str_buff_gtrid = new StringBuffer (MAXGTRIDSIZE * 2); 517 StringBuffer str_buff_bqual = new StringBuffer (MAXBQUALSIZE * 2); 518 519 gtrid_local = new byte[MAXGTRIDSIZE]; 520 ByteBuffer aa = ByteBuffer.wrap(gtrid_local); 521 522 System.arraycopy(gtrid, 0, gtrid_local, 0, gtrid_length); 523 524 for (int i=0; i < gtrid_length; i++) { 525 byteToHex(aa.get(), str_buff_gtrid ); 526 } 527 528 bqual_local = new byte[MAXBQUALSIZE]; 529 ByteBuffer bb = ByteBuffer.wrap(bqual_local); 530 531 if (bqual != null) { 532 System.arraycopy(bqual, 0, bqual_local, 0, bqual_length); 533 534 for (int i=0; i < bqual_length; i++) { 535 byteToHex(bb.get(), str_buff_bqual); 536 } 537 } 538 539 if ((gtrid_length > 30) && !Full ) { int strlen = str_buff_gtrid.length(); 541 str_buff_gtrid.replace( (strlen / 6), (strlen / 6) + 2, "..."); 542 str_buff_gtrid.delete( (strlen / 6) + 3, strlen - 5); 543 } 544 545 if ((bqual_length > 30) && !Full ) { int strlen = str_buff_bqual.length(); 547 str_buff_bqual.replace( (strlen / 6), (strlen / 6) + 2, "..."); 548 str_buff_bqual.delete( (strlen / 6) + 3, strlen - 5); 549 } 550 551 if (Full) { 552 fullString = Long.toHexString(formatId) + ":" + 553 Long.toHexString(gtrid_length) + ":" + 554 Long.toHexString(bqual_length) + ":" + 555 str_buff_gtrid.toString() + ":" + 556 str_buff_bqual.toString(); 557 return fullString; 558 } 559 560 shortString = Long.toHexString(formatId) + ":" + 561 Long.toHexString(gtrid_length) + ":" + 562 Long.toHexString(bqual_length) + ":" + 563 str_buff_gtrid.toString() + ":" + 564 str_buff_bqual.toString(); 565 return shortString; 566 } 567 568 588 589 private byte[] makeGtrid() { 590 makeGtridBase(); 591 long uniqueTimeStamp; 592 593 synchronized( getClass() ) { 594 uniqueTimeStamp = System.currentTimeMillis() * 1024 + count; 595 count++; 596 } 597 598 ByteBuffer bb = ByteBuffer.allocate(gtrid_base.length+8); 599 bb.put(gtrid_base); 600 bb.putLong(uniqueTimeStamp); 601 return bb.array(); 602 } 603 604 private void makeGtridBase() { 605 609 synchronized( getClass() ) { 610 if (rand == null) { 611 rand = new SecureRandom (); 612 613 if (uuidsRecovered == false) { uuid0 = rand.nextLong(); 617 uuid1 = rand.nextLong(); 618 XACommittingTx LogId = null; 619 620 634 byte [] UniqueID = new byte[3+8+8]; 635 byte [] [] UniqueIDRecord = new byte [1][3+8+8]; 636 637 String rt1 = "RU1"; 638 639 ByteBuffer rr1 = ByteBuffer.wrap(UniqueID); 640 rr1.put(rt1.getBytes()); 641 rr1.putLong(uuid0); 642 rr1.putLong(uuid1); 643 644 UniqueIDRecord [0] = UniqueID; 645 646 if (Current.getDefaultRecovery()) { 647 try { 648 LogId = TransactionRecoveryImpl.getTransactionRecovery().howlCommitLog(UniqueIDRecord); 649 } catch (Exception e) { 650 String howlerror = 652 "Cannot howlCommitLog:" 653 + e 654 + " --" 655 + e.getMessage(); 656 TraceTm.recovery.error( 657 "Got LogException from howlCommitLog writing UniqueIDRecord: "+ howlerror); 658 659 } 661 if (TraceTm.recovery.isDebugEnabled()) { 662 TraceTm.recovery.debug("Wrote UniqueIDRecord; at:" + LogId.getLogKey() + " uuid0:" + uuid0 + " uuid1:" + uuid1); 663 } 664 } 665 } 666 667 host = ""; 668 server = ""; 669 host = (host+" ").substring(0,15); 671 server = (server+" ").substring(0,14); 672 gtrid_base = new byte[1+8+8+16+15]; 673 ByteBuffer bb = ByteBuffer.wrap(gtrid_base); 674 bb.put(internalVersId); 675 bb.putLong(uuid0); 676 bb.putLong(uuid1); 677 bb.put(host.getBytes()); 678 bb.put(server.getBytes()); 679 } 680 } 681 } 682 683 689 690 public boolean IsThisOneOfOurs( byte[] gtrid_or_bqual ) { 691 if (rand == null) { 692 makeGtrid(); 693 } 694 695 boolean ret = false; 696 697 if (gtrid_or_bqual != null && 698 gtrid_or_bqual.length >= gtrid_base.length) { 699 byte[] gbase; 700 701 if (gtrid_or_bqual.length == gtrid_base.length) { 702 gbase = gtrid_base; 703 } else { 704 gbase = new byte[gtrid_base.length]; 705 System.arraycopy(gtrid_base,0,gbase,0,gtrid_base.length); 706 } 707 708 byte[] gtrid_local = null; 709 byte[] gtrid_bqual_local = null; 710 711 StringBuffer str_buff_gtrid_bqual = new StringBuffer (gtrid_base.length * 2); 713 StringBuffer str_buff_gbase = new StringBuffer (gtrid_base.length * 2); 714 715 gtrid_local = new byte[gtrid_base.length]; 716 ByteBuffer aa = ByteBuffer.wrap(gtrid_local); 717 718 System.arraycopy(gtrid_base, 0, gtrid_local, 0, gtrid_base.length); 719 720 for (int i=0; i < gtrid_base.length; i++) { 721 byteToHex(aa.get(), str_buff_gbase ); 722 } 723 724 gtrid_bqual_local = new byte[gtrid_base.length]; 725 ByteBuffer bb = ByteBuffer.wrap(gtrid_local); 726 727 System.arraycopy(gtrid_or_bqual, 0, gtrid_bqual_local, 0, gtrid_base.length); 728 729 for (int i=0; i < gtrid_base.length; i++) { 730 byteToHex(bb.get(), str_buff_gtrid_bqual ); 731 } 732 733 if (TraceTm.jotm.isDebugEnabled()) { 734 TraceTm.jotm.debug("gtrid_or_bqual= " + str_buff_gtrid_bqual); 735 TraceTm.jotm.debug("gbase= " + str_buff_gbase); 736 } 737 738 if (str_buff_gtrid_bqual.toString().equals(str_buff_gbase.toString())) { 739 ret = true; 740 } 741 } 742 return ret; 743 } 744 745 749 752 public boolean equals( Object obj2 ) { 753 754 XidImpl xid2 = (XidImpl) obj2; 755 756 if (formatId == xid2.getFormatId() 757 && java.util.Arrays.equals(bqual, xid2.getBranchQualifier()) 758 && java.util.Arrays.equals(gtrid, xid2.getGlobalTransactionId())) { 759 return true; 760 } else { 761 return false; 762 } 763 } 764 765 768 public int hashCode() { 769 770 int hc = 0; 771 772 if (hashcodevalid == false) { 773 774 for (int i = 0; i < gtrid.length; i++) { 775 hc = hc * 37 + gtrid[i]; 776 } 777 778 for (int i = 0; i < bqual.length; i++ ) { 779 hc = hc * 37 + bqual[i]; 780 } 781 782 myhashcode = hc; 783 hashcodevalid = true; 784 } 785 return myhashcode; 786 } 787 } 788 | Popular Tags |