Source code: org/apache/derby/iapi/store/access/xa/XAXactId.java
1 /*
2
3 Derby - Class org.apache.derby.iapi.store.access.xa.XAXactId
4
5 Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.iapi.store.access.xa;
22
23 import org.apache.derby.iapi.services.sanity.SanityManager;
24
25 import org.apache.derby.iapi.store.access.GlobalXact;
26
27 import javax.transaction.xa.Xid;
28 import javax.transaction.xa.XAException;
29
30 /**
31
32 The XAXactId class is a specific implementation of the JTA Xid interface. It
33 is only used by the TransactionTable.restore() interface to return an array
34 of Xid's back to the caller, as part of serving the XAresource.restore()
35 interface.
36 <P>
37 It is NOT the object that is stored in the log. One reason for this is that
38 the Formattable and Xid interface's define two different return values for
39 the getFormatId() interface.
40
41 **/
42
43 public class XAXactId extends GlobalXact implements Xid
44 {
45 /**************************************************************************
46 * Private Fields of the class
47 **************************************************************************
48 */
49 private static final char COLON = ':';
50
51 /**************************************************************************
52 * Constructors for This class:
53 **************************************************************************
54 */
55
56 /**
57 * initialize by making array copies of appropriate fields.
58 * <p>
59 **/
60 private void copy_init_xid(
61 int format_id,
62 byte[] global_id,
63 byte[] branch_id)
64 {
65 this.format_id = format_id;
66 this.global_id = new byte[global_id.length];
67 System.arraycopy(global_id, 0, this.global_id, 0, global_id.length);
68 this.branch_id = new byte[branch_id.length];
69 System.arraycopy(branch_id, 0, this.branch_id, 0, branch_id.length);
70 }
71
72 /**
73 * Construct from given pieces of an Xid. Makes copies of arrays.
74 * <p>
75 **/
76 public XAXactId(
77 int format_id,
78 byte[] global_id,
79 byte[] branch_id)
80 {
81 copy_init_xid(format_id, global_id, branch_id);
82 }
83
84 /**
85 * Construct an Xid using an external Xid.
86 * <p>
87 * @exception XAException invalid external xid
88 */
89 public XAXactId(Xid xid) throws XAException
90 {
91 if (xid == null)
92 throw new XAException(XAException.XAER_NOTA);
93
94 copy_init_xid(
95 xid.getFormatId(),
96 xid.getGlobalTransactionId(),
97 xid.getBranchQualifier());
98 }
99
100
101
102
103
104 public String toHexString()
105 {
106 // the ascii representation of xid where xid is of
107 // format_id = f
108 // global_id = byte[N]
109 // branch_id = byte[M]
110 //
111 // :xx:yy:ffffffff:n...n:mmmm...m:
112 // where xx = N (up to 64 max)
113 // yy = M (up to 64 max)
114 // n..n = hex dump of global_id (0 to 128 bytes max)
115 // m..m = hex dump of branch_qualifier (0 to 128 bytes max)
116
117 // 1+2+1+2+1+9+1+1+1
118 int maxLength = 20+(global_id.length+branch_id.length)*2;
119
120 StringBuffer hexdump = new StringBuffer(maxLength);
121 hexdump.append(COLON).
122 append(Integer.toString(global_id.length)).append(COLON).
123 append(Integer.toString(branch_id.length)).append(COLON).
124 append(Integer.toString(format_id, 16)).append(COLON).
125 append(org.apache.derby.iapi.util.StringUtil.toHexString(global_id, 0, global_id.length)).append(COLON).
126 append(org.apache.derby.iapi.util.StringUtil.toHexString(branch_id, 0, branch_id.length)).append(COLON);
127
128 return hexdump.toString();
129
130 }
131
132 public XAXactId(String xactIdString)
133 {
134 // extract it in pieces delimited by COLON
135 int start, end, length;
136
137 // xx
138 start = 1;
139 end = xactIdString.indexOf(COLON, start);
140 if (SanityManager.DEBUG)
141 SanityManager.ASSERT(end != -1, "illegal string format");
142
143 String xx = xactIdString.substring(start, end);
144 int N = Integer.parseInt(xx);
145
146 if (SanityManager.DEBUG)
147 {
148 SanityManager.ASSERT(N > 0 && N <= Xid.MAXGTRIDSIZE, "illegal gtrid size");
149 }
150
151 // yy
152 start = end+1; // skip the COLON
153 end = xactIdString.indexOf(COLON, start);
154 if (SanityManager.DEBUG)
155 SanityManager.ASSERT(end != -1, "illegal string format");
156
157 String yy = xactIdString.substring(start,end);
158 int M = Integer.parseInt(yy);
159
160 if (SanityManager.DEBUG)
161 SanityManager.ASSERT(M > 0 && N <= Xid.MAXBQUALSIZE, "illegal bqual size");
162
163 // ffffffff
164 start = end+1; // skip the COLON
165 end = xactIdString.indexOf(COLON, start);
166 if (SanityManager.DEBUG)
167 SanityManager.ASSERT(end != -1, "illegal string format");
168
169 String f = xactIdString.substring(start,end);
170 format_id = Integer.parseInt(f, 16);
171
172 // n...n
173 start = end+1; // skip the COLON
174 end = xactIdString.indexOf(COLON, start);
175 if (SanityManager.DEBUG)
176 SanityManager.ASSERT(end != -1, "illegal string format");
177
178 global_id = org.apache.derby.iapi.util.StringUtil.fromHexString(xactIdString, start, (end-start));
179
180 if (SanityManager.DEBUG)
181 SanityManager.ASSERT(global_id.length == N, "inconsistent global_id length");
182
183
184 // m...m
185 start = end+1; // skip the COLON
186 end = xactIdString.indexOf(COLON, start);
187 if (SanityManager.DEBUG)
188 SanityManager.ASSERT(end != -1, "illegal string format");
189
190 branch_id = org.apache.derby.iapi.util.StringUtil.fromHexString(xactIdString, start, (end-start));
191
192 if (SanityManager.DEBUG)
193 SanityManager.ASSERT(branch_id.length == M,
194 "inconsistent branch_id length, expect " + M + " got " +
195 branch_id.length);
196
197 }
198
199
200
201 /**************************************************************************
202 * Private/Protected methods of This class:
203 **************************************************************************
204 */
205
206 /**************************************************************************
207 * Public Methods implementing the Xid interface:
208 **************************************************************************
209 */
210
211 /**
212 * Obtain the format id part of the Xid.
213 * <p>
214 *
215 * @return Format identifier. O means the OSI CCR format.
216 **/
217 public int getFormatId()
218 {
219 return(format_id);
220 }
221
222 /**
223 * Obtain the global transaction identifier part of XID as an array of
224 * bytes.
225 * <p>
226 *
227 * @return A byte array containing the global transaction identifier.
228 **/
229 public byte[] getGlobalTransactionId()
230 {
231 return(global_id);
232 }
233
234 /**
235 * Obtain the transaction branch qualifier part of the Xid in a byte array.
236 * <p>
237 *
238 * @return A byte array containing the branch qualifier of the transaction.
239 **/
240 public byte[] getBranchQualifier()
241 {
242 return(branch_id);
243 }
244
245
246
247 public boolean equals(Object other)
248 {
249 if (other == this)
250 return true;
251
252 if (other == null)
253 return false;
254
255 try
256 {
257 if (other instanceof GlobalXact)
258 return super.equals(other);
259 // Just cast it and catch the exception rather than doing the type
260 // checking twice.
261 Xid other_xid = (Xid) other;
262
263 return(
264 java.util.Arrays.equals(
265 other_xid.getGlobalTransactionId(),
266 this.global_id) &&
267 java.util.Arrays.equals(
268 other_xid.getBranchQualifier(),
269 this.branch_id) &&
270 other_xid.getFormatId() == this.format_id);
271
272 }
273 catch(ClassCastException cce)
274 {
275 // this class only knows how to compare with other Xids
276 if (SanityManager.DEBUG)
277 SanityManager.THROWASSERT("comparing XAXactId with " +
278 other.getClass().getName());
279
280 return false;
281 }
282 }
283
284
285 }
286
287
288