/* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.tm; import javax.transaction.xa.Xid; /** * This object encapsulates the ID of a transaction. * This implementation is immutable and always serializable at runtime. * * @see TransactionImpl * @author Rickard Öberg * @author Ole Husgaard * @version $Revision: 1.2.2.2 $ */ public class XidImpl implements Xid, java.io.Serializable { // Constants ----------------------------------------------------- public static final int JBOSS_FORMAT_ID = 0x0101; // Attributes ---------------------------------------------------- /** * Hash code of this instance. This is really a sequence number. */ private final int hash; /** * Global transaction id of this instance. * The coding of this class depends on the fact that this variable is * initialized in the constructor and never modified. References to * this array are never given away, instead a clone is delivered. */ private final byte[] globalId; /** * Branch qualifier of this instance. * This identifies the branch of a transaction. */ private final byte[] branchId; // Static -------------------------------------------------------- /** * Return a string that describes any Xid instance. */ static String toString(Xid id) { if (id == null) return "[NULL Xid]"; String s = id.getClass().getName(); s = s.substring(s.lastIndexOf('.') + 1); s = s + " [FormatId=" + id.getFormatId() + ", GlobalId=" + new String(id.getGlobalTransactionId()).trim() + ", BranchQual=" + new String(id.getBranchQualifier()).trim()+"]"; return s; } // Constructors -------------------------------------------------- /** * Create a new instance. */ public XidImpl(byte[] globalId, byte[] branchId, int hash) { this.globalId = globalId; this.branchId = branchId; this.hash = hash; } /** * Create a new branch of an existing global transaction ID. * * @param xid The transaction ID to create a new branch of. * @param branchId The ID of the new branch. * */ public XidImpl(final Xid xid, final byte[] branchId) { if (xid instanceof XidImpl) { this.hash = ((XidImpl)xid).hash; this.globalId = ((XidImpl)xid).globalId; // reuse array instance, we never modify. } // end of if () else { this.hash = xid.hashCode(); this.globalId = xid.getGlobalTransactionId(); } // end of else this.branchId = branchId; } // Public -------------------------------------------------------- // Xid implementation -------------------------------------------- /** * Return the global transaction id of this transaction. */ public byte[] getGlobalTransactionId() { return (byte[])globalId.clone(); } /** * Return the branch qualifier of this transaction. */ public byte[] getBranchQualifier() { if (branchId.length == 0) return branchId; // Zero length arrays are immutable. else return (byte[])branchId.clone(); } /** * Return the format identifier of this transaction. * * The format identifier augments the global id and specifies * how the global id and branch qualifier should be interpreted. */ public int getFormatId() { // The id we return here should be different from all other transaction // implementations. // Known IDs are: // -1: Sometimes used to denote a null transaction id. // 0: OSI TP (javadoc states OSI CCR, but that is a bit misleading // as OSI CCR doesn't even have ACID properties. But OSI CCR and // OSI TP do have the same id format.) // 1: Was used by early betas of jBoss. // 0x0101: The JBOSS_FORMAT_ID we use here. // 0xBB14: Used by JONAS. // 0xBB20: Used by JONAS. return JBOSS_FORMAT_ID; } /** * Compare for equality. * * Instances are considered equal if they are both instances of XidImpl, * and if they have the same global transaction id and transaction * branch qualifier. */ public boolean equals(Object obj) { if(obj==this) return true; if (obj instanceof XidImpl) { XidImpl other = (XidImpl)obj; if (globalId.length != other.globalId.length || branchId.length != other.branchId.length) return false; for (int i = 0; i < globalId.length; ++i) if (globalId[i] != other.globalId[i]) return false; for (int i = 0; i < branchId.length; ++i) if (branchId[i] != other.branchId[i]) return false; return true; } return false; } public int hashCode() { return hash; } public String toString() { return toString(this); } // Package protected --------------------------------------------- /** * Return the global transaction id of this transaction. * Unlike the {@link #getGlobalTransactionId()} method, this one * returns a reference to the global id byte array that may not * be changed. */ byte[] getInternalGlobalTransactionId() { return globalId; } // Protected ----------------------------------------------------- // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }