Package com.atomikos.icatch.system

Source Code of com.atomikos.icatch.system.Configuration

/**
* Copyright (C) 2000-2012 Atomikos <info@atomikos.com>
*
* This code ("Atomikos TransactionsEssentials"), by itself,
* is being distributed under the
* Apache License, Version 2.0 ("License"), a copy of which may be found at
* http://www.atomikos.com/licenses/apache-license-2.0.txt .
* You may not use this file except in compliance with the License.
*
* While the License grants certain patent license rights,
* those patent license rights only extend to the use of
* Atomikos TransactionsEssentials by itself.
*
* This code (Atomikos TransactionsEssentials) contains certain interfaces
* in package (namespace) com.atomikos.icatch
* (including com.atomikos.icatch.Participant) which, if implemented, may
* infringe one or more patents held by Atomikos.
* It should be appreciated that you may NOT implement such interfaces;
* licensing to implement these interfaces must be obtained separately from Atomikos.
*
* 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.
*/


package com.atomikos.icatch.system;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Vector;

import com.atomikos.datasource.RecoverableResource;
import com.atomikos.icatch.CompositeTransactionManager;
import com.atomikos.icatch.ExportingTransactionManager;
import com.atomikos.icatch.ImportingTransactionManager;
import com.atomikos.icatch.RecoveryService;
import com.atomikos.icatch.TSListener;
import com.atomikos.icatch.TransactionService;
import com.atomikos.icatch.admin.LogAdministrator;
import com.atomikos.icatch.admin.LogControl;
import com.atomikos.logging.Logger;
import com.atomikos.logging.LoggerFactory;

/**
* Configuration is a facade for the icatch transaction management facilities.
* Allows the application server code to find the transaction manager, even if
* the actual implementation varies over time.
*/

@SuppressWarnings("all")
public final class Configuration
{
  private static final Logger LOGGER = LoggerFactory.createLogger(Configuration.class);


    private static CompositeTransactionManager ctxmgr_ = null;
    // the tm for the virtual machine instance

    private static ImportingTransactionManager imptxmgr_ = null;
    private static ExportingTransactionManager exptxmgr_ = null;

    private static Hashtable resources_ = new Hashtable ();
    // filled on startup, contains all resources managed by the
    // transaction manager.

    private static Vector resourceList_ = new Vector ();
    // keep resources in a list, to enable ordered search of XAResource
    // this way, an AcceptAllXATransactionalResource can be added at the end

    private static Vector logAdministrators_ = new Vector ();
    // the registered log administrators

    private static LogControl logControl_;
    // the log control for administrators

    private static RecoveryService recoveryService_;
    // needed for addResource to do recovery

    private static TransactionService service_;
    // the transaction service for this VM.

    private static Vector tsListenersList_ = new Vector ();

    private static List shutdownHooks_ = new ArrayList();


  private static void purgeResources ()
    {
        Enumeration enumm = getResources ();
        while ( enumm.hasMoreElements () ) {
            RecoverableResource res = (RecoverableResource) enumm.nextElement ();
            if ( res.isClosed () )
                removeResource ( res.getName () );
        }
    }

    /**
     * Construction not allowed.
     *
     */
    private Configuration ()
    {
    }

    /**
     * Installs the transaction service in use.
     *
     * @param service
     *            The service.
     */

    public static synchronized void installTransactionService (
            TransactionService service )
    {
        service_ = service;
        addAllTSListenerServicesFromClasspath();
        Iterator it = tsListenersList_.iterator ();
        while ( it.hasNext () && service != null ) {
            TSListener l = (TSListener) it.next ();
            service_.addTSListener ( l );
        }
    }

    private static void addAllTSListenerServicesFromClasspath() {
    ServiceLoader<TSListener> loader = ServiceLoader.load(TSListener.class);
    for (TSListener l : loader ) {
      addTSListener(l);
    }
  }

  /**
     * Adds a shutdown hook to the configuration.
     * Shutdown hooks are managed here, since regular shutdown
     * of the transaction core should remove hooks
     * (cf case 21519).
     *
     * @param hook
     */
    public static synchronized void addShutdownHook ( Thread hook )
    {
      if ( shutdownHooks_.contains ( hook ) ) return;

      shutdownHooks_.add ( hook );
      try {
        Runtime.getRuntime().addShutdownHook ( hook );
      }
      catch ( IllegalStateException alreadyShuttingDownVm ) {
      //ignore: this happens when the VM exits and this method
      //is called as part of one of the shutdown hooks executing
    }
    }

