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 package org.apache.activemq.command; 018 019 import java.util.ArrayList; 020 import java.util.Arrays; 021 import javax.transaction.xa.Xid; 022 import org.apache.activemq.util.HexSupport; 023 024 /** 025 * @openwire:marshaller code="112" 026 * 027 */ 028 public class XATransactionId extends TransactionId implements Xid, Comparable { 029 030 public static final byte DATA_STRUCTURE_TYPE = CommandTypes.ACTIVEMQ_XA_TRANSACTION_ID; 031 032 private int formatId; 033 private byte[] branchQualifier; 034 private byte[] globalTransactionId; 035 036 private transient int hash; 037 private transient String transactionKey; 038 private transient ArrayList<MessageAck> preparedAcks; 039 040 public XATransactionId() { 041 } 042 043 public XATransactionId(Xid xid) { 044 this.formatId = xid.getFormatId(); 045 this.globalTransactionId = xid.getGlobalTransactionId(); 046 this.branchQualifier = xid.getBranchQualifier(); 047 } 048 049 public byte getDataStructureType() { 050 return DATA_STRUCTURE_TYPE; 051 } 052 053 public synchronized String getTransactionKey() { 054 if (transactionKey == null) { 055 StringBuffer s = new StringBuffer(); 056 s.append("XID:[globalId="); 057 for (int i = 0; i < globalTransactionId.length; i++) { 058 s.append(Integer.toHexString(globalTransactionId[i])); 059 } 060 s.append(",branchId="); 061 for (int i = 0; i < branchQualifier.length; i++) { 062 s.append(Integer.toHexString(branchQualifier[i])); 063 } 064 s.append("]"); 065 transactionKey = s.toString(); 066 } 067 return transactionKey; 068 } 069 070 public String toString() { 071 return getTransactionKey(); 072 } 073 074 public boolean isXATransaction() { 075 return true; 076 } 077 078 public boolean isLocalTransaction() { 079 return false; 080 } 081 082 /** 083 * @openwire:property version=1 084 */ 085 public int getFormatId() { 086 return formatId; 087 } 088 089 /** 090 * @openwire:property version=1 091 */ 092 public byte[] getGlobalTransactionId() { 093 return globalTransactionId; 094 } 095 096 /** 097 * @openwire:property version=1 098 */ 099 public byte[] getBranchQualifier() { 100 return branchQualifier; 101 } 102 103 public void setBranchQualifier(byte[] branchQualifier) { 104 this.branchQualifier = branchQualifier; 105 this.hash = 0; 106 } 107 108 public void setFormatId(int formatId) { 109 this.formatId = formatId; 110 this.hash = 0; 111 } 112 113 public void setGlobalTransactionId(byte[] globalTransactionId) { 114 this.globalTransactionId = globalTransactionId; 115 this.hash = 0; 116 } 117 118 public int hashCode() { 119 if (hash == 0) { 120 hash = formatId; 121 hash = hash(globalTransactionId, hash); 122 hash = hash(branchQualifier, hash); 123 if (hash == 0) { 124 hash = 0xaceace; 125 } 126 } 127 return hash; 128 } 129 130 private static int hash(byte[] bytes, int hash) { 131 int size = bytes.length; 132 for (int i = 0; i < size; i++) { 133 hash ^= bytes[i] << ((i % 4) * 8); 134 } 135 return hash; 136 } 137 138 public boolean equals(Object o) { 139 if (o == null || o.getClass() != XATransactionId.class) { 140 return false; 141 } 142 XATransactionId xid = (XATransactionId)o; 143 return xid.formatId == formatId && Arrays.equals(xid.globalTransactionId, globalTransactionId) 144 && Arrays.equals(xid.branchQualifier, branchQualifier); 145 } 146 147 public int compareTo(Object o) { 148 if (o == null || o.getClass() != XATransactionId.class) { 149 return -1; 150 } 151 XATransactionId xid = (XATransactionId)o; 152 return getTransactionKey().compareTo(xid.getTransactionKey()); 153 } 154 155 public void setPreparedAcks(ArrayList<MessageAck> preparedAcks) { 156 this.preparedAcks = preparedAcks; 157 } 158 159 public ArrayList<MessageAck> getPreparedAcks() { 160 return preparedAcks; 161 } 162 }