001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.pool;
018    
019    import javax.annotation.PostConstruct;
020    import javax.annotation.PreDestroy;
021    import javax.jms.ConnectionFactory;
022    import javax.transaction.TransactionManager;
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    import org.apache.commons.pool.ObjectPoolFactory;
026    
027    /**
028     * Simple factory bean used to create a jencks connection pool.
029     * Depending on the properties set, it will create a simple pool,
030     * a transaction aware connection pool, or a jca aware connection pool.
031     *
032     * <pre class="code">
033     * <bean id="pooledConnectionFactory" class="javax.script.ScriptEngineFactory.PooledConnectionFactoryFactoryBean">
034     *   <property name="connectionFactory" ref="connectionFactory" />
035     *   <property name="transactionManager" ref="transactionManager" />
036     *   <property name="resourceName" value="ResourceName" />
037     * </bean>
038     * </pre>
039     *
040     * The <code>resourceName</code> property should be used along with the {@link ActiveMQResourceManager} and have
041     * the same value than its <code>resourceName</code> property. This will make sure the transaction manager
042     * maps correctly the connection factory to the recovery process.
043     *
044     * @org.apache.xbean.XBean
045     */
046    public class PooledConnectionFactoryBean {
047    
048        private static final Log LOGGER = LogFactory.getLog(PooledConnectionFactoryBean.class);
049    
050        private PooledConnectionFactory pooledConnectionFactory;
051        private ConnectionFactory connectionFactory;
052        private int maxConnections = 1;
053        private int maximumActive = 500;
054        private Object transactionManager;
055        private String resourceName;
056        private ObjectPoolFactory poolFactory;
057    
058        public int getMaxConnections() {
059            return maxConnections;
060        }
061    
062        public void setMaxConnections(int maxConnections) {
063            this.maxConnections = maxConnections;
064        }
065    
066        public int getMaximumActive() {
067            return maximumActive;
068        }
069    
070        public void setMaximumActive(int maximumActive) {
071            this.maximumActive = maximumActive;
072        }
073    
074        public Object getTransactionManager() {
075            return transactionManager;
076        }
077    
078        public void setTransactionManager(Object transactionManager) {
079            this.transactionManager = transactionManager;
080        }
081    
082        public String getResourceName() {
083            return resourceName;
084        }
085    
086        public void setResourceName(String resourceName) {
087            this.resourceName = resourceName;
088        }
089    
090        public ConnectionFactory getConnectionFactory() {
091            return connectionFactory;
092        }
093    
094        public void setConnectionFactory(ConnectionFactory connectionFactory) {
095            this.connectionFactory = connectionFactory;
096        }
097    
098        public ObjectPoolFactory getPoolFactory() {
099            return poolFactory;
100        }
101    
102        public void setPoolFactory(ObjectPoolFactory poolFactory) {
103            this.poolFactory = poolFactory;
104        }
105    
106        /**
107         *
108         * @throws Exception
109         * @org.apache.xbean.InitMethod
110         */
111        @PostConstruct
112        public void afterPropertiesSet() throws Exception {
113            if (pooledConnectionFactory == null && transactionManager != null && resourceName != null) {
114                try {
115                    LOGGER.debug("Trying to build a JcaPooledConnectionFactory");
116                    JcaPooledConnectionFactory f = new JcaPooledConnectionFactory();
117                    f.setName(resourceName);
118                    f.setTransactionManager((TransactionManager) transactionManager);
119                    f.setMaxConnections(maxConnections);
120                    f.setMaximumActive(maximumActive);
121                    f.setConnectionFactory(connectionFactory);
122                    f.setPoolFactory(poolFactory);
123                    this.pooledConnectionFactory = f;
124                } catch (Throwable t) {
125                    LOGGER.debug("Could not create JCA enabled connection factory: " + t, t);
126                }
127            }
128            if (pooledConnectionFactory == null && transactionManager != null) {
129                try {
130                    LOGGER.debug("Trying to build a XaPooledConnectionFactory");
131                    XaPooledConnectionFactory f = new XaPooledConnectionFactory();
132                    f.setTransactionManager((TransactionManager) transactionManager);
133                    f.setMaxConnections(maxConnections);
134                    f.setMaximumActive(maximumActive);
135                    f.setConnectionFactory(connectionFactory);
136                    f.setPoolFactory(poolFactory);
137                    this.pooledConnectionFactory = f;
138                } catch (Throwable t) {
139                    LOGGER.debug("Could not create XA enabled connection factory: " + t, t);
140                }
141            }
142            if (pooledConnectionFactory == null) {
143                try {
144                    LOGGER.debug("Trying to build a PooledConnectionFactory");
145                    PooledConnectionFactory f = new PooledConnectionFactory();
146                    f.setMaxConnections(maxConnections);
147                    f.setMaximumActive(maximumActive);
148                    f.setConnectionFactory(connectionFactory);
149                    f.setPoolFactory(poolFactory);
150                    this.pooledConnectionFactory = f;
151                } catch (Throwable t) {
152                    LOGGER.debug("Could not create pooled connection factory: " + t, t);
153                }
154            }
155            if (pooledConnectionFactory == null) {
156                throw new IllegalStateException("Unable to create pooled connection factory.  Enable DEBUG log level for more informations");
157            }
158        }
159    
160        /**
161         *
162         * @throws Exception
163         * @org.apache.xbean.DestroyMethod
164         */
165        @PreDestroy
166        public void destroy() throws Exception {
167            if (pooledConnectionFactory != null) {
168                pooledConnectionFactory.stop();
169                pooledConnectionFactory = null;
170            }
171        }
172    }