1 /** 2 * 3 * Copyright 2003-2004 The Apache Software Foundation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.geronimo.transaction.manager; 19 20 import javax.transaction.xa.Xid; 21 import java.net.InetAddress; 22 import java.net.UnknownHostException; 23 24 /** 25 * Factory for transaction ids. 26 * The Xid is constructed of three parts: 27 * <ol><li>8 byte count (LSB first)</li> 28 * <li>4 byte system id</li> 29 * <li>4 or 16 byte IP address of host</li> 30 * <ol> 31 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $ 32 * todo Should have a way of setting baseId 33 */ 34 public class XidFactoryImpl implements XidFactory { 35 private final byte[] baseId = new byte[Xid.MAXGTRIDSIZE]; 36 private long count = 1; 37 38 public XidFactoryImpl(byte[] tmId) { 39 System.arraycopy(tmId, 0, baseId, 8, tmId.length); 40 } 41 42 public XidFactoryImpl() { 43 byte[] hostid; 44 try { 45 hostid = InetAddress.getLocalHost().getAddress(); 46 } catch (UnknownHostException e) { 47 hostid = new byte[]{127, 0, 0, 1}; 48 } 49 int uid = System.identityHashCode(this); 50 baseId[8] = (byte) uid; 51 baseId[9] = (byte) (uid >>> 8); 52 baseId[10] = (byte) (uid >>> 16); 53 baseId[11] = (byte) (uid >>> 24); 54 System.arraycopy(hostid, 0, baseId, 12, hostid.length); 55 } 56 57 public Xid createXid() { 58 byte[] globalId = (byte[]) baseId.clone(); 59 long id; 60 synchronized (this) { 61 id = count++; 62 } 63 globalId[0] = (byte) id; 64 globalId[1] = (byte) (id >>> 8); 65 globalId[2] = (byte) (id >>> 16); 66 globalId[3] = (byte) (id >>> 24); 67 globalId[4] = (byte) (id >>> 32); 68 globalId[5] = (byte) (id >>> 40); 69 globalId[6] = (byte) (id >>> 48); 70 globalId[7] = (byte) (id >>> 56); 71 return new XidImpl(globalId); 72 } 73 74 public Xid createBranch(Xid globalId, int branch) { 75 byte[] branchId = (byte[]) baseId.clone(); 76 branchId[0] = (byte) branch; 77 branchId[1] = (byte) (branch >>> 8); 78 branchId[2] = (byte) (branch >>> 16); 79 branchId[3] = (byte) (branch >>> 24); 80 return new XidImpl(globalId, branchId); 81 } 82 83 public boolean matchesGlobalId(byte[] globalTransactionId) { 84 if (globalTransactionId.length != Xid.MAXGTRIDSIZE) { 85 return false; 86 } 87 for (int i = 8; i < globalTransactionId.length; i++) { 88 if (globalTransactionId[i] != baseId[i]) { 89 return false; 90 } 91 } 92 return true; 93 } 94 95 public boolean matchesBranchId(byte[] branchQualifier) { 96 if (branchQualifier.length != Xid.MAXBQUALSIZE) { 97 return false; 98 } 99 for (int i = 8; i < branchQualifier.length; i++) { 100 if (branchQualifier[i] != baseId[i]) { 101 return false; 102 } 103 } 104 return true; 105 } 106 107 public Xid recover(int formatId, byte[] globalTransactionid, byte[] branchQualifier) { 108 return new XidImpl(formatId, globalTransactionid, branchQualifier); 109 } 110 111 }