Source Code Cross Referenced for ConnectionManagerImpl.java in  » J2EE » JOnAS-4.8.6 » org » objectweb » jonas » resource » 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 » J2EE » JOnAS 4.8.6 » org.objectweb.jonas.resource 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * JOnAS: Java(TM) Open Application Server
0003:         * Copyright (C) 1999 Bull S.A.
0004:         * Contact: jonas-team@objectweb.org
0005:         *
0006:         * This library is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU Lesser General Public
0008:         * License as published by the Free Software Foundation; either
0009:         * version 2.1 of the License, or any later version.
0010:         *
0011:         * This library is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         * Lesser General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU Lesser General Public
0017:         * License along with this library; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
0019:         * USA
0020:         *
0021:         * --------------------------------------------------------------------------
0022:         * $Id: ConnectionManagerImpl.java 9932 2007-01-18 00:03:16Z ehardesty $
0023:         * --------------------------------------------------------------------------
0024:         */package org.objectweb.jonas.resource;
0025:
0026:        import java.io.PrintWriter;
0027:        import java.sql.Connection;
0028:        import java.sql.PreparedStatement;
0029:        import java.sql.ResultSet;
0030:        import java.sql.SQLException;
0031:        import java.util.Enumeration;
0032:        import java.util.HashSet;
0033:        import java.util.Hashtable;
0034:        import java.util.Iterator;
0035:        import java.util.Properties;
0036:        import java.util.Set;
0037:        import java.util.Vector;
0038:
0039:        import javax.naming.Context;
0040:        import javax.naming.NamingException;
0041:        import javax.resource.NotSupportedException;
0042:        import javax.resource.ResourceException;
0043:        import javax.resource.spi.ConnectionEvent;
0044:        import javax.resource.spi.ConnectionEventListener;
0045:        import javax.resource.spi.ConnectionManager;
0046:        import javax.resource.spi.ConnectionRequestInfo;
0047:        import javax.resource.spi.ManagedConnection;
0048:        import javax.resource.spi.ManagedConnectionFactory;
0049:        import javax.resource.spi.ResourceAllocationException;
0050:        import javax.resource.spi.ValidatingManagedConnectionFactory;
0051:        import javax.security.auth.Subject;
0052:        import javax.transaction.RollbackException;
0053:        import javax.transaction.Transaction;
0054:        import javax.transaction.xa.XAResource;
0055:
0056:        import org.objectweb.jonas.common.Log;
0057:        import org.objectweb.jonas.resource.pool.api.Pool;
0058:        import org.objectweb.jonas.resource.pool.api.PoolMatchFactory;
0059:        import org.objectweb.jonas.resource.pool.lib.HArrayPool;
0060:        import org.objectweb.jotm.Current;
0061:        import org.objectweb.jotm.TransactionResourceManager;
0062:        import org.objectweb.transaction.jta.ResourceManagerEventListener;
0063:        import org.objectweb.transaction.jta.TransactionManager;
0064:        import org.objectweb.util.monolog.api.BasicLevel;
0065:        import org.objectweb.util.monolog.api.Logger;
0066:        import org.objectweb.util.monolog.api.LoggerFactory;
0067:        import org.objectweb.util.monolog.wrapper.printwriter.LoggerImpl;
0068:
0069:        /**
0070:         *  Description of the ConnectionManagerImpl
0071:         *
0072:         *@author     chassand
0073:         *created    15 novembre 2001
0074:         */
0075:        public class ConnectionManagerImpl implements  ConnectionEventListener,
0076:                ConnectionManager, PoolMatchFactory, SQLManager,
0077:                TransactionResourceManager {
0078:
0079:            /**
0080:             * Main logger
0081:             */
0082:            protected static Logger trace = null;
0083:            /**
0084:             * Connection Management logger
0085:             */
0086:            protected static Logger conTrace = null;
0087:            /**
0088:             * Pool infomation logger
0089:             */
0090:            protected static Logger poolTrace = null;
0091:
0092:            /**
0093:             *  Used by the server to register connections when no
0094:             *  transactionnal context exists
0095:             */
0096:            protected ResourceManagerEventListener rmel = null;
0097:
0098:            /**
0099:             *  Holds the resource bundle name
0100:             */
0101:            private String resourceBundleName = null;
0102:
0103:            /**
0104:             *  The transaction manager in server
0105:             */
0106:            protected TransactionManager tm;
0107:
0108:            /**
0109:             *  This hashtable allows to find the list of connection handle associated to a
0110:             *  ManagedConnection
0111:             */
0112:            protected Hashtable mc2mci = null;
0113:
0114:            /**
0115:             *  The jndiname of the associated factory
0116:             */
0117:            protected String jndiname = null;
0118:
0119:            /**
0120:             *  The max pool size of ManagedConnection. The default value is -1.
0121:             */
0122:            private int mcMaxPoolSize = -1;
0123:
0124:            /**
0125:             *  The min pool size of ManagedConnection. The default value is 0
0126:             */
0127:            private int mcMinPoolSize = 0;
0128:
0129:            /**
0130:             *  The ManagedConnectionFactory instance which represents the resource
0131:             *  adapter.
0132:             */
0133:            private ManagedConnectionFactory mcf;
0134:            /**
0135:             *  The ValidatingManagedConnectionFactory instance which represents the resource
0136:             *  adapter.
0137:             */
0138:            private ValidatingManagedConnectionFactory vmcf = null;
0139:
0140:            /**
0141:             *  The pool of ManagedConnections associated to a ManagedConnectionFactory
0142:             *  There's one instance of pool by instance for one instance of this class (ConnectionManagerImpl).
0143:             *  The synchronization of the methods of this are ensured through synchronized
0144:             *  blocks on the poolMCs instance. Thus, the lock are shared between the two objects and that
0145:             *  avoids deadlock issues when the poolMCs.getRessource() is waiting for a connection releasing
0146:             *  (max nb of instances is reached in the pool).
0147:             */
0148:            protected Pool poolMCs = null;
0149:
0150:            /**
0151:             *  The list of used ManagedConnections key = transaction reference value =
0152:             *  MCInfo
0153:             */
0154:            protected Hashtable usedMCs = null;
0155:
0156:            /**
0157:             *  The default max pool size of pstmts per ManagedConnection.
0158:             */
0159:            static final int MAX_PSTMT_SIZE = 20;
0160:
0161:            /**
0162:             * PrepareStatement cache max pool size
0163:             */
0164:            private int maxPstmtPoolSize = MAX_PSTMT_SIZE;
0165:
0166:            /**
0167:             *  JDBC connection level value
0168:             */
0169:            private int jdbcConnLevel = 0;
0170:            /**
0171:             *  JDBC connection level value
0172:             */
0173:            private String jdbcConnTestStmt = "";
0174:
0175:            /**
0176:             *  The list of managedConnection used without transaction
0177:             */
0178:            protected Vector mcs = new Vector();
0179:
0180:            /**
0181:             *  The list of Synchronisation instance managed in this ConnectionManager
0182:             */
0183:            protected Vector synchros = new Vector();
0184:
0185:            /**
0186:             *  This is a cache to the last instance of ResourceSpec used by the
0187:             *  ConnectionManager. Indeed this instance is always the same.
0188:             */
0189:            private ResourceSpec rs = null;
0190:
0191:            /**
0192:             *  The holds the transaction support level for the associated RAR file
0193:             */
0194:            private String transSupport = null;
0195:
0196:            /**
0197:             * This constant is used in the by the init method
0198:             */
0199:            public final static String RESOURCE_BUNDLE_NAME = "resourceBundleName";
0200:            /**
0201:             * This constant is used in the by the init method
0202:             */
0203:            public final static String LOGGER = "org.objectweb.util.monolog.logger";
0204:            /**
0205:             * This constant is used in the by the init method
0206:             */
0207:            public final static String POOL_LOGGER = "org.objectweb.util.monolog.logger_pool";
0208:            /**
0209:             * This constant is used in the by the init method
0210:             */
0211:            public final static String JNDINAME = "jndiname";
0212:            /**
0213:             * This constant is used in the by the init method
0214:             */
0215:            public final static String LOGGER_FACTORY = "org.objectweb.util.monolog.loggerFactory";
0216:            /**
0217:             * This constant is used in the by the init method
0218:             */
0219:            public final static String TRANSACTION_MANAGER = "transactionManager";
0220:            /**
0221:             * This constant is used in the by the init method
0222:             */
0223:            public final static String RESOURCE_MANAGER_EVENT_LISTENER = "resourceManagerEventListener";
0224:            /**
0225:             * This constant is used in the by the init method
0226:             */
0227:            public final static String RESOURCE_ADAPTER = "resourceAdapter";
0228:            /**
0229:             * This constant is used in the by the init method
0230:             */
0231:            public final static String PRINT_WRITER = "printWriter";
0232:
0233:            /*
0234:             * These constants define the different transaction support values
0235:             */
0236:            /**
0237:             * Rar doesn't support transactions
0238:             */
0239:            public final static String NO_TRANS_SUPPORT = "NoTransaction";
0240:            /**
0241:             * Rar supports local transactions
0242:             */
0243:            public final static String LOCAL_TRANS_SUPPORT = "LocalTransaction";
0244:            /**
0245:             * Rar supports XA transactions
0246:             */
0247:            public final static String XA_TRANS_SUPPORT = "XATransaction";
0248:
0249:            /**
0250:             * Constants to determine which PreparedStatement types to call
0251:             *
0252:             */
0253:            public final static int PSWRAP_1 = 1;
0254:            public final static int PSWRAP_2 = 2;
0255:            public final static int PSWRAP_3 = 3;
0256:            public final static int PSWRAP_4 = 4;
0257:            public final static int PSWRAP_5 = 5;
0258:
0259:            /**
0260:             * Constants for use with JDBC connection level
0261:             */
0262:            public final static int JDBC_NO_TEST = 0;
0263:            public final static int JDBC_CHECK_CONNECTION = 1;
0264:            public final static int JDBC_SEND_STATEMENT = 2;
0265:            public final static int JDBC_KEEP_ALIVE = 3;
0266:
0267:            // JOTM variables
0268:            /**
0269:             * ManagedConnection used with JOTM recovery
0270:             */
0271:            private ManagedConnection jotmMc = null;
0272:            /**
0273:             * XAResource used with JOTM recovery
0274:             */
0275:            private XAResource jotmXar = null;
0276:            /**
0277:             * XA Name used with JOTM recovery
0278:             */
0279:            private String xaName = null;
0280:
0281:            /**
0282:             * Debug is enabled ?
0283:             */
0284:            private boolean isEnabledDebug = false;
0285:
0286:            /**
0287:             * ConnectionManagerImpl constructor
0288:             * @param transSupport String defining level of support needed
0289:             */
0290:            public ConnectionManagerImpl(String transSupport) {
0291:                if (transSupport.length() == 0) {
0292:                    transSupport = NO_TRANS_SUPPORT;
0293:                } else {
0294:                    this .transSupport = transSupport;
0295:                }
0296:            }
0297:
0298:            /**
0299:             *  Setters method to initialize the ConnectionManager The logger instance
0300:             *  where events are logged
0301:             *
0302:             *@param  l  The new Logger value
0303:             */
0304:            public void setLogger(Logger l) {
0305:                trace = l;
0306:                isEnabledDebug = trace.isLoggable(BasicLevel.DEBUG);
0307:            }
0308:
0309:            /**
0310:             *  Setters method to initialize the ConnectionManager A logger factory to
0311:             *  obtain a logger
0312:             *
0313:             *@param  lf  The new LoggerFactory value
0314:             */
0315:            public void setLoggerFactory(LoggerFactory lf) {
0316:                trace = lf.getLogger("org.objectweb.resource.server");
0317:                isEnabledDebug = trace.isLoggable(BasicLevel.DEBUG);
0318:            }
0319:
0320:            /**
0321:             *  Setters method to initialize the ConnectionManager The printwriter where
0322:             *  event are logged
0323:             *
0324:             *@param  pw  The new PrintWriter value
0325:             */
0326:            public void setPrintWriter(PrintWriter pw) {
0327:                trace = new LoggerImpl(pw);
0328:            }
0329:
0330:            /**
0331:             *  Setters method to initialize the ConnectionManager The logger instance
0332:             *  where events are logged
0333:             *
0334:             *@param  rmel  The new ResourceManagerEventListener value
0335:             */
0336:            public void setResourceManagerEventListener(
0337:                    ResourceManagerEventListener rmel) {
0338:                this .rmel = rmel;
0339:            }
0340:
0341:            /**
0342:             *  Setters method to initialize the ConnectionManager The Transaction manager
0343:             *  linked to this resource managed
0344:             *
0345:             *@param  tm  TransactionManager value
0346:             */
0347:            public void setTransactionManager(TransactionManager tm) {
0348:                this .tm = tm;
0349:            }
0350:
0351:            /**
0352:             *  Setters method to initialize the ConnectionManager The
0353:             *  managedConnectionFactory instance of the resource which must be managed by
0354:             *  this connectionManager
0355:             *
0356:             *@param  tmcf           The new ResourceAdapter value
0357:             *@exception  Exception  Description of Exception
0358:             */
0359:            public void setResourceAdapter(ManagedConnectionFactory tmcf)
0360:                    throws Exception {
0361:                setResourceAdapter(tmcf, new ConnectionManagerPoolParams());
0362:            }
0363:
0364:            /**
0365:             *  Setters method to initialize the ConnectionManager The
0366:             *  managedConnectionFactory instance of the resource which must be maneged by
0367:             *  this connectionManager
0368:             *
0369:             *@param  tmcf  The ManagedConnectionFactory object
0370:             *@param  cmpp  The pool parameters
0371:             *@exception  Exception  Description of Exception
0372:             */
0373:            public void setResourceAdapter(ManagedConnectionFactory tmcf,
0374:                    ConnectionManagerPoolParams cmpp) throws Exception {
0375:
0376:                // set the max/min pool values
0377:                if (cmpp.getPoolMax() != 0) {
0378:                    mcMaxPoolSize = cmpp.getPoolMax();
0379:                }
0380:                if (cmpp.getPoolMin() > 0) {
0381:                    mcMinPoolSize = cmpp.getPoolMin();
0382:                }
0383:
0384:                // set the jdbc connection info
0385:                jdbcConnLevel = cmpp.getJdbcConnLevel();
0386:                jdbcConnTestStmt = cmpp.getJdbcConnTestStmt();
0387:
0388:                mcf = tmcf;
0389:                if (mcf instanceof  ValidatingManagedConnectionFactory) {
0390:                    vmcf = (ValidatingManagedConnectionFactory) mcf;
0391:                }
0392:
0393:                poolMCs = new HArrayPool(poolTrace, jndiname);
0394:                poolMCs.setMatchFactory(this );
0395:
0396:                if (cmpp.getPoolMaxAge() > 0) {
0397:                    int min = (int) (cmpp.getPoolMaxAge() / 60);
0398:                    poolMCs.setMaxAge(min);
0399:                } else {
0400:                    poolMCs.setMaxAge(cmpp.getPoolMaxAgeMinutes());
0401:                }
0402:
0403:                if (cmpp.getPoolMaxOpentime() > 0) {
0404:                    poolMCs.setMaxOpentime(cmpp.getPoolMaxOpentime());
0405:                }
0406:                poolMCs.setMaxWaiters(cmpp.getPoolMaxWaiters());
0407:                if (cmpp.getPoolMaxWaittime() > 0) {
0408:                    poolMCs.setMaxWaitTime(cmpp.getPoolMaxWaittime());
0409:                }
0410:
0411:                poolMCs.setMaxSize(mcMaxPoolSize);
0412:                poolMCs.setInitSize(cmpp.getPoolInit());
0413:                poolMCs.setMinSize(mcMinPoolSize);
0414:                poolMCs.setJdbcConnLevel(jdbcConnLevel);
0415:                poolMCs.setJdbcTestStatement(jdbcConnTestStmt);
0416:
0417:                poolMCs.startMonitor();
0418:                poolMCs.setSamplingPeriod(cmpp.getPoolSamplingPeriod());
0419:                maxPstmtPoolSize = cmpp.getPstmtMax();
0420:
0421:                usedMCs = new Hashtable();
0422:                rs = new ResourceSpec(null, null);
0423:
0424:                if (isEnabledDebug) {
0425:                    trace.log(BasicLevel.DEBUG, "");
0426:                }
0427:            }
0428:
0429:            /**
0430:             *  This method permits to initialize the ConnectionManager with the following
0431:             *  parameter: RESOURCE_BUNDLE_NAME: The name of the resource bundle in order
0432:             *  to internationalize the logging LOGGER: The logger instance where events
0433:             *  are logged LOGGER_FACTORY: A logger factory to obtain a logger
0434:             *  PRINT_WRITER: The printwriter where event are logged TRANSACTION_MANAGER:
0435:             *  The Transaction manager linked to this resource manager
0436:             *  RESOURCE_MANAGER_EVENT_LISTENER: The resource manage event listener which
0437:             *  subscribed to later connection enlistement. RESOURCE_ADAPTER: The
0438:             *  managedConnectionFactory instance of the resource which must be maneged by
0439:             *  this connectionManager
0440:             *  JNDINAME: JndiName from the factory associated with this ConnectionManager
0441:             *
0442:             *@param  ctx            Description of Parameter
0443:             *@exception  Exception  Description of Exception
0444:             */
0445:            public void init(Context ctx) throws Exception {
0446:                mc2mci = new Hashtable();
0447:
0448:                // Get the resource bundle name to internationalise the log
0449:                // Optional
0450:                String resourceBundleName = null;
0451:                try {
0452:                    resourceBundleName = (String) ctx
0453:                            .lookup(RESOURCE_BUNDLE_NAME);
0454:                } catch (NamingException e) {
0455:                }
0456:
0457:                // Get the logger or the logger factory or the printwriter
0458:                try {
0459:                    trace = (Logger) ctx.lookup(LOGGER);
0460:                    poolTrace = (Logger) ctx.lookup(POOL_LOGGER);
0461:                } catch (NamingException e) {
0462:                }
0463:
0464:                conTrace = Log.getLogger(Log.JONAS_JCA_PREFIX + ".connection");
0465:                if (trace == null) {
0466:                    try {
0467:                        setLoggerFactory((LoggerFactory) ctx
0468:                                .lookup(LOGGER_FACTORY));
0469:                    } catch (NamingException e2) {
0470:                    }
0471:                }
0472:                if (trace == null) {
0473:                    PrintWriter pw = null;
0474:                    try {
0475:                        pw = (PrintWriter) ctx.lookup(PRINT_WRITER);
0476:                    } catch (NamingException e3) {
0477:                    }
0478:                    setPrintWriter(pw);
0479:                }
0480:                if (trace != null) {
0481:                    isEnabledDebug = trace.isLoggable(BasicLevel.DEBUG);
0482:                }
0483:
0484:                if (!transSupport.equalsIgnoreCase(NO_TRANS_SUPPORT)) {
0485:                    // Get the transaction manager
0486:                    tm = (TransactionManager) ctx.lookup(TRANSACTION_MANAGER);
0487:                }
0488:
0489:                // Get the set of connection
0490:                try {
0491:                    rmel = (ResourceManagerEventListener) ctx
0492:                            .lookup(RESOURCE_MANAGER_EVENT_LISTENER);
0493:                } catch (NamingException ne) {
0494:                }
0495:
0496:                // Get the managedConnectionFactory instance which represents the resource
0497:                // adapter
0498:                try {
0499:                    setResourceAdapter((ManagedConnectionFactory) ctx
0500:                            .lookup(RESOURCE_ADAPTER));
0501:                } catch (NamingException ne) {
0502:                }
0503:
0504:                // Get the jndiname
0505:                try {
0506:                    jndiname = (String) ctx.lookup(JNDINAME);
0507:                } catch (NamingException ne) {
0508:                }
0509:
0510:            }
0511:
0512:            /**
0513:             *  Description of the Method
0514:             *
0515:             *@exception  ResourceException  Description of Exception
0516:             */
0517:            public void cleanResourceAdapter() throws ResourceException {
0518:
0519:                synchronized (poolMCs) {
0520:
0521:                    // Delete the PreparedStatements
0522:                    PreparedStatementWrapper pw = null;
0523:                    while (mcs != null && mcs.size() > 0) {
0524:                        MCInfo mci = (MCInfo) mcs.remove(0);
0525:                        mci.usedCs.clear();
0526:                        synchronized (mci.pStmts) {
0527:                            // Remove the PreparedStatements on the MC
0528:                            while (mci.pStmts != null && mci.pStmts.size() > 0) {
0529:                                pw = (PreparedStatementWrapper) mci.pStmts
0530:                                        .remove(0);
0531:                                try {
0532:                                    pw.destroy();
0533:                                } catch (Exception ex) {
0534:                                }
0535:                            }
0536:                        }
0537:                        try {
0538:                            mc2mci.remove(mci.mc);
0539:                            //                    mci.mc.destroy();
0540:                        } catch (Exception ex) {
0541:                        }
0542:                    }
0543:                    if (usedMCs != null) {
0544:                        for (Enumeration en = usedMCs.keys(); en
0545:                                .hasMoreElements();) {
0546:                            Transaction tx = (Transaction) en.nextElement();
0547:                            MCInfo mci = (MCInfo) usedMCs.get(tx);
0548:                            if (mci == null) {
0549:                                continue;
0550:                            }
0551:                            if (mci.rmeCalled) {
0552:                                mci.rme.isValid = false;
0553:                                rmel.connectionClosed(mci.rme);
0554:                                mci.rmeCalled = false;
0555:                            }
0556:                            mci.usedCs.clear();
0557:                            // Remove the PreparedStatements on the MC
0558:                            synchronized (mci.pStmts) {
0559:                                while (mci.pStmts != null
0560:                                        && mci.pStmts.size() > 0) {
0561:                                    pw = (PreparedStatementWrapper) mci.pStmts
0562:                                            .remove(0);
0563:                                    try {
0564:                                        pw.destroy();
0565:                                    } catch (Exception ex) {
0566:                                    }
0567:                                }
0568:                            }
0569:                            try {
0570:                                mc2mci.remove(mci.mc);
0571:                                //                        mci.mc.destroy();
0572:                            } catch (Exception ex) {
0573:                            }
0574:                        }
0575:                    }
0576:                    while (synchros != null && synchros.size() > 0) {
0577:                        MCInfo mci = (MCInfo) synchros.remove(0);
0578:                        mci.usedCs.clear();
0579:                        // Remove the PreparedStatements on the MC
0580:                        synchronized (mci.pStmts) {
0581:                            while (mci.pStmts != null && mci.pStmts.size() > 0) {
0582:                                pw = (PreparedStatementWrapper) mci.pStmts
0583:                                        .remove(0);
0584:                                try {
0585:                                    pw.destroy();
0586:                                } catch (Exception ex) {
0587:                                }
0588:                            }
0589:                        }
0590:                        try {
0591:                            mc2mci.remove(mci.mc);
0592:                            //                    mci.mc.destroy();
0593:                        } catch (Exception ex) {
0594:                        }
0595:                    }
0596:                }
0597:                poolMCs.closeAllConnections();
0598:            }
0599:
0600:            /**
0601:             *
0602:             *  The method allocateConnection gets called by the resource adapter's
0603:             *  connection factory instance.
0604:             *
0605:             * @see javax.resource.cci.ConnectionManager
0606:             */
0607:            public Object allocateConnection(ManagedConnectionFactory pMcf,
0608:                    ConnectionRequestInfo cxRequestInfo)
0609:                    throws ResourceException {
0610:
0611:                MCInfo mci = null;
0612:                Transaction currentTx = null;
0613:                Object connection = null;
0614:                int retries = 0;
0615:                Subject subject = null;
0616:
0617:                trace.log(BasicLevel.DEBUG, "");
0618:                while (connection == null && retries < 20) {
0619:                    synchronized (poolMCs) {
0620:                        if (mcf != pMcf && !pMcf.equals(mcf)) {
0621:                            throw new ResourceException(
0622:                                    "This ConnectionManager doesn't manage this RA:"
0623:                                            + mcf);
0624:                        }
0625:
0626:                        currentTx = null;
0627:                        try {
0628:                            if (tm != null) {
0629:                                currentTx = tm.getTransaction();
0630:                            }
0631:                        } catch (Exception e) {
0632:                            trace
0633:                                    .log(
0634:                                            BasicLevel.ERROR,
0635:                                            "Impossible to get the current transaction",
0636:                                            e, "ConnectionManagerImpl",
0637:                                            "allocateConnection");
0638:                        }
0639:
0640:                        //if there is a transaction check if a MC is already associated
0641:                        mci = (currentTx == null ? null : (MCInfo) usedMCs
0642:                                .get(currentTx));
0643:                        if (mci != null) {
0644:                            if (mci.mc != null) {
0645:                                // There are connections, try to match with the
0646:                                // ManagedConnectionFactory
0647:                                if (isEnabledDebug) {
0648:                                    trace
0649:                                            .log(
0650:                                                    BasicLevel.DEBUG,
0651:                                                    "MC ("
0652:                                                            + mci.mc
0653:                                                            + ") associated to the current Tx ("
0654:                                                            + currentTx
0655:                                                            + ") found");
0656:                                }
0657:                                Set s = new HashSet();
0658:                                s.add(mci.mc);
0659:                                if (mci.mc != mcf.matchManagedConnections(s,
0660:                                        null, cxRequestInfo)) {
0661:                                    throw new ResourceException(
0662:                                            "ConnectionManagerImpl.allocateConnection: illegal state : no mc is matched by mcf");
0663:                                }
0664:                                if (isEnabledDebug) {
0665:                                    trace.log(BasicLevel.DEBUG, "XA Resource "
0666:                                            + mci.getXAResource()
0667:                                            + " is already enlisted in Tx:"
0668:                                            + mci.ctx);
0669:                                }
0670:                            } else {
0671:                                // This connection occurred an error before
0672:                                trace.log(BasicLevel.INFO,
0673:                                        "remnant of an old failed connection");
0674:                                mci.ctx = null;
0675:                                mci = null;
0676:                                usedMCs.remove(currentTx);
0677:                            }
0678:                        }
0679:
0680:                        if (mci == null) {
0681:                            // No managed connection found => get a free ManagedConnection
0682:                            // from the right pool
0683:
0684:                            //ri.rs.subject = null; // Never set => already at null
0685:                            rs.cxRequestInfo = cxRequestInfo;
0686:                            if (subject == null && cxRequestInfo != null) {
0687:                                // Create a subject to pass on
0688:                            }
0689:                            try {
0690:                                ManagedConnection mc = (ManagedConnection) poolMCs
0691:                                        .getResource(rs);
0692:                                if (mc == null) {
0693:                                    throw new ResourceException(
0694:                                            "ConnectionManagerImpl.allocateConnection: cannot allocate a ManagedConnection");
0695:                                }
0696:                                mci = (MCInfo) mc2mci.get(mc);
0697:                                if (mci == null) {
0698:                                    mci = new MCInfo(mc);
0699:                                    mc2mci.put(mc, mci);
0700:                                }
0701:                                if (isEnabledDebug) {
0702:                                    trace.log(BasicLevel.DEBUG,
0703:                                            "get a MC from the ra pool, mc="
0704:                                                    + mci.mc);
0705:                                }
0706:                                conTrace.log(BasicLevel.DEBUG,
0707:                                        " returning mc = " + mc);
0708:
0709:                                if (transSupport
0710:                                        .equalsIgnoreCase(LOCAL_TRANS_SUPPORT)) {
0711:                                    if (mci.lw == null) {
0712:                                        mci.lw = new LocalXAWrapper(mci.mc
0713:                                                .getLocalTransaction(), trace);
0714:                                    }
0715:                                } else if (mci.lw != null) {
0716:                                    mci.lw = null;
0717:                                }
0718:                                if (!mci.connectionEventListener) {
0719:                                    mci.mc.addConnectionEventListener(this );
0720:                                    mci.connectionEventListener = true;
0721:                                }
0722:                                mci.synchro = null;
0723:                                // If a global transaction is already started then enlist the
0724:                                // ManagedConnection instance
0725:                                if (currentTx != null) {
0726:                                    if (isEnabledDebug) {
0727:                                        trace
0728:                                                .log(
0729:                                                        BasicLevel.DEBUG,
0730:                                                        "Enlist the XA Resource "
0731:                                                                + mci
0732:                                                                        .getXAResource()
0733:                                                                + " in Tx:"
0734:                                                                + currentTx);
0735:                                    }
0736:                                    currentTx.enlistResource(mci
0737:                                            .getXAResource());
0738:                                    usedMCs.put(currentTx, mci);
0739:                                    mci.ctx = currentTx;
0740:                                } else {
0741:                                    // There are not Transaction at the moment but the user can
0742:                                    // start a transaction after the getConnection call.
0743:                                    mci.ctx = null;
0744:                                    // must be clean
0745:                                    mcs.add(mci);
0746:                                    // NoTransaction is specified, so don't register the MC
0747:                                    if (!transSupport
0748:                                            .equalsIgnoreCase(NO_TRANS_SUPPORT)) {
0749:                                        mci.rme = new RMEImpl(mci, trace);
0750:                                        if (isEnabledDebug) {
0751:                                            trace
0752:                                                    .log(BasicLevel.DEBUG,
0753:                                                            "Register the managed connection (no tx)");
0754:                                        }
0755:                                        // Always put in list, fix bug on connection late enlistment
0756:                                        if (!mci.rmeCalled) {
0757:                                            mci.rme.isValid = true;
0758:                                            rmel.connectionOpened(mci.rme);
0759:                                            mci.rmeCalled = true;
0760:                                        }
0761:                                    }
0762:                                }
0763:                            } catch (ResourceException re) {
0764:                                trace
0765:                                        .log(BasicLevel.ERROR, re.getMessage(),
0766:                                                re);
0767:                                throw re;
0768:                            } catch (Exception e) {
0769:                                String err = "Error related allocation of ManagedConnection";
0770:                                trace.log(BasicLevel.ERROR, err, e);
0771:                                throw new ResourceException(err, e);
0772:                            }
0773:
0774:                        }
0775:
0776:                        //Fetch a free Connection from the ManagedConnection
0777:                        connection = mci.mc.getConnection(null, cxRequestInfo);
0778:                        // Want to add the non-wrapped Connection object
0779:                        mci.usedCs.add(connection);
0780:
0781:                        conTrace.log(BasicLevel.DEBUG, " getting con("
0782:                                + connection + ") from mc(" + mci.mc
0783:                                + ") of factory(" + jndiname + ")");
0784:                    }
0785:
0786:                    if (connection instanceof  java.sql.Connection) {
0787:                        try {
0788:                            // Need a wrapper for non JOnAS jdbc ConnectionImpl
0789:                            org.objectweb.jonas.jdbc.ConnectionImpl jdbcConn = null;
0790:                            if (connection instanceof  org.objectweb.jonas.jdbc.ConnectionImpl) {
0791:                                jdbcConn = (org.objectweb.jonas.jdbc.ConnectionImpl) connection;
0792:                                jdbcConn.setJonasInfo(mci, this );
0793:                                // This used to be done in the ConnectionImpl constructor, but a synchronized block
0794:                                //  is needed and we don't want any DB I/O within the block
0795:                                jdbcConn.setUser();
0796:                                // in case we do not start a Tx
0797:                                if (currentTx == null) {
0798:                                    jdbcConn.setAutoCommit(true);
0799:                                }
0800:                            } else {
0801:                                connection = JonasSQLWrapper.createSQLWrapper(
0802:                                        connection, mci, this , trace);
0803:                            }
0804:                            // Check the connection before reusing it
0805:                            if (jdbcConnLevel > JDBC_NO_TEST) {
0806:                                try {
0807:                                    if (isEnabledDebug) {
0808:                                        trace.log(BasicLevel.DEBUG,
0809:                                                "Check the JDBC connection");
0810:                                    }
0811:                                    boolean isClosed = true;
0812:                                    // Used for logical testing of connection
0813:                                    if (connection instanceof  org.objectweb.jonas.jdbc.ConnectionImpl) {
0814:                                        isClosed = jdbcConn
0815:                                                .isPhysicallyClosed();
0816:                                    } else {
0817:                                        isClosed = ((Connection) connection)
0818:                                                .isClosed();
0819:                                    }
0820:                                    if (isClosed) {
0821:                                        connectionErrorOccurred(new ConnectionEvent(
0822:                                                mci.mc,
0823:                                                ConnectionEvent.CONNECTION_ERROR_OCCURRED));
0824:                                        try {
0825:                                            mci.usedCs.remove(connection);
0826:                                        } catch (Exception ex) {
0827:                                        }
0828:                                        connection = null;
0829:                                        retries++;
0830:                                        continue;
0831:                                    }
0832:                                    if (jdbcConnLevel > JDBC_CHECK_CONNECTION
0833:                                            && jdbcConnTestStmt != null
0834:                                            && jdbcConnTestStmt.length() > 0) {
0835:                                        if (isEnabledDebug) {
0836:                                            trace.log(BasicLevel.DEBUG,
0837:                                                    "retrying connection: "
0838:                                                            + jdbcConnTestStmt);
0839:                                        }
0840:                                        java.sql.Statement stmt = ((Connection) connection)
0841:                                                .createStatement();
0842:                                        stmt.execute(jdbcConnTestStmt);
0843:                                        stmt.close();
0844:                                    }
0845:                                } catch (Exception e) {
0846:                                    trace.log(BasicLevel.ERROR,
0847:                                            "Error on connection: removing invalid managed connection "
0848:                                                    + mci.mc + ": ", e);
0849:                                    connectionErrorOccurred(new ConnectionEvent(
0850:                                            mci.mc,
0851:                                            ConnectionEvent.CONNECTION_ERROR_OCCURRED));
0852:                                    try {
0853:                                        mci.usedCs.remove(connection);
0854:                                    } catch (Exception ex) {
0855:                                    }
0856:                                    connection = null;
0857:                                    retries++;
0858:                                    continue;
0859:                                }
0860:                            }
0861:                        } catch (Exception ex) {
0862:                            trace.log(BasicLevel.ERROR, ex.getMessage(), ex);
0863:                            throw new ResourceException(ex);
0864:                        }
0865:                    }
0866:                }
0867:                if (isEnabledDebug) {
0868:                    trace.log(BasicLevel.DEBUG,
0869:                            "get a logical connection on MC:" + connection);
0870:                }
0871:
0872:                if (connection == null) {
0873:                    if (retries > 0) {
0874:                        throw new ResourceAllocationException(
0875:                                "Unable to obtain a connection object.  Check the validity of the jdbc-test-statement");
0876:                    } else {
0877:                        throw new ResourceAllocationException(
0878:                                "Unable to obtain a connection object");
0879:                    }
0880:                }
0881:
0882:                return connection;
0883:            }
0884:
0885:            /**
0886:             *  All method of the pool match to the right type of ManagedConnection because
0887:             *  there is one pool by ManagedConnectionFactory.
0888:             *
0889:             * @see org.objectweb.util.pool.api.PoolMatchFactory
0890:             */
0891:            public boolean matchResource(Object res, Object hints) {
0892:                return true;
0893:            }
0894:
0895:            /**
0896:             *  All method of the pool match to the right type of ManagedConnection because
0897:             *  there is one pool by ManagedConnectionFactory.
0898:             *
0899:             * @see org.objectweb.util.pool.api.PoolMatchFactory
0900:             */
0901:            public Object matchResource(Set res, Object hints) throws Exception {
0902:                ResourceSpec spec = (hints != null) ? (ResourceSpec) hints
0903:                        : new ResourceSpec(null, null);
0904:                // If not supported, then just return null so another one will be created
0905:                Object con = null;
0906:                try {
0907:                    con = mcf.matchManagedConnections(res, null,
0908:                            spec.cxRequestInfo);
0909:                } catch (NotSupportedException nse) {
0910:                }
0911:                return con;
0912:            }
0913:
0914:            /**
0915:             *  Call the ManagedConnectionFactory in order to create a new instance. of
0916:             *  ManagedConnection. The Object is a ManagedConnection instance. The hints is a
0917:             *  local structure: ResourceSpec
0918:             *
0919:             * @see org.objectweb.util.pool.api.PoolMatchFactory
0920:             */
0921:            public Object createResource(Object hints) throws Exception {
0922:                ResourceSpec spec = (hints != null) ? (ResourceSpec) hints
0923:                        : new ResourceSpec(null, null);
0924:                ManagedConnection mc = mcf.createManagedConnection(
0925:                        spec.subject, spec.cxRequestInfo);
0926:                if (isEnabledDebug) {
0927:                    trace.log(BasicLevel.DEBUG, "Created MC: " + mc);
0928:                }
0929:                return mc;
0930:            }
0931:
0932:            /**
0933:             *  If supported, call the ManagedConnectionFactory to validate the ManagedConnections
0934:             *
0935:             * @see org.objectweb.util.pool.api.PoolMatchFactory
0936:             */
0937:            public void validateResource(Set res) throws Exception {
0938:                if (vmcf == null) {
0939:                    return;
0940:                }
0941:                try {
0942:                    Set invMcs = vmcf.getInvalidConnections(res);
0943:                    Iterator it = invMcs.iterator();
0944:                    while (it.hasNext()) {
0945:                        Object obj = it.next();
0946:                        poolMCs.releaseResource(obj, true, true);
0947:                    }
0948:                } catch (Exception ex) {
0949:                    if (isEnabledDebug) {
0950:                        trace.log(BasicLevel.DEBUG,
0951:                                "Error trying to validate Connections for "
0952:                                        + mcf, ex);
0953:                    }
0954:                }
0955:            }
0956:
0957:            /** IMPLEMENTATION OF INTERFACE SQLManager
0958:             */
0959:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
0960:                    String user, String sql) throws SQLException {
0961:                return getPStatement(mcinfo, conn, user, sql,
0962:                        ResultSet.TYPE_FORWARD_ONLY,
0963:                        ResultSet.CONCUR_READ_ONLY, -1, -1, null, null,
0964:                        PSWRAP_1);
0965:
0966:            }
0967:
0968:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
0969:                    String user, String sql, int resultSetType,
0970:                    int resultSetConcurrency) throws SQLException {
0971:                return getPStatement(mcinfo, conn, user, sql, resultSetType,
0972:                        resultSetConcurrency, -1, -1, null, null, PSWRAP_1);
0973:            }
0974:
0975:            // JDBC 3.0
0976:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
0977:                    String user, String sql, int resultSetType,
0978:                    int resultSetConcurrency, int resultSetHoldability)
0979:                    throws SQLException {
0980:                return getPStatement(mcinfo, conn, user, sql, resultSetType,
0981:                        resultSetConcurrency, resultSetHoldability, -1, null,
0982:                        null, PSWRAP_2);
0983:            }
0984:
0985:            // JDBC 3.0
0986:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
0987:                    String user, String sql, int autoGeneratedKeys)
0988:                    throws SQLException {
0989:                return getPStatement(mcinfo, conn, user, sql, -1, -1, -1,
0990:                        autoGeneratedKeys, null, null, PSWRAP_3);
0991:            }
0992:
0993:            // JDBC 3.0
0994:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
0995:                    String user, String sql, int[] columnIndexes)
0996:                    throws SQLException {
0997:                return getPStatement(mcinfo, conn, user, sql, -1, -1, -1, -1,
0998:                        columnIndexes, null, PSWRAP_4);
0999:            }
1000:
1001:            // JDBC 3.0
1002:            public PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
1003:                    String user, String sql, String[] columnNames)
1004:                    throws SQLException {
1005:                return getPStatement(mcinfo, conn, user, sql, -1, -1, -1, -1,
1006:                        null, columnNames, PSWRAP_5);
1007:            }
1008:
1009:            private PreparedStatement getPStatement(MCInfo mcinfo, Object conn,
1010:                    String user, String sql, int resultSetType,
1011:                    int resultSetConcurrency, int resultSetHoldability,
1012:                    int autoGeneratedKeys, int[] columnIndexes,
1013:                    String[] columnNames, int pswrapType) throws SQLException {
1014:
1015:                if (isEnabledDebug) {
1016:                    trace.log(BasicLevel.DEBUG, "Sql: " + sql + " User: "
1017:                            + user);
1018:                }
1019:                // Use for the equals test
1020:                PreparedStatementWrapper psw = null;
1021:                switch (pswrapType) {
1022:                case PSWRAP_1:
1023:                    psw = new PreparedStatementWrapper(user, sql,
1024:                            resultSetType, resultSetConcurrency, trace,
1025:                            isEnabledDebug);
1026:                    break;
1027:                case PSWRAP_2:
1028:                    psw = new PreparedStatementWrapper(user, sql,
1029:                            resultSetType, resultSetConcurrency,
1030:                            resultSetHoldability, trace, isEnabledDebug);
1031:                    break;
1032:                case PSWRAP_3:
1033:                    psw = new PreparedStatementWrapper(user, sql,
1034:                            autoGeneratedKeys, trace, isEnabledDebug);
1035:                    break;
1036:                case PSWRAP_4:
1037:                    psw = new PreparedStatementWrapper(user, sql,
1038:                            columnIndexes, trace, isEnabledDebug);
1039:                    break;
1040:                case PSWRAP_5:
1041:                    psw = new PreparedStatementWrapper(user, sql, columnNames,
1042:                            trace, isEnabledDebug);
1043:                    break;
1044:                default:
1045:                    break;
1046:                }
1047:
1048:                synchronized (mcinfo.pStmts) {
1049:                    if (isEnabledDebug) {
1050:                        trace.log(BasicLevel.DEBUG, "MC pStmts: "
1051:                                + mcinfo.pStmts);
1052:                    }
1053:                    //Check if statement matches ManagedConnection list & valid
1054:                    // use lastIndexOf as when a statement is found, it is put at the end.
1055:                    int indexPstmt = mcinfo.pStmts.lastIndexOf(psw);
1056:                    if (indexPstmt != -1) {
1057:                        PreparedStatementWrapper ps = (PreparedStatementWrapper) mcinfo.pStmts
1058:                                .remove(indexPstmt);
1059:                        ps.clearPstmtValues();
1060:                        mcinfo.pStmts.add(ps); // add last
1061:                        return ps;
1062:                    } else if (isEnabledDebug) {
1063:                        trace
1064:                                .log(BasicLevel.DEBUG,
1065:                                        "No statement in cache, need to build a new one");
1066:                    }
1067:
1068:                    //If not in either, call con.prepareStatement, wrap the returned one
1069:                    // and add it to MC pool
1070:                    PreparedStatement ps = null;
1071:                    switch (pswrapType) {
1072:                    case PSWRAP_1:
1073:                        ps = ((java.sql.Connection) conn).prepareStatement(sql,
1074:                                resultSetType, resultSetConcurrency);
1075:                        break;
1076:                    case PSWRAP_2:
1077:                        ps = ((java.sql.Connection) conn).prepareStatement(sql,
1078:                                resultSetType, resultSetConcurrency,
1079:                                resultSetHoldability);
1080:                        break;
1081:                    case PSWRAP_3:
1082:                        ps = ((java.sql.Connection) conn).prepareStatement(sql,
1083:                                autoGeneratedKeys);
1084:                        break;
1085:                    case PSWRAP_4:
1086:                        ps = ((java.sql.Connection) conn).prepareStatement(sql,
1087:                                columnIndexes);
1088:                        break;
1089:                    case PSWRAP_5:
1090:                        ps = ((java.sql.Connection) conn).prepareStatement(sql,
1091:                                columnNames);
1092:                        break;
1093:                    default:
1094:                        break;
1095:                    }
1096:                    if (maxPstmtPoolSize < 0) {
1097:                        // No prepared statement pool
1098:                        if (isEnabledDebug) {
1099:                            trace.log(BasicLevel.DEBUG, "Pooling is disabled");
1100:                        }
1101:                        return ps;
1102:                    } else if (maxPstmtPoolSize == 0
1103:                            || mcinfo.pStmts.size() < maxPstmtPoolSize) {
1104:                        psw.setPreparedStatement(ps);
1105:                        mcinfo.pStmts.add(psw);
1106:                        if (isEnabledDebug) {
1107:                            trace.log(BasicLevel.DEBUG, "Adding PStmt: " + psw);
1108:                        }
1109:                        return psw;
1110:                    } else {
1111:                        int offset = mcinfo.findFreeStmt();
1112:                        if (offset >= 0) {
1113:                            // Remove that entry from the current pool
1114:                            PreparedStatementWrapper pw = (PreparedStatementWrapper) mcinfo.pStmts
1115:                                    .remove(offset);
1116:                            pw.destroy();
1117:                            psw.setPreparedStatement(ps);
1118:                            mcinfo.pStmts.add(psw);
1119:                            if (isEnabledDebug) {
1120:                                trace.log(BasicLevel.DEBUG, "Replacing " + pw
1121:                                        + " with " + psw);
1122:                            }
1123:                            return psw;
1124:                        } else {
1125:                            // No room for the Wrapped statement just return the PreparedStatement
1126:                            if (isEnabledDebug) {
1127:                                trace.log(BasicLevel.DEBUG, "No room in pool");
1128:                            }
1129:                            return ps;
1130:                        }
1131:                    }
1132:                }
1133:            }
1134:
1135:            /**
1136:             * Release the ManagedConnection object resource
1137:             * @param rMc Object to release
1138:             * @throws Exception if an Exception occurs
1139:             */
1140:            public void releaseResource(Object rMc) throws Exception {
1141:
1142:                synchronized (poolMCs) {
1143:
1144:                    if (isEnabledDebug) {
1145:                        trace.log(BasicLevel.DEBUG, "MC: " + rMc);
1146:                    }
1147:                    if (rMc instanceof  ManagedConnection) {
1148:                        ManagedConnection mc = (ManagedConnection) rMc;
1149:                        MCInfo mcinfo = (MCInfo) mc2mci.remove(mc);
1150:                        if (mcinfo != null) {
1151:                            destroyPStmts(mcinfo);
1152:                        }
1153:                    }
1154:                }
1155:            }
1156:
1157:            /**
1158:             * Destroying of the PreparedStatement objects of the Pool
1159:             * @param mcinfo ManagedConnection information
1160:             * @throws Exception Exception
1161:             */
1162:            public void destroyPStmts(MCInfo mcinfo) throws Exception {
1163:                if (isEnabledDebug) {
1164:                    trace.log(BasicLevel.DEBUG, "MCInfo: " + mcinfo);
1165:                }
1166:                synchronized (mcinfo.pStmts) {
1167:                    if (mcinfo.pStmts.size() <= 0) {
1168:                        return;
1169:                    }
1170:                    int stmtSize = mcinfo.pStmts.size();
1171:                    try {
1172:                        for (int i = 0; i < stmtSize; i++) {
1173:                            PreparedStatementWrapper psw = (PreparedStatementWrapper) mcinfo.pStmts
1174:                                    .remove(0);
1175:                            psw.closePstmt();
1176:                        }
1177:                    } catch (Exception ex) {
1178:                        throw ex;
1179:                    }
1180:                }
1181:            }
1182:
1183:            /**
1184:             *  IMPLEMENTATION OF INTERFACE ConnectionEventListener *
1185:             *
1186:             *  A ManagedConnection instance calls the connectionClosed method to notify
1187:             *  its registered set of listeners when an application component closes a
1188:             *  connection handle. The application server uses this connection close event
1189:             *  to make a decision on whether or not to put the ManagedConnection instance
1190:             *  back into the connection pool.
1191:             *
1192:             * @see javax.resource.spi.ConnectionEventListener
1193:             */
1194:            public void connectionClosed(ConnectionEvent event) {
1195:
1196:                synchronized (poolMCs) {
1197:
1198:                    ManagedConnection mc = (ManagedConnection) event
1199:                            .getSource();
1200:                    if (mc == null) {
1201:                        trace.log(BasicLevel.ERROR, "no mc found in Event!");
1202:                    }
1203:
1204:                    MCInfo mci = (MCInfo) mc2mci.get(mc);
1205:                    if (mci == null) {
1206:                        trace.log(BasicLevel.ERROR, "no mci found!");
1207:                        return;
1208:                    }
1209:
1210:                    if (isEnabledDebug) {
1211:                        trace.log(BasicLevel.DEBUG, "enter\n" + getState("\t"));
1212:                    }
1213:
1214:                    mci.usedCs.remove(event.getConnectionHandle());
1215:
1216:                    if (mci.usedCs.isEmpty()) {
1217:                        if (isEnabledDebug) {
1218:                            trace.log(BasicLevel.DEBUG,
1219:                                    "Last Connection has just been removed");
1220:                        }
1221:
1222:                        try {
1223:                            Transaction currentTx = null;
1224:                            if (tm != null) {
1225:                                currentTx = tm.getTransaction();
1226:                            }
1227:
1228:                            if (mci.localTransaction && currentTx == null) {
1229:                                trace
1230:                                        .log(
1231:                                                BasicLevel.ERROR,
1232:                                                "The managed connection is being closed while a localtransaction is not finished");
1233:                            }
1234:
1235:                            if (currentTx != null) {
1236:                                mci.ctx = currentTx;
1237:
1238:                                if (mci.synchro == null) {
1239:                                    try {
1240:                                        currentTx
1241:                                                .registerSynchronization(new MySynchro(
1242:                                                        this , mci));
1243:                                        if (isEnabledDebug) {
1244:                                            trace.log(BasicLevel.DEBUG,
1245:                                                    "registerSynchro mc="
1246:                                                            + mci.mc);
1247:                                        }
1248:                                    } catch (RollbackException e) {
1249:                                        // The transaction has been marked as rollbackOnly
1250:                                        // but the synchronization is registered.
1251:                                        trace.log(BasicLevel.INFO,
1252:                                                "registerSynchronization on transaction marked as Rollback only, mc="
1253:                                                        + mci.mc);
1254:                                    }
1255:                                }
1256:                            } else if (mci.localTransaction) {
1257:                                if (isEnabledDebug) {
1258:                                    trace
1259:                                            .log(BasicLevel.DEBUG,
1260:                                                    "MC isn't released because local transaction is not finished");
1261:                                }
1262:
1263:                            } else {
1264:                                if (isEnabledDebug) {
1265:                                    trace.log(BasicLevel.DEBUG, "no currentTx");
1266:                                }
1267:
1268:                                mcs.remove(mci);
1269:
1270:                                if (mci.ctx != null) {
1271:                                    usedMCs.remove(mci.ctx);
1272:                                    mci.ctx = null;
1273:                                }
1274:
1275:                                mci.mc.cleanup();
1276:
1277:                                // Free up the PreparedStatements
1278:                                //                      mci.stmtHash.clear();
1279:
1280:                                // Release the MC from its pool
1281:                                poolMCs.releaseResource(mci.mc, false, true);
1282:
1283:                            }
1284:                            if (mci.rmeCalled) {
1285:                                //Signal to the RessourceManagerEventListener mc is released
1286:                                mci.rme.isValid = false;
1287:                                rmel.connectionClosed(mci.rme);
1288:                                mci.rmeCalled = false;
1289:                            }
1290:                        } catch (Exception e) {
1291:                            trace
1292:                                    .log(
1293:                                            BasicLevel.ERROR,
1294:                                            "an error during delisting of ManagedConection: ",
1295:                                            e);
1296:                        }
1297:                        if (isEnabledDebug) {
1298:                            trace.log(BasicLevel.DEBUG, "exit\n"
1299:                                    + getState("\t"));
1300:                        }
1301:                    }
1302:                }
1303:            }
1304:
1305:            /**
1306:             *  The connectionErrorOccurred method indicates that the associated
1307:             *  ManagedConnection instance is now invalid and unusable. The application
1308:             *  server handles the connection error event notification by initiating
1309:             *  application server-specific cleanup (for example, removing
1310:             *  ManagedConnection instance from the connection pool) and then calling
1311:             *  ManagedConnection.destroy method to destroy the physical connection..
1312:             *
1313:             * @see javax.resource.spi.ConnectionEventListener
1314:             */
1315:            public void connectionErrorOccurred(ConnectionEvent event) {
1316:
1317:                synchronized (poolMCs) {
1318:
1319:                    ManagedConnection mc = (ManagedConnection) event
1320:                            .getSource();
1321:                    if (mc == null) {
1322:                        trace.log(BasicLevel.ERROR, "no mc found in Event!");
1323:                    }
1324:
1325:                    MCInfo mci = (MCInfo) mc2mci.get(mc);
1326:                    if (mci == null) {
1327:                        trace.log(BasicLevel.ERROR, "no mci found!");
1328:                        return;
1329:                    }
1330:
1331:                    if (poolTrace.isLoggable(BasicLevel.DEBUG)) {
1332:                        poolTrace.log(BasicLevel.DEBUG, "enter\n"
1333:                                + getState("\t"));
1334:                    }
1335:
1336:                    mci.usedCs.clear();
1337:
1338:                    try {
1339:                        if (mci.rmeCalled) {
1340:                            //Signal to the RessourceManagerEventListener mc is released
1341:                            mci.rme.isValid = false;
1342:                            rmel.connectionErrorOccured(mci.rme);
1343:                            mci.rmeCalled = false;
1344:                        }
1345:                        // Detach the connectionManager from the mc
1346:                        mc.removeConnectionEventListener(this );
1347:                        // Remove the association (transaction ctx / mc)
1348:                        if (mci.ctx != null) {
1349:                            usedMCs.remove(mci.ctx);
1350:                            mci.ctx = null;
1351:                        } else {
1352:                            mcs.remove(mci);
1353:                        }
1354:
1355:                        if (isEnabledDebug) {
1356:                            trace.log(BasicLevel.DEBUG,
1357:                                    "Destroying managed connection (" + mc
1358:                                            + ")");
1359:                        }
1360:                        // Destroy the PreparedStatements
1361:                        destroyPStmts(mci);
1362:
1363:                        poolMCs.releaseResource(mc, true, false);
1364:                        if (poolTrace.isLoggable(BasicLevel.DEBUG)) {
1365:                            poolTrace.log(BasicLevel.DEBUG, "enter\n"
1366:                                    + getState("\t"));
1367:                        }
1368:
1369:                        mc2mci.remove(mc);
1370:
1371:                    } catch (Exception e) {
1372:                        trace
1373:                                .log(BasicLevel.ERROR,
1374:                                        "an error related during delisting of ManagedConection");
1375:                    }
1376:                }
1377:            }
1378:
1379:            /**
1380:             *  Notifies that a Resource Manager Local Transaction was committed on the
1381:             *  ManagedConnection instance.
1382:             *
1383:             * @see javax.resource.spi.ConnectionEventListener
1384:             */
1385:            public void localTransactionCommitted(ConnectionEvent event) {
1386:
1387:                synchronized (poolMCs) {
1388:
1389:                    ManagedConnection mc = (ManagedConnection) event
1390:                            .getSource();
1391:                    if (mc == null) {
1392:                        trace.log(BasicLevel.ERROR, "no mc found in Event!");
1393:                    }
1394:
1395:                    MCInfo mci = (MCInfo) mc2mci.get(mc);
1396:                    if (mci == null) {
1397:                        trace.log(BasicLevel.ERROR, "no mci found!");
1398:                        return;
1399:                    }
1400:                    mci.localTransaction = false;
1401:
1402:                    if (mci.usedCs.isEmpty()) {
1403:                        if (isEnabledDebug) {
1404:                            trace.log(BasicLevel.DEBUG,
1405:                                    "Close the managed connection");
1406:                        }
1407:
1408:                        if (mci.rmeCalled) {
1409:                            //Signal to the RessourceManagerEventListener mc is released
1410:                            mci.rme.isValid = false;
1411:                            rmel.connectionClosed(mci.rme);
1412:                            mci.rmeCalled = false;
1413:                        }
1414:
1415:                        if (mci.synchro == null) {
1416:                            mcs.remove(mci);
1417:                            if (mci.ctx != null) {
1418:                                usedMCs.remove(mci.ctx);
1419:                                mci.ctx = null;
1420:                            }
1421:
1422:                            try {
1423:                                mci.mc.cleanup();
1424:
1425:                                // Release the MC from its pool
1426:                                poolMCs.releaseResource(mci.mc, false, true);
1427:                            } catch (Exception e) {
1428:                                trace
1429:                                        .log(
1430:                                                BasicLevel.ERROR,
1431:                                                "an error related ManagedConection release",
1432:                                                e, "ConnectionManagerImpl",
1433:                                                "localTransactionCommitted");
1434:                            }
1435:                        }
1436:                    }
1437:                }
1438:
1439:            }
1440:
1441:            /**
1442:             *  Notifies that a Resource Manager Local Transaction was rolled back on the
1443:             *  ManagedConnection instance.
1444:             *
1445:             * @see javax.resource.spi.ConnectionEventListener
1446:             */
1447:            public void localTransactionRolledback(ConnectionEvent event) {
1448:
1449:                synchronized (poolMCs) {
1450:
1451:                    ManagedConnection mc = (ManagedConnection) event
1452:                            .getSource();
1453:                    if (mc == null) {
1454:                        trace.log(BasicLevel.ERROR, "no mc found in Event!");
1455:                    }
1456:
1457:                    MCInfo mci = (MCInfo) mc2mci.get(mc);
1458:                    if (mci == null) {
1459:                        trace.log(BasicLevel.ERROR, "no mci found!");
1460:                        return;
1461:                    }
1462:                    mci.localTransaction = false;
1463:
1464:                    if (mci.usedCs.isEmpty()) {
1465:                        if (isEnabledDebug) {
1466:                            trace.log(BasicLevel.DEBUG,
1467:                                    "Close the managed connection");
1468:                        }
1469:
1470:                        if (mci.rmeCalled) {
1471:                            //Signal to the ResourceManagerEventListener mc is released
1472:                            mci.rme.isValid = false;
1473:                            rmel.connectionClosed(mci.rme);
1474:                            mci.rmeCalled = false;
1475:                        }
1476:
1477:                        if (mci.synchro == null) {
1478:                            mcs.remove(mci);
1479:                            if (mci.ctx != null) {
1480:                                usedMCs.remove(mci.ctx);
1481:                                mci.ctx = null;
1482:                            }
1483:
1484:                            try {
1485:                                mci.mc.cleanup();
1486:
1487:                                // Release the MC from its pool
1488:                                poolMCs.releaseResource(mci.mc, false, true);
1489:                            } catch (Exception e) {
1490:                                trace
1491:                                        .log(
1492:                                                BasicLevel.ERROR,
1493:                                                "an error related during ManagedConection release:",
1494:                                                e, "ConnectionManagerImpl",
1495:                                                "localTransactionRolledback");
1496:                            }
1497:                        }
1498:                    }
1499:                }
1500:            }
1501:
1502:            /**
1503:             *  Notifies that a Resource Manager Local Transaction was started on the
1504:             *  ManagedConnection instance.
1505:             *
1506:             * @see javax.resource.spi.ConnectionEventListener
1507:             */
1508:            public void localTransactionStarted(ConnectionEvent event) {
1509:
1510:                synchronized (poolMCs) {
1511:
1512:                    ManagedConnection mc = (ManagedConnection) event
1513:                            .getSource();
1514:                    if (mc == null) {
1515:                        trace.log(BasicLevel.ERROR, "no mc found in Event!");
1516:                    }
1517:
1518:                    MCInfo mci = (MCInfo) mc2mci.get(mc);
1519:                    if (mci == null) {
1520:                        trace.log(BasicLevel.ERROR, "no mci found!");
1521:                        return;
1522:                    }
1523:                    mci.localTransaction = true;
1524:
1525:                }
1526:            }
1527:
1528:            /**
1529:             *  Description of the Method
1530:             *
1531:             *@return    Description of the Returned Value
1532:             */
1533:            public String toString() {
1534:                String m = super .toString();
1535:                // remove package name
1536:                int c1 = 0;
1537:                int current = m.indexOf(".");
1538:                while (current != -1) {
1539:                    c1 = current;
1540:                    current = m.indexOf(".", current + 1);
1541:                }
1542:                return m.substring(c1 + 1, m.length());
1543:            }
1544:
1545:            /**
1546:             *  Gets the State attribute of the ConnectionManagerImpl object
1547:             *
1548:             *@param  prefix  Description of Parameter
1549:             *@return         The State value
1550:             */
1551:            protected String getState(String prefix) {
1552:                String res = null;
1553:                synchronized (poolMCs) {
1554:                    res = prefix + "mcf=" + mcf + "\n";
1555:                    res += prefix + "ResourceSpec=" + rs.toString() + "\n";
1556:                    res += prefix + "size of MC pool:" + poolMCs.getSize()
1557:                            + "\n";
1558:                    res += prefix + "size of usedMCs:" + usedMCs.size() + "\n";
1559:                    res += prefix + "mcs attached to a tx:\n";
1560:                    for (Enumeration en = usedMCs.keys(); en.hasMoreElements();) {
1561:                        Object tx = en.nextElement();
1562:                        MCInfo mci = (MCInfo) usedMCs.get(tx);
1563:                        res += prefix + "MCI : tx=" + tx + "\n";
1564:                        res += mci.getState(prefix + "\t");
1565:                    }
1566:                    res += prefix + "mcs not attached to a tx:\n";
1567:                    for (Enumeration en = mcs.elements(); en.hasMoreElements();) {
1568:                        MCInfo mci = (MCInfo) en.nextElement();
1569:                        res += mci.getState(prefix + "\t");
1570:                    }
1571:                    res += prefix + "mcs waiting for tx commit or rollback:\n";
1572:                    for (Enumeration en = synchros.elements(); en
1573:                            .hasMoreElements();) {
1574:                        MCInfo mci = (MCInfo) en.nextElement();
1575:                        res += mci.getState(prefix + "\t");
1576:                    }
1577:                }
1578:                return res;
1579:            }
1580:
1581:            /**
1582:             * Set the XAName to use
1583:             * @param xanm String of XA Name
1584:             */
1585:            public void setXAName(String xanm) {
1586:                xaName = xanm;
1587:            }
1588:
1589:            /**
1590:             * Get the XAName to use
1591:             * @return String of XA Name
1592:             */
1593:            public String getXAName() {
1594:                return (xaName);
1595:            }
1596:
1597:            /**
1598:             * Register an XAResource with JOTM for recovery
1599:             */
1600:            public void registerXAResource(Properties tmProp) {
1601:
1602:                synchronized (poolMCs) {
1603:
1604:                    // If no RM or the RAR doesn't support XA, then just return
1605:                    if (tm == null) {
1606:                        return;
1607:                    }
1608:                    if (!transSupport.equalsIgnoreCase(XA_TRANS_SUPPORT)) {
1609:                        return;
1610:                    }
1611:
1612:                    // Find an entry in free pool
1613:                    // If none, then create one
1614:                    MCInfo mci = null;
1615:                    XAResource xar = null;
1616:                    try {
1617:                        ManagedConnection mc = (ManagedConnection) poolMCs
1618:                                .getResource(rs);
1619:                        if (mc == null) {
1620:                            if (isEnabledDebug) {
1621:                                trace
1622:                                        .log(BasicLevel.DEBUG,
1623:                                                "Cannot allocate a ManagedConnection for registerXAResource");
1624:                            }
1625:                            return;
1626:                        }
1627:
1628:                        mci = (MCInfo) mc2mci.get(mc);
1629:                        if (mci == null) {
1630:                            mci = new MCInfo(mc);
1631:                            mc2mci.put(mc, mci);
1632:                        }
1633:
1634:                        xar = mc.getXAResource();
1635:                        if (isEnabledDebug) {
1636:                            trace.log(BasicLevel.DEBUG,
1637:                                    "got a MC from the ra pool, mc=" + mci.mc
1638:                                            + " xar=" + xar);
1639:                        }
1640:
1641:                        if (!mci.connectionEventListener) {
1642:                            mci.mc.addConnectionEventListener(this );
1643:                            mci.connectionEventListener = true;
1644:                        }
1645:
1646:                        mci.synchro = null;
1647:
1648:                    } catch (ResourceException re) {
1649:                        return;
1650:                    } catch (Exception e) {
1651:                        trace.log(BasicLevel.ERROR, e.getMessage(), e);
1652:                        return;
1653:                    }
1654:
1655:                    // Setup globals so it can be returned to the pool
1656:                    jotmMc = mci.mc;
1657:                    jotmXar = xar;
1658:
1659:                    // Call to register it
1660:                    try {
1661:                        if (isEnabledDebug) {
1662:                            trace.log(BasicLevel.DEBUG, "Registering name = "
1663:                                    + xaName + " xar = " + jotmXar);
1664:                        }
1665:                        ((Current) tm).getTransactionRecovery()
1666:                                .registerResourceManager(xaName, jotmXar, "",
1667:                                        tmProp, this );
1668:                    } catch (Exception ex) {
1669:                        trace.log(BasicLevel.ERROR, ex.getMessage(), ex);
1670:                        returnXAResource(xaName, jotmXar);
1671:                    }
1672:                }
1673:            }
1674:
1675:            /**
1676:             * Called from JOTM to free the XAResource and associated Managed Connection
1677:             * when recovery is complete
1678:             *
1679:             * @param rmName The Resource Manager to be unregistered.
1680:             * @param rmXares XAResource to be returned
1681:             */
1682:            public void returnXAResource(String rmName, XAResource rmXares) {
1683:
1684:                synchronized (poolMCs) {
1685:                    // Get the associated MC
1686:                    // Clean it up and return it to the free pool
1687:                    if (isEnabledDebug) {
1688:                        trace.log(BasicLevel.DEBUG, "Removing name = " + xaName
1689:                                + " xar = " + jotmXar);
1690:                    }
1691:                    if (jotmXar == null) {
1692:                        return;
1693:                    }
1694:                    if (!rmXares.equals(jotmXar)) {
1695:                        trace.log(BasicLevel.ERROR, "XAResource of " + rmXares
1696:                                + " and " + jotmXar + " not equal!");
1697:                        return;
1698:                    }
1699:
1700:                    MCInfo mci = (MCInfo) mc2mci.get(jotmMc);
1701:                    if (mci == null) {
1702:                        trace.log(BasicLevel.ERROR, "no mci found for "
1703:                                + jotmMc);
1704:                        return;
1705:                    }
1706:
1707:                    try {
1708:                        mci.mc.cleanup();
1709:
1710:                        // Release the MC from its pool
1711:                        poolMCs.releaseResource(mci.mc, false, true);
1712:                    } catch (Exception ex) {
1713:                        trace.log(BasicLevel.ERROR, ex.getMessage(), ex);
1714:                    }
1715:
1716:                    jotmMc = null;
1717:                    jotmXar = null;
1718:                }
1719:            }
1720:
1721:            // JSR 77 (JCAConnectionFactory methods)
1722:
1723:            public Pool getPool() {
1724:                return poolMCs;
1725:            }
1726:
1727:            public int getCheckLevel() {
1728:                return jdbcConnLevel;
1729:            }
1730:
1731:            public void setCheckLevel(int level) {
1732:                jdbcConnLevel = level;
1733:            }
1734:
1735:            public String getTestStatement() {
1736:                return jdbcConnTestStmt;
1737:            }
1738:
1739:            public void setTestStatement(String stmt) {
1740:                jdbcConnTestStmt = stmt;
1741:            }
1742:
1743:            public int getCurrentInTx() {
1744:                return usedMCs.size();
1745:            }
1746:
1747:            /**
1748:             * @return Returns the maxPstmtPoolSize.
1749:             */
1750:            public int getMaxPstmtPoolSize() {
1751:                return maxPstmtPoolSize;
1752:            }
1753:
1754:            /**
1755:             * @param maxPstmtPoolSize The maxPstmtPoolSize to set.
1756:             */
1757:            public void setMaxPstmtPoolSize(int maxPstmtPoolSize) {
1758:                this.maxPstmtPoolSize = maxPstmtPoolSize;
1759:            }
1760:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.