All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.activemq.apollo.broker.XidImpl Maven / Gradle / Ivy

The newest version!
/**
 * 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.activemq.apollo.broker;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import javax.transaction.xa.Xid;

import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.DataByteArrayOutputStream;

/**
 * An implementation of JTA transaction identifier (javax.transaction.xa.Xid).
 */
public class XidImpl implements Xid, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = -5363901495878210611L;
    private static final Buffer EMPTY_BUFFER = new Buffer(new byte[]{});

    // The format identifier for the XID. A value of -1 indicates the NULLXID
    private int formatId = -1; // default format
    Buffer globalTransactionId = EMPTY_BUFFER;
    Buffer branchQualifier = EMPTY_BUFFER;

    /////////////////////////////// Constructors /////////////////////////////
    /**
     * Constructs a new null XID.
     * 

* After construction the data within the XID should be initialized. */ public XidImpl() { } public XidImpl(int formatID, byte[] globalTxnID, byte[] branchID) { this.formatId = formatID; setGlobalTransactionId(globalTxnID); setBranchQualifier(branchID); } public XidImpl(int formatID, Buffer globalTransactionId, Buffer branchQualifier) { this.formatId = formatID; this.globalTransactionId = globalTransactionId; this.branchQualifier=branchQualifier; } /** * Initialize an XID using another XID as the source of data. * * @param from * the XID to initialize this XID from */ public XidImpl(Xid from) { if ((from == null) || (from.getFormatId() == -1)) { formatId = -1; setGlobalTransactionId(null); setBranchQualifier(null); } else { formatId = from.getFormatId(); setGlobalTransactionId(from.getGlobalTransactionId()); setBranchQualifier(from.getBranchQualifier()); } } // used for test purpose public XidImpl(String globalTxnId, String branchId) { this(99, globalTxnId.getBytes(), branchId.getBytes()); } //////////// Public Methods ////////////// /** * Determine whether or not two objects of this type are equal. * * @param o * the other XID object to be compared with this XID. * * @return Returns true of the supplied object represents the same global * transaction as this, otherwise returns false. */ public boolean equals(Object o) { if (o.getClass() != XidImpl.class) return false; XidImpl other = (XidImpl) o; if (formatId == -1 && other.formatId == -1) return true; return formatId == other.formatId && globalTransactionId.equals(other.globalTransactionId) && branchQualifier.equals(other.branchQualifier); } /** * Compute the hash code. * * @return the computed hashcode */ public int hashCode() { if (formatId == -1) return (-1); return formatId ^ globalTransactionId.hashCode() ^ branchQualifier.hashCode(); } /** * Return a string representing this XID. *

* This is normally used to display the XID when debugging. * * @return the string representation of this XID */ public String toString() { String gtString = new String(getGlobalTransactionId()); String brString = new String(getBranchQualifier()); return new String("{Xid: " + "formatID=" + formatId + ", " + "gtrid[" + globalTransactionId.length + "]=" + gtString + ", " + "brid[" + branchQualifier.length + "]=" + brString + "}"); } /** * Obtain the format identifier part of the XID. * * @return Format identifier. -1 indicates a null XID */ public int getFormatId() { return formatId; } /** * Returns the global transaction identifier for this XID. * * @return the global transaction identifier */ public byte[] getGlobalTransactionId() { // TODO.. may want to compact() first and keep cache that.. return globalTransactionId.toByteArray(); } /** * Returns the branch qualifier for this XID. * * @return the branch qualifier */ public byte[] getBranchQualifier() { // TODO.. may want to compact() first and keep cache that.. return branchQualifier.toByteArray(); } ///////////////////////// private methods //////////////////////////////// /** * Set the branch qualifier for this XID. Note that the branch qualifier has * a maximum size. * * @param branchID * a Byte array containing the branch qualifier to be set. If the * size of the array exceeds MAXBQUALSIZE, only the first * MAXBQUALSIZE elements of qual will be used. */ private void setBranchQualifier(byte[] branchID) { if (branchID == null) { branchQualifier = EMPTY_BUFFER; } else { int length = branchID.length > MAXBQUALSIZE ? MAXBQUALSIZE : branchID.length; // TODO: Do we really need to copy the bytes?? branchQualifier = new Buffer(new byte[length]); System.arraycopy(branchID, 0, branchQualifier.data, 0, length); } } private void setGlobalTransactionId(byte[] globalTxnID) { if (globalTxnID == null) { globalTransactionId = EMPTY_BUFFER; } else { int length = globalTxnID.length > MAXGTRIDSIZE ? MAXGTRIDSIZE : globalTxnID.length; // TODO: Do we really need to copy the bytes?? globalTransactionId = new Buffer(new byte[length]); System.arraycopy(globalTxnID, 0, globalTransactionId.data, 0, length); } } public int getMemorySize() { return 4 // formatId + 4 // length of globalTxnId + globalTransactionId.length // globalTxnId + 4 // length of branchId + branchQualifier.length; // branchId } /** * Writes this XidImpl's data to the DataOutput destination * * @param out The DataOutput destination */ public void writebody(DataOutput out) throws IOException { out.writeInt(formatId); // format ID out.writeInt(globalTransactionId.length); // length of global Txn ID out.write(globalTransactionId.data, globalTransactionId.offset, globalTransactionId.length); // global transaction ID out.writeInt(branchQualifier.length); // length of branch ID out.write(branchQualifier.data, branchQualifier.offset, branchQualifier.length); // branch ID } /** * read xid from an Array and set each fields. * * @param in * the data input array * @throws IOException */ public void readbody(DataInput in) throws IOException { formatId = in.readInt(); int length = in.readInt(); byte[] data = new byte[length]; in.readFully(data); setGlobalTransactionId(data); length = in.readInt(); data = new byte[length]; in.readFully(data); setBranchQualifier(data); } /** * @param xid * @return */ public static Buffer toBuffer(Xid xid) { XidImpl x = new XidImpl(xid); DataByteArrayOutputStream baos = new DataByteArrayOutputStream(x.getMemorySize()); try { x.writebody(baos); } catch (IOException e) { //Shouldn't happen: throw new RuntimeException(e); } return baos.toBuffer(); } } // class XidImpl





© 2015 - 2025 Weber Informatics LLC | Privacy Policy