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 }