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}