001    /**
002     * 
003     * Copyright 2005 LogicBlaze, Inc. http://www.logicblaze.com
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * 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     **/
018    package org.jencks.factory;
019    
020    import java.util.Collection;
021    import java.util.Map;
022    
023    import javax.resource.spi.BootstrapContext;
024    import javax.resource.spi.work.WorkManager;
025    import javax.transaction.xa.XAException;
026    
027    import org.apache.geronimo.connector.work.GeronimoWorkManager;
028    import org.apache.geronimo.transaction.ExtendedTransactionManager;
029    import org.apache.geronimo.transaction.context.TransactionContextManager;
030    import org.apache.geronimo.transaction.log.UnrecoverableLog;
031    import org.apache.geronimo.transaction.manager.TransactionLog;
032    import org.apache.geronimo.transaction.manager.TransactionManagerImpl;
033    import org.apache.geronimo.transaction.manager.XidImporter;
034    import org.springframework.beans.factory.FactoryBean;
035    import org.springframework.beans.factory.InitializingBean;
036    import org.springframework.context.ApplicationContext;
037    import org.springframework.context.ApplicationContextAware;
038    
039    /**
040     * A Spring {@link FactoryBean} for creating a {@link BootstrapContext} for the JCA container
041     * with the {@link WorkManager} and {@link ExtendedTransactionManager}.
042     *
043     * @version $Revision: 1.5 $
044     */
045    public class WorkManagerFactoryBean implements FactoryBean, InitializingBean, ApplicationContextAware {
046    
047            private ApplicationContext applicationContext;
048        private GeronimoWorkManager workManager;
049        private TransactionContextManager transactionContextManager;
050        private int threadPoolSize = 30;
051        private ExtendedTransactionManager transactionManager;
052        private XidImporter xidImporter;
053        private int defaultTransactionTimeoutSeconds = 600;
054        private TransactionLog transactionLog;
055        private Collection resourceManagers;
056    
057        public Object getObject() throws Exception {
058            return workManager;
059        }
060    
061        public Class getObjectType() {
062            return WorkManager.class;
063        }
064    
065        public boolean isSingleton() {
066            return true;
067        }
068        
069        public void setApplicationContext(ApplicationContext applicationContext) {
070            this.applicationContext = applicationContext;
071        }
072    
073        public void afterPropertiesSet() throws Exception {
074            workManager = createWorkManager();
075            workManager.doStart();
076        }
077    
078        public GeronimoWorkManager getWorkManager() throws Exception {
079            if (workManager == null) {
080                afterPropertiesSet();
081            }
082            return workManager;
083        }
084    
085        public TransactionContextManager getTransactionContextManager() throws XAException {
086                    if (transactionContextManager == null && applicationContext != null) {
087                            Map map = applicationContext.getBeansOfType(TransactionContextManager.class);
088                            if (map.size() > 1) {
089                                    throw new IllegalStateException("only one TransactionContextManager can be registered");
090                            } else if (map.size() == 1) {
091                                    transactionContextManager = (TransactionContextManager) map.values().iterator().next();
092                            }
093                    }
094                    if (transactionContextManager == null) {
095                transactionContextManager = createTransactionContextManager();
096                    }
097            return transactionContextManager;
098        }
099    
100        public void setTransactionContextManager(TransactionContextManager transactionContextManager) {
101            this.transactionContextManager = transactionContextManager;
102        }
103    
104        public int getThreadPoolSize() {
105            return threadPoolSize;
106        }
107    
108        public void setThreadPoolSize(int threadPoolSize) {
109            this.threadPoolSize = threadPoolSize;
110        }
111    
112        public ExtendedTransactionManager getTransactionManager() throws XAException {
113                    if (transactionManager == null && applicationContext != null) {
114                            Map map = applicationContext.getBeansOfType(ExtendedTransactionManager.class);
115                            if (map.size() > 1) {
116                                    throw new IllegalStateException("only one ExtendedTransactionManager can be registered");
117                            } else if (map.size() == 1) {
118                                    transactionManager = (ExtendedTransactionManager) map.values().iterator().next();
119                            }
120                    }
121                    if (transactionManager == null) {
122                transactionManager = new TransactionManagerImpl(getDefaultTransactionTimeoutSeconds(), getTransactionLog(), getResourceManagers());
123                    }
124            return transactionManager;
125        }
126    
127        public void setTransactionManager(ExtendedTransactionManager transactionManager) {
128            this.transactionManager = transactionManager;
129        }
130    
131        public XidImporter getXidImporter() {
132            if (xidImporter == null && transactionManager instanceof XidImporter) {
133                xidImporter = (XidImporter) transactionManager;
134            }
135            return xidImporter;
136        }
137    
138        public void setXidImporter(XidImporter xidImporter) {
139            this.xidImporter = xidImporter;
140        }
141    
142        public int getDefaultTransactionTimeoutSeconds() {
143            return defaultTransactionTimeoutSeconds;
144        }
145    
146        public void setDefaultTransactionTimeoutSeconds(int defaultTransactionTimeoutSeconds) {
147            this.defaultTransactionTimeoutSeconds = defaultTransactionTimeoutSeconds;
148        }
149    
150        public TransactionLog getTransactionLog() {
151            if (transactionLog == null) {
152                transactionLog = new UnrecoverableLog();
153            }
154            return transactionLog;
155        }
156    
157        public void setTransactionLog(TransactionLog transactionLog) {
158            this.transactionLog = transactionLog;
159        }
160    
161        public Collection getResourceManagers() {
162            return resourceManagers;
163        }
164    
165        public void setResourceManagers(Collection resourceManagers) {
166            this.resourceManagers = resourceManagers;
167        }
168    
169        // Implementation methods
170        //-------------------------------------------------------------------------
171        protected TransactionContextManager createTransactionContextManager() throws XAException {
172            return new TransactionContextManager(getTransactionManager(), getXidImporter());
173        }
174    
175        protected GeronimoWorkManager createWorkManager() throws XAException {
176            return new GeronimoWorkManager(getThreadPoolSize(), getTransactionContextManager());
177        }
178    }