001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 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 }