KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jotm > XidImpl


1 /*
2  * @(#) XidImpl.java
3  *
4  * JOTM: Java Open Transaction Manager
5  *
6  *
7  * This module was originally developed by
8  *
9  * - Bull S.A. as part of the JOnAS application server code released in
10  * July 1999 (www.bull.com)
11  *
12  * --------------------------------------------------------------------------
13  * The original code and portions created by Bull SA are
14  * Copyright (c) 1999 BULL SA
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are met:
19  *
20  * -Redistributions of source code must retain the above copyright notice, this
21  * list of conditions and the following disclaimer.
22  *
23  * -Redistributions in binary form must reproduce the above copyright notice,
24  * this list of conditions and the following disclaimer in the documentation
25  * and/or other materials provided with the distribution.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  *
39  * --------------------------------------------------------------------------
40  * $Id: XidImpl.java,v 1.28 2005/04/22 17:53:46 tonyortiz Exp $
41  * --------------------------------------------------------------------------
42  */

43 package org.objectweb.jotm;
44
45 import java.io.Serializable JavaDoc;
46 import java.nio.ByteBuffer JavaDoc;
47 import java.security.SecureRandom JavaDoc;
48
49 import org.objectweb.howl.log.xa.XACommittingTx;
50
51 /**
52  * Xid implementation for JTA
53  *
54  * XID has the following format as defined by X/Open Specification:
55  *
56  * XID
57  * long formatId format identifier
58  * long gtrid_length value 1-64
59  * long bqual_length value 1-64
60  * byte data [XIDDATASIZE] where XIDDATASIZE = 128
61  *
62  * The data field comprises at most two contiguous components:
63  * a global transaction identifier (gtrid) and a branch qualifier (bqual)
64  * which are defined as:
65  *
66  * byte gtrid [1-64] global transaction identfier
67  * byte bqual [1-64] branch qualifier
68  *
69  */

70 public class XidImpl implements Xid, Serializable JavaDoc {
71
72     public static final int JOTM_FORMAT_ID = 0xBB14;
73
74     // these cells are gated by this.getClass()
75
private static SecureRandom JavaDoc rand = null; // (also used as first-time flag)
76
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; // created by makeGtridBase()
82
private static String JavaDoc host, server;
83
84     private String JavaDoc fullString = "";
85     private String JavaDoc shortString = "";
86     
87     private boolean hashcodevalid = false;
88     private int myhashcode;
89
90     static String JavaDoc 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     /**
126      * format id
127      * @serial
128      */

129     private int formatId;
130
131     /**
132      * gtrid length
133      * @serial
134      */

135     private int gtrid_length;
136
137     /**
138      * bqual length
139      * @serial
140      */

141     private int bqual_length;
142
143     /**
144      * global transaction id
145      * @serial
146      */

147     private byte[] gtrid;
148
149     /**
150      * branch qualifier
151      * @serial
152      */

153     private byte[] bqual;
154
155     // -------------------------------------------------------------------
156
// Constructors
157
// -------------------------------------------------------------------
158

159     /**
160      * Build an Xid for a local transaction
161      */

162     public XidImpl( String JavaDoc 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         // compute gtrid
179
// compute JOnAS gtrid
180
String JavaDoc 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         // XXX bqual is equal to gtrid in this constructor
196
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     /**
205      * Build an Xid from an otid_t CORBA
206      */

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
213
formatId = fid;
214
215         // gtrid
216
int gtridsz = tid.length - bqualsz;
217         gtrid = new byte[gtridsz];
218         System.arraycopy(tid, bqualsz, gtrid, 0, gtridsz);
219
220         // bqual
221
bqual = new byte[bqualsz];
222         System.arraycopy(tid, 0, bqual, 0, bqualsz);
223
224         // gtrid_length
225
gtrid_length = gtridsz;
226
227         // bqual_length
228
bqual_length = bqualsz;
229     }
230
231     /**
232      * build Xid with all its components
233      * (for performance on java serialization)
234      */

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     /**
245      * build a new Xid with a null BQual
246      */

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     /**
257      * build a new Xid from an existing Xid, preserving the gtrid,
258      * and using the 'index' as part of the unique but recognizable BQual.
259      * The important thing is that this method must return the same result
260      * on successive calls given the same input.
261      */

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 JavaDoc bb = ByteBuffer.wrap(bqual);
277         bb.put(gtrid_base);
278         bb.putLong(0L); // (time stamp not used on bqual)
279
bb.putLong(index+0L); // and this makes the bqual unique
280
bqual_length = bqual.length;
281     }
282     
283     /**
284      * Construct an Xid from a byteBuffer. This is necessary for use
285      * during recovery when the Xid has been converted to a String so
286      * that it can be written to a file. The Xid must be reconstructed
287      * from the byte array resulting from toString(true). Note that the
288      * byte array includes ':' characters as separators between
289      * components.
290      *
291      * NOTE: Current position of input ByteBuffer is employed!!
292      *
293      */

