001    /*
002     * Copyright 2002-2005 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jencks.factory;
018    
019    import java.util.Map;
020    
021    import javax.resource.spi.ConnectionManager;
022    
023    import org.apache.geronimo.connector.outbound.GenericConnectionManager;
024    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.NoPool;
025    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.NoTransactions;
026    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
027    import org.apache.geronimo.connector.outbound.connectionmanagerconfig.TransactionSupport;
028    import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTracker;
029    import org.apache.geronimo.transaction.context.TransactionContextManager;
030    import org.springframework.beans.factory.FactoryBean;
031    import org.springframework.beans.factory.InitializingBean;
032    import org.springframework.context.ApplicationContext;
033    import org.springframework.context.ApplicationContextAware;
034    
035    /**
036     * This FactoryBean creates a local JCA connection factory outside
037     * a J2EE application server.
038     * <p/>
039     * The connection manager will be then injected in the
040     * LocalConnectionFactoryBean, class of the JCA support of Spring.
041     *
042     * @author Thierry Templier
043     * @see org.springframework.jca.support.LocalConnectionFactoryBean#setConnectionManager(ConnectionManager)
044     * @see NoTransactionFactoryBean
045     * @see LocalTransactionFactoryBean
046     * @see XATransactionFactoryBean
047     * @see PartitionedPoolFactoryBean
048     * @see SinglePoolFactoryBean
049     */
050    public class ConnectionManagerFactoryBean implements FactoryBean, InitializingBean, ApplicationContextAware {
051    
052            private ApplicationContext applicationContext;
053        private TransactionSupport transactionSupport;
054        private PoolingSupport poolingSupport;
055        private boolean containerManagedSecurity;
056        private TransactionContextManager transactionContextManager;
057        private ConnectionTracker connectionTracker;
058        private ConnectionManager connectionManager;
059    
060        public Object getObject() throws Exception {
061            if (connectionManager == null) {
062                    // Instanciate the Geronimo Connection Manager
063                    this.connectionManager = new GenericConnectionManager(
064                                    this.transactionSupport, 
065                                    this.poolingSupport,
066                            this.containerManagedSecurity, 
067                            getConnectionTracker(), 
068                            getTransactionContextManager(),
069                            getClass().getName(), 
070                            getClass().getClassLoader());
071            }
072            return connectionManager;
073        }
074    
075        public Class getObjectType() {
076            return ConnectionManager.class;
077        }
078    
079        public boolean isSingleton() {
080            return true;
081        }
082    
083            public void setApplicationContext(ApplicationContext applicationContext) {
084                    this.applicationContext = applicationContext;
085            }
086    
087        /**
088         * Set the pooling support for the Geronimo Connection Manager.
089         * Geronimo provides two kinds of pool: single and partitioned.
090         *
091         * @see org.apache.geronimo.connector.outbound.connectionmanagerconfig.SinglePool
092         * @see org.apache.geronimo.connector.outbound.connectionmanagerconfig.PartitionedPool
093         */
094        public void setPoolingSupport(PoolingSupport support) {
095            poolingSupport = support;
096        }
097    
098        /**
099         * Set the transaction context manager for the Geronimo Connection Manager.
100         */
101        public void setTransactionContextManager(TransactionContextManager manager) {
102            transactionContextManager = manager;
103        }
104    
105        /**
106         * Set the transaction support for the Geronimo Connection Manager.
107         * Geronimo provides in this case three kinds of support like the
108         * JCA specification: no transaction, local transactions, XA transactions.
109         *
110         * @see NoTransactions
111         * @see org.apache.geronimo.connector.outbound.connectionmanagerconfig.LocalTransactions
112         * @see org.apache.geronimo.connector.outbound.connectionmanagerconfig.XATransactions
113         */
114        public void setTransactionSupport(TransactionSupport support) {
115            transactionSupport = support;
116        }
117    
118        /**
119         * Set the connection tracker for the Geronimo Connection Manager.
120         */
121        public void setConnectionTracker(ConnectionTracker tracker) {
122            connectionTracker = tracker;
123        }
124    
125        /**
126         * Enables/disables container managed security
127         */
128        public void setContainerManagedSecurity(boolean containerManagedSecurity) {
129            this.containerManagedSecurity = containerManagedSecurity;
130        }
131    
132        /**
133         * This method checks all the needed parameters to construct
134         * the Geronimo connection manager which is implemented by the
135         * GenericConnectionManager class.
136         * If the transaction support property is not set, the method
137         * configures the connection manager with the no transaction value.
138         * If the pooling support property is not set, the method
139         * configures the connection manager with the no pool value.
140         * If the realm bridge is not set, the method configure
141         * the connection manager with an identity realm bridge.
142         *
143         * @see GenericConnectionManager
144         */
145        public void afterPropertiesSet() throws Exception {
146            // Apply the default value for property if necessary
147            if (this.transactionSupport == null) {
148                // No transaction
149                this.transactionSupport = NoTransactions.INSTANCE;
150            }
151            if (this.poolingSupport == null) {
152                // No pool
153                this.poolingSupport = new NoPool();
154            }
155        }
156    
157            public ConnectionTracker getConnectionTracker() {
158                    if (connectionTracker == null && applicationContext != null) {
159                            Map map = applicationContext.getBeansOfType(ConnectionTracker.class);
160                            if (map.size() == 1) {
161                                    connectionTracker = (ConnectionTracker) map.values().iterator().next();
162                            }
163                    }
164                    return connectionTracker;
165            }
166    
167            public TransactionContextManager getTransactionContextManager() {
168                    if (transactionContextManager == null) {
169                            if (applicationContext != null) {
170                                    Map map = applicationContext.getBeansOfType(TransactionContextManager.class);
171                                    if (map.size() == 1) {
172                                            transactionContextManager = (TransactionContextManager) map.values().iterator().next();
173                                    } else {
174                                            throw new IllegalStateException("no TransactionContextManager is registered");
175                                    }
176                            } else {
177                                    throw new IllegalStateException("no TransactionContextManager is set");
178                            }
179                    }
180                    return transactionContextManager;
181            }
182    
183    }