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 }