    /**
     * Removes all shutdown hooks from the system.
     * This method should be called on shutdown of the core.
     */

    public static synchronized void removeShutdownHooks()
    {
      Iterator it = shutdownHooks_.iterator();

      //first check if we are not already doing a VM exit;
      //don't remove the hooks if so
      boolean vmShutdown = false;
      while ( it.hasNext() ) {
        Thread t = ( Thread ) it.next();
        if ( t.equals ( Thread.currentThread() ) ) vmShutdown = true;
      }

      it = shutdownHooks_.iterator();
      while ( !vmShutdown && it.hasNext() ) {
        Thread hook = ( Thread ) it.next();
        it.remove();
        try {
          Runtime.getRuntime().removeShutdownHook ( hook );
        }
        catch ( IllegalStateException alreadyShuttingDownVm ) {
          //ignore: this happens when the VM exits and this method
          //is called as part of one of the shutdown hooks executing
        }
      }
    }

    /**
     * Retrieves the transaction service being used.
     *
     * @return TransactionService The transaction service.
     */

    public static TransactionService getTransactionService ()
    {
        return service_;
    }

    /**
     * Add a transaction service listener.
     *
     * @param l
     *            The listener.
     */
    public synchronized static void addTSListener ( TSListener l )
    {

        if ( service_ != null ) {
            service_.addTSListener ( l );
        }
        tsListenersList_.add ( l );
    }

    /**
     * Remove a transaction service listener.
     *
     * @param l
     *            The listener.
     */
    public synchronized static void removeTSListener ( TSListener l )
    {
        if ( service_ != null ) {
            service_.removeTSListener ( l );
        }
        tsListenersList_.remove ( l );
    }

    /**
     * Installs a composite transaction manager as a Singleton.
     *
     * @param compositeTransactionManager
     *            The instance to install.
     */

    public static synchronized void installCompositeTransactionManager (
            CompositeTransactionManager compositeTransactionManager )
    {

        ctxmgr_ = compositeTransactionManager;
    }

    /**
     * Installs a recovery service as a Singleton.
     *
     * @param service
     *            The recovery service.
     */

    public static synchronized void installRecoveryService (
            RecoveryService service )
    {
        recoveryService_ = service;
        if ( service != null ) {
            // notify all currently registered resources
            Enumeration resources = getResources ();
            while ( resources.hasMoreElements () ) {
                RecoverableResource next = (RecoverableResource) resources
                        .nextElement ();
                next.setRecoveryService ( service );

            }

        }
    }

    /**
     * Installs the log control interface to use.
     *
     * @param control
     */

    public static synchronized void installLogControl ( LogControl control )
    {

        logControl_ = control;
        if ( logControl_ != null ) {
            Enumeration enumm = getLogAdministrators ();
            while ( enumm.hasMoreElements () ) {
                LogAdministrator admin = (LogAdministrator) enumm.nextElement ();
                admin.registerLogControl ( control );
            }
        }
    }

    /**
     * Installs an importing transaction manager as a Singleton.
     *
     * @param importingTransactionManager
     *            The instance to install.
     */

    public static synchronized void installImportingTransactionManager (
            ImportingTransactionManager importingTransactionManager )
    {

        imptxmgr_ = importingTransactionManager;
    }

    /**
     * Installs an exporting transaction manager as a Singleton.
     *
     * @param exportingTransactionManager
     *            The instance to install.
     */

    public static synchronized void installExportingTransactionManager (
            ExportingTransactionManager exportingTransactionManager )
    {

        exptxmgr_ = exportingTransactionManager;
    }

    /**
     * Get the composite transaction manager.
     *
     * @return CompositeTransactionManager The instance, or null if none.
     */

    public static CompositeTransactionManager getCompositeTransactionManager ()
    {
        return ctxmgr_;
    }

    /**
     * Get the importing transaction manager.
     *
     * @return ImportingTransactionManager The instance, or null if none.
     */

