Source Code Cross Referenced for JBossManagedConnectionPool.java in  » EJB-Server-JBoss-4.2.1 » connector » org » jboss » resource » connectionmanager » 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 » EJB Server JBoss 4.2.1 » connector » org.jboss.resource.connectionmanager 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JBoss, Home of Professional Open Source.
0003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004:         * as indicated by the @author tags. See the copyright.txt file in the
0005:         * distribution for a full listing of individual contributors.
0006:         *
0007:         * This is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU Lesser General Public License as
0009:         * published by the Free Software Foundation; either version 2.1 of
0010:         * the License, or (at your option) any later version.
0011:         *
0012:         * This software is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this software; if not, write to the Free
0019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021:         */
0022:        package org.jboss.resource.connectionmanager;
0023:
0024:        import java.security.AccessController;
0025:        import java.security.PrivilegedAction;
0026:        import java.util.Iterator;
0027:        import java.util.Map;
0028:
0029:        import javax.management.Notification;
0030:        import javax.management.NotificationFilter;
0031:        import javax.management.NotificationListener;
0032:        import javax.management.ObjectName;
0033:        import javax.resource.ResourceException;
0034:        import javax.resource.spi.ConnectionRequestInfo;
0035:        import javax.resource.spi.ManagedConnectionFactory;
0036:        import javax.security.auth.Subject;
0037:        import javax.transaction.Transaction;
0038:        import javax.transaction.TransactionManager;
0039:
0040:        import org.jboss.deployment.DeploymentException;
0041:        import org.jboss.logging.Logger;
0042:        import org.jboss.mx.util.JMXExceptionDecoder;
0043:        import org.jboss.resource.JBossResourceException;
0044:        import org.jboss.resource.connectionmanager.InternalManagedConnectionPool.PoolParams;
0045:        import org.jboss.system.ServiceMBeanSupport;
0046:        import org.jboss.tm.TransactionLocal;
0047:
0048:        import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
0049:
0050:        /**
0051:         * The JBossManagedConnectionPool mbean configures and supplies pooling of
0052:         * JBossConnectionEventListeners to the BaseConnectionManager2 mbean.<p>
0053:         *   
0054:         * It may be replaced by any mbean with a readable ManagedConnectionPool attribute
0055:         * of type ManagedConnectionPool.  Normal pooling parameters are supplied,
0056:         * and the criteria to distinguish ManagedConnections is set in the Criteria attribute.
0057:         *
0058:         * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
0059:         * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
0060:         * @author <a href="weston.price@jboss.com">Weston Price</a>
0061:         * 
0062:         * @version $Revision: 59880 $
0063:         */
0064:        public class JBossManagedConnectionPool extends ServiceMBeanSupport
0065:                implements  JBossManagedConnectionPoolMBean,
0066:                NotificationListener {
0067:
0068:            /** The log */
0069:            private static final Logger log = Logger
0070:                    .getLogger(JBossManagedConnectionPool.class);
0071:
0072:            /** The managed connection factory name */
0073:            private ObjectName managedConnectionFactoryName;
0074:
0075:            /** The pooling criteria */
0076:            private String criteria;
0077:
0078:            /** The pooling strategy */
0079:            private ManagedConnectionPool poolingStrategy;
0080:
0081:            /** The pooling parameters */
0082:            private final InternalManagedConnectionPool.PoolParams poolParams = new InternalManagedConnectionPool.PoolParams();
0083:
0084:            /** Whether to use separate pools for transactional and non-transaction use */
0085:            private boolean noTxSeparatePools;
0086:
0087:            private String poolJndiName;
0088:
0089:            public JBossManagedConnectionPool() {
0090:            }
0091:
0092:            public ManagedConnectionPool getManagedConnectionPool() {
0093:                return poolingStrategy;
0094:            }
0095:
0096:            public ObjectName getManagedConnectionFactoryName() {
0097:                return managedConnectionFactoryName;
0098:            }
0099:
0100:            public void setManagedConnectionFactoryName(
0101:                    ObjectName newManagedConnectionFactoryName) {
0102:                this .managedConnectionFactoryName = newManagedConnectionFactoryName;
0103:            }
0104:
0105:            public long getAvailableConnectionCount() {
0106:                return (poolingStrategy == null) ? 0 : poolingStrategy
0107:                        .getAvailableConnectionCount();
0108:            }
0109:
0110:            public long getMaxConnectionsInUseCount() {
0111:                return (poolingStrategy == null) ? 0 : poolingStrategy
0112:                        .getMaxConnectionsInUseCount();
0113:            }
0114:
0115:            public long getInUseConnectionCount() {
0116:                return (poolingStrategy == null) ? 0 : poolingStrategy
0117:                        .getInUseConnectionCount();
0118:            }
0119:
0120:            public int getMinSize() {
0121:                return poolParams.minSize;
0122:            }
0123:
0124:            public void setMinSize(int newMinSize) {
0125:                poolParams.minSize = newMinSize;
0126:            }
0127:
0128:            public int getMaxSize() {
0129:                return poolParams.maxSize;
0130:            }
0131:
0132:            public void setMaxSize(int newMaxSize) {
0133:                poolParams.maxSize = newMaxSize;
0134:            }
0135:
0136:            public int getBlockingTimeoutMillis() {
0137:                return poolParams.blockingTimeout;
0138:            }
0139:
0140:            public void setBlockingTimeoutMillis(int newBlockingTimeout) {
0141:                poolParams.blockingTimeout = newBlockingTimeout;
0142:            }
0143:
0144:            public long getIdleTimeoutMinutes() {
0145:                return poolParams.idleTimeout / (1000 * 60);
0146:            }
0147:
0148:            public void setIdleTimeoutMinutes(long newIdleTimeoutMinutes) {
0149:                poolParams.idleTimeout = newIdleTimeoutMinutes * 1000 * 60;
0150:            }
0151:
0152:            /**
0153:             * Get the IdleTimeout value.
0154:             *
0155:             * @return the IdleTimeout value.
0156:             */
0157:            public long getIdleTimeout() {
0158:                return poolParams.idleTimeout;
0159:            }
0160:
0161:            /**
0162:             * Set the IdleTimeout value.
0163:             *
0164:             * @param newIdleTimeout The new IdleTimeout value.
0165:             */
0166:            public void setIdleTimeout(long newIdleTimeout) {
0167:                poolParams.idleTimeout = newIdleTimeout;
0168:            }
0169:
0170:            public String getCriteria() {
0171:                return criteria;
0172:            }
0173:
0174:            public void setCriteria(String newCriteria) {
0175:                this .criteria = newCriteria;
0176:            }
0177:
0178:            public boolean getNoTxSeparatePools() {
0179:                return noTxSeparatePools;
0180:            }
0181:
0182:            public void setNoTxSeparatePools(boolean value) {
0183:                this .noTxSeparatePools = value;
0184:            }
0185:
0186:            public boolean getBackGroundValidation() {
0187:                return poolParams.backgroundValidation;
0188:            }
0189:
0190:            public void setBackGroundValidation(boolean backgroundValidation) {
0191:
0192:                poolParams.backgroundValidation = backgroundValidation;
0193:
0194:            }
0195:
0196:            public long getBackGroundValidationMinutes() {
0197:
0198:                return poolParams.backgroundInterval / (1000 * 60);
0199:            }
0200:
0201:            public void setBackGroundValidationMinutes(
0202:                    long backgroundValidationInterval) {
0203:
0204:                poolParams.backgroundInterval = backgroundValidationInterval * 1000 * 60;
0205:
0206:            }
0207:
0208:            public boolean getPreFill() {
0209:                return this .poolParams.prefill;
0210:            }
0211:
0212:            public void setPreFill(boolean prefill) {
0213:                this .poolParams.prefill = prefill;
0214:            }
0215:
0216:            public boolean getUseFastFail() {
0217:                return this .poolParams.useFastFail;
0218:            }
0219:
0220:            public void setUseFastFail(boolean useFastFail) {
0221:                this .poolParams.useFastFail = useFastFail;
0222:            }
0223:
0224:            public void flush() {
0225:                if (poolingStrategy == null)
0226:                    throw new IllegalStateException(
0227:                            "The connection pool is not started");
0228:
0229:                poolingStrategy.flush();
0230:
0231:                if (poolingStrategy instanceof  PreFillPoolSupport) {
0232:                    final PreFillPoolSupport pfs = (PreFillPoolSupport) poolingStrategy;
0233:
0234:                    if (pfs.shouldPreFill())
0235:                        pfs.prefill(noTxSeparatePools);
0236:
0237:                }
0238:            }
0239:
0240:            public int getConnectionCount() {
0241:                return (poolingStrategy == null) ? 0 : poolingStrategy
0242:                        .getConnectionCount();
0243:            }
0244:
0245:            public int getConnectionCreatedCount() {
0246:                return (poolingStrategy == null) ? 0 : poolingStrategy
0247:                        .getConnectionCreatedCount();
0248:            }
0249:
0250:            public int getConnectionDestroyedCount() {
0251:                return (poolingStrategy == null) ? 0 : poolingStrategy
0252:                        .getConnectionDestroyedCount();
0253:            }
0254:
0255:            public String getName() {
0256:                return "JBossManagedConnectionPool";
0257:            }
0258:
0259:            public String getPoolJndiName() {
0260:                return this .poolJndiName;
0261:            }
0262:
0263:            public void setPoolJndiName(String poolName) {
0264:                this .poolJndiName = poolName;
0265:            }
0266:
0267:            protected void startService() throws Exception {
0268:                ManagedConnectionFactory mcf = null;
0269:                if (managedConnectionFactoryName == null)
0270:                    throw new DeploymentException(
0271:                            "ManagedConnectionFactory not set!");
0272:
0273:                try {
0274:                    //We are getting the actual mcf instance itself.  This will require
0275:                    //some work if the mcf is an xmbean of itself.
0276:                    mcf = (ManagedConnectionFactory) server.getAttribute(
0277:                            managedConnectionFactoryName, "McfInstance");
0278:                } catch (Exception e) {
0279:                    JMXExceptionDecoder.rethrow(e);
0280:                }
0281:                getServer().addNotificationListener(
0282:                        managedConnectionFactoryName, this ,
0283:                        new NotificationFilter() {
0284:                            private static final long serialVersionUID = -9211456539783257343L;
0285:
0286:                            public boolean isNotificationEnabled(Notification n) {
0287:                                return RARDeployment.MCF_ATTRIBUTE_CHANGED_NOTIFICATION
0288:                                        .equals(n.getType())
0289:                                        && managedConnectionFactoryName
0290:                                                .equals(n.getSource());
0291:                            }
0292:                        }, null);
0293:
0294:                if ("ByContainerAndApplication".equals(criteria))
0295:                    poolingStrategy = new PoolBySubjectAndCri(mcf,
0296:                            poolJndiName, poolParams, noTxSeparatePools, log);
0297:                else if ("ByContainer".equals(criteria))
0298:                    poolingStrategy = new PoolBySubject(mcf, poolJndiName,
0299:                            poolParams, noTxSeparatePools, log);
0300:                else if ("ByApplication".equals(criteria))
0301:                    poolingStrategy = new PoolByCri(mcf, poolJndiName,
0302:                            poolParams, noTxSeparatePools, log);
0303:                else if ("ByNothing".equals(criteria))
0304:                    poolingStrategy = new OnePool(mcf, poolJndiName,
0305:                            poolParams, noTxSeparatePools, log);
0306:                else
0307:                    throw new DeploymentException("Unknown pooling criteria: "
0308:                            + criteria);
0309:
0310:            }
0311:
0312:            protected void stopService() throws Exception {
0313:                if (poolingStrategy != null)
0314:                    poolingStrategy.shutdown();
0315:
0316:                getServer().removeNotificationListener(
0317:                        managedConnectionFactoryName, this );
0318:                poolingStrategy = null;
0319:            }
0320:
0321:            public void handleNotification(Notification notification,
0322:                    Object handback) {
0323:                flush();
0324:            }
0325:
0326:            public static class SubPoolContext {
0327:                /** The subpool */
0328:                private InternalManagedConnectionPool subPool;
0329:
0330:                /** The track by transaction transaction local */
0331:                private TransactionLocal trackByTx;
0332:
0333:                /**
0334:                 * Create a new SubPoolContext.
0335:                 * 
0336:                 * @param tm the transaction manager
0337:                 * @param mcf the managed connection factory
0338:                 * @param clf the connection listener factory
0339:                 * @param subject the subject
0340:                 * @param cri the connection request info
0341:                 * @param poolParams the pool parameters
0342:                 * @param log the log
0343:                 */
0344:                public SubPoolContext(TransactionManager tm,
0345:                        ManagedConnectionFactory mcf,
0346:                        ConnectionListenerFactory clf, Subject subject,
0347:                        ConnectionRequestInfo cri, PoolParams poolParams,
0348:                        Logger log) {
0349:                    subPool = new InternalManagedConnectionPool(mcf, clf,
0350:                            subject, cri, poolParams, log);
0351:                    if (tm != null)
0352:                        trackByTx = new TransactionLocal(tm);
0353:                }
0354:
0355:                /**
0356:                 * Get the sub pool
0357:                 * 
0358:                 * @return the sub pool
0359:                 */
0360:                public InternalManagedConnectionPool getSubPool() {
0361:                    return subPool;
0362:                }
0363:
0364:                /**
0365:                 * Get the track by transaction
0366:                 * 
0367:                 * @return the transaction local
0368:                 */
0369:                public TransactionLocal getTrackByTx() {
0370:                    return trackByTx;
0371:                }
0372:
0373:                /**
0374:                 * Initialize the subpool context
0375:                 */
0376:                public void initialize() {
0377:                    subPool.initialize();
0378:                }
0379:            }
0380:
0381:            /**
0382:             * The base pool implementation
0383:             */
0384:            public abstract static class BasePool implements 
0385:                    ManagedConnectionPool, PreFillPoolSupport {
0386:                /** The subpools */
0387:                private final Map subPools = new ConcurrentReaderHashMap();
0388:
0389:                /** The managed connection factory */
0390:                private final ManagedConnectionFactory mcf;
0391:
0392:                /** The connection listener factory */
0393:                private ConnectionListenerFactory clf;
0394:
0395:                /** The pool parameters */
0396:                protected final InternalManagedConnectionPool.PoolParams poolParams;
0397:
0398:                /** Whether to use separate pools for transactional and non-transaction use */
0399:                protected boolean noTxSeparatePools;
0400:
0401:                /** The logger */
0402:                private final Logger log;
0403:
0404:                /** Is trace enabled */
0405:                private boolean traceEnabled = false;
0406:
0407:                /** The poolName */
0408:                private String poolName;
0409:
0410:                public BasePool(
0411:                        final ManagedConnectionFactory mcf,
0412:                        final InternalManagedConnectionPool.PoolParams poolParams,
0413:                        final boolean noTxSeparatePools, final Logger log) {
0414:
0415:                    this (mcf, null, poolParams, noTxSeparatePools, log);
0416:
0417:                }
0418:
0419:                /**
0420:                 * Create a new base pool
0421:                 * 
0422:                 * @param mcf the managed connection factory
0423:                 * @param poolParams the pooling parameters
0424:                 * @param log the log
0425:                 */
0426:                public BasePool(
0427:                        final ManagedConnectionFactory mcf,
0428:                        final String poolName,
0429:                        final InternalManagedConnectionPool.PoolParams poolParams,
0430:                        final boolean noTxSeparatePools, final Logger log) {
0431:                    this .mcf = mcf;
0432:                    this .poolParams = poolParams;
0433:                    this .noTxSeparatePools = noTxSeparatePools;
0434:                    this .log = log;
0435:                    this .traceEnabled = log.isTraceEnabled();
0436:                    this .poolName = poolName;
0437:                }
0438:
0439:                /**
0440:                 * Retrieve the key for this request
0441:                 * 
0442:                 * @param subject the subject 
0443:                 * @param cri the connection request information
0444:                 * @return the key
0445:                 * @throws ResourceException for any error
0446:                 */
0447:                protected abstract Object getKey(Subject subject,
0448:                        ConnectionRequestInfo cri, boolean separateNoTx)
0449:                        throws ResourceException;
0450:
0451:                public ManagedConnectionFactory getManagedConnectionFactory() {
0452:                    return mcf;
0453:                }
0454:
0455:                public void setConnectionListenerFactory(
0456:                        ConnectionListenerFactory clf) {
0457:                    this .clf = clf;
0458:                }
0459:
0460:                public ConnectionListener getConnection(
0461:                        Transaction trackByTransaction, Subject subject,
0462:                        ConnectionRequestInfo cri) throws ResourceException {
0463:                    // Determine the pool key for this request
0464:                    boolean separateNoTx = false;
0465:                    if (noTxSeparatePools)
0466:                        separateNoTx = clf.isTransactional();
0467:                    Object key = getKey(subject, cri, separateNoTx);
0468:                    SubPoolContext subPool = getSubPool(key, subject, cri);
0469:
0470:                    InternalManagedConnectionPool mcp = subPool.getSubPool();
0471:
0472:                    // Are we doing track by connection?
0473:                    TransactionLocal trackByTx = subPool.getTrackByTx();
0474:
0475:                    // Simple case
0476:                    if (trackByTransaction == null || trackByTx == null) {
0477:                        ConnectionListener cl = mcp.getConnection(subject, cri);
0478:                        if (traceEnabled)
0479:                            dump("Got connection from pool " + cl);
0480:                        return cl;
0481:                    }
0482:
0483:                    // Track by transaction
0484:                    try {
0485:                        trackByTx.lock(trackByTransaction);
0486:                    } catch (Throwable t) {
0487:                        JBossResourceException.rethrowAsResourceException(
0488:                                "Unable to get connection from the pool for tx="
0489:                                        + trackByTransaction, t);
0490:                    }
0491:                    try {
0492:                        // Already got one
0493:                        ConnectionListener cl = (ConnectionListener) trackByTx
0494:                                .get(trackByTransaction);
0495:                        if (cl != null) {
0496:                            if (traceEnabled)
0497:                                dump("Previous connection tracked by transaction "
0498:                                        + cl + " tx=" + trackByTransaction);
0499:                            return cl;
0500:                        }
0501:                    } finally {
0502:                        trackByTx.unlock(trackByTransaction);
0503:                    }
0504:
0505:                    // Need a new one for this transaction
0506:                    // This must be done outside the tx local lock, otherwise
0507:                    // the tx timeout won't work and get connection can do a lot of other work
0508:                    // with many opportunities for deadlocks.
0509:                    // Instead we do a double check after we got the transaction to see
0510:                    // whether another thread beat us to the punch.
0511:                    ConnectionListener cl = mcp.getConnection(subject, cri);
0512:                    if (traceEnabled)
0513:                        dump("Got connection from pool tracked by transaction "
0514:                                + cl + " tx=" + trackByTransaction);
0515:
0516:                    // Relock and check/set status
0517:                    try {
0518:                        trackByTx.lock(trackByTransaction);
0519:                    } catch (Throwable t) {
0520:                        mcp.returnConnection(cl, false);
0521:                        if (traceEnabled)
0522:                            dump("Had to return connection tracked by transaction "
0523:                                    + cl
0524:                                    + " tx="
0525:                                    + trackByTransaction
0526:                                    + " error=" + t.getMessage());
0527:                        JBossResourceException.rethrowAsResourceException(
0528:                                "Unable to get connection from the pool for tx="
0529:                                        + trackByTransaction, t);
0530:                    }
0531:                    try {
0532:                        // Check we weren't racing with another transaction
0533:                        ConnectionListener other = (ConnectionListener) trackByTx
0534:                                .get(trackByTransaction);
0535:                        if (other != null) {
0536:                            mcp.returnConnection(cl, false);
0537:                            if (traceEnabled)
0538:                                dump("Another thread already got a connection tracked by transaction "
0539:                                        + other + " tx=" + trackByTransaction);
0540:                            return other;
0541:                        }
0542:
0543:                        // This is the connection for this transaction
0544:                        cl.setTrackByTx(true);
0545:                        trackByTx.set(cl);
0546:                        if (traceEnabled)
0547:                            dump("Using connection from pool tracked by transaction "
0548:                                    + cl + " tx=" + trackByTransaction);
0549:                        return cl;
0550:                    } finally {
0551:                        trackByTx.unlock(trackByTransaction);
0552:                    }
0553:                }
0554:
0555:                public boolean shouldPreFill() {
0556:                    return getPreFill();
0557:                }
0558:
0559:                public void prefill() {
0560:
0561:                    prefill(null, null, false);
0562:
0563:                }
0564:
0565:                public void prefill(boolean noTxSeperatePool) {
0566:
0567:                    prefill(null, null, noTxSeperatePool);
0568:
0569:                }
0570:
0571:                public void prefill(Subject subject, ConnectionRequestInfo cri,
0572:                        boolean noTxSeperatePool) {
0573:                    if (getPreFill()) {
0574:
0575:                        log
0576:                                .debug("Attempting to prefill pool for pool with jndi name"
0577:                                        + poolName);
0578:
0579:                        try {
0580:
0581:                            getSubPool(getKey(subject, cri, noTxSeparatePools),
0582:                                    subject, cri);
0583:
0584:                        } catch (Throwable t) {
0585:                            //No real need to throw here being that pool remains in the same state as before.
0586:                            log.error("Unable to prefill pool with jndi name"
0587:                                    + getPoolName(), t);
0588:
0589:                        }
0590:
0591:                    }
0592:
0593:                }
0594:
0595:                public void returnConnection(ConnectionListener cl, boolean kill)
0596:                        throws ResourceException {
0597:                    cl.setTrackByTx(false);
0598:                    InternalManagedConnectionPool mcp = (InternalManagedConnectionPool) cl
0599:                            .getContext();
0600:                    mcp.returnConnection(cl, kill);
0601:                    if (traceEnabled)
0602:                        dump("Returning connection to pool " + cl);
0603:                }
0604:
0605:                /**
0606:                 * Return the inuse count
0607:                 * 
0608:                 * @return the count
0609:                 */
0610:                public int getInUseConnectionCount() {
0611:                    int count = 0;
0612:                    synchronized (subPools) {
0613:                        for (Iterator i = subPools.values().iterator(); i
0614:                                .hasNext();) {
0615:                            SubPoolContext subPool = (SubPoolContext) i.next();
0616:                            count += subPool.getSubPool()
0617:                                    .getConnectionInUseCount();
0618:                        }
0619:                    }
0620:                    return count;
0621:                }
0622:
0623:                public int getConnectionCount() {
0624:                    int count = 0;
0625:                    synchronized (subPools) {
0626:                        for (Iterator i = subPools.values().iterator(); i
0627:                                .hasNext();) {
0628:                            SubPoolContext subPool = (SubPoolContext) i.next();
0629:                            count += subPool.getSubPool().getConnectionCount();
0630:                        }
0631:                    }
0632:                    return count;
0633:                }
0634:
0635:                public String getPoolName() {
0636:                    return poolName;
0637:                }
0638:
0639:                public boolean getPreFill() {
0640:                    return this .poolParams.prefill;
0641:
0642:                }
0643:
0644:                public int getConnectionCreatedCount() {
0645:                    int count = 0;
0646:                    synchronized (subPools) {
0647:                        for (Iterator i = subPools.values().iterator(); i
0648:                                .hasNext();) {
0649:                            SubPoolContext subPool = (SubPoolContext) i.next();
0650:                            count += subPool.getSubPool()
0651:                                    .getConnectionCreatedCount();
0652:                        }
0653:                    }
0654:                    return count;
0655:                }
0656:
0657:                public int getConnectionDestroyedCount() {
0658:                    int count = 0;
0659:                    synchronized (subPools) {
0660:                        for (Iterator i = subPools.values().iterator(); i
0661:                                .hasNext();) {
0662:                            SubPoolContext subPool = (SubPoolContext) i.next();
0663:                            count += subPool.getSubPool()
0664:                                    .getConnectionDestroyedCount();
0665:                        }
0666:                    }
0667:                    return count;
0668:                }
0669:
0670:                public long getAvailableConnectionCount() {
0671:                    long count = 0;
0672:                    synchronized (subPools) {
0673:                        if (subPools.size() == 0)
0674:                            return poolParams.maxSize;
0675:                        for (Iterator i = subPools.values().iterator(); i
0676:                                .hasNext();) {
0677:                            SubPoolContext subPool = (SubPoolContext) i.next();
0678:                            count += subPool.getSubPool()
0679:                                    .getAvailableConnections();
0680:                        }
0681:                    }
0682:                    return count;
0683:                }
0684:
0685:                public int getMaxConnectionsInUseCount() {
0686:                    int count = 0;
0687:                    synchronized (subPools) {
0688:                        for (Iterator i = subPools.values().iterator(); i
0689:                                .hasNext();) {
0690:                            SubPoolContext subPool = (SubPoolContext) i.next();
0691:                            count += subPool.getSubPool()
0692:                                    .getMaxConnectionsInUseCount();
0693:                        }
0694:                    }
0695:                    return count;
0696:                }
0697:
0698:                public void shutdown() {
0699:                    synchronized (subPools) {
0700:                        for (Iterator i = subPools.values().iterator(); i
0701:                                .hasNext();) {
0702:                            SubPoolContext subPool = (SubPoolContext) i.next();
0703:                            subPool.getSubPool().shutdown();
0704:                        }
0705:                        subPools.clear();
0706:                    }
0707:                }
0708:
0709:                public void flush() {
0710:
0711:                    for (Iterator i = subPools.values().iterator(); i.hasNext();) {
0712:
0713:                        SubPoolContext subPool = (SubPoolContext) i.next();
0714:                        subPool.getSubPool().shutdown();
0715:                    }
0716:                    subPools.clear();
0717:
0718:                }
0719:
0720:                /**
0721:                 * For testing
0722:                 */
0723:                protected void shutdownWithoutClear() {
0724:                    synchronized (subPools) {
0725:                        for (Iterator i = subPools.values().iterator(); i
0726:                                .hasNext();) {
0727:                            SubPoolContext subPool = (SubPoolContext) i.next();
0728:                            subPool.getSubPool().shutdown();
0729:                        }
0730:                    }
0731:                }
0732:
0733:                /**
0734:                 * Get any transaction manager associated with the pool
0735:                 * 
0736:                 * @return the transaction manager
0737:                 */
0738:                protected TransactionManager getTransactionManager() {
0739:                    if (clf != null)
0740:                        return clf.getTransactionManagerInstance();
0741:                    else
0742:                        return null;
0743:                }
0744:
0745:                /**
0746:                 * Determine the correct pool for this request,
0747:                 * creates a new one when necessary
0748:                 * 
0749:                 * @param key the key to the pool
0750:                 * @param subject the subject of the pool
0751:                 * @param cri the connection request info
0752:                 * @return the subpool context
0753:                 * @throws ResourceException for any error
0754:                 */
0755:                protected SubPoolContext getSubPool(Object key,
0756:                        Subject subject, ConnectionRequestInfo cri)
0757:                        throws ResourceException {
0758:                    SubPoolContext subPool = (SubPoolContext) subPools.get(key);
0759:                    if (subPool == null) {
0760:                        TransactionManager tm = getTransactionManager();
0761:                        subPool = new SubPoolContext(tm, mcf, clf, subject,
0762:                                cri, poolParams, log);
0763:                        synchronized (subPools) {
0764:                            if (subPools.containsKey(key))
0765:                                subPool = (SubPoolContext) subPools.get(key);
0766:                            else {
0767:                                subPool.initialize();
0768:                                subPools.put(key, subPool);
0769:                            }
0770:                        }
0771:                    }
0772:                    return subPool;
0773:                }
0774:
0775:                protected SubPoolContext getSubPool(Object key) {
0776:
0777:                    return null;
0778:                }
0779:
0780:                /**
0781:                 * Dump the stats to the trace log
0782:                 * 
0783:                 * @param info some context
0784:                 */
0785:                private void dump(String info) {
0786:                    if (traceEnabled) {
0787:                        StringBuffer toLog = new StringBuffer(100);
0788:                        toLog.append(info).append(" [InUse/Available/Max]: [");
0789:                        toLog.append(this .getInUseConnectionCount())
0790:                                .append("/");
0791:                        toLog.append(this .getAvailableConnectionCount())
0792:                                .append("/");
0793:                        toLog.append(this .poolParams.maxSize);
0794:                        toLog.append("]");
0795:                        ;
0796:                        log.trace(toLog);
0797:                    }
0798:                }
0799:            }
0800:
0801:            /**
0802:             * Pooling by subject and connection request information
0803:             */
0804:            public static class PoolBySubjectAndCri extends BasePool {
0805:
0806:                public PoolBySubjectAndCri(
0807:                        final ManagedConnectionFactory mcf,
0808:                        final InternalManagedConnectionPool.PoolParams poolParams,
0809:                        final boolean noTxSeparatePools, final Logger log) {
0810:                    this (mcf, null, poolParams, noTxSeparatePools, log);
0811:
0812:                }
0813:
0814:                public PoolBySubjectAndCri(
0815:                        final ManagedConnectionFactory mcf,
0816:                        final String poolName,
0817:                        final InternalManagedConnectionPool.PoolParams poolParams,
0818:                        final boolean noTxSeparatePools, final Logger log) {
0819:                    super (mcf, poolName, poolParams, noTxSeparatePools, log);
0820:                }
0821:
0822:                protected Object getKey(final Subject subject,
0823:                        final ConnectionRequestInfo cri,
0824:                        final boolean separateNoTx) throws ResourceException {
0825:                    return new SubjectCriKey(subject, cri, separateNoTx);
0826:                }
0827:
0828:                public void prefill() {
0829:                    prefill(null, null, false);
0830:                }
0831:
0832:                public void prefill(boolean noTxSeperatePool) {
0833:                    prefill(null, null, noTxSeperatePool);
0834:                }
0835:
0836:                public void prefill(Subject subject, ConnectionRequestInfo cri) {
0837:                    prefill(subject, cri, false);
0838:
0839:                }
0840:
0841:                public void prefill(Subject subject, ConnectionRequestInfo cri,
0842:                        boolean noTxSeperatePool) {
0843:                    if (getPreFill()) {
0844:                        log
0845:                                .warn("Prefill pool option was selected for pool with JNDI name "
0846:                                        + getPoolName()
0847:                                        + " that does not support this feature.");
0848:                        log
0849:                                .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false.");
0850:
0851:                    }
0852:                }
0853:
0854:            }
0855:
0856:            /**
0857:             * Pool by subject and criteria
0858:             */
0859:            private static class SubjectCriKey {
0860:                /** Identifies no subject */
0861:                private static final Subject NOSUBJECT = new Subject();
0862:
0863:                /** Identifies no connection request information */
0864:                private static final Object NOCRI = new Object();
0865:
0866:                /** The subject */
0867:                private final Subject subject;
0868:
0869:                /** The connection request information */
0870:                private final Object cri;
0871:
0872:                /** The cached hashCode */
0873:                private int hashCode = Integer.MAX_VALUE;
0874:
0875:                /** Separate no tx */
0876:                private boolean separateNoTx;
0877:
0878:                SubjectCriKey(Subject subject, ConnectionRequestInfo cri,
0879:                        boolean separateNoTx) {
0880:                    this .subject = (subject == null) ? NOSUBJECT : subject;
0881:                    this .cri = (cri == null) ? NOCRI : cri;
0882:                    this .separateNoTx = separateNoTx;
0883:                }
0884:
0885:                public int hashCode() {
0886:                    if (hashCode == Integer.MAX_VALUE)
0887:                        hashCode = SubjectActions.hashCode(subject)
0888:                                ^ cri.hashCode();
0889:                    return hashCode;
0890:                }
0891:
0892:                public boolean equals(Object obj) {
0893:                    if (this  == obj)
0894:                        return true;
0895:                    if (obj == null || (obj instanceof  SubjectCriKey) == false)
0896:                        return false;
0897:                    SubjectCriKey other = (SubjectCriKey) obj;
0898:                    return SubjectActions.equals(subject, other.subject)
0899:                            && cri.equals(other.cri)
0900:                            && separateNoTx == other.separateNoTx;
0901:                }
0902:            }
0903:
0904:            /**
0905:             * Pool by subject
0906:             */
0907:            public static class PoolBySubject extends BasePool {
0908:                public PoolBySubject(
0909:                        final ManagedConnectionFactory mcf,
0910:                        final InternalManagedConnectionPool.PoolParams poolParams,
0911:                        final boolean noTxSeparatePools, final Logger log) {
0912:                    this (mcf, null, poolParams, noTxSeparatePools, log);
0913:                }
0914:
0915:                public PoolBySubject(
0916:                        final ManagedConnectionFactory mcf,
0917:                        final String poolJndiName,
0918:                        final InternalManagedConnectionPool.PoolParams poolParams,
0919:                        final boolean noTxSeparatePools, final Logger log) {
0920:                    super (mcf, poolJndiName, poolParams, noTxSeparatePools, log);
0921:                }
0922:
0923:                protected Object getKey(final Subject subject,
0924:                        final ConnectionRequestInfo cri, boolean separateNoTx) {
0925:                    return new SubjectKey(subject, separateNoTx);
0926:                }
0927:
0928:                public void prefill() {
0929:                    prefill(null, null, false);
0930:                }
0931:
0932:                public void prefill(boolean noTxSeperatePool) {
0933:                    prefill(null, null, noTxSeperatePool);
0934:                }
0935:
0936:                public void prefill(Subject subject, ConnectionRequestInfo cri) {
0937:                    prefill(subject, cri, false);
0938:
0939:                }
0940:
0941:                public void prefill(Subject subject, ConnectionRequestInfo cri,
0942:                        boolean noTxSeperatePool) {
0943:                    if (getPreFill()) {
0944:                        log
0945:                                .warn("Prefill pool option was selected for pool with JNDI name "
0946:                                        + getPoolName()
0947:                                        + " that does not support this feature.");
0948:                        log
0949:                                .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false.");
0950:
0951:                    }
0952:                }
0953:            }
0954:
0955:            /**
0956:             * Pool by subject
0957:             */
0958:            private static class SubjectKey {
0959:                /** Identifies no subject */
0960:                private static final Subject NOSUBJECT = new Subject();
0961:
0962:                /** The subject */
0963:                private final Subject subject;
0964:
0965:                /** Separate no tx */
0966:                private boolean separateNoTx;
0967:
0968:                /** The cached hashCode */
0969:                private int hashCode = Integer.MAX_VALUE;
0970:
0971:                SubjectKey(Subject subject, boolean separateNoTx) {
0972:                    this .subject = (subject == null) ? NOSUBJECT : subject;
0973:                    this .separateNoTx = separateNoTx;
0974:                }
0975:
0976:                public int hashCode() {
0977:                    if (hashCode == Integer.MAX_VALUE)
0978:                        hashCode = SubjectActions.hashCode(subject);
0979:                    return hashCode;
0980:                }
0981:
0982:                public boolean equals(Object obj) {
0983:                    if (this  == obj)
0984:                        return true;
0985:                    if (obj == null || (obj instanceof  SubjectKey) == false)
0986:                        return false;
0987:                    SubjectKey other = (SubjectKey) obj;
0988:                    return SubjectActions.equals(subject, other.subject)
0989:                            && separateNoTx == other.separateNoTx;
0990:                }
0991:
0992:            }
0993:
0994:            /**
0995:             * Pool by connection request information
0996:             */
0997:            public static class PoolByCri extends BasePool {
0998:
0999:                public PoolByCri(
1000:                        final ManagedConnectionFactory mcf,
1001:                        final InternalManagedConnectionPool.PoolParams poolParams,
1002:                        final boolean noTxSeparatePools, final Logger log) {
1003:                    this (mcf, null, poolParams, noTxSeparatePools, log);
1004:                }
1005:
1006:                public PoolByCri(
1007:                        final ManagedConnectionFactory mcf,
1008:                        final String poolJndiName,
1009:                        final InternalManagedConnectionPool.PoolParams poolParams,
1010:                        final boolean noTxSeparatePools, final Logger log) {
1011:                    super (mcf, poolJndiName, poolParams, noTxSeparatePools, log);
1012:                }
1013:
1014:                protected Object getKey(final Subject subject,
1015:                        final ConnectionRequestInfo cri, boolean separateNoTx) {
1016:                    return new CriKey(cri, separateNoTx);
1017:                }
1018:
1019:                public void prefill() {
1020:                    prefill(null, null, false);
1021:                }
1022:
1023:                public void prefill(boolean noTxSeperatePool) {
1024:                    prefill(null, null, noTxSeperatePool);
1025:                }
1026:
1027:                public void prefill(Subject subject, ConnectionRequestInfo cri) {
1028:                    prefill(subject, cri, false);
1029:
1030:                }
1031:
1032:                public void prefill(Subject subject, ConnectionRequestInfo cri,
1033:                        boolean noTxSeperatePool) {
1034:                    if (getPreFill()) {
1035:                        log
1036:                                .warn("Prefill pool option was selected for pool with JNDI name "
1037:                                        + getPoolName()
1038:                                        + " that does not support this feature.");
1039:                        log
1040:                                .warn("Please verify your *-ds.xml file that corresponds with this resource and either remove the <prefill>true|false</prefill element or explicitly set this value to false.");
1041:
1042:                    }
1043:                }
1044:            }
1045:
1046:            /**
1047:             * Pool by subject and criteria
1048:             */
1049:            private static class CriKey {
1050:                /** Identifies no connection request information */
1051:                private static final Object NOCRI = new Object();
1052:
1053:                /** The connection request information */
1054:                private final Object cri;
1055:
1056:                /** Separate no tx */
1057:                private boolean separateNoTx;
1058:
1059:                /** The cached hashCode */
1060:                private int hashCode = Integer.MAX_VALUE;
1061:
1062:                CriKey(ConnectionRequestInfo cri, boolean separateNoTx) {
1063:                    this .cri = (cri == null) ? NOCRI : cri;
1064:                    this .separateNoTx = separateNoTx;
1065:                }
1066:
1067:                public int hashCode() {
1068:                    if (hashCode == Integer.MAX_VALUE)
1069:                        hashCode = cri.hashCode();
1070:                    return hashCode;
1071:                }
1072:
1073:                public boolean equals(Object obj) {
1074:                    if (this  == obj)
1075:                        return true;
1076:                    if (obj == null || (obj instanceof  CriKey) == false)
1077:                        return false;
1078:                    CriKey other = (CriKey) obj;
1079:                    return cri.equals(other.cri)
1080:                            && separateNoTx == other.separateNoTx;
1081:                }
1082:            }
1083:
1084:            /**
1085:             * One pool
1086:             */
1087:            public static class OnePool extends BasePool {
1088:
1089:                public OnePool(
1090:                        final ManagedConnectionFactory mcf,
1091:                        final InternalManagedConnectionPool.PoolParams poolParams,
1092:                        final boolean noTxSeparatePools, final Logger log) {
1093:                    this (mcf, null, poolParams, noTxSeparatePools, log);
1094:                }
1095:
1096:                public OnePool(
1097:                        final ManagedConnectionFactory mcf,
1098:                        final String poolName,
1099:                        final InternalManagedConnectionPool.PoolParams poolParams,
1100:                        final boolean noTxSeparatePools, final Logger log) {
1101:                    super (mcf, poolName, poolParams, noTxSeparatePools, log);
1102:                }
1103:
1104:                protected Object getKey(final Subject subject,
1105:                        final ConnectionRequestInfo cri, boolean separateNoTx) {
1106:                    if (separateNoTx)
1107:                        return Boolean.TRUE;
1108:                    else
1109:                        return Boolean.FALSE;
1110:                }
1111:
1112:            }
1113:
1114:            private static class SubjectActions implements  PrivilegedAction {
1115:                Subject subject;
1116:
1117:                Subject other;
1118:
1119:                SubjectActions(Subject subject, Subject other) {
1120:                    this .subject = subject;
1121:                    this .other = other;
1122:                }
1123:
1124:                public Object run() {
1125:                    Object value = null;
1126:                    if (other == null)
1127:                        value = new Integer(subject.hashCode());
1128:                    else
1129:                        value = new Boolean(subject.equals(other));
1130:                    return value;
1131:                }
1132:
1133:                static int hashCode(Subject subject) {
1134:                    SubjectActions action = new SubjectActions(subject, null);
1135:                    Integer hash = (Integer) AccessController
1136:                            .doPrivileged(action);
1137:                    return hash.intValue();
1138:                }
1139:
1140:                static boolean equals(Subject subject, Subject other) {
1141:                    SubjectActions action = new SubjectActions(subject, other);
1142:                    Boolean equals = (Boolean) AccessController
1143:                            .doPrivileged(action);
1144:                    return equals.booleanValue();
1145:                }
1146:            }
1147:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.