Package org.datanucleus

Source Code of org.datanucleus.OMFContext

/**********************************************************************
Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
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.

Contributors:
2004 Andy Jefferson - added MetaDataManager
2006 Andy Jefferson - added ClassLoaderResolver
2006 Andy Jefferson - added direct relation with StoreManager
    ...
**********************************************************************/
package org.datanucleus;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.datanucleus.ObjectManager.ObjectManagerListener;
import org.datanucleus.api.ApiAdapter;
import org.datanucleus.api.ApiAdapterFactory;
import org.datanucleus.exceptions.ClassNotResolvedException;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.identity.IdentityTranslator;
import org.datanucleus.jta.TransactionManagerFinder;
import org.datanucleus.management.ManagementManager;
import org.datanucleus.metadata.MetaDataManager;
import org.datanucleus.plugin.ConfigurationElement;
import org.datanucleus.plugin.Extension;
import org.datanucleus.plugin.PluginManager;
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.query.QueryManager;
import org.datanucleus.store.types.TypeManager;
import org.datanucleus.transaction.NucleusTransactionException;
import org.datanucleus.transaction.TransactionManager;
import org.datanucleus.util.NucleusLogger;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.StringUtils;

/**
* Represents the context of an ObjectManagerFactory, holding state information and components that it needs
* to perform its task.
* <ul>
* <li><b>Lifecycle</b> - created by a PMF/EMF when constructed, and closed by the PMF/EMF when it closes</li>
* <li><b>Role</b> - maintains key components/resources required by a PMF/EMF during its lifetime</li>
* </ul>
*/
public class OMFContext
{
    /** Localisation of messages. */
    protected static final Localiser LOCALISER = Localiser.getInstance("org.datanucleus.Localisation",
        ObjectManager.class.getClassLoader());

    /** Persistence context. */
    public static final int CONTEXT_PERSISTENCE = 1;

    /** Enhancement context. */
    public static final int CONTEXT_ENHANCE = 2;

    private int context;

    /** ImplementationCreator for any persistent interfaces. */
    private ImplementationCreator ic;

    /** Flag for whether we have initialised the implementation creator. */
    private boolean icInitialised = false;

    /** Manager for the datastore used by this PMF. */
    private StoreManager storeMgr = null;

    /** MetaDataManager for handling the MetaData for this PMF. */
    private MetaDataManager metaDataManager = null;

    /** Transaction Manager. */
    private TransactionManager txManager = null;

    /** JTA Transaction Manager. TODO Maybe merge this with txManager above. */
    private javax.transaction.TransactionManager jtaTxManager = null;

    /** The PersistenceConfiguration defining features of the persistence process. */
    private final PersistenceConfiguration persistenceConfig;

    /** Manager for JMX features. */
    private ManagementManager jmxManager = null;

    /** Manager for Plug-ins. */
    private final PluginManager pluginManager;

    /** Manager for types and JavaTypeMappings **/
    private final TypeManager typeManager;

    /** ApiAdapter to be used by the factory. **/
    private ApiAdapter apiAdapter;

    /** Name of the API used by this factory. **/
    private String apiName = "JDO";

    /** Map of the ClassLoaderResolver, keyed by the clr class and the primaryLoader name. */
    private Map<String, ClassLoaderResolver> classLoaderResolverMap = new HashMap<String, ClassLoaderResolver>();

    /** Name of the class providing the ClassLoaderResolver. */
    private String classLoaderResolverClassName = null;

    /** Class to use for datastore-identity. */
    private Class datastoreIdentityClass = null;

    /** Identity translator (if any). */
    private IdentityTranslator idTranslator = null;

    /** Flag for whether we have initialised the id translator. */
    private boolean idTranslatorInitialised = false;

    /** ConnectionFactoryRegistry **/
    private ConnectionFactoryRegistry connFactoryRegistry;
   
    /** ConnectionManager **/
    private ConnectionManager connmgr;

    /** QueryManager **/
    private QueryManager queryManager;

    private List<ObjectManagerListener> objectManagerListeners = new ArrayList();

    /**
     * Constructor for the context.
     * @param persistenceConfig The persistence configuration
     */
    public OMFContext(PersistenceConfiguration persistenceConfig)
    {
        this(persistenceConfig, CONTEXT_PERSISTENCE);
    }

