View Javadoc

1   /**
2    *
3    * Copyright 2003-2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.geronimo.transaction.manager;
19  
20  import javax.transaction.xa.Xid;
21  import java.net.InetAddress;
22  import java.net.UnknownHostException;
23  
24  /**
25   * Factory for transaction ids.
26   * The Xid is constructed of three parts:
27   * <ol><li>8 byte count (LSB first)</li>
28   * <li>4 byte system id</li>
29   * <li>4 or 16 byte IP address of host</li>
30   * <ol>
31   * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
32   * todo Should have a way of setting baseId
33   */
34  public class XidFactoryImpl implements XidFactory {
35      private final byte[] baseId = new byte[Xid.MAXGTRIDSIZE];
36      private long count = 1;
37  
38      public XidFactoryImpl(byte[] tmId) {
39         System.arraycopy(tmId, 0, baseId, 8, tmId.length);
40      }
41  
42      public XidFactoryImpl() {
43          byte[] hostid;
44          try {
45              hostid = InetAddress.getLocalHost().getAddress();
46          } catch (UnknownHostException e) {
47              hostid = new byte[]{127, 0, 0, 1};
48          }
49          int uid = System.identityHashCode(this);
50          baseId[8] = (byte) uid;
51          baseId[9] = (byte) (uid >>> 8);
52          baseId[10] = (byte) (uid >>> 16);
53          baseId[11] = (byte) (uid >>> 24);
54          System.arraycopy(hostid, 0, baseId, 12, hostid.length);
55      }
56  
57      public Xid createXid() {
58          byte[] globalId = (byte[]) baseId.clone();
59          long id;
60          synchronized (this) {
61              id = count++;
62          }
63          globalId[0] = (byte) id;
64          globalId[1] = (byte) (id >>> 8);
65          globalId[2] = (byte) (id >>> 16);
66          globalId[3] = (byte) (id >>> 24);
67          globalId[4] = (byte) (id >>> 32);
68          globalId[5] = (byte) (id >>> 40);
69          globalId[6] = (byte) (id >>> 48);
70          globalId[7] = (byte) (id >>> 56);
71          return new XidImpl(globalId);
72      }
73  
74      public Xid createBranch(Xid globalId, int branch) {
75          byte[] branchId = (byte[]) baseId.clone();
76          branchId[0] = (byte) branch;
77          branchId[1] = (byte) (branch >>> 8);
78          branchId[2] = (byte) (branch >>> 16);
79          branchId[3] = (byte) (branch >>> 24);
80          return new XidImpl(globalId, branchId);
81      }
82  
83      public boolean matchesGlobalId(byte[] globalTransactionId) {
84          if (globalTransactionId.length != Xid.MAXGTRIDSIZE) {
85              return false;
86          }
87          for (int i = 8; i < globalTransactionId.length; i++) {
88              if (globalTransactionId[i] != baseId[i]) {
89                  return false;
90              }
91          }
92          return true;
93      }
94  
95      public boolean matchesBranchId(byte[] branchQualifier) {
96          if (branchQualifier.length != Xid.MAXBQUALSIZE) {
97              return false;
98          }
99          for (int i = 8; i < branchQualifier.length; i++) {
100             if (branchQualifier[i] != baseId[i]) {
101                 return false;
102             }
103         }
104         return true;
105     }
106 
107     public Xid recover(int formatId, byte[] globalTransactionid, byte[] branchQualifier) {
108         return new XidImpl(formatId, globalTransactionid, branchQualifier);
109     }
110 
111 }