    public static ImportingTransactionManager getImportingTransactionManager ()
    {
        return imptxmgr_;
    }

    /**
     * Get the exporting transaction manager.
     *
     * @return ExportingTransactionManager The instance, or null if none.
     */

    public static ExportingTransactionManager getExportingTransactionManager ()
    {
        return exptxmgr_;
    }

    /**
     * Add a resource to the transaction manager domain. Should be called for
     * all resources that have to be recovered, BEFORE initializing the
     * transaction manager! The purpose of registering resources is mainly to be
     * able the recovery the ResourceTransaction context for each prepared
     * ResourceTransction. This is needed for those ResourceTransaction
     * instances that do not encapsulate the full state themselves, as in the
     * XAResource case.
     *
     * @param resource
     *            The resource to add.
     *
     * @exception IllegalStateException
     *                If the name of the resource is already in use.
     */

    public static synchronized void addResource ( RecoverableResource resource )
            throws IllegalStateException
    {
        // ADDED with new recovery: temporary resources:
        // memory overflow can only happen upon addition of resources
        // so before each add, first purge closed resources to make room
        purgeResources ();
        int numResources = resources_.size ();
        if ( numResources > 100 ) {
          LOGGER.logWarning ( numResources
                    + " RESOURCES IN CONFIGURATION -- "
                    + "SOME XARESOURCE IMPLEMENTATIONS MAY NOT CORRECTLY IMPLEMENT isSameRM()!" );
          LOGGER.logWarning ( "TO SAVE MEMORY, USE EXPLICIT RESOURCE REGISTRATION MODE." );
        }

        if ( resources_.containsKey ( resource.getName () ) )
            throw new IllegalStateException ( "Attempt to register second "
                    + "resource with name " + resource.getName () );

        LOGGER.logDebug ( "Configuration: adding resource " + resource.getName () );

        resources_.put ( resource.getName (), resource );
        resourceList_.add ( resource );
        resource.setRecoveryService ( recoveryService_ );

        LOGGER.logDebug ( "Configuration: added resource " + resource.getName () );
    }

    /**
     * Add a log administrator.
     *
     * @param admin
     */
    public static synchronized void addLogAdministrator ( LogAdministrator admin )
    {
      if ( logAdministrators_.contains ( admin ) ) return;

        logAdministrators_.add ( admin );
        if ( logControl_ != null ) {
            admin.registerLogControl ( logControl_ );
        }
    }

    /**
     * Remove a log administrator.
     *
     * @param admin
     */
    public static void removeLogAdministrator ( LogAdministrator admin )
    {
        logAdministrators_.remove ( admin );
        if ( logControl_ != null )
            admin.deregisterLogControl ( logControl_ );
    }

    /**
     * Get all registered logadministrators.
     *
     * @return Enumeration The logadministrators.
     */
    public static Enumeration getLogAdministrators ()
    {
        Vector v = (Vector) logAdministrators_.clone ();
        return v.elements ();
    }

    /**
     * Removes a resource from the config.
     *
     * @param name
     *            The resource's name.
     * @return RecoverableResource The removed object.
     */

    public static RecoverableResource removeResource ( String name )
    {
        RecoverableResource ret = null;
        if ( name != null ) {
          ret = (RecoverableResource) resources_.remove ( name );
          if ( ret != null ) resourceList_.remove ( ret );

        }
        LOGGER.logDebug ( "Configuration: removed resource " + name );
        return ret;
    }

    /**
     * Get the resource with the given name.
     *
     * @return RecoverableResource The resource.
     * @param name
     *            The name to find.
     */

    public static RecoverableResource getResource ( String name )
    {
        RecoverableResource res = null;
        if ( name != null ) res = (RecoverableResource) resources_.get ( name );
        return res;
    }

    /**
     * Get all resources added so far, in the order that they were added.
     *
     * @return Enumeration The resources.
     */

    public static Enumeration getResources ()
    {
        // clone to avoid concurrency problems with
        // add/removeResource (new recovery makes this possible)
        Vector ret = (Vector) resourceList_.clone ();
        return ret.elements ();
    }

}
TOP

Related Classes of com.atomikos.icatch.system.Configuration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.