/* * Copyright 2005 Ralf Joachim * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.castor.transactionmanager; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.castor.core.util.AbstractProperties; import org.castor.cpa.CPAProperties; /** * Registry for {@link TransactionManager} instances obtained by their name. * * @author <a href="mailto:ralf DOT joachim AT syscon DOT eu">Ralf Joachim</a> * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $ * @since 1.0 */ public final class TransactionManagerRegistry { //-------------------------------------------------------------------------- /** The <a href="http://jakarta.apache.org/commons/logging/">Jakarta * Commons Logging</a> instance used for all logging. */ private static final Log LOG = LogFactory.getLog(TransactionManagerRegistry.class); /** Registry to get TransactionManagerFactory's from. */ private TransactionManagerFactoryRegistry _registry; /** Shell the TransactionManager be initialized at registration or lazily when * requested for the first time? */ private boolean _initializationAtRegistration; /** Association between TransactionManager name and instance. */ private Map<String, Loader> _managers = new HashMap<String, Loader>(); //-------------------------------------------------------------------------- /** * Loader class for TransactionManager's. */ private class Loader { /** The TransactionManagerFactory to get the TransactionManager from. */ private TransactionManagerFactory _factory; /** The properties passed to the TransactionManager at initialization. */ private Properties _properties; /** The TransactionManager instance. */ private TransactionManager _managerInstance; /** * Construct a loader for a TransactionManager that is requested form the * TransactionManagerFactory with given name and initialized with given * properties. * * @param factoryName The name of the TransactionManagerFactory. * @param properties The properties passed to the TransactionManager. * @throws TransactionManagerAcquireException If TransactoinManagerFactory * with given name could not be found. */ public Loader(final String factoryName, final Properties properties) throws TransactionManagerAcquireException { _factory = _registry.getTransactionManagerFactory(factoryName); _properties = properties; _managerInstance = null; } /** * Construct a dummy loader with the given TransactionManager instance. * * @param managerInstance The TransactionManager instance. */ public Loader(final TransactionManager managerInstance) { _factory = null; _properties = null; _managerInstance = managerInstance; } /** * Get the TransactionManager instance. * * @return The TransactionManager instance. * @throws TransactionManagerAcquireException If any failure occured at * initialization of the TransactionManager. */ public TransactionManager getManagerInstance() throws TransactionManagerAcquireException { initialize(); return _managerInstance; } /** * Initialize the TransactionManager instance. * * @throws TransactionManagerAcquireException If any failure occured at * initialization of the TransactionManager. */ public synchronized void initialize() throws TransactionManagerAcquireException { if (_managerInstance == null) { _managerInstance = _factory.getTransactionManager(_properties); } } } //-------------------------------------------------------------------------- /** * Construct an instance of TransactionManagerRegistry that uses given * LocalConfiguration to get required configuration properties. * * @param properties The properties. */ public TransactionManagerRegistry(final AbstractProperties properties) { _registry = new TransactionManagerFactoryRegistry(properties); _initializationAtRegistration = properties.getBoolean( CPAProperties.TRANSACTION_MANAGER_INIT, false); } //-------------------------------------------------------------------------- /** * Register TransactionManager with given name. The method requires the name * of the TransactionManagerFactory and properties to initialize the manager * to be passed as parameters. Depending on the value of configuration property * <tt>org.castor.jdo.TransactionManagerInitializeAtRegistration</tt> the * manager will be initialized at registration or lazily when requested. * * @param managerName The name of the TransactionManager to register. * @param factoryName The name of the TransactionManagerFactory used to get * the factory from TransactionManagerFactoryRegistry. * @param properties The properties passed to the TransactionManager at * initialization. * @throws TransactionManagerAcquireException If a TransactionManager with the * same name has already been registered or if any failure occured at * initialization of the TransactionManager. */ public void registerTransactionManager(final String managerName, final String factoryName, final Properties properties) throws TransactionManagerAcquireException { Loader loader = new Loader(factoryName, properties); registerTransactionManager(managerName, loader); if (_initializationAtRegistration) { loader.initialize(); } } /** * Register given TransactionManager with given name. * * @param managerName The name of the TransactionManager to register. * @param managerInstance The TransactionManager instance. * @throws TransactionManagerAcquireException If a TransactionManager with the * same name has already been registered. */ public void registerTransactionManager(final String managerName, final TransactionManager managerInstance) throws TransactionManagerAcquireException { Loader loader = new Loader(managerInstance); registerTransactionManager(managerName, loader); } /** * Register TransactionManager with given name. The given loader may hold a * preconfigured TransactionManager instance or only the information required * to acquire one. * * @param managerName The name of the TransactionManager to register. * @param loader The loader for the TransactionManager. * @throws TransactionManagerAcquireException If a TransactionManager with the * same name has already been registered. */ private void registerTransactionManager(final String managerName, final Loader loader) throws TransactionManagerAcquireException { synchronized (_managers) { if (_managers.containsKey(managerName)) { String msg = "A TransactionManager with the name '" + managerName + "' " + "has already been registered."; LOG.error(msg); throw new TransactionManagerAcquireException(msg); } _managers.put(managerName, loader); } } /** * Deregister TransactionManager with given name. * * @param managerName The name of the TransactionManager to deregister. */ public void deregisterTransactionManager(final String managerName) { synchronized (_managers) { _managers.remove(managerName); } } /** * Returns the names of all the registered {@link TransactionManager}'s. * * @return Names of {@link TransactionManager}'s. */ public String[] getTransactionManagerNames() { synchronized (_managers) { String[] names = new String[_managers.size()]; return _managers.keySet().toArray(names); } } /** * Get the TransactionManager with given name. * * @param managerName The name of the TransactionManager to return. * @return The TransactionManager. * @throws TransactionManagerAcquireException If a TransactionManager with name * has not been registered or if any failure occured at initialization * of the TransactionManager. */ public TransactionManager getTransactionManager(final String managerName) throws TransactionManagerAcquireException { Loader loader = null; synchronized (_managers) { loader = _managers.get(managerName); } if (loader == null) { String msg = "A TransactionManager with the name '" + managerName + "' " + "has not been registered."; LOG.error(msg); throw new TransactionManagerAcquireException(msg); } return loader.getManagerInstance(); } //-------------------------------------------------------------------------- }