Package org.datanucleus

Source Code of org.datanucleus.ObjectManagerFactoryImpl

/**********************************************************************
Copyright (c) 2006 Andy Jefferson 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:
    ...
**********************************************************************/
package org.datanucleus;

import java.lang.reflect.Constructor;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TimeZone;

import org.datanucleus.cache.Level2Cache;
import org.datanucleus.cache.NullLevel2Cache;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.store.FederationManager;
import org.datanucleus.store.StoreManager;
import org.datanucleus.util.NucleusLogger;

/**
* ObjectManagerFactory responsible for creation of ObjectManagers for persistence of objects to datastores.
* Will typically be either extended or utilised by PersistenceManagerFactory (JDO) or EntityManagerFactory (JPA).
*/
public class ObjectManagerFactoryImpl extends PersistenceConfiguration
{
    /** Version of DataNucleus being used. Read in at startup from properties. */
    private static String versionNumber = null;

    /** Vendor of this system. */
    private static String vendorName = null;

    /** The context that this ObjectManagerFactory uses. */
    protected OMFContext omfContext;

    /** Level 2 Cache, caching across ObjectManagers. */
    protected Level2Cache cache;

    /** Whether the ObjectManagerFactory is closed */
    private boolean closed;

    /** Manager for dynamic fetch groups defined on the OMF. */
    private FetchGroupManager fetchGrpMgr;

    FederationManager fed;
   
    /**
     * Constructor.
     */
    public ObjectManagerFactoryImpl()
    {
        super();
    }

    /**
     * Asserts that the factory is open.
     * @throws NucleusUserException if it is already closed
     */
    protected void assertIsOpen()
    {
        if (isClosed())
        {
            throw new NucleusUserException(LOCALISER.msg("008002"));
        }
    }

    /**
     * Method to log the configuration of this factory.
     */
    protected void logConfiguration()
    {
        // Log the Factory configuration
        NucleusLogger.PERSISTENCE.info("================= Persistence Configuration ===============");
        NucleusLogger.PERSISTENCE.info(LOCALISER.msg("008000", getVendorName(), getVersionNumber()));
        NucleusLogger.PERSISTENCE.info(LOCALISER.msg("008001",
            getStringProperty("datanucleus.ConnectionURL"),
            getStringProperty("datanucleus.ConnectionDriverName"),
            getStringProperty("datanucleus.ConnectionUserName")));
        if (NucleusLogger.PERSISTENCE.isDebugEnabled())
        {
            NucleusLogger.PERSISTENCE.debug("JDK : " + System.getProperty("java.version") + " on " + System.getProperty("os.name"));
            NucleusLogger.PERSISTENCE.debug("Persistence API : " + getOMFContext().getApi());
            NucleusLogger.PERSISTENCE.debug("Plugin Registry : " + getOMFContext().getPluginManager().getRegistryClassName());
            if (hasProperty("datanucleus.PersistenceUnitName"))
            {
                NucleusLogger.PERSISTENCE.debug("Persistence-Unit : " + getStringProperty("datanucleus.PersistenceUnitName"));
            }

            String timeZoneID = getStringProperty("datanucleus.ServerTimeZoneID");
            if (timeZoneID == null)
            {
                timeZoneID = TimeZone.getDefault().getID();
            }
            NucleusLogger.PERSISTENCE.debug("Standard Options : " +
                (getBooleanProperty("datanucleus.Multithreaded") ? "multithreaded" : "singlethreaded") +
                (getBooleanProperty("datanucleus.RetainValues") ? ", retain-values" : "") +
                (getBooleanProperty("datanucleus.RestoreValues") ? ", restore-values" : "") +
                (getBooleanProperty("datanucleus.NontransactionalRead") ? ", nontransactional-read" : "") +
                (getBooleanProperty("datanucleus.NontransactionalWrite") ? ", nontransactional-write" : "") +
                (getBooleanProperty("datanucleus.IgnoreCache") ? ", ignoreCache" : "") +
                ", serverTimeZone=" + timeZoneID);
            NucleusLogger.PERSISTENCE.debug("Persistence Options :" +
                (getBooleanProperty("datanucleus.persistenceByReachabilityAtCommit") ? " reachability-at-commit" : "") +
                (getBooleanProperty("datanucleus.DetachAllOnCommit") ? " detach-all-on-commit" : "") +
                (getBooleanProperty("datanucleus.DetachOnClose") ? " detach-on-close" : "") +
                (getBooleanProperty("datanucleus.manageRelationships") ?
                    (getBooleanProperty("datanucleus.manageRelationshipsChecks") ? " managed-relations(checked)" : "managed-relations(unchecked)") : "") +
                " deletion-policy=" + getStringProperty("datanucleus.deletionPolicy"));
            NucleusLogger.PERSISTENCE.debug("Transactions : type=" + getStringProperty("datanucleus.TransactionType") +
                " mode=" + (getBooleanProperty("datanucleus.Optimistic") ? "optimistic" : "datastore") +
                " isolation=" + getStringProperty("datanucleus.transactionIsolation"));
            NucleusLogger.PERSISTENCE.debug("Value Generation :" +
                " txn-isolation=" + getStringProperty("datanucleus.valuegeneration.transactionIsolation") +
                " connection=" + (getStringProperty("datanucleus.valuegeneration.transactionAttribute").equalsIgnoreCase("New") ? "New" : "PM"));
            Object primCL = getProperty("datanucleus.primaryClassLoader");
            NucleusLogger.PERSISTENCE.debug("ClassLoading : " + getStringProperty("datanucleus.classLoaderResolverName") +
                (primCL != null ? ("primary=" + primCL) : ""));
            NucleusLogger.PERSISTENCE.debug("Cache : Level1 (" + getStringProperty("datanucleus.cache.level1.type") + ")" +
                ", Level2 (" + getStringProperty("datanucleus.cache.level2.type") + ")" +
                ", Query (" + getStringProperty("datanucleus.cache.query.type") + ")" +
                (getBooleanProperty("datanucleus.cache.collections") ? ", Collections/Maps " : ""));
        }
        NucleusLogger.PERSISTENCE.info("===========================================================");
    }