    /**
     * Constructor for the context.
     * @param persistenceConfig The persistence configuration
     * @param context The context that this is used
     */
    public OMFContext(PersistenceConfiguration persistenceConfig, int context)
    {
        this.context = context;
        this.persistenceConfig = persistenceConfig;

        // Use JDOClassLoaderResolver here since we need the plugin mechanism before being able to create our specified CLR
        ClassLoaderResolver clr = new JDOClassLoaderResolver(this.getClass().getClassLoader());
        clr.registerUserClassLoader((ClassLoader)persistenceConfig.getProperty("datanucleus.primaryClassLoader"));

        // Instantiate manager for the plugins
        this.pluginManager = new PluginManager(this.persistenceConfig, clr);
        this.pluginManager.registerExtensionPoints();
        this.pluginManager.registerExtensions();
        this.pluginManager.resolveConstraints();

        // Load up any default properties from the plugins
        persistenceConfig.setDefaultProperties(pluginManager);

        // Initialise support for API, java types
        this.apiAdapter = ApiAdapterFactory.getInstance().getApiAdapter(apiName, pluginManager);
        this.typeManager = new TypeManager(apiAdapter, this.pluginManager, getClassLoaderResolver(null));

        if (context == CONTEXT_PERSISTENCE)
        {
            // Initialise support for JMX, transactions, connections, and queries
            this.jmxManager = getJMXManager();
            txManager = new TransactionManager();
            if (jmxManager != null)
            {
                txManager.registerMbean(jmxManager.getDomainName(), jmxManager.getInstanceName(),
                    jmxManager.getManagementServer());
            }

            connFactoryRegistry = new ConnectionFactoryRegistry(this);
            connmgr = new ConnectionManagerImpl(this);

            // Initialise support for queries
            queryManager = new QueryManager(this);
        }
    }

    public int getContext()
    {
        return context;
    }

    /**
     * Clear out resources
     */
    public synchronized void close()
    {
        if (storeMgr != null)
        {
            storeMgr.close();
            storeMgr = null;
        }

        if (metaDataManager != null)
        {
            metaDataManager.close();
            metaDataManager = null;
        }

        if (jmxManager != null)
        {
            jmxManager.close();
            jmxManager = null;
        }

        if (queryManager != null)
        {
            queryManager.close();
        }

        classLoaderResolverMap.clear();
        classLoaderResolverMap = null;
        classLoaderResolverClassName = null;

        datastoreIdentityClass = null;
    }

    /**
     * Accessor for the class to use for datastore identity.
     * @return Class for datastore-identity
     */
    public Class getDatastoreIdentityClass()
    {
        if (datastoreIdentityClass == null)
        {
            String dsidName = persistenceConfig.getStringProperty("datanucleus.datastoreIdentityType");
            String datastoreIdentityClassName = pluginManager.getAttributeValueForExtension(
                "org.datanucleus.store_datastoreidentity", "name", dsidName, "class-name");
            if (datastoreIdentityClassName == null)
            {
                // User has specified a datastore_identity plugin that has not registered
                throw new NucleusUserException(LOCALISER.msg("002001", dsidName)).setFatal();
            }

            // Try to load the class
            ClassLoaderResolver clr = getClassLoaderResolver(null);
            try
            {
                datastoreIdentityClass = clr.classForName(datastoreIdentityClassName,OMFContext.class.getClassLoader());
            }
            catch (ClassNotResolvedException cnre)
            {
                throw new NucleusUserException(LOCALISER.msg("002002", dsidName,
                    datastoreIdentityClassName)).setFatal();
            }
        }
        return datastoreIdentityClass;
    }

    /**
     * Accessor for the current identity translator to use (if any).
     * @return Identity translator instance (or null if persistence property not set)
     */
    public IdentityTranslator getIdentityTranslator()
    {
        if (idTranslatorInitialised)
        {
            return idTranslator;
        }

        // Identity translation
        idTranslatorInitialised = true;
        String translatorType = persistenceConfig.getStringProperty("datanucleus.identityTranslatorType");
        if (translatorType != null)
        {
            try
            {
                idTranslator = (IdentityTranslator)pluginManager.createExecutableExtension(
                    "org.datanucleus.identity_translator", "name", translatorType, "class-name", null, null);
                return idTranslator;
            }
            catch (Exception e)
            {
                // User has specified an identity translator plugin that has not registered
                throw new NucleusUserException(LOCALISER.msg("002001", translatorType)).setFatal();
            }
        }
        return null;
    }

    /**
     * Accessor for the JMX manager (if required).
     * If the user has set the persistence property "datanucleus.managedRuntime" to true then this will
     * return a JMX manager.
     * @return The JMX manager
     */
    public ManagementManager getJMXManager()
    {
        if (jmxManager == null && persistenceConfig.getBooleanProperty("datanucleus.managedRuntime"))
        {
            // User requires managed runtime, and not yet present so create manager
            jmxManager = new ManagementManager(this);
        }
        return jmxManager;
    }

