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 java.io.Serializable;
021 import java.util.Arrays;
022 import javax.transaction.xa.Xid;
023
024 /**
025 * Unique id for a transaction.
026 *
027 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
028 */
029 public class XidImpl implements Xid, Serializable {
030 private static int FORMAT_ID = 0x4765526f; // Gero
031 private final int formatId;
032 private final byte[] globalId;
033 private final byte[] branchId;
034 private int hash; //apparently never used by our code, so don't compute it.
035
036 /**
037 * Constructor taking a global id (for the main transaction)
038 * @param globalId the global transaction id
039 */
040 public XidImpl(byte[] globalId) {
041 this.formatId = FORMAT_ID;
042 this.globalId = globalId;
043 //this.hash = hash(0, globalId);
044 branchId = new byte[Xid.MAXBQUALSIZE];
045 }
046
047 /**
048 * Constructor for a branch id
049 * @param global the xid of the global transaction this branch belongs to
050 * @param branch the branch id
051 */
052 public XidImpl(Xid global, byte[] branch) {
053 this.formatId = FORMAT_ID;
054 //int hash;
055 if (global instanceof XidImpl) {
056 globalId = ((XidImpl) global).globalId;
057 //hash = ((XidImpl) global).hash;
058 } else {
059 globalId = global.getGlobalTransactionId();
060 //hash = hash(0, globalId);
061 }
062 branchId = branch;
063 //this.hash = hash(hash, branchId);
064 }
065
066 public XidImpl(int formatId, byte[] globalId, byte[] branchId) {
067 this.formatId = formatId;
068 this.globalId = globalId;
069 this.branchId = branchId;
070 }
071
072 private int hash(int hash, byte[] id) {
073 for (int i = 0; i < id.length; i++) {
074 hash = (hash * 37) + id[i];
075 }
076 return hash;
077 }
078
079 public int getFormatId() {
080 return formatId;
081 }
082
083 public byte[] getGlobalTransactionId() {
084 return (byte[]) globalId.clone();
085 }
086
087 public byte[] getBranchQualifier() {
088 return (byte[]) branchId.clone();
089 }
090
091 public boolean equals(Object obj) {
092 if (obj instanceof XidImpl == false) {
093 return false;
094 }
095 XidImpl other = (XidImpl) obj;
096 return formatId == other.formatId
097 && Arrays.equals(globalId, other.globalId)
098 && Arrays.equals(branchId, other.branchId);
099 }
100
101 public int hashCode() {
102 if (hash == 0) {
103 hash = hash(hash(0, globalId), branchId);
104 }
105 return hash;
106 }
107
108 public String toString() {
109 StringBuffer s = new StringBuffer();
110 s.append("[globalId=");
111 for (int i = 0; i < globalId.length; i++) {
112 s.append(Integer.toHexString(globalId[i]));
113 }
114 s.append(",branchId=");
115 for (int i = 0; i < branchId.length; i++) {
116 s.append(Integer.toHexString(branchId[i]));
117 }
118 s.append("]");
119 return s.toString();
120 }
121 }