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

com.taobao.metamorphosis.transaction.XATransactionId Maven / Gradle / Ivy

/*
 * (C) 2007-2012 Alibaba Group Holding Limited.
 * 
 * Licensed 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.
 * Authors:
 *   wuhua  , boyan 
 */
package com.taobao.metamorphosis.transaction;

import java.io.Serializable;
import java.util.Arrays;
import java.util.regex.Pattern;

import javax.transaction.xa.Xid;

import com.taobao.metamorphosis.utils.HexSupport;
import com.taobao.metamorphosis.utils.PatternUtils;


/**
 * XA????id
 * 
 * @author boyan
 * 
 */
public class XATransactionId extends TransactionId implements Xid, Comparable, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 7130168769221529970L;
    private int formatId;
    private byte[] branchQualifier;
    private byte[] globalTransactionId;

    private transient int hash;
    private transient String transactionKey;


    @Override
    public boolean isNull() {
        return false;
    }


    public XATransactionId() {
    }


    /**
     * Just for test
     * 
     * @param formatId
     * @param branchQualifier
     * @param globalTransactionId
     */
    public XATransactionId(final int formatId, final byte[] branchQualifier, final byte[] globalTransactionId) {
        super();
        this.formatId = formatId;
        this.branchQualifier = branchQualifier;
        this.globalTransactionId = globalTransactionId;
    }

    static final Pattern pattern = Pattern.compile(":");


    public XATransactionId(final String key) {
        final String[] tmps = PatternUtils.split(pattern, key);
        if (tmps.length != 4) {
            throw new IllegalArgumentException("Illegal transaction key" + key);
        }
        assert tmps[0].equals("XID");
        this.formatId = Integer.parseInt(tmps[1]);
        this.globalTransactionId = HexSupport.toBytesFromHex(tmps[2]);
        this.branchQualifier = HexSupport.toBytesFromHex(tmps[3]);
    }


    public XATransactionId(final Xid xid) {
        this.formatId = xid.getFormatId();
        this.globalTransactionId = xid.getGlobalTransactionId();
        this.branchQualifier = xid.getBranchQualifier();
    }


    @Override
    public synchronized String getTransactionKey() {
        if (this.transactionKey == null) {
            this.transactionKey =
                    "XID:" + this.formatId + ":" + HexSupport.toHexFromBytes(this.globalTransactionId) + ":"
                            + HexSupport.toHexFromBytes(this.branchQualifier);
        }
        return this.transactionKey;
    }


    @Override
    public String toString() {
        return this.getTransactionKey();
    }


    @Override
    public boolean isXATransaction() {
        return true;
    }


    @Override
    public boolean isLocalTransaction() {
        return false;
    }


    /**
     * @openwire:property version=1
     */
    @Override
    public int getFormatId() {
        return this.formatId;
    }


    /**
     * @openwire:property version=1
     */
    @Override
    public byte[] getGlobalTransactionId() {
        return this.globalTransactionId;
    }


    /**
     * @openwire:property version=1
     */
    @Override
    public byte[] getBranchQualifier() {
        return this.branchQualifier;
    }


    public void setBranchQualifier(final byte[] branchQualifier) {
        this.branchQualifier = branchQualifier;
        this.hash = 0;
    }


    public void setFormatId(final int formatId) {
        this.formatId = formatId;
        this.hash = 0;
    }


    public void setGlobalTransactionId(final byte[] globalTransactionId) {
        this.globalTransactionId = globalTransactionId;
        this.hash = 0;
    }


    @Override
    public int hashCode() {
        if (this.hash == 0) {
            this.hash = this.formatId;
            this.hash = hash(this.globalTransactionId, this.hash);
            this.hash = hash(this.branchQualifier, this.hash);
            if (this.hash == 0) {
                this.hash = 0xaceace;
            }
        }
        return this.hash;
    }


    private static int hash(final byte[] bytes, int hash) {
        final int size = bytes.length;
        for (int i = 0; i < size; i++) {
            hash ^= bytes[i] << i % 4 * 8;
        }
        return hash;
    }


    @Override
    public boolean equals(final Object o) {
        if (o == null || !(o instanceof XATransactionId)) {
            return false;
        }
        final XATransactionId xid = (XATransactionId) o;
        return xid.formatId == this.formatId && Arrays.equals(xid.globalTransactionId, this.globalTransactionId)
                && Arrays.equals(xid.branchQualifier, this.branchQualifier);
    }


    @Override
    public int compareTo(final XATransactionId o) {
        if (o == null || o.getClass() != XATransactionId.class) {
            return -1;
        }
        final XATransactionId xid = o;
        return this.getTransactionKey().compareTo(xid.getTransactionKey());
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy