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