    /**
     * Accessor for a ClassLoaderResolver to use in resolving classes.
     * @param primaryLoader Loader to use as the primary loader.
     * @return The ClassLoader resolver
     */
    public ClassLoaderResolver getClassLoaderResolver(ClassLoader primaryLoader)
    {
// Commented out since it is possible to find the JDOClassLoaderResolver and then the users specified loader
//      if (classLoaderResolverClassName == null)
//      {
            // See what the factory has been specified to use
            String clrName = persistenceConfig.getStringProperty("datanucleus.classLoaderResolverName");
            classLoaderResolverClassName = pluginManager.getAttributeValueForExtension("org.datanucleus.classloader_resolver",
                "name", clrName, "class-name");
            if (classLoaderResolverClassName == null)
            {
                // User has specified a classloader_resolver plugin that has not registered
                throw new NucleusUserException(LOCALISER.msg("001001", clrName)).setFatal();
            }
//      }
       
        // Set the key we will refer to this loader by
        String key = classLoaderResolverClassName;
        if (primaryLoader != null)
        {
            key += ":[" + StringUtils.toJVMIDString(primaryLoader) + "]";
        }

        // See if we have the loader cached
        ClassLoaderResolver clr = classLoaderResolverMap.get(key);
        if (clr == null)
        {
            // Create the ClassLoaderResolver of this type with this primary loader
            try
            {
                Class cls = Class.forName(classLoaderResolverClassName);
                Class[] ctrArgs = null;
                Object[] ctrParams = null;
                if (primaryLoader != null)
                {
                    ctrArgs = new Class[] {ClassLoader.class};
                    ctrParams = new Object[] {primaryLoader};
                }
                Constructor ctor = cls.getConstructor(ctrArgs);
                clr = (ClassLoaderResolver)ctor.newInstance(ctrParams);
                clr.registerUserClassLoader((ClassLoader)persistenceConfig.getProperty("datanucleus.primaryClassLoader"));
            }
            catch (ClassNotFoundException cnfe)
            {
                throw new NucleusUserException(LOCALISER.msg("001002",
                    classLoaderResolverClassName), cnfe).setFatal();
            }
            catch (Exception e)
            {
                throw new NucleusUserException(LOCALISER.msg("001003",
                    classLoaderResolverClassName), e).setFatal();
            }
            classLoaderResolverMap.put(key, clr);
        }

        return clr;
    }

