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 */
017package org.apache.activemq.pool;
018
019import javax.annotation.PostConstruct;
020import javax.annotation.PreDestroy;
021import javax.jms.ConnectionFactory;
022import javax.transaction.TransactionManager;
023
024import org.slf4j.Logger;
025import org.slf4j.LoggerFactory;
026import org.apache.commons.pool.ObjectPoolFactory;
027import org.springframework.beans.factory.FactoryBean;
028
029/**
030 * Simple factory bean used to create a jencks connection pool.
031 * Depending on the properties set, it will create a simple pool,
032 * a transaction aware connection pool, or a jca aware connection pool.
033 *
034 * <pre class="code">
035 * <bean id="pooledConnectionFactory" class="javax.script.ScriptEngineFactory.PooledConnectionFactoryFactoryBean">
036 *   <property name="connectionFactory" ref="connectionFactory" />
037 *   <property name="transactionManager" ref="transactionManager" />
038 *   <property name="resourceName" value="ResourceName" />
039 * </bean>
040 * </pre>
041 *
042 * The <code>resourceName</code> property should be used along with the {@link ActiveMQResourceManager} and have
043 * the same value than its <code>resourceName</code> property. This will make sure the transaction manager
044 * maps correctly the connection factory to the recovery process.
045 *
046 * @org.apache.xbean.XBean
047 */
048public class PooledConnectionFactoryBean implements FactoryBean {
049
050    private static final Logger LOGGER = LoggerFactory.getLogger(PooledConnectionFactoryBean.class);
051
052    private PooledConnectionFactory pooledConnectionFactory;
053    private ConnectionFactory connectionFactory;
054    private int maxConnections = 1;
055    private int maximumActive = 500;
056    private Object transactionManager;
057    private String resourceName;
058    private ObjectPoolFactory poolFactory;
059
060    public int getMaxConnections() {
061        return maxConnections;
062    }
063
064    public void setMaxConnections(int maxConnections) {
065        this.maxConnections = maxConnections;
066    }
067
068    public int getMaximumActive() {
069        return maximumActive;
070    }
071
072    public void setMaximumActive(int maximumActive) {
073        this.maximumActive = maximumActive;
074    }
075
076    public Object getTransactionManager() {
077        return transactionManager;
078    }
079
080    public void setTransactionManager(Object transactionManager) {
081        this.transactionManager = transactionManager;
082    }
083
084    public String getResourceName() {
085        return resourceName;
086    }
087
088    public void setResourceName(String resourceName) {
089        this.resourceName = resourceName;
090    }
091
092    public ConnectionFactory getConnectionFactory() {
093        return connectionFactory;
094    }
095
096    public void setConnectionFactory(ConnectionFactory connectionFactory) {
097        this.connectionFactory = connectionFactory;
098    }
099
100    public ObjectPoolFactory getPoolFactory() {
101        return poolFactory;
102    }
103
104    public void setPoolFactory(ObjectPoolFactory poolFactory) {
105        this.poolFactory = poolFactory;
106    }
107
108    /**
109     *
110     * @throws Exception
111     * @org.apache.xbean.InitMethod
112     */
113    @PostConstruct
114    public void afterPropertiesSet() throws Exception {
115        /*if (pooledConnectionFactory == null && transactionManager != null && resourceName != null) {
116            try {
117                LOGGER.debug("Trying to build a JcaPooledConnectionFactory");
118                JcaPooledConnectionFactory f = new JcaPooledConnectionFactory();
119                f.setName(resourceName);
120                f.setTransactionManager((TransactionManager) transactionManager);
121                f.setMaxConnections(maxConnections);
122                f.setMaximumActive(maximumActive);
123                f.setConnectionFactory(connectionFactory);
124                f.setPoolFactory(poolFactory);
125                this.pooledConnectionFactory = f;
126            } catch (Throwable t) {
127                LOGGER.debug("Could not create JCA enabled connection factory: " + t, t);
128            }
129        }*/
130        if (pooledConnectionFactory == null && transactionManager != null) {
131            try {
132                LOGGER.debug("Trying to build a XaPooledConnectionFactory");
133                XaPooledConnectionFactory f = new XaPooledConnectionFactory();
134                f.setTransactionManager((TransactionManager) transactionManager);
135                f.setMaxConnections(maxConnections);
136                f.setMaximumActive(maximumActive);
137                f.setConnectionFactory(connectionFactory);
138                f.setPoolFactory(poolFactory);
139                this.pooledConnectionFactory = f;
140            } catch (Throwable t) {
141                LOGGER.debug("Could not create XA enabled connection factory: " + t, t);
142            }
143        }
144        if (pooledConnectionFactory == null) {
145            try {
146                LOGGER.debug("Trying to build a PooledConnectionFactory");
147                PooledConnectionFactory f = new PooledConnectionFactory();
148                f.setMaxConnections(maxConnections);
149                f.setMaximumActive(maximumActive);
150                f.setConnectionFactory(connectionFactory);
151                f.setPoolFactory(poolFactory);
152                this.pooledConnectionFactory = f;
153            } catch (Throwable t) {
154                LOGGER.debug("Could not create pooled connection factory: " + t, t);
155            }
156        }
157        if (pooledConnectionFactory == null) {
158            throw new IllegalStateException("Unable to create pooled connection factory.  Enable DEBUG log level for more informations");
159        }
160    }
161
162    /**
163     *
164     * @throws Exception
165     * @org.apache.xbean.DestroyMethod
166     */
167    @PreDestroy
168    public void destroy() throws Exception {
169        if (pooledConnectionFactory != null) {
170            pooledConnectionFactory.stop();
171            pooledConnectionFactory = null;
172        }
173    }
174
175    // FactoryBean methods
176    public Object getObject() throws Exception {
177        return pooledConnectionFactory;
178    }
179
180    public Class getObjectType() {
181        return ConnectionFactory.class;
182    }
183
184    public boolean isSingleton() {
185        return true;
186    }
187}