001 /* Licensed to the Apache Software Foundation (ASF) under one
002 * or more contributor license agreements. See the NOTICE file
003 * distributed with this work for additional information
004 * regarding copyright ownership. The ASF licenses this file
005 * to you under the Apache License, Version 2.0 (the
006 * "License"); you may not use this file except in compliance
007 * with 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,
012 * software distributed under the License is distributed on an
013 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
014 * KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations
016 * under the License.
017 */
018 package org.apache.qpid.dtx;
019
020 import org.slf4j.Logger;
021 import org.slf4j.LoggerFactory;
022 import org.apache.qpid.QpidException;
023
024 import javax.transaction.xa.Xid;
025
026 import java.io.*;
027
028 /**
029 * Implements javax.transaction.dtx.Xid
030 */
031 public class XidImpl implements Xid
032 {
033 /**
034 * this session's logger
035 */
036 private static final Logger _logger = LoggerFactory.getLogger(XidImpl.class);
037
038 /**
039 * the transaction branch identifier part of XID as an array of bytes
040 */
041 private byte[] _branchQualifier;
042
043 /**
044 * the format identifier part of the XID.
045 */
046 private int _formatID;
047
048 /**
049 * the global transaction identifier part of XID as an array of bytes.
050 */
051 private byte[] _globalTransactionID;
052
053 //--- Constructors
054
055 /**
056 * Create new Xid.
057 * this is an empty constructor.
058 */
059 public XidImpl()
060 {
061
062 }
063
064 /**
065 * Create a new XidImpl from an existing Xid.
066 * <p> Usefull for casting external Xids
067 *
068 * @param xid Foreign Xid.
069 */
070 public XidImpl(Xid xid)
071 {
072 _branchQualifier = xid.getBranchQualifier();
073 _formatID = xid.getFormatId();
074 _globalTransactionID = xid.getGlobalTransactionId();
075 }
076
077 /**
078 * Create a new Xid.
079 *
080 * @param branchQualifier The transaction branch identifier part of XID as an array of bytes.
081 * @param format The format identifier part of the XID.
082 * @param globalTransactionID The global transaction identifier part of XID as an array of bytes.
083 */
084 public XidImpl(byte[] branchQualifier, int format, byte[] globalTransactionID)
085 {
086 _branchQualifier = branchQualifier;
087 _formatID = format;
088 _globalTransactionID = globalTransactionID;
089 }
090
091 /**
092 * Create a new Xid form its String form
093 * 4 1 1 g b
094 * +---+---+---+---+---+---+---+- -+---+---+- -+---+
095 * | format_id | g | b | txn-id | br-id |
096 * +---+---+---+---+---+---+---+- -+---+---+- -+---+
097 * 0 4 5 6 6+g 6+g+b
098 * format_id: an implementation specific format identifier
099 * <p/>
100 * gtrid_length: how many bytes of this form the transaction id
101 * <p/>
102 * bqual_length: how many bytes of this form the branch id
103 * <p/>
104 * data: a sequence of octets of at most 128 bytes containing the txn id and the
105 * branch id
106 * <p/>
107 * Note - The sum of the two lengths must equal the length of the data field.
108 *
109 * @param xid an XID STring Form
110 * @throws QpidException If the string does not represent a valid Xid
111 */
112 public XidImpl(String xid) throws QpidException
113 {
114 if (_logger.isDebugEnabled())
115 {
116 _logger.debug("converting string " + xid + " into XidImpl");
117 }
118 try
119 {
120 DataInputStream input = new DataInputStream(new ByteArrayInputStream(xid.getBytes()));
121 _formatID = (int) input.readLong();
122 int g = input.readByte();
123 int b = input.readByte();
124 _globalTransactionID = new byte[g];
125 _branchQualifier = new byte[b];
126 if (input.read(_globalTransactionID, 0, g) != g)
127 {
128 throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null);
129 }
130 if (input.read(_branchQualifier, 0, b) != b)
131 {
132 throw new QpidException("Cannot convert the string " + xid + " into an Xid", null, null);
133 }
134 }
135 catch (IOException e)
136 {
137 throw new QpidException("cannot convert the string " + xid + " into an Xid", null, e);
138 }
139 }
140
141 //--- Xid interface implementation
142
143 /**
144 * Format identifier. O means the OSI CCR format.
145 *
146 * @return Global transaction identifier.
147 */
148 public byte[] getGlobalTransactionId()
149 {
150 return _globalTransactionID;
151 }
152
153 /**
154 * Obtain the transaction branch identifier part of XID as an array of bytes.
155 *
156 * @return Branch identifier part of XID.
157 */
158 public byte[] getBranchQualifier()
159 {
160 return _branchQualifier;
161 }
162
163 /**
164 * Obtain the format identifier part of the XID.
165 *
166 * @return Format identifier. O means the OSI CCR format.
167 */
168 public int getFormatId()
169 {
170 return _formatID;
171 }
172
173 //--- Object operations
174
175 /**
176 * Indicates whether some other Xid is "equal to" this one.
177 * <p> Two Xids are equal if and only if their three elementary parts are equal
178 *
179 * @param o the object to compare this <code>XidImpl</code> against.
180 * @return true if the <code>XidImpl</code> are equal, false otherwise.
181 */
182 public boolean equals(Object o)
183 {
184 if (this == o)
185 {
186 return true;
187 }
188 if (o instanceof XidImpl)
189 {
190 XidImpl other = (XidImpl) o;
191 if (_formatID == other.getFormatId())
192 {
193 if (_branchQualifier.length == other.getBranchQualifier().length)
194 {
195 for (int i = 0; i < _branchQualifier.length; i++)
196 {
197 if (_branchQualifier[i] != other.getBranchQualifier()[i])
198 {
199 return false;
200 }
201 }
202 if (_globalTransactionID.length == other.getGlobalTransactionId().length)
203 {
204 for (int i = 0; i < _globalTransactionID.length; i++)
205 {
206 if (_globalTransactionID[i] != other.getGlobalTransactionId()[i])
207 {
208 return false;
209 }
210 }
211 // everithing is equal
212 return true;
213 }
214 }
215 }
216 }
217 return false;
218 }
219
220 //-- Static helper method
221 /**
222 * Convert an Xid into the AMQP String format.
223 *
224 * 4 1 1 g b
225 * +---+---+---+---+---+---+---+- -+---+---+- -+---+
226 * | format_id | g | b | txn-id | br-id |
227 * +---+---+---+---+---+---+---+- -+---+---+- -+---+
228 * 0 4 5 6 6+g 6+g+b
229 * format_id: an implementation specific format identifier
230 * <p/>
231 * gtrid_length: how many bytes of this form the transaction id
232 * <p/>
233 * bqual_length: how many bytes of this form the branch id
234 * <p/>
235 * data: a sequence of octets of at most 128 bytes containing the txn id and the
236 * branch id
237 * <p/>
238 * Note - The sum of the two lengths must equal the length of the data field.
239 *
240 * @param xid an Xid to convert.
241 * @return The String representation of this Xid
242 * @throws QpidException In case of problem when converting this Xid into a string.
243 */
244 public static org.apache.qpid.transport.Xid convert(Xid xid) throws QpidException
245 {
246 return new org.apache.qpid.transport.Xid(xid.getFormatId(),
247 xid.getGlobalTransactionId(),
248 xid.getBranchQualifier());
249 }
250 }
|