001: /*
002:
003: Derby - Class org.apache.derby.client.net.NetXAConnectionReply
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.client.net;
023:
024: import javax.transaction.xa.XAResource;
025: import javax.transaction.xa.Xid;
026:
027: import org.apache.derby.client.am.ConnectionCallbackInterface;
028: import org.apache.derby.client.am.DisconnectException;
029:
030: public class NetXAConnectionReply extends NetResultSetReply {
031: NetXAConnectionReply(NetAgent netAgent, int bufferSize) {
032: super (netAgent, bufferSize);
033: }
034:
035: //----------------------------- entry points ---------------------------------
036:
037: public void readLocalXAStart(ConnectionCallbackInterface connection)
038: throws DisconnectException {
039: }
040:
041: public void readLocalXACommit(ConnectionCallbackInterface connection)
042: throws DisconnectException {
043:
044: startSameIdChainParse();
045: parseSYNCCTLreply(connection);
046: endOfSameIdChainData();
047:
048: NetXACallInfo callInfo = netAgent_.netConnection_.xares_.callInfoArray_[netAgent_.netConnection_.currXACallInfoOffset_];
049: callInfo.xaInProgress_ = false;
050: callInfo.xaWasSuspended = false;
051: connection.completeLocalCommit();
052: }
053:
054: public void readLocalXARollback(
055: ConnectionCallbackInterface connection)
056: throws DisconnectException {
057: startSameIdChainParse();
058: parseSYNCCTLreply(connection);
059: endOfSameIdChainData();
060: connection.completeLocalRollback();
061: }
062:
063: protected void readXaStartUnitOfWork(NetConnection conn)
064: throws DisconnectException {
065: startSameIdChainParse();
066: parseSYNCCTLreply(conn);
067: endOfSameIdChainData();
068: }
069:
070: protected int readXaEndUnitOfWork(NetConnection conn)
071: throws DisconnectException {
072: NetXACallInfo callInfo = conn.xares_.callInfoArray_[conn.currXACallInfoOffset_];
073: int xaFlags = callInfo.xaFlags_;
074:
075: startSameIdChainParse();
076: parseSYNCCTLreply(conn);
077: endOfSameIdChainData();
078: if (xaFlags == XAResource.TMFAIL) {
079: return javax.transaction.xa.XAException.XA_RBROLLBACK;
080: }
081: return javax.transaction.xa.XAResource.XA_OK;
082: }
083:
084: protected int readXaPrepare(NetConnection conn)
085: throws DisconnectException {
086: startSameIdChainParse();
087: int synctype = parseSYNCCTLreply(conn);
088: endOfSameIdChainData();
089:
090: NetXACallInfo callInfo = conn.xares_.callInfoArray_[conn.currXACallInfoOffset_];
091: if (synctype == XAResource.XA_RDONLY) { // xaretval of read-only, make sure flag agrees
092: callInfo.setReadOnlyTransactionFlag(true);
093: } else { // xaretval NOT read-only, make sure flag agrees
094: callInfo.setReadOnlyTransactionFlag(false);
095: }
096: return synctype;
097: }
098:
099: protected void readXaCommit(NetConnection conn)
100: throws DisconnectException {
101: startSameIdChainParse();
102: parseSYNCCTLreply(conn);
103: endOfSameIdChainData();
104:
105: NetXACallInfo callInfo = conn.xares_.callInfoArray_[conn.currXACallInfoOffset_];
106: callInfo.xaInProgress_ = false;
107: conn.completeLocalCommit();
108: }
109:
110: protected int readXaRollback(NetConnection conn)
111: throws DisconnectException {
112: startSameIdChainParse();
113: parseSYNCCTLreply(conn);
114: endOfSameIdChainData();
115:
116: NetXACallInfo callInfo = conn.xares_.callInfoArray_[conn.currXACallInfoOffset_];
117: callInfo.xaInProgress_ = false;
118: callInfo.xaWasSuspended = false;
119: conn.completeLocalRollback();
120:
121: return javax.transaction.xa.XAResource.XA_OK;
122: }
123:
124: protected void readXaRecover(NetConnection conn)
125: throws DisconnectException {
126: startSameIdChainParse();
127: parseSYNCCTLreply(conn);
128: endOfSameIdChainData();
129: }
130:
131: protected void readXaForget(NetConnection conn)
132: throws DisconnectException {
133: startSameIdChainParse();
134: parseSYNCCTLreply(conn);
135: endOfSameIdChainData();
136: }
137:
138: //----------------------helper methods----------------------------------------
139:
140: //--------------------- parse DDM Reply Data--------------------------------------
141:
142: // The SYNCCRD Reply Mesage
143: //
144: // Returned from Server:
145: // XARETVAL - required
146: int parseSYNCCRD(ConnectionCallbackInterface connection)
147: throws DisconnectException {
148: boolean svrcodReceived = false;
149: int svrcod = CodePoint.SVRCOD_INFO;
150: int xaretval = 0;
151: int synctype = 0;
152: java.util.Hashtable indoubtTransactions = null;
153: NetConnection conn = netAgent_.netConnection_;
154:
155: parseLengthAndMatchCodePoint(CodePoint.SYNCCRD);
156: pushLengthOnCollectionStack();
157: int peekCP = peekCodePoint();
158:
159: while (peekCP != Reply.END_OF_COLLECTION) {
160:
161: boolean foundInPass = false;
162:
163: if (peekCP == CodePoint.SVRCOD) {
164: foundInPass = true;
165: svrcodReceived = checkAndGetReceivedFlag(svrcodReceived);
166: svrcod = parseSVRCOD(CodePoint.SVRCOD_ERROR,
167: CodePoint.SVRCOD_ERROR);
168: peekCP = peekCodePoint();
169: }
170:
171: if (peekCP == CodePoint.XARETVAL) {
172: foundInPass = true;
173: xaretval = parseXARETVAL();
174: conn.xares_.callInfoArray_[conn.currXACallInfoOffset_].xaRetVal_ = xaretval;
175: peekCP = peekCodePoint();
176: }
177:
178: if (peekCP == CodePoint.SYNCTYPE) {
179: foundInPass = true;
180: synctype = parseSYNCTYPE();
181: peekCP = peekCodePoint();
182: }
183:
184: if (peekCP == CodePoint.PRPHRCLST) {
185: foundInPass = true;
186: indoubtTransactions = parseIndoubtList();
187: conn.setIndoubtTransactions(indoubtTransactions);
188: peekCP = peekCodePoint();
189: }
190:
191: if (!foundInPass) {
192: doPrmnsprmSemantics(peekCP);
193: }
194: }
195: popCollectionStack();
196:
197: return xaretval;
198:
199: }
200:
201: // Process XA return value
202: protected int parseXARETVAL() throws DisconnectException {
203: parseLengthAndMatchCodePoint(CodePoint.XARETVAL);
204: return readInt();
205: }
206:
207: // Process XA return value
208: protected byte parseSYNCTYPE() throws DisconnectException {
209: parseLengthAndMatchCodePoint(CodePoint.SYNCTYPE);
210: return readByte();
211: }
212:
213: // This method handles the parsing of all command replies and reply data
214: // for the SYNNCTL command.
215: protected int parseSYNCCTLreply(
216: ConnectionCallbackInterface connection)
217: throws DisconnectException {
218: int retval = 0;
219: int peekCP = peekCodePoint();
220:
221: if (peekCP != CodePoint.SYNCCRD) {
222: parseSYNCCTLError(peekCP);
223: return -1;
224: }
225: retval = parseSYNCCRD(connection);
226:
227: peekCP = peekCodePoint();
228: while (peekCP == CodePoint.SQLSTT) {
229: String s = parseSQLSTT();
230: //JCFTMP, need to null out the client list?
231: netAgent_.netConnection_.xares_.addSpecialRegisters(s);
232: peekCP = peekCodePoint();
233: }
234:
235: return retval;
236: }
237:
238: //------------------------parse DDM Scalars-----------------------------
239:
240: private String parseSQLSTT() throws DisconnectException {
241: parseLengthAndMatchCodePoint(CodePoint.SQLSTT);
242: return parseSQLSTTGRPNOCMorNOCS();
243: }
244:
245: private String parseSQLSTTGRPNOCMorNOCS()
246: throws DisconnectException {
247: int mixedNullInd = readUnsignedByte();
248: int singleNullInd = 0;
249: String sqlsttString = null;
250: int stringLength = 0;
251:
252: if (mixedNullInd == CodePoint.NULLDATA) {
253: singleNullInd = readUnsignedByte();
254: if (singleNullInd == CodePoint.NULLDATA) {
255: // throw DTAMCHRM
256: doDtamchrmSemantics();
257: }
258: // read 4-byte length
259: stringLength = readInt();
260: // read sqlstt string
261: sqlsttString = readString(stringLength,
262: netAgent_.targetTypdef_.getCcsidSbcEncoding());
263: } else {
264: // read 4-byte length
265: stringLength = readInt();
266: // read sqlstt string
267: sqlsttString = readString(stringLength,
268: netAgent_.targetTypdef_.getCcsidMbcEncoding());
269: // read null indicator
270: singleNullInd = readUnsignedByte();
271: }
272: return sqlsttString;
273: }
274:
275: protected int parseXIDCNT() throws DisconnectException {
276: parseLengthAndMatchCodePoint(CodePoint.XIDCNT);
277: return readUnsignedShort();
278: }
279:
280: protected Xid parseXID() throws DisconnectException {
281: parseLengthAndMatchCodePoint(CodePoint.XID);
282: int formatId = readInt();
283: int gtridLen = readInt();
284: int bqualLen = readInt();
285: byte[] gtrid = readBytes(gtridLen);
286: byte[] bqual = readBytes(bqualLen);
287:
288: return new org.apache.derby.client.ClientXid(formatId, gtrid,
289: bqual);
290: }
291:
292: protected java.util.Hashtable parseIndoubtList()
293: throws DisconnectException {
294: boolean found = false;
295: int port = 0;
296: int numXid = 0;
297: String sIpAddr = null;
298: int peekCP = peekCodePoint();
299: parseLengthAndMatchCodePoint(CodePoint.PRPHRCLST);
300: peekCP = peekCodePoint();
301: if (peekCP == CodePoint.XIDCNT) {
302: found = true;
303: numXid = parseXIDCNT();
304: peekCP = peekCodePoint();
305: }
306:
307: java.util.Hashtable indoubtTransactions = new java.util.Hashtable();
308: while (peekCP == CodePoint.XID) {
309: Xid xid = parseXID();
310: indoubtTransactions.put(xid, new NetIndoubtTransaction(xid,
311: null, null, null, sIpAddr, port));
312: peekCP = peekCodePoint();
313: }
314:
315: return indoubtTransactions;
316: }
317:
318: }
|