001 /** 002 * 003 * Copyright 2003-2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.transaction.manager; 019 020 import javax.transaction.xa.Xid; 021 import java.net.InetAddress; 022 import java.net.UnknownHostException; 023 024 /** 025 * Factory for transaction ids. 026 * The Xid is constructed of three parts: 027 * <ol><li>8 byte count (LSB first)</li> 028 * <li>4 byte system id</li> 029 * <li>4 or 16 byte IP address of host</li> 030 * <ol> 031 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $ 032 * todo Should have a way of setting baseId 033 */ 034 public class XidFactoryImpl implements XidFactory { 035 private final byte[] baseId = new byte[Xid.MAXGTRIDSIZE]; 036 private long count = 1; 037 038 public XidFactoryImpl(byte[] tmId) { 039 System.arraycopy(tmId, 0, baseId, 8, tmId.length); 040 } 041 042 public XidFactoryImpl() { 043 byte[] hostid; 044 try { 045 hostid = InetAddress.getLocalHost().getAddress(); 046 } catch (UnknownHostException e) { 047 hostid = new byte[]{127, 0, 0, 1}; 048 } 049 int uid = System.identityHashCode(this); 050 baseId[8] = (byte) uid; 051 baseId[9] = (byte) (uid >>> 8); 052 baseId[10] = (byte) (uid >>> 16); 053 baseId[11] = (byte) (uid >>> 24); 054 System.arraycopy(hostid, 0, baseId, 12, hostid.length); 055 } 056 057 public Xid createXid() { 058 byte[] globalId = (byte[]) baseId.clone(); 059 long id; 060 synchronized (this) { 061 id = count++; 062 } 063 globalId[0] = (byte) id; 064 globalId[1] = (byte) (id >>> 8); 065 globalId[2] = (byte) (id >>> 16); 066 globalId[3] = (byte) (id >>> 24); 067 globalId[4] = (byte) (id >>> 32); 068 globalId[5] = (byte) (id >>> 40); 069 globalId[6] = (byte) (id >>> 48); 070 globalId[7] = (byte) (id >>> 56); 071 return new XidImpl(globalId); 072 } 073 074 public Xid createBranch(Xid globalId, int branch) { 075 byte[] branchId = (byte[]) baseId.clone(); 076 branchId[0] = (byte) branch; 077 branchId[1] = (byte) (branch >>> 8); 078 branchId[2] = (byte) (branch >>> 16); 079 branchId[3] = (byte) (branch >>> 24); 080 return new XidImpl(globalId, branchId); 081 } 082 083 public boolean matchesGlobalId(byte[] globalTransactionId) { 084 if (globalTransactionId.length != Xid.MAXGTRIDSIZE) { 085 return false; 086 } 087 for (int i = 8; i < globalTransactionId.length; i++) { 088 if (globalTransactionId[i] != baseId[i]) { 089 return false; 090 } 091 } 092 return true; 093 } 094 095 public boolean matchesBranchId(byte[] branchQualifier) { 096 if (branchQualifier.length != Xid.MAXBQUALSIZE) { 097 return false; 098 } 099 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 }