    /**
     * Accessor for the implementation creator for this context.
     * @return The implementation creator
     */
    public ImplementationCreator getImplementationCreator()
    {
        if (!icInitialised)
        {
            // Create if not already present
            String implCreatorName = persistenceConfig.getStringProperty("datanucleus.implementationCreatorName");
            try
            {
                Class cls = null;
                ConfigurationElement elem =
                    getPluginManager().getConfigurationElementForExtension("org.datanucleus.implementation_creator",
                        "name", implCreatorName);
                if (elem != null)
                {
                    try
                    {
                        cls = Class.forName(elem.getAttribute("class-name"), true,
                            ObjectManagerFactoryImpl.class.getClassLoader());
                        ic = (ImplementationCreator)cls.newInstance();
                    }
                    catch (Exception e)
                    {
                        // Creator not found
                        NucleusLogger.PERSISTENCE.info(LOCALISER.msg("008006", implCreatorName));
                    }
                }
                if (ic == null)
                {
                    // Selection not found so find the first available
                    Extension[] exts =
                        getPluginManager().getExtensionPoint("org.datanucleus.implementation_creator").getExtensions();
                    for (int i=0; ic==null && i<exts.length; i++)
                    {
                        for (int j=0; ic==null && j<exts[i].getConfigurationElements().length; j++)
                        {
                            cls = Class.forName(exts[i].getConfigurationElements()[j].getAttribute("class-name"), true,
                                ObjectManagerFactoryImpl.class.getClassLoader());
                            ic = (ImplementationCreator)cls.newInstance();
                            if (ic != null)
                            {
                                // Found one that is present so use it
                                break;
                            }
                        }
                    }
                }
                if (NucleusLogger.PERSISTENCE.isDebugEnabled())
                {
                    if (ic == null)
                    {
                        NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("008007"));
                    }
                    else
                    {
                        NucleusLogger.PERSISTENCE.debug(LOCALISER.msg("008008",cls.getName()));
                    }
                }
            }
            catch (InstantiationException e)
            {
                throw new NucleusException(e.toString(),e).setFatal();
            }
            catch (IllegalAccessException e)
            {
                throw new NucleusException(e.toString(),e).setFatal();
            }
            catch (ClassNotFoundException e)
            {
                // Implementation creator not present maybe
                NucleusLogger.PERSISTENCE.warn(LOCALISER.msg("008006", implCreatorName));
                ic = null;
            }
            catch (NoClassDefFoundError e)
            {
                // Dependency (of implementation creator) not present maybe
                NucleusLogger.PERSISTENCE.warn(LOCALISER.msg("008006", implCreatorName));
                ic = null;
            }
        }
        icInitialised = true;
        return ic;
    }

    /**
     * Accessor for the Meta-Data Manager.
     * @return Returns the MetaDataManager.
     */
    public synchronized MetaDataManager getMetaDataManager()
    {
        if (metaDataManager == null)
        {
            try
            {
                metaDataManager = (MetaDataManager) getPluginManager().createExecutableExtension(
                    "org.datanucleus.metadata_manager", new String[]{"name"}, new String[]{apiName},
                    "class", new Class[] {OMFContext.class}, new Object[]{this});
            }
            catch (Exception e)
            {
                throw new NucleusException(LOCALISER.msg("008010", apiName, e.getMessage()), e);
            }
            if (metaDataManager == null)
            {
                throw new NucleusException(LOCALISER.msg("008009", apiName));
            }
        }

        return metaDataManager;
    }

    /**
     * Accessor for the persistence configuration.
     * @return Returns the persistence configuration.
     */
    public PersistenceConfiguration getPersistenceConfiguration()
    {
        return persistenceConfig;
    }
   
    /**
     * Accessor for the Plugin Manager
     * @return the PluginManager
     */
    public PluginManager getPluginManager()
    {
        return pluginManager;
    }
   
    /**
     * Accessor for the Type Manager
     * @return the TypeManager
     */
    public TypeManager getTypeManager()
    {
        return typeManager;
    }

    /**
     * Accessor for the transaction manager.
     * @return The transaction manager.
     */
    public TransactionManager getTransactionManager()
    {
        return txManager;
    }

    /**
     * Accessor for the JTA transaction manager (if using JTA).
     * @return the JTA Transaction Manager
     */
    public javax.transaction.TransactionManager getJtaTransactionManager()
    {
        if (jtaTxManager == null)
        {
            // Find the JTA transaction manager
            // Before J2EE 5 there is no standard way to do this so use the finder process.
            // See http://www.onjava.com/pub/a/onjava/2005/07/20/transactions.html
            jtaTxManager = new TransactionManagerFinder(this).getTransactionManager(
                getClassLoaderResolver((ClassLoader)persistenceConfig.getProperty("datanucleus.primaryClassLoader")));
            if (jtaTxManager == null)
            {
                throw new NucleusTransactionException(LOCALISER.msg("015030"));
            }
        }
        return jtaTxManager;
    }

    /**
     * Accessor for the StoreManager
     * @return the StoreManager
     */
    public StoreManager getStoreManager()
    {
        return storeMgr;
    }

    /**
     * Mutator for the store manager.
     * Can only be set once.
     * @param storeMgr The store manager
     */
    public void setStoreManager(StoreManager storeMgr)
    {
        if (this.storeMgr == null)
        {
            this.storeMgr = storeMgr;
        }
    }

    /**
     * Accessor for the ApiAdapter
     * @return the ApiAdapter
     */
    public ApiAdapter getApiAdapter()
    {
        return apiAdapter;
    }

    /**
     * Accessor for the API name.
     * @return the api
     */
    public String getApi()
    {
        return apiName;
    }

    /**
     * Configure the API to be used
     * @param name the API name
     */
    public void setApi(String name)
    {
        this.apiName = name;
        ApiAdapter adapter = ApiAdapterFactory.getInstance().getApiAdapter(name, pluginManager);
        if (adapter != null)
        {
            this.apiAdapter = adapter;
        }
        else
        {
            NucleusLogger.JDO.warn(LOCALISER.msg("008003", name));
        }
    }
   
    public ConnectionFactoryRegistry getConnectionFactoryRegistry()
    {
        return connFactoryRegistry;
    }

    public ConnectionManager getConnectionManager()
    {
        return connmgr;
    }

    /**
     * Object the array of registered ObjectManagerListener's
     * @return array of {@link ObjectManagerListener}
     */
    public ObjectManagerListener[] getObjectManagerListeners()
    {
        return objectManagerListeners.toArray(new ObjectManagerListener[objectManagerListeners.size()]);
    }
   
    /**
     * Register a new Listener for ObjectManager's events
     * @param listener the listener to register
     */
    public void addObjectManagerListener(ObjectManagerListener listener)
    {
        objectManagerListeners.add(listener);
    }    

    /**
     * Unregister a Listener from ObjectManager's events
     * @param listener the listener to unregister
     */
    public void removeObjectManagerListener(ObjectManagerListener listener)
    {
        objectManagerListeners.remove(listener);
    }    

    /**
     * Accessor to the QueryManager
     * @return the QueryManager
     */
    public QueryManager getQueryManager()
    {
        return queryManager;
    }
}
TOP

Related Classes of org.datanucleus.OMFContext

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.