    /**
     * Method to initialise the OMFContext.
     * This should be performed after setting any persistence properties that affect the content
     * of the OMFContext (e.g PluginRegistry, ClassLoaderResolver, etc).
     */
    protected void initialiseOMFContext()
    {
        omfContext = new OMFContext(this);
    }

    /**
     * Method to initialise the StoreManager used by this factory.
     * @param clr ClassLoaderResolver to use for class loading issues
     */
    protected void initialiseStoreManager(ClassLoaderResolver clr)
    {
        fed = new FederationManager(clr,getOMFContext());
    }

    /**
     * Convenience accessor for the StoreManager.
     * This is for public access to DataNucleus APIs.
     * TODO Rework this when there is a FederationManager.
     * @return The StoreManager
     */
    public StoreManager getStoreManager()
    {
        return getOMFContext().getStoreManager();
    }

    /**
     * Method to initialise the L2 cache.
     */
    protected void initialiseLevel2Cache()
    {
        String level2Type = getStringProperty("datanucleus.cache.level2.type");

        // Find the L2 cache class name from its plugin name
        String level2ClassName = getOMFContext().getPluginManager().getAttributeValueForExtension(
            "org.datanucleus.cache_level2", "name", level2Type, "class-name");
        if (level2ClassName == null)
        {
            // Plugin of this name not found
            throw new NucleusUserException(LOCALISER.msg("004000", level2Type)).setFatal();
        }

        try
        {
            // Create an instance of the L2 Cache
            Class level2CacheClass = Class.forName(level2ClassName);
            Class[] ctrArgsClasses = new Class[] {OMFContext.class};
            Object[] ctrArgs = new Object[] {omfContext};
            Constructor ctr = level2CacheClass.getConstructor(ctrArgsClasses);
            cache = (Level2Cache)ctr.newInstance(ctrArgs);
            if (NucleusLogger.CACHE.isDebugEnabled())
            {
                NucleusLogger.CACHE.debug(LOCALISER.msg("004002", level2ClassName));
            }
        }
        catch (Exception e)
        {
            // Class name for this L2 cache plugin is not found!
            throw new NucleusUserException(LOCALISER.msg("004001", level2Type, level2ClassName), e).setFatal();
        }
    }

    public boolean hasLevel2Cache()
    {
        return (cache != null && !(cache instanceof NullLevel2Cache));
    }

    /**
     * Close the ObjectManagerFactory.
     * Cleans out all objects in the Level2 cache and closes the context, marking the factory as closed.
     */
    public synchronized void close()
    {
        if (cache != null)
        {
            // Close the L2 Cache
            cache.close();
            NucleusLogger.CACHE.info(LOCALISER.msg("004009"));
        }

        // Clear out all fetch groups
        if (fetchGrpMgr != null)
        {
            getFetchGroupManager().clearFetchGroups();
        }

        if (omfContext != null)
        {
            omfContext.close();
            omfContext = null;
        }
        closed = true;
    }

