001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.tx; 019 020import java.nio.ByteBuffer; 021import java.util.Random; 022 023import javax.transaction.xa.Xid; 024 025/** 026 * Factory for generating transaction identifiers. 027 * Only the serialization methods are used during runtime, as {@link Xid}s are determined by the underlying XAResource. 028 * @author Paul Ferraro 029 */ 030public class XidTransactionIdentifierFactory implements TransactionIdentifierFactory<Xid> 031{ 032 /** 033 * {@inheritDoc} 034 * Only used for testing purposes. 035 * @see net.sf.hajdbc.tx.TransactionIdentifierFactory#createTransactionIdentifier() 036 */ 037 @Override 038 public Xid createTransactionIdentifier() 039 { 040 Random random = new Random(System.currentTimeMillis()); 041 042 final int formatId = random.nextInt(); 043 final byte[] globalTransactionId = new byte[Xid.MAXGTRIDSIZE]; 044 random.nextBytes(globalTransactionId); 045 final byte[] branchQualifier = new byte[Xid.MAXBQUALSIZE]; 046 random.nextBytes(branchQualifier); 047 048 return new Xid() 049 { 050 @Override 051 public int getFormatId() 052 { 053 return formatId; 054 } 055 056 @Override 057 public byte[] getGlobalTransactionId() 058 { 059 return globalTransactionId; 060 } 061 062 @Override 063 public byte[] getBranchQualifier() 064 { 065 return branchQualifier; 066 } 067 }; 068 } 069 070 /** 071 * {@inheritDoc} 072 * @see net.sf.hajdbc.tx.TransactionIdentifierFactory#serialize(java.lang.Object) 073 */ 074 @Override 075 public byte[] serialize(Xid xid) 076 { 077 return ByteBuffer.allocate(this.size()).putInt(xid.getFormatId()).put(xid.getGlobalTransactionId()).put(xid.getBranchQualifier()).array(); 078 } 079 080 /** 081 * {@inheritDoc} 082 * @see net.sf.hajdbc.tx.TransactionIdentifierFactory#deserialize(byte[]) 083 */ 084 @Override 085 public Xid deserialize(byte[] bytes) 086 { 087 ByteBuffer buffer = ByteBuffer.wrap(bytes); 088 final int formatId = buffer.getInt(); 089 final byte[] globalTransactionId = new byte[Xid.MAXGTRIDSIZE]; 090 buffer.get(globalTransactionId); 091 final byte[] branchQualifier = new byte[Xid.MAXBQUALSIZE]; 092 buffer.get(branchQualifier); 093 094 return new Xid() 095 { 096 @Override 097 public int getFormatId() 098 { 099 return formatId; 100 } 101 102 @Override 103 public byte[] getGlobalTransactionId() 104 { 105 return globalTransactionId; 106 } 107 108 @Override 109 public byte[] getBranchQualifier() 110 { 111 return branchQualifier; 112 } 113 }; 114 } 115 116 /** 117 * {@inheritDoc} 118 * @see net.sf.hajdbc.tx.TransactionIdentifierFactory#size() 119 */ 120 @Override 121 public int size() 122 { 123 return Integer.SIZE + Xid.MAXGTRIDSIZE + Xid.MAXBQUALSIZE; 124 } 125}