diff options
Diffstat (limited to 'qpid/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java')
-rw-r--r-- | qpid/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java b/qpid/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java new file mode 100644 index 0000000000..69457ca4a9 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpid/dtx/XidImpl.java @@ -0,0 +1,259 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.dtx; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.qpid.AMQInvalidArgumentException; + +import javax.transaction.xa.Xid; + +import java.io.*; +import java.util.Arrays; + +/** + * Implements javax.transaction.dtx.Xid + */ +public class XidImpl implements Xid +{ + /** + * this session's logger + */ + private static final Logger _logger = LoggerFactory.getLogger(XidImpl.class); + + /** + * the transaction branch identifier part of XID as an array of bytes + */ + private byte[] _branchQualifier; + + /** + * the format identifier part of the XID. + */ + private int _formatID; + + /** + * the global transaction identifier part of XID as an array of bytes. + */ + private byte[] _globalTransactionID; + + //--- Constructors + + /** + * Create new Xid. + * this is an empty constructor. + */ + public XidImpl() + { + + } + + /** + * Create a new XidImpl from an existing Xid. + * <p> Usefull for casting external Xids + * + * @param xid Foreign Xid. + */ + public XidImpl(Xid xid) + { + _branchQualifier = xid.getBranchQualifier(); + _formatID = xid.getFormatId(); + _globalTransactionID = xid.getGlobalTransactionId(); + } + + /** + * Create a new Xid. + * + * @param branchQualifier The transaction branch identifier part of XID as an array of bytes. + * @param format The format identifier part of the XID. + * @param globalTransactionID The global transaction identifier part of XID as an array of bytes. + */ + public XidImpl(byte[] branchQualifier, int format, byte[] globalTransactionID) + { + _branchQualifier = branchQualifier; + _formatID = format; + _globalTransactionID = globalTransactionID; + } + + /** + * Create a new Xid form its String form + * 4 1 1 g b + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * | format_id | g | b | txn-id | br-id | + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * 0 4 5 6 6+g 6+g+b + * format_id: an implementation specific format identifier + * <p/> + * gtrid_length: how many bytes of this form the transaction id + * <p/> + * bqual_length: how many bytes of this form the branch id + * <p/> + * data: a sequence of octets of at most 128 bytes containing the txn id and the + * branch id + * <p/> + * Note - The sum of the two lengths must equal the length of the data field. + * + * @param xid an XID STring Form + * @throws AMQInvalidArgumentException If the string does not represent a valid Xid + */ + public XidImpl(String xid) throws AMQInvalidArgumentException + { + if (_logger.isDebugEnabled()) + { + _logger.debug("converting string " + xid + " into XidImpl"); + } + try + { + DataInputStream input = new DataInputStream(new ByteArrayInputStream(xid.getBytes())); + _formatID = (int) input.readLong(); + int g = input.readByte(); + int b = input.readByte(); + _globalTransactionID = new byte[g]; + _branchQualifier = new byte[b]; + if (input.read(_globalTransactionID, 0, g) != g) + { + throw new AMQInvalidArgumentException("Cannot convert the string " + xid + " into an Xid", null); + } + if (input.read(_branchQualifier, 0, b) != b) + { + throw new AMQInvalidArgumentException("Cannot convert the string " + xid + " into an Xid", null); + } + } + catch (IOException e) + { + throw new AMQInvalidArgumentException("cannot convert the string " + xid + " into an Xid", e); + } + } + + //--- Xid interface implementation + + /** + * Format identifier. O means the OSI CCR format. + * + * @return Global transaction identifier. + */ + public byte[] getGlobalTransactionId() + { + return _globalTransactionID; + } + + /** + * Obtain the transaction branch identifier part of XID as an array of bytes. + * + * @return Branch identifier part of XID. + */ + public byte[] getBranchQualifier() + { + return _branchQualifier; + } + + /** + * Obtain the format identifier part of the XID. + * + * @return Format identifier. O means the OSI CCR format. + */ + public int getFormatId() + { + return _formatID; + } + + //--- Object operations + + /** + * Indicates whether some other Xid is "equal to" this one. + * <p> Two Xids are equal if and only if their three elementary parts are equal + * + * @param o the object to compare this <code>XidImpl</code> against. + * @return true if the <code>XidImpl</code> are equal, false otherwise. + */ + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o instanceof XidImpl) + { + XidImpl other = (XidImpl) o; + if (_formatID == other.getFormatId()) + { + if (_branchQualifier.length == other.getBranchQualifier().length) + { + for (int i = 0; i < _branchQualifier.length; i++) + { + if (_branchQualifier[i] != other.getBranchQualifier()[i]) + { + return false; + } + } + if (_globalTransactionID.length == other.getGlobalTransactionId().length) + { + for (int i = 0; i < _globalTransactionID.length; i++) + { + if (_globalTransactionID[i] != other.getGlobalTransactionId()[i]) + { + return false; + } + } + // everithing is equal + return true; + } + } + } + } + return false; + } + + @Override + public int hashCode() + { + int result = _branchQualifier != null ? Arrays.hashCode(_branchQualifier) : 0; + result = 31 * result + _formatID; + result = 31 * result + (_globalTransactionID != null ? Arrays.hashCode(_globalTransactionID) : 0); + return result; + } + + //-- Static helper method + /** + * Convert an Xid into the AMQP String format. + * + * 4 1 1 g b + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * | format_id | g | b | txn-id | br-id | + * +---+---+---+---+---+---+---+- -+---+---+- -+---+ + * 0 4 5 6 6+g 6+g+b + * format_id: an implementation specific format identifier + * <p/> + * gtrid_length: how many bytes of this form the transaction id + * <p/> + * bqual_length: how many bytes of this form the branch id + * <p/> + * data: a sequence of octets of at most 128 bytes containing the txn id and the + * branch id + * <p/> + * Note - The sum of the two lengths must equal the length of the data field. + * + * @param xid an Xid to convert. + * @return The String representation of this Xid + */ + public static org.apache.qpid.transport.Xid convert(Xid xid) + { + return new org.apache.qpid.transport.Xid(xid.getFormatId(), + xid.getGlobalTransactionId(), + xid.getBranchQualifier()); + } +} |