    /**
     * Utility to return whether the factory is closed or not.
     * @return Whether it is closed.
     */
    public boolean isClosed()
    {
        return closed;
    }

    /**
     * Gets the context for this ObjectManagerFactory
     * @return Returns the context.
     */
    public OMFContext getOMFContext()
    {
        if (omfContext == null)
        {
            // Construct the OMFContext when it is needed
            initialiseOMFContext();
        }
        return omfContext;
    }

    /**
     * Accessor for the PersistenceConfiguration.
     * @return Returns the persistence config.
     */
    public PersistenceConfiguration getPersistenceConfiguration()
    {
        return this;
    }

    /**
     * Accessor for the DataStore (level 2) Cache
     * @return The datastore cache
     */
    public Level2Cache getLevel2Cache()
    {
        return cache;
    }

    /**
     * Utility to get the version of DataNucleus.
     * @return Version number for DataNucleus.
     */
    public static String getVersionNumber()
    {
        if (versionNumber != null)
        {
            return versionNumber;
        }
       
        String version = "Unknown";
        try
        {
            ResourceBundle bundle = ResourceBundle.getBundle("org.datanucleus.DataNucleusVersion");
            try
            {
                version = bundle.getString("datanucleus.version");
            }
            catch (Exception e1)
            {
            }
        }
        catch (Exception e)
        {
        }
       
        return versionNumber = version;
    }

    /**
     * Utility to get the vendor of DataNucleus.
     * @return Vendor name for DataNucleus.
     */
    public static String getVendorName()
    {
        if (vendorName != null)
        {
            return vendorName;
        }
       
        String vendor = "DataNucleus";
        try
        {
            ResourceBundle bundle = ResourceBundle.getBundle("org.datanucleus.DataNucleusVersion");
            try
            {
                vendor = bundle.getString("datanucleus.vendor");
            }
            catch (Exception e1)
            {
            }
        }
        catch (Exception e)
        {
        }

        return vendorName = vendor;
    }

    // --------------------------- Fetch Groups ---------------------------------

    /**
     * Convenience accessor for the FetchGroupManager.
     * Creates it if not yet existing.
     * @return The FetchGroupManager
     */
    protected FetchGroupManager getFetchGroupManager()
    {
        if (fetchGrpMgr == null)
        {
            fetchGrpMgr = new FetchGroupManager(getOMFContext());
        }
        return fetchGrpMgr;
    }

    /**
     * Method to add a dynamic FetchGroup for use by this OMF.
     * @param grp The group
     */
    protected void addInternalFetchGroup(FetchGroup grp)
    {
        getFetchGroupManager().addFetchGroup(grp);
    }

    /**
     * Method to remove a dynamic FetchGroup from use by this OMF.
     * @param grp The group
     */
    protected void removeInternalFetchGroup(FetchGroup grp)
    {
        getFetchGroupManager().removeFetchGroup(grp);
    }

    /**
     * Method to create a new internal fetch group for the class+name.
     * @param cls Class that it applies to
     * @param name Name of group
     * @return The group
     */
    public FetchGroup createInternalFetchGroup(Class cls, String name)
    {
        if (!cls.isInterface() && !getOMFContext().getApiAdapter().isPersistable(cls))
        {
            // Class but not persistable!
            throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable");
        }
        else if (cls.isInterface() && !getOMFContext().getMetaDataManager().isPersistentInterface(cls.getName()))
        {
            // Interface but not persistent
            throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable");
        }
        return getFetchGroupManager().createFetchGroup(cls, name);
    }

    /**
     * Accessor for an internal fetch group for the specified class.
     * @param cls The class
     * @param name Name of the group
     * @return The FetchGroup
     * @throws NucleusUserException if the class is not persistable
     */
    public FetchGroup getInternalFetchGroup(Class cls, String name)
    {
        if (!cls.isInterface() && !getOMFContext().getApiAdapter().isPersistable(cls))
        {
            // Class but not persistable!
            throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable");
        }
        else if (cls.isInterface() && !getOMFContext().getMetaDataManager().isPersistentInterface(cls.getName()))
        {
            // Interface but not persistent
            throw new NucleusUserException("Cannot create FetchGroup for " + cls + " since it is not persistable");
        }
        return getFetchGroupManager().getFetchGroup(cls, name);
    }

    /**
     * Accessor for the fetch groups for the specified name.
     * @param name Name of the group
     * @return The FetchGroup
     */
    public Set getFetchGroupsWithName(String name)
    {
        return getFetchGroupManager().getFetchGroupsWithName(name);
    }
}
TOP

Related Classes of org.datanucleus.ObjectManagerFactoryImpl

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.