294     
295     public XidImpl( ByteBuffer JavaDoc 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     /**
349      * Construct an Xid from a byte array. This is necessary for use
350      * during recovery when the Xid has been converted to a byte array so
351      * that it can be written to the Howl log. The Xid must be reconstructed
352      * from the byte array resulting from toString(true). Note that the
353      * byte array includes ':' characters as separators between components.
354      *
355      */

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     /**
425       * The xid was passed from an external EIS (inflow transaction).
426       * Need to store the formatId, gtrid.length, bqual.length, gtrid,
427       * and bqual from the passed xid.
428       */

429
430     public XidImpl( javax.transaction.xa.Xid JavaDoc 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     // -------------------------------------------------------------------
443
// Xid implementation
444
// -------------------------------------------------------------------
445

446     /**
447      * Provide static interface to recover uuid0 & uuid1 after journal
448      * replay.
449      */

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     /**
461      * Get the format id for that Xid
462      */

463     public int getFormatId() {
464         return formatId;
465     }
466
467     /**
468      * Get the Global Id for that Xid
469      */

470     public byte[] getGlobalTransactionId() {
471         return gtrid;
472     }
473
474     /**
475      * Get the Branch Qualifier for that Xid
476      */

477     public byte[] getBranchQualifier() {
478         return bqual;
479     }
480
481     // -------------------------------------------------------------------
482
// other methods
483
// -------------------------------------------------------------------
484

485     /**
486      * Hex Dump of byte
487      */

488     static final void byteToHex( byte inbyte, StringBuffer JavaDoc str_buff ) {
489
490         int myByte = 0xFF & inbyte;
491         
492         str_buff.append( HexDigits[myByte] );
493         return;
494     }
495
496     /**
497      * String form
498      * default toString() compresses Xid's
499      */

500     public String JavaDoc toString() {
501         return this.toString( false );
502     }
503
504     public String JavaDoc 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         // Buffers need two hex characters per byte
516
StringBuffer JavaDoc str_buff_gtrid = new StringBuffer JavaDoc(MAXGTRIDSIZE * 2);
517         StringBuffer JavaDoc str_buff_bqual = new StringBuffer JavaDoc(MAXBQUALSIZE * 2);
518
519         gtrid_local = new byte[MAXGTRIDSIZE];
520         ByteBuffer JavaDoc 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 JavaDoc 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 ) { // be prepared to reduce output string
540
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 ) { // be prepared to reduce output string
546
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     /*
569      * make a unique but recognizable gtrid.
570      *
571      * format:
572      * 1. internal version identifier - 1 byte
573      * 2. uuid - 16 bytes
574      * 3. host name - 16 bytes
575      * 4. server name - 15 bytes
576      * 5. timestamp - 8 bytes
577      * 6. [reserved for use by bqual - 8 bytes]
578      *
579      * Items 1 thru 4 are generated by makeGtridBase and comprise the recognizable
580      * portion of a gtrid or bqual. Together, these serve to make Xids generated on
581      * this system unique from those generated on other systems.
582      * Item 5 is generated by this routine and serves to make gtrids unique.
583      * Item 6 serves to distinguish different bquals belonging
584      * to the same Xid, and is generated elsewhere.
585      *
586      * Items 1 thru 4 are used to determine if we (JOTM) generated this gtrid/bqual.
587      */

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 JavaDoc 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         // acquire the configured uuid, host and server name.
606
// fabricate a uuid if one does not yet exist.
607
// and append a unique timestamp.
608

609         synchronized( getClass() ) {
610             if (rand == null) {
611                 rand = new SecureRandom JavaDoc();
612                 
613                 if (uuidsRecovered == false) { // first time or no journal
614
//uuid0 = Long.parseLong(System.getProperty("jotm.uuid.part1"),16);
615
//uuid1 = Long.parseLong(System.getProperty("jotm.uuid.part2"),16);
616
uuid0 = rand.nextLong();
617                     uuid1 = rand.nextLong();
618                     XACommittingTx LogId = null;
619                     
620                     // We build the Inique ID Record in makeGtridBase
621
// Store the Unique ID Record using HOWL so it can manage for us.
622
// It will never have a DONE record written.
623
//
624
// The Unique ID record consists of two fields:
625
// 1. uuid0
626
// 2. uuid1
627
//
628
// The XA Unique ID record format:
629
// Unique ID record type1 (byte[3]) - 'RU1'
630
// Unique ID record stored uuido (long) - 8 bytes
631
// Unique ID record stored uuid1 (long) - 8 bytes
632
//
633

634                     byte [] UniqueID = new byte[3+8+8];
635                     byte [] [] UniqueIDRecord = new byte [1][3+8+8];
636
637                     String JavaDoc rt1 = "RU1";
638
639                     ByteBuffer JavaDoc 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 JavaDoc e) {
650                             // If we cannot write the Log, we cannot perform recovery
651
String JavaDoc howlerror =
652                                 "Cannot howlCommitLog:"
653                                 + e
654                                 + " --"
655                                 + e.getMessage();
656                              TraceTm.recovery.error(
657                                  "Got LogException from howlCommitLog writing UniqueIDRecord: "+ howlerror);
658
659 // XXX throw new TransactionRolledbackException();
660
}
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                 // make host & server names fixed length, as defined above
670
host = (host+" ").substring(0,15);
671                 server = (server+" ").substring(0,14);
672                 gtrid_base = new byte[1+8+8+16+15];
673                 ByteBuffer JavaDoc 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     /*
684      * Check if the specified gtrid or bqual is one which was generated
685      * by this version of JOTM.
686      *
687      * @return true or false
688      */

689     
690     public boolean IsThisOneOfOurs( byte[] gtrid_or_bqual ) {
691         if (rand == null) {
692             makeGtrid(); /* init gtrid_base if not yet done */
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             // Buffers need two hex characters per byte
712
StringBuffer JavaDoc str_buff_gtrid_bqual = new StringBuffer JavaDoc(gtrid_base.length * 2);
713             StringBuffer JavaDoc str_buff_gbase = new StringBuffer JavaDoc(gtrid_base.length * 2);
714
715             gtrid_local = new byte[gtrid_base.length];
716             ByteBuffer JavaDoc 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 JavaDoc 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     // -------------------------------------------------------------------
746
// equals and hashCode
747
// -------------------------------------------------------------------
748

749     /**
750      * return true if objects are identical
751      */

752     public boolean equals( Object JavaDoc 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     /**
766      * return a hashcode value for this object
767      */

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