Source Code Cross Referenced for NetXAResource.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » client » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.client.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.client.net.NetXAResource
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:        /**********************************************************************
0022:         *
0023:         *
0024:         *  Component Name =
0025:         *
0026:         *      Package Name = org.apache.derby.client.net
0027:         *
0028:         *  Descriptive Name = class implements XAResource
0029:         *
0030:         *  Status = New code
0031:         *
0032:         *  Function = Handle XA methods
0033:         *
0034:         *  List of Classes
0035:         *              - NetXAResource
0036:         *
0037:         *  Restrictions : None
0038:         *
0039:         **********************************************************************/package org.apache.derby.client.net;
0040:
0041:        import java.net.InetAddress;
0042:        import java.net.UnknownHostException;
0043:        import java.util.Collections;
0044:        import java.util.Enumeration;
0045:        import java.util.LinkedList;
0046:        import java.util.List;
0047:        import java.util.Vector;
0048:        import javax.sql.XAConnection;
0049:        import javax.transaction.xa.XAException;
0050:        import javax.transaction.xa.XAResource;
0051:        import javax.transaction.xa.Xid;
0052:
0053:        import org.apache.derby.client.ClientXid;
0054:        import org.apache.derby.client.am.Connection;
0055:        import org.apache.derby.client.am.SqlException;
0056:        import org.apache.derby.client.am.ClientMessageId;
0057:        import org.apache.derby.shared.common.reference.SQLState;
0058:
0059:        public class NetXAResource implements  XAResource {
0060:            public static final int TMTIMEOUT = 0x00000100;
0061:            public static final int ACTIVE_ONLY = -1;
0062:            public static final int XA_NULL_XID = -1; // null Xid has Format Id of -1
0063:            public static final int INITIAL_CALLINFO_ELEMENTS = 1;
0064:            public static final int RECOVER_XID_ARRAY_LENGTH = 10;
0065:            public static final ClientXid nullXid = new ClientXid();
0066:
0067:            // xaFunction defines, shows which queued XA function is being performed
0068:            public static final int XAFUNC_NONE = 0;
0069:            public static final int XAFUNC_COMMIT = 1;
0070:            public static final int XAFUNC_END = 2;
0071:            public static final int XAFUNC_FORGET = 3;
0072:            public static final int XAFUNC_PREPARE = 4;
0073:            public static final int XAFUNC_RECOVER = 5;
0074:            public static final int XAFUNC_ROLLBACK = 6;
0075:            public static final int XAFUNC_START = 7;
0076:            public static final String XAFUNCSTR_NONE = "No XA Function";
0077:            public static final String XAFUNCSTR_COMMIT = "XAResource.commit()";
0078:            public static final String XAFUNCSTR_END = "XAResource.end()";
0079:            public static final String XAFUNCSTR_FORGET = "XAResource.forget()";
0080:            public static final String XAFUNCSTR_PREPARE = "XAResource.prepare()";
0081:            public static final String XAFUNCSTR_RECOVER = "XAResource.recover()";
0082:            public static final String XAFUNCSTR_ROLLBACK = "XAResource.rollback()";
0083:            public static final String XAFUNCSTR_START = "XAResource.start()";
0084:
0085:            public int nextElement = 0;
0086:
0087:            // XAResources with same RM group list
0088:            protected static Vector xaResourceSameRMGroup_ = new Vector();
0089:            protected int sameRMGroupIndex_ = 0;
0090:            protected NetXAResource nextSameRM_ = null;
0091:            protected boolean ignoreMe_ = false;
0092:
0093:            public org.apache.derby.client.am.SqlException exceptionsOnXA = null;
0094:
0095:            XAConnection xaconn_;
0096:            org.apache.derby.client.net.NetXAConnection netXAConn_;
0097:            org.apache.derby.client.net.NetConnection conn_;
0098:            int rmId_; // unique RmId generated by XAConnection
0099:            // TODO: change to a single callInfo field (not an array)
0100:            NetXACallInfo callInfoArray_[] = new NetXACallInfo[INITIAL_CALLINFO_ELEMENTS];
0101:            int numXACallInfo_ = INITIAL_CALLINFO_ELEMENTS;
0102:            int connectionCount_ = 1;
0103:            int activeXATransCount_ = 0;
0104:            String rmIdx_; // userid in case we need to create a secondary connection
0105:            String rmIdy_; // password in case we need to create a secondary connection
0106:            // TODO: remove port and ipaddr_
0107:            int port_; // port needed to make secondary connection for recover in DS mode.
0108:            String ipaddr_; // ip address needed to make secondary connection for recover in DS mode.
0109:
0110:            private List specialRegisters_ = Collections
0111:                    .synchronizedList(new LinkedList());
0112:
0113:            public NetXAResource(XAConnection xaconn, int rmId, String userId,
0114:                    String password,
0115:                    org.apache.derby.client.net.NetXAConnection conn) {
0116:                xaconn_ = xaconn;
0117:                rmId_ = rmId;
0118:                conn_ = conn.getNetConnection();
0119:                netXAConn_ = conn;
0120:                rmIdx_ = userId;
0121:                rmIdy_ = password;
0122:                port_ = conn_.netAgent_.getPort();
0123:                ipaddr_ = conn_.netAgent_.socket_.getLocalAddress()
0124:                        .getHostAddress();
0125:                conn.setNetXAResource(this );
0126:
0127:                // link the primary connection to the first XACallInfo element
0128:                conn_.currXACallInfoOffset_ = 0;
0129:
0130:                // construct the NetXACallInfo object for the array.
0131:                for (int i = 0; i < INITIAL_CALLINFO_ELEMENTS; ++i) {
0132:                    callInfoArray_[i] = new NetXACallInfo(null,
0133:                            XAResource.TMNOFLAGS, this , null);
0134:                }
0135:
0136:                // initialize the first XACallInfo element with the information from the
0137:                //  primary connection
0138:                callInfoArray_[0].actualConn_ = conn;
0139:                callInfoArray_[0].currConnection_ = true;
0140:                callInfoArray_[0].freeEntry_ = false;
0141:                // ~~~ save conn_ connection variables in callInfoArray_[0]
0142:                callInfoArray_[0].saveConnectionVariables();
0143:
0144:                // add this new XAResource to the list of other XAResources for the Same RM
0145:                initForReuse();
0146:            }
0147:
0148:            public void commit(Xid xid, boolean onePhase) throws XAException {
0149:                NetAgent netAgent = conn_.netAgent_;
0150:                int rc = XAResource.XA_OK;
0151:
0152:                exceptionsOnXA = null;
0153:                if (conn_.agent_.loggingEnabled()) {
0154:                    conn_.agent_.logWriter_.traceEntry(this , "commit", xid,
0155:                            onePhase);
0156:                }
0157:                if (conn_.isPhysicalConnClosed()) {
0158:                    connectionClosedFailure();
0159:                }
0160:
0161:                // update the XACallInfo
0162:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0163:                callInfo.xaFlags_ = (onePhase ? XAResource.TMONEPHASE
0164:                        : XAResource.TMNOFLAGS);
0165:                callInfo.xid_ = xid;
0166:                callInfo.xaResource_ = this ;
0167:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0168:                try {
0169:                    netAgent.beginWriteChainOutsideUOW();
0170:                    netAgent.netConnectionRequest_.writeXaCommit(conn_, xid);
0171:                    netAgent.flowOutsideUOW();
0172:                    netAgent.netConnectionReply_.readXaCommit(conn_);
0173:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0174:                        callInfo.xaFunction_ = XAFUNC_COMMIT;
0175:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0176:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0177:                    }
0178:                    netAgent.endReadChain();
0179:                } catch (SqlException sqle) {
0180:                    rc = XAException.XAER_RMERR;
0181:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0182:                            .accumulateSQLException(sqle, exceptionsOnXA);
0183:                } finally {
0184:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0185:                }
0186:                if (rc != XAResource.XA_OK) {
0187:                    throwXAException(rc, false);
0188:                }
0189:            }
0190:
0191:            /**
0192:             * Ends the work performed on behalf of a transaction branch. The resource manager dissociates the XA resource from
0193:             * the transaction branch specified and let the transaction be completed.
0194:             * <p/>
0195:             * If TMSUSPEND is specified in flags, the transaction branch is temporarily suspended in incomplete state. The
0196:             * transaction context is in suspened state and must be resumed via start with TMRESUME specified.
0197:             * <p/>
0198:             * If TMFAIL is specified, the portion of work has failed. The resource manager may mark the transaction as
0199:             * rollback-only
0200:             * <p/>
0201:             * If TMSUCCESS is specified, the portion of work has completed successfully.
0202:             *
0203:             * @param xid   A global transaction identifier that is the same as what was used previously in the start method.
0204:             * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND
0205:             *
0206:             * @throws XAException An error has occurred. Possible XAException values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA,
0207:             *                     XAER_INVAL, XAER_PROTO, or XA_RB*.
0208:             */
0209:
0210:            public void end(Xid xid, int flags) throws XAException {
0211:
0212:                NetAgent netAgent = conn_.netAgent_;
0213:                int rc = XAResource.XA_OK;
0214:                exceptionsOnXA = null;
0215:                if (conn_.agent_.loggingEnabled()) {
0216:                    conn_.agent_.logWriter_.traceEntry(this , "end", xid, flags);
0217:                }
0218:                if (conn_.isPhysicalConnClosed()) {
0219:                    connectionClosedFailure();
0220:                }
0221:
0222:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0223:                callInfo.setReadOnlyTransactionFlag(conn_.readOnlyTransaction_);
0224:                callInfo.xaFlags_ = flags;
0225:                callInfo.xid_ = xid;
0226:                callInfo.xaResource_ = this ;
0227:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0228:                try {
0229:                    netAgent.beginWriteChainOutsideUOW();
0230:                    netAgent.netConnectionRequest_.writeXaEndUnitOfWork(conn_);
0231:                    netAgent.flowOutsideUOW();
0232:                    rc = netAgent.netConnectionReply_
0233:                            .readXaEndUnitOfWork(conn_);
0234:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending end
0235:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0236:                        callInfo.xaFunction_ = XAFUNC_END;
0237:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0238:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0239:                    }
0240:                    netAgent.endReadChain();
0241:                } catch (SqlException sqle) {
0242:                    rc = XAException.XAER_RMERR;
0243:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0244:                            .accumulateSQLException(sqle, exceptionsOnXA);
0245:                } finally {
0246:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0247:                }
0248:                if (rc != XAResource.XA_OK) {
0249:                    throwXAException(rc, false);
0250:                } else {
0251:                    conn_.setXAState(Connection.XA_T0_NOT_ASSOCIATED);
0252:                }
0253:            }
0254:
0255:            /**
0256:             * Tell the resource manager to forget about a heuristically (MANUALLY) completed transaction branch.
0257:             *
0258:             * @param xid A global transaction identifier
0259:             *
0260:             * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA,
0261:             *                     XAER_INVAL, or XAER_PROTO.
0262:             */
0263:
0264:            public void forget(Xid xid) throws XAException {
0265:                NetAgent netAgent = conn_.netAgent_;
0266:                int rc = XAResource.XA_OK;
0267:                exceptionsOnXA = null;
0268:
0269:                if (conn_.agent_.loggingEnabled()) {
0270:                    conn_.agent_.logWriter_.traceEntry(this , "forget", xid);
0271:                }
0272:                if (conn_.isPhysicalConnClosed()) {
0273:                    connectionClosedFailure();
0274:                }
0275:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0276:                callInfo.xid_ = xid;
0277:                callInfo.xaResource_ = this ;
0278:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0279:                try {
0280:                    // flow the required PROTOCOL to the server
0281:                    netAgent.beginWriteChainOutsideUOW();
0282:
0283:                    // sent the commit PROTOCOL
0284:                    netAgent.netConnectionRequest_.writeXaForget(
0285:                            netAgent.netConnection_, xid);
0286:
0287:                    netAgent.flowOutsideUOW();
0288:
0289:                    // read the reply to the commit
0290:                    netAgent.netConnectionReply_
0291:                            .readXaForget(netAgent.netConnection_);
0292:
0293:                    netAgent.endReadChain();
0294:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0295:                        callInfo.xaFunction_ = XAFUNC_FORGET;
0296:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0297:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0298:                    }
0299:                } catch (SqlException sqle) {
0300:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0301:                            .accumulateSQLException(sqle, exceptionsOnXA);
0302:                    throwXAException(XAException.XAER_RMERR);
0303:                } finally {
0304:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0305:                }
0306:                if (rc != XAResource.XA_OK) {
0307:                    throwXAException(rc, false);
0308:                }
0309:
0310:            }
0311:
0312:            /**
0313:             * Obtain the current transaction timeout value set for this XAResource instance. If
0314:             * <CODE>XAResource.setTransactionTimeout</CODE> was not use prior to invoking this method, the return value is the
0315:             * default timeout set for the resource manager; otherwise, the value used in the previous
0316:             * <CODE>setTransactionTimeout</CODE> call is returned.
0317:             *
0318:             * @return the transaction timeout value in seconds.
0319:             *
0320:             * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
0321:             */
0322:            public int getTransactionTimeout() throws XAException {
0323:                if (conn_.agent_.loggingEnabled()) {
0324:                    conn_.agent_.logWriter_.traceEntry(this ,
0325:                            "getTransactionTimeout");
0326:                }
0327:                exceptionsOnXA = null;
0328:                if (conn_.isPhysicalConnClosed()) {
0329:                    connectionClosedFailure();
0330:                }
0331:
0332:                if (conn_.agent_.loggingEnabled()) {
0333:                    conn_.agent_.logWriter_.traceExit(this ,
0334:                            "getTransactionTimeout", 0);
0335:                }
0336:                return 0; // we don't support transaction timeout
0337:            }
0338:
0339:            /**
0340:             * Ask the resource manager to prepare for a transaction commit of the transaction specified in xid.
0341:             *
0342:             * @param xid A global transaction identifier
0343:             *
0344:             * @return A value indicating the resource manager's vote on the outcome of the transaction. The possible values
0345:             *         are: XA_RDONLY or XA_OK. If the resource manager wants to roll back the transaction, it should do so by
0346:             *         raising an appropriate XAException in the prepare method.
0347:             *
0348:             * @throws XAException An error has occurred. Possible exception values are: XA_RB*, XAER_RMERR, XAER_RMFAIL,
0349:             *                     XAER_NOTA, XAER_INVAL, or XAER_PROTO.
0350:             */
0351:            public int prepare(Xid xid) throws XAException { // public interface for prepare
0352:                // just call prepareX with the recursion flag set to true
0353:                exceptionsOnXA = null;
0354:
0355:                if (conn_.agent_.loggingEnabled()) {
0356:                    conn_.agent_.logWriter_.traceEntry(this , "prepare", xid);
0357:                }
0358:                if (conn_.isPhysicalConnClosed()) {
0359:                    connectionClosedFailure();
0360:                }
0361:
0362:                /// update the XACallInfo
0363:                NetAgent netAgent = conn_.netAgent_;
0364:                int rc = XAResource.XA_OK;
0365:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0366:                callInfo.xid_ = xid;
0367:                callInfo.xaResource_ = this ;
0368:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0369:                try {
0370:                    netAgent.beginWriteChainOutsideUOW();
0371:                    // sent the prepare PROTOCOL
0372:                    netAgent.netConnectionRequest_.writeXaPrepare(conn_);
0373:                    netAgent.flowOutsideUOW();
0374:
0375:                    // read the reply to the prepare
0376:                    rc = netAgent.netConnectionReply_.readXaPrepare(conn_);
0377:                    if ((callInfo.xaRetVal_ != XAResource.XA_OK)
0378:                            && (callInfo.xaRetVal_ != XAException.XA_RDONLY)) { // xaRetVal has possible error, format it
0379:                        callInfo.xaFunction_ = XAFUNC_PREPARE;
0380:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0381:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0382:                    }
0383:
0384:                    netAgent.endReadChain();
0385:                } catch (SqlException sqle) {
0386:                    rc = XAException.XAER_RMERR;
0387:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0388:                            .accumulateSQLException(sqle, exceptionsOnXA);
0389:                } finally {
0390:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0391:                }
0392:                if ((rc != XAResource.XA_OK) && (rc != XAResource.XA_RDONLY)) {
0393:                    throwXAException(rc, false);
0394:                }
0395:                if (conn_.agent_.loggingEnabled()) {
0396:                    conn_.agent_.logWriter_.traceExit(this , "prepare", rc);
0397:                }
0398:                return rc;
0399:            }
0400:
0401:            /**
0402:             * Obtain a list of prepared transaction branches from a resource manager. The transaction manager calls this method
0403:             * during recovery to obtain the list of transaction branches that are currently in prepared or heuristically
0404:             * completed states.
0405:             *
0406:             * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS must be used when no other flags are set in
0407:             *             flags.
0408:             *
0409:             * @return The resource manager returns zero or more XIDs for the transaction branches that are currently in a
0410:             *         prepared or heuristically completed state. If an error occurs during the operation, the resource manager
0411:             *         should raise the appropriate XAException.
0412:             *
0413:             * @throws XAException An error has occurred. Possible values are XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and
0414:             *                     XAER_PROTO.
0415:             */
0416:            public Xid[] recover(int flag) throws XAException {
0417:                int rc = XAResource.XA_OK;
0418:                NetAgent netAgent = conn_.netAgent_;
0419:
0420:                if (conn_.agent_.loggingEnabled()) {
0421:                    conn_.agent_.logWriter_.traceEntry(this , "recover", flag);
0422:                }
0423:                exceptionsOnXA = null;
0424:                if (conn_.isPhysicalConnClosed()) {
0425:                    connectionClosedFailure();
0426:                }
0427:
0428:                Xid[] xidList = null;
0429:                int numXid = 0;
0430:
0431:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0432:                callInfo.xaFlags_ = flag;
0433:                callInfo.xaResource_ = this ;
0434:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0435:                try {
0436:                    netAgent.beginWriteChainOutsideUOW();
0437:                    // sent the recover PROTOCOL
0438:                    netAgent.netConnectionRequest_.writeXaRecover(conn_, flag);
0439:                    netAgent.flowOutsideUOW();
0440:                    netAgent.netConnectionReply_.readXaRecover(conn_);
0441:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0442:                        callInfo.xaFunction_ = XAFUNC_RECOVER;
0443:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0444:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0445:                    }
0446:                    netAgent.endReadChain();
0447:                    if (conn_.indoubtTransactions_ != null) {
0448:                        numXid = conn_.indoubtTransactions_.size();
0449:                        xidList = new Xid[numXid];
0450:                        int i = 0;
0451:                        nextElement = 0;
0452:                        for (Enumeration e = conn_.indoubtTransactions_.keys(); e
0453:                                .hasMoreElements(); i++) {
0454:                            xidList[i] = (Xid) e.nextElement();
0455:                        }
0456:                    }
0457:                } catch (SqlException sqle) {
0458:                    rc = XAException.XAER_RMERR;
0459:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0460:                            .accumulateSQLException(sqle, exceptionsOnXA);
0461:                } finally {
0462:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0463:                }
0464:                if (rc != XAResource.XA_OK) {
0465:                    throwXAException(rc, false);
0466:                }
0467:
0468:                if (conn_.agent_.loggingEnabled()) {
0469:                    conn_.agent_.logWriter_.traceExit(this , "recover", xidList);
0470:                }
0471:                return xidList;
0472:            }
0473:
0474:            /**
0475:             * Inform the resource manager to roll back work done on behalf of a transaction branch
0476:             *
0477:             * @param xid A global transaction identifier
0478:             *
0479:             * @throws XAException An error has occurred
0480:             */
0481:            public void rollback(Xid xid) throws XAException {
0482:                NetAgent netAgent = conn_.netAgent_;
0483:                int rc = XAResource.XA_OK;
0484:                exceptionsOnXA = null;
0485:
0486:                if (conn_.agent_.loggingEnabled()) {
0487:                    conn_.agent_.logWriter_.traceEntry(this , "rollback", xid);
0488:                }
0489:                if (conn_.isPhysicalConnClosed()) {
0490:                    connectionClosedFailure();
0491:                }
0492:
0493:                // update the XACallInfo
0494:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0495:                callInfo.xid_ = xid;
0496:                callInfo.xaResource_ = this ;
0497:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0498:                try {
0499:                    netAgent.beginWriteChainOutsideUOW();
0500:                    netAgent.netConnectionRequest_.writeXaRollback(conn_, xid);
0501:                    netAgent.flowOutsideUOW();
0502:                    // read the reply to the rollback
0503:                    rc = netAgent.netConnectionReply_.readXaRollback(conn_);
0504:                    netAgent.endReadChain();
0505:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0506:                        callInfo.xaFunction_ = XAFUNC_END;
0507:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0508:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0509:                    }
0510:                } catch (SqlException sqle) {
0511:                    rc = XAException.XAER_RMERR;
0512:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0513:                            .accumulateSQLException(sqle, exceptionsOnXA);
0514:                } finally {
0515:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0516:                }
0517:                if (rc != XAResource.XA_OK) {
0518:                    throwXAException(rc, false);
0519:                }
0520:
0521:            }
0522:
0523:            /**
0524:             * <P>Set the current transaction timeout value for this <CODE>XAResource</CODE> instance. This value overwrites the
0525:             * default transaction timeout value in the resource manager. The newly assigned timeout value is effective for the
0526:             * life of this <CODE>XAResource</CODE> instance unless a new value is set.<P>
0527:             *
0528:             * @param seconds the transaction timeout value in seconds.
0529:             *
0530:             * @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL.
0531:             */
0532:            public boolean setTransactionTimeout(int seconds)
0533:                    throws XAException {
0534:                if (conn_.agent_.loggingEnabled()) {
0535:                    conn_.agent_.logWriter_.traceExit(this ,
0536:                            "setTransactionTimeout", false);
0537:                }
0538:                exceptionsOnXA = null;
0539:                return false; // we don't support transaction timeout in our layer.
0540:                /* int rc = xaSetTransTimeOut(seconds);
0541:                   if (rc != XAResource.XA_OK)
0542:                     throwXAException(rc); */
0543:            }
0544:
0545:            /**
0546:             * Start work on behalf of a transaction branch specified in xid
0547:             *
0548:             * @param xid   A global transaction identifier to be associated with the resource
0549:             * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME
0550:             *
0551:             * @throws XAException An error has occurred. Possible exceptions   * are XA_RB*, XAER_RMERR, XAER_RMFAIL,
0552:             *                     XAER_DUPID, XAER_OUTSIDE, XAER_NOTA, XAER_INVAL, or XAER_PROTO.
0553:             */
0554:            public synchronized void start(Xid xid, int flags)
0555:                    throws XAException {
0556:
0557:                NetAgent netAgent = conn_.netAgent_;
0558:                int rc = XAResource.XA_OK;
0559:                exceptionsOnXA = null;
0560:                if (conn_.agent_.loggingEnabled()) {
0561:                    conn_.agent_.logWriter_.traceEntry(this , "start", xid,
0562:                            flags);
0563:                }
0564:                if (conn_.isPhysicalConnClosed()) {
0565:                    connectionClosedFailure();
0566:                }
0567:
0568:                // DERBY-1025 - Flow an auto-commit if in auto-commit mode before 
0569:                // entering a global transaction
0570:                try {
0571:                    if (conn_.autoCommit_)
0572:                        conn_.flowAutoCommit();
0573:                } catch (SqlException sqle) {
0574:                    rc = XAException.XAER_RMERR;
0575:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0576:                            .accumulateSQLException(sqle, exceptionsOnXA);
0577:                }
0578:
0579:                // update the XACallInfo
0580:                NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0581:                callInfo.xaFlags_ = flags;
0582:                callInfo.xaInProgress_ = true;
0583:                callInfo.xid_ = xid;
0584:                callInfo.xaResource_ = this ;
0585:                callInfo.xaRetVal_ = XAResource.XA_OK; // initialize XARETVAL
0586:                try {
0587:                    netAgent.beginWriteChainOutsideUOW();
0588:                    netAgent.netConnectionRequest_
0589:                            .writeXaStartUnitOfWork(conn_);
0590:                    netAgent.flowOutsideUOW();
0591:                    netAgent.netConnectionReply_.readXaStartUnitOfWork(conn_);
0592:                    if (callInfo.xaRetVal_ != XAResource.XA_OK) { // xaRetVal has possible error, format it
0593:                        callInfo.xaFunction_ = XAFUNC_START;
0594:                        rc = xaRetValErrorAccumSQL(callInfo, rc);
0595:                        callInfo.xaRetVal_ = XAResource.XA_OK; // re-initialize XARETVAL
0596:                    }
0597:                    // Setting this is currently required to avoid client from sending
0598:                    // commit for autocommit.
0599:                    if (rc == XAResource.XA_OK) {
0600:                        conn_.setXAState(Connection.XA_T1_ASSOCIATED);
0601:                    }
0602:
0603:                } catch (SqlException sqle) {
0604:                    rc = XAException.XAER_RMERR;
0605:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0606:                            .accumulateSQLException(sqle, exceptionsOnXA);
0607:                } finally {
0608:                    conn_.pendingEndXACallinfoOffset_ = -1; // indicate no pending callinfo
0609:                }
0610:                if (rc != XAResource.XA_OK) {
0611:                    throwXAException(rc, false);
0612:                }
0613:            }
0614:
0615:            protected void throwXAException(int rc) throws XAException {
0616:                throwXAException(rc, rc != XAException.XAER_NOTA);
0617:            }
0618:
0619:            private String getXAExceptionText(int rc) {
0620:                String xaExceptionText;
0621:                switch (rc) {
0622:                case javax.transaction.xa.XAException.XA_RBROLLBACK:
0623:                    xaExceptionText = "XA_RBROLLBACK";
0624:                    break;
0625:                case javax.transaction.xa.XAException.XA_RBCOMMFAIL:
0626:                    xaExceptionText = "XA_RBCOMMFAIL";
0627:                    break;
0628:                case javax.transaction.xa.XAException.XA_RBDEADLOCK:
0629:                    xaExceptionText = "XA_RBDEADLOCK";
0630:                    break;
0631:                case javax.transaction.xa.XAException.XA_RBINTEGRITY:
0632:                    xaExceptionText = "XA_RBINTEGRITY";
0633:                    break;
0634:                case javax.transaction.xa.XAException.XA_RBOTHER:
0635:                    xaExceptionText = "XA_RBOTHER";
0636:                    break;
0637:                case javax.transaction.xa.XAException.XA_RBPROTO:
0638:                    xaExceptionText = "XA_RBPROTO";
0639:                    break;
0640:                case javax.transaction.xa.XAException.XA_RBTIMEOUT:
0641:                    xaExceptionText = "XA_RBTIMEOUT";
0642:                    break;
0643:                case javax.transaction.xa.XAException.XA_RBTRANSIENT:
0644:                    xaExceptionText = "XA_RBTRANSIENT";
0645:                    break;
0646:                case javax.transaction.xa.XAException.XA_NOMIGRATE:
0647:                    xaExceptionText = "XA_NOMIGRATE";
0648:                    break;
0649:                case javax.transaction.xa.XAException.XA_HEURHAZ:
0650:                    xaExceptionText = "XA_HEURHAZ";
0651:                    break;
0652:                case javax.transaction.xa.XAException.XA_HEURCOM:
0653:                    xaExceptionText = "XA_HEURCOM";
0654:                    break;
0655:                case javax.transaction.xa.XAException.XA_HEURRB:
0656:                    xaExceptionText = "XA_HEURRB";
0657:                    break;
0658:                case javax.transaction.xa.XAException.XA_HEURMIX:
0659:                    xaExceptionText = "XA_HEURMIX";
0660:                    break;
0661:                case javax.transaction.xa.XAException.XA_RETRY:
0662:                    xaExceptionText = "XA_RETRY";
0663:                    break;
0664:                case javax.transaction.xa.XAException.XA_RDONLY:
0665:                    xaExceptionText = "XA_RDONLY";
0666:                    break;
0667:                case javax.transaction.xa.XAException.XAER_ASYNC:
0668:                    xaExceptionText = "XAER_ASYNC";
0669:                    break;
0670:                case javax.transaction.xa.XAException.XAER_RMERR:
0671:                    xaExceptionText = "XAER_RMERR";
0672:                    break;
0673:                case javax.transaction.xa.XAException.XAER_NOTA:
0674:                    xaExceptionText = "XAER_NOTA";
0675:                    break;
0676:                case javax.transaction.xa.XAException.XAER_INVAL:
0677:                    xaExceptionText = "XAER_INVAL";
0678:                    break;
0679:                case javax.transaction.xa.XAException.XAER_PROTO:
0680:                    xaExceptionText = "XAER_PROTO";
0681:                    break;
0682:                case javax.transaction.xa.XAException.XAER_RMFAIL:
0683:                    xaExceptionText = "XAER_RMFAIL";
0684:                    break;
0685:                case javax.transaction.xa.XAException.XAER_DUPID:
0686:                    xaExceptionText = "XAER_DUPID";
0687:                    break;
0688:                case javax.transaction.xa.XAException.XAER_OUTSIDE:
0689:                    xaExceptionText = "XAER_OUTSIDE";
0690:                    break;
0691:                case XAResource.XA_OK:
0692:                    xaExceptionText = "XA_OK";
0693:                    break;
0694:                default:
0695:                    xaExceptionText = "Unknown Error";
0696:                    break;
0697:                }
0698:                return xaExceptionText;
0699:            }
0700:
0701:            protected void throwXAException(int rc, boolean resetFlag)
0702:                    throws XAException { // ~~~
0703:                String xaExceptionText;
0704:                if (resetFlag) {
0705:                    // reset the state of the failed connection
0706:                    NetXACallInfo callInfo = callInfoArray_[conn_.currXACallInfoOffset_];
0707:                    callInfo.xaInProgress_ = false;
0708:                    callInfo.xaWasSuspended = false;
0709:                }
0710:
0711:                xaExceptionText = getXAExceptionText(rc);
0712:                // save the SqlException chain to add it to the XAException
0713:                org.apache.derby.client.am.SqlException sqlExceptions = exceptionsOnXA;
0714:
0715:                while (exceptionsOnXA != null) { // one or more SqlExceptions received, format them
0716:                    xaExceptionText = xaExceptionText + " : "
0717:                            + exceptionsOnXA.getMessage();
0718:                    exceptionsOnXA = (org.apache.derby.client.am.SqlException) exceptionsOnXA
0719:                            .getNextException();
0720:                }
0721:                org.apache.derby.client.am.XaException xaException = new org.apache.derby.client.am.XaException(
0722:                        conn_.agent_.logWriter_, sqlExceptions, xaExceptionText);
0723:                xaException.errorCode = rc;
0724:                setXaStateForXAException(rc);
0725:                throw xaException;
0726:            }
0727:
0728:            /**
0729:             * Reset the transaction branch association state  to XA_T0_NOT_ASSOCIATED
0730:             * for XAER_RM* and XA_RB* Exceptions. All other exeptions leave the state 
0731:             * unchanged
0732:             * 
0733:             * @param rc  // return code from XAException
0734:             * @throws XAException
0735:             */
0736:            private void setXaStateForXAException(int rc) {
0737:                switch (rc) {
0738:                // Reset to T0, not  associated for XA_RB*, RM*
0739:                // XAER_RMFAIL and XAER_RMERR will be fatal to the connection
0740:                // but that is not dealt with here
0741:                case javax.transaction.xa.XAException.XAER_RMFAIL:
0742:                case javax.transaction.xa.XAException.XAER_RMERR:
0743:                case javax.transaction.xa.XAException.XA_RBROLLBACK:
0744:                case javax.transaction.xa.XAException.XA_RBCOMMFAIL:
0745:                case javax.transaction.xa.XAException.XA_RBDEADLOCK:
0746:                case javax.transaction.xa.XAException.XA_RBINTEGRITY:
0747:                case javax.transaction.xa.XAException.XA_RBOTHER:
0748:                case javax.transaction.xa.XAException.XA_RBPROTO:
0749:                case javax.transaction.xa.XAException.XA_RBTIMEOUT:
0750:                case javax.transaction.xa.XAException.XA_RBTRANSIENT:
0751:                    conn_.setXAState(Connection.XA_T0_NOT_ASSOCIATED);
0752:                    break;
0753:                // No change for other XAExceptions
0754:                // javax.transaction.xa.XAException.XA_NOMIGRATE
0755:                //javax.transaction.xa.XAException.XA_HEURHAZ
0756:                // javax.transaction.xa.XAException.XA_HEURCOM
0757:                // javax.transaction.xa.XAException.XA_HEURRB
0758:                // javax.transaction.xa.XAException.XA_HEURMIX
0759:                // javax.transaction.xa.XAException.XA_RETRY
0760:                // javax.transaction.xa.XAException.XA_RDONLY
0761:                // javax.transaction.xa.XAException.XAER_ASYNC
0762:                // javax.transaction.xa.XAException.XAER_NOTA
0763:                // javax.transaction.xa.XAException.XAER_INVAL                
0764:                // javax.transaction.xa.XAException.XAER_PROTO
0765:                // javax.transaction.xa.XAException.XAER_DUPID
0766:                // javax.transaction.xa.XAException.XAER_OUTSIDE            	
0767:                default:
0768:                    return;
0769:                }
0770:            }
0771:
0772:            public boolean isSameRM(XAResource xares) throws XAException {
0773:                boolean isSame = false; // preset that the RMs are NOT the same
0774:                exceptionsOnXA = null;
0775:
0776:                if (conn_.agent_.loggingEnabled()) {
0777:                    conn_.agent_.logWriter_.traceEntry(this , "isSameRM", xares);
0778:                }
0779:                if (conn_.isPhysicalConnClosed()) {
0780:                    connectionClosedFailure();
0781:                }
0782:
0783:                if (xares instanceof  org.apache.derby.client.net.NetXAResource) { // both are NetXAResource so check to see if this is the same RM
0784:                    // remember, isSame is initialized to false
0785:                    NetXAResource derbyxares = (NetXAResource) xares;
0786:                    while (true) {
0787:                        if (!conn_.databaseName_
0788:                                .equalsIgnoreCase(derbyxares.conn_.databaseName_)) {
0789:                            break; // database names are not equal, not same RM
0790:                        }
0791:                        if (!conn_.netAgent_.server_
0792:                                .equalsIgnoreCase(derbyxares.conn_.netAgent_.server_)) { // server name strings not equal, compare IP addresses
0793:                            try {
0794:                                // 1st convert "localhost" to actual server name
0795:                                String server1 = this 
0796:                                        .processLocalHost(conn_.netAgent_.server_);
0797:                                String server2 = this 
0798:                                        .processLocalHost(derbyxares.conn_.netAgent_.server_);
0799:                                // now convert the server name to ip address
0800:                                InetAddress serverIP1 = InetAddress
0801:                                        .getByName(server1);
0802:                                InetAddress serverIP2 = InetAddress
0803:                                        .getByName(server2);
0804:                                if (!serverIP1.equals(serverIP2)) {
0805:                                    break; // server IPs are not equal, not same RM
0806:                                }
0807:                            } catch (UnknownHostException ue) {
0808:                                break;
0809:                            }
0810:                        }
0811:                        if (conn_.netAgent_.port_ != derbyxares.conn_.netAgent_.port_) {
0812:                            break; // ports are not equal, not same RM
0813:                        }
0814:                        isSame = true; // everything the same, set RMs are the same
0815:                        break;
0816:                    }
0817:                }
0818:
0819:                if (conn_.agent_.loggingEnabled()) {
0820:                    conn_.agent_.logWriter_.traceExit(this , "isSameRM", isSame);
0821:                }
0822:                return isSame;
0823:            }
0824:
0825:            public static boolean xidsEqual(Xid xid1, Xid xid2) { // determine if the 2 xids contain the same values even if not same object
0826:                // comapre the format ids
0827:                if (xid1.getFormatId() != xid2.getFormatId()) {
0828:                    return false; // format ids are not the same
0829:                }
0830:
0831:                // compare the global transaction ids
0832:                int xid1Length = xid1.getGlobalTransactionId().length;
0833:                if (xid1Length != xid2.getGlobalTransactionId().length) {
0834:                    return false; // length of the global trans ids are not the same
0835:                }
0836:                byte[] xid1Bytes = xid1.getGlobalTransactionId();
0837:                byte[] xid2Bytes = xid2.getGlobalTransactionId();
0838:                int i;
0839:                for (i = 0; i < xid1Length; ++i) { // check all bytes are the same
0840:                    if (xid1Bytes[i] != xid2Bytes[i]) {
0841:                        return false; // bytes in the global trans ids are not the same
0842:                    }
0843:                }
0844:
0845:                // compare the branch qualifiers
0846:                xid1Length = xid1.getBranchQualifier().length;
0847:                if (xid1Length != xid2.getBranchQualifier().length) {
0848:                    return false; // length of the global trans ids are not the same
0849:                }
0850:                xid1Bytes = xid1.getBranchQualifier();
0851:                xid2Bytes = xid2.getBranchQualifier();
0852:                for (i = 0; i < xid1Length; ++i) { // check all bytes are the same
0853:                    if (xid1Bytes[i] != xid2Bytes[i]) {
0854:                        return false; // bytes in the global trans ids are not the same
0855:                    }
0856:                }
0857:
0858:                return true; // all of the fields are the same, xid1 == xid2
0859:            }
0860:
0861:            public List getSpecialRegisters() {
0862:                return specialRegisters_;
0863:            }
0864:
0865:            public void addSpecialRegisters(String s) {
0866:                if (s.substring(0, 1).equals("@")) {
0867:                    // SET statement is coming from Client
0868:                    if (specialRegisters_.remove(s.substring(1))) {
0869:                        specialRegisters_.remove(s);
0870:                        specialRegisters_.add(s.substring(1));
0871:                    } else {
0872:                        specialRegisters_.remove(s);
0873:                        specialRegisters_.add(s);
0874:                    }
0875:                } else { // SET statement is coming from Server
0876:                    specialRegisters_.remove(s);
0877:                    specialRegisters_.add(s);
0878:                }
0879:            }
0880:
0881:            private void connectionClosedFailure() throws XAException { // throw an XAException XAER_RMFAIL, with a chained SqlException - closed
0882:                exceptionsOnXA = org.apache.derby.client.am.Utils
0883:                        .accumulateSQLException(new SqlException(null,
0884:                                new ClientMessageId(
0885:                                        SQLState.NO_CURRENT_CONNECTION)),
0886:                                exceptionsOnXA);
0887:                throwXAException(javax.transaction.xa.XAException.XAER_RMFAIL);
0888:            }
0889:
0890:            private String getXAFuncStr(int xaFunc) {
0891:                switch (xaFunc) {
0892:                case XAFUNC_COMMIT:
0893:                    return XAFUNCSTR_COMMIT;
0894:                case XAFUNC_END:
0895:                    return XAFUNCSTR_END;
0896:                case XAFUNC_FORGET:
0897:                    return XAFUNCSTR_FORGET;
0898:                case XAFUNC_PREPARE:
0899:                    return XAFUNCSTR_PREPARE;
0900:                case XAFUNC_RECOVER:
0901:                    return XAFUNCSTR_RECOVER;
0902:                case XAFUNC_ROLLBACK:
0903:                    return XAFUNCSTR_ROLLBACK;
0904:                case XAFUNC_START:
0905:                    return XAFUNCSTR_START;
0906:                }
0907:                return XAFUNCSTR_NONE;
0908:            }
0909:
0910:            protected int xaRetValErrorAccumSQL(NetXACallInfo callInfo,
0911:                    int currentRC) {
0912:
0913:                // xaRetVal_ is set by the server to be one of the
0914:                // standard constants from XAException.
0915:                int rc = callInfo.xaRetVal_;
0916:
0917:                if (rc != XAResource.XA_OK) { // error was detected
0918:                    // create an SqlException to report this error within
0919:                    SqlException accumSql = new SqlException(
0920:                            conn_.netAgent_.logWriter_, new ClientMessageId(
0921:                                    SQLState.NET_XARETVAL_ERROR),
0922:                            getXAFuncStr(callInfo.xaFunction_),
0923:                            getXAExceptionText(rc),
0924:                            org.apache.derby.client.am.SqlCode.queuedXAError);
0925:                    exceptionsOnXA = org.apache.derby.client.am.Utils
0926:                            .accumulateSQLException(accumSql, exceptionsOnXA);
0927:
0928:                    if (currentRC != XAResource.XA_OK) { // the rc passed into this function had an error also, prioritize error
0929:                        if (currentRC < 0) { // rc passed in was a major error use it instead of current error
0930:                            return currentRC;
0931:                        }
0932:                    }
0933:                }
0934:                return rc;
0935:            }
0936:
0937:            private String processLocalHost(String serverName) {
0938:                if (serverName.equalsIgnoreCase("localhost")) { // this is a localhost, find hostname
0939:                    try {
0940:                        InetAddress localhostNameIA = InetAddress
0941:                                .getLocalHost();
0942:                        String localhostName = localhostNameIA.getHostName();
0943:                        return localhostName;
0944:                    } catch (SecurityException se) {
0945:                        return serverName;
0946:                    } catch (UnknownHostException ue) {
0947:                        return serverName;
0948:                    }
0949:                }
0950:                // not "localhost", return original server name
0951:                return serverName;
0952:            }
0953:
0954:            protected void removeXaresFromSameRMchain() {
0955:                // check all NetXAResources on the same RM for the NetXAResource to remove
0956:                try {
0957:                    this .ignoreMe_ = true; // use the ignoreMe_ flag to indicate the
0958:                    // XAResource to remove
0959:                    NetXAResource prevXAResource = null;
0960:                    NetXAResource currXAResource;
0961:                    synchronized (xaResourceSameRMGroup_) { // make sure no one changes this vector list
0962:                        currXAResource = (NetXAResource) xaResourceSameRMGroup_
0963:                                .elementAt(sameRMGroupIndex_);
0964:                        while (currXAResource != null) { // is this the XAResource to remove?
0965:                            if (currXAResource.ignoreMe_) { // this NetXAResource is the one to remove
0966:                                if (prevXAResource != null) { // this XAResource is not first in chain, just move next to prev
0967:                                    prevXAResource.nextSameRM_ = currXAResource.nextSameRM_;
0968:                                } else { // this XAResource is  first in chain, just move next to root
0969:                                    xaResourceSameRMGroup_.set(
0970:                                            sameRMGroupIndex_,
0971:                                            currXAResource.nextSameRM_);
0972:                                }
0973:                                return;
0974:                            }
0975:                            // this is not the NetXAResource to remove, try the next one
0976:                            prevXAResource = currXAResource;
0977:                            currXAResource = currXAResource.nextSameRM_;
0978:                        }
0979:                    }
0980:                } finally {
0981:                    this .ignoreMe_ = false;
0982:                }
0983:            }
0984:
0985:            public void initForReuse() {
0986:                // add this new XAResource to the list of other XAResources for the Same RM
0987:                // first find out if there are any other XAResources for the same RM
0988:                // then check to make sure it is not already in the chain
0989:                synchronized (xaResourceSameRMGroup_) { // make sure no one changes this vector list
0990:                    int groupCount = xaResourceSameRMGroup_.size();
0991:                    int index = 0;
0992:                    int firstFreeElement = -1;
0993:                    NetXAResource xaResourceGroup = null;
0994:
0995:                    for (; index < groupCount; ++index) { // check if this group is the same RM
0996:                        xaResourceGroup = (NetXAResource) xaResourceSameRMGroup_
0997:                                .elementAt(index);
0998:                        if (xaResourceGroup == null) { // this is a free element, save its index if first found
0999:                            if (firstFreeElement == -1) { // first free element, save index
1000:                                firstFreeElement = index;
1001:                            }
1002:                            continue; // go to next element
1003:                        }
1004:                        try {
1005:                            if (xaResourceGroup.isSameRM(this )) { // it is the same RM add this XAResource to the chain if not there
1006:                                NetXAResource nextXares = (NetXAResource) xaResourceSameRMGroup_
1007:                                        .elementAt(sameRMGroupIndex_);
1008:                                while (nextXares != null) { // is this NetXAResource the one we are trying to add?
1009:                                    if (nextXares.equals(this )) { // the XAResource to be added already is in chain, don't add
1010:                                        break;
1011:                                    }
1012:                                    // Xid was not on that NetXAResource, try the next one
1013:                                    nextXares = nextXares.nextSameRM_;
1014:                                }
1015:
1016:                                if (nextXares == null) { // XAResource to be added is not in the chain already, add it
1017:                                    // add it at the head of the chain
1018:                                    sameRMGroupIndex_ = index;
1019:                                    this .nextSameRM_ = xaResourceGroup.nextSameRM_;
1020:                                    xaResourceGroup.nextSameRM_ = this ;
1021:                                }
1022:                                return; // done
1023:                            }
1024:                        } catch (XAException xae) {
1025:                        }
1026:                    }
1027:
1028:                    // no other same RM was found, add this as first of new group
1029:                    if (firstFreeElement == -1) { // no free element found, add new element to end
1030:                        xaResourceSameRMGroup_.add(this );
1031:                        sameRMGroupIndex_ = groupCount;
1032:                    } else { // use first free element found
1033:                        xaResourceSameRMGroup_.setElementAt(this,
1034:                                firstFreeElement);
1035:                        sameRMGroupIndex_ = firstFreeElement;
1036:                    }
1037:                }
1038:            }
1039:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.