Package org.jpox

Source Code of org.jpox.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.jpox;

import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.TimeZone;

import org.jpox.cache.Level2Cache;
import org.jpox.cache.NullLevel2Cache;
import org.jpox.exceptions.JPOXUserException;
import org.jpox.store.FederationManager;
import org.jpox.util.JPOXLogger;
import org.jpox.util.MultiMap;

/**
* 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).
*
* @version $Revision: 1.15 $
*/
public class ObjectManagerFactoryImpl extends PersistenceConfiguration
{
    /** Version of JPOX being used. Read in at startup from properties. */
    private static String jpoxVersion = null;

    /** Vendor of this version of JPOX. */
    private static String jpoxVendor = 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;

    /** Map of dynamic fetch groups, keyed by the name + class name. */
    private MultiMap fetchGroupByNameClass;

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

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

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

            String timeZoneID = getStringProperty("org.jpox.ServerTimeZoneID");
            if (timeZoneID == null)
            {
                timeZoneID = TimeZone.getDefault().getID();
            }
            JPOXLogger.PERSISTENCE.debug("Standard Options : " +
                (getBooleanProperty("org.jpox.Multithreaded") ? "multithreaded" : "singlethreaded") +
                (getBooleanProperty("org.jpox.RetainValues") ? ", retain-values" : "") +
                (getBooleanProperty("org.jpox.RestoreValues") ? ", restore-values" : "") +
                (getBooleanProperty("org.jpox.NontransactionalRead") ? ", nontransactional-read" : "") +
                (getBooleanProperty("org.jpox.NontransactionalWrite") ? ", nontransactional-write" : "") +
                (getBooleanProperty("org.jpox.IgnoreCache") ? ", ignoreCache" : "") +
                ", serverTimeZone=" + timeZoneID);
            JPOXLogger.PERSISTENCE.debug("Persistence Options :" +
                (getBooleanProperty("org.jpox.persistenceByReachabilityAtCommit") ? " reachability-at-commit" : "") +
                (getBooleanProperty("org.jpox.DetachAllOnCommit") ? " detach-all-on-commit" : "") +
                (getBooleanProperty("org.jpox.DetachOnClose") ? " detach-on-close" : "") +
                (getBooleanProperty("org.jpox.manageRelationships") ?
                    (getBooleanProperty("org.jpox.manageRelationshipsChecks") ? " managed-relations(checked)" : "managed-relations(unchecked)") : "") +
                " deletion-policy=" + getStringProperty("org.jpox.deletionPolicy"));
            // TODO This is RDBMS so move to that
            JPOXLogger.PERSISTENCE.debug("Types : string-default-length=" + getIntProperty("org.jpox.rdbms.stringDefaultLength"));
            JPOXLogger.PERSISTENCE.debug("Transactions : type=" + getStringProperty("org.jpox.TransactionType") +
                " mode=" + (getBooleanProperty("org.jpox.Optimistic") ? "optimistic" : "datastore") +
                " isolation=" + getStringProperty("org.jpox.transactionIsolation"));
            JPOXLogger.PERSISTENCE.debug("Identity Generation :" +
                " txn-isolation=" + getStringProperty("org.jpox.poid.transactionIsolation") +
                " connection=" + (getStringProperty("org.jpox.poid.transactionAttribute").equalsIgnoreCase("New") ? "New" : "PM"));
            Object primCL = getProperty("org.jpox.primaryClassLoader");
            JPOXLogger.PERSISTENCE.debug("ClassLoading : " + getStringProperty("org.jpox.classLoaderResolverName") +
                (primCL != null ? ("primary=" + primCL) : ""));
            JPOXLogger.PERSISTENCE.debug("Cache : Level1 (" + getStringProperty("org.jpox.cache.level1.type") + ")" +
                (getBooleanProperty("org.jpox.cache.level2") ? (", Level2 (" + getStringProperty("org.jpox.cache.level2.type") + ")") : "") +
                (getBooleanProperty("org.jpox.cache.collections") ? ", Collections/Maps " : ""));
        }
        JPOXLogger.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());
    }

    /**
     * Method to initialise the L2 cache.
     */
    protected void initialiseLevel2Cache()
    {
        if (getBooleanProperty("org.jpox.cache.level2"))
        {
            // Find the L2 cache class name from its plugin name
            String level2Type = getStringProperty("org.jpox.cache.level2.type");
            String level2ClassName = getOMFContext().getPluginManager().getAttributeValueForExtension("org.jpox.cache_level2",
                "name", level2Type, "class-name");
            if (level2ClassName == null)
            {
                // Plugin of this name not found
                throw new JPOXUserException(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 (JPOXLogger.CACHE.isDebugEnabled())
                {
                    JPOXLogger.CACHE.debug(LOCALISER.msg("004002", level2ClassName));
                }
            }
            catch (Exception e)
            {
                // Class name for this L2 cache plugin is not found!
                throw new JPOXUserException(LOCALISER.msg("004001", level2Type, level2ClassName), e).setFatal();
            }
        }
        else
        {
            cache = new 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()
    {
        // Clear the Cache
        if (getBooleanProperty("org.jpox.cache.level2") && cache != null)
        {
            cache.clear();
            JPOXLogger.CACHE.info(LOCALISER.msg("004009"));
        }

        // Clear out all fetch groups
        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
     * @since 1.1
     */
    public Level2Cache getLevel2Cache()
    {
        return cache;
    }

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

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

        return jpoxVendor = vendor;
    }

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

    /**
     * Method to create a (dynamic) fetch group.
     * @param name Name of the group
     * @param cls Class being represented.
     */
    public FetchGroup createFetchGroup(String name, Class cls)
    {
        return new FetchGroupImpl(name, cls);
    }

    /**
     * Method to add a fetch group for use by this PMF.
     * @param group The FetchGroup
     */
    public void addFetchGroup(FetchGroup group)
    {
        if (fetchGroupByNameClass == null)
        {
            fetchGroupByNameClass = new MultiMap();
        }

        Collection coll = (Collection)fetchGroupByNameClass.get(group.getName());
        if (coll != null)
        {
            // Check for existing entry for this name and class
            Iterator iter = coll.iterator();
            while (iter.hasNext())
            {
                FetchGroupImpl grp = (FetchGroupImpl)iter.next();
                if (grp.getName().equals(group.getName()) && grp.getClassName().equals(group.getClassName()))
                {
                    // Already have a group for this name and class so replace it
                    grp.disconnectFromListeners(); // Remove the old group from use
                    iter.remove(); // Remove the old group
                }
            }
        }
       
        // TODO Make a copy of the group
        fetchGroupByNameClass.put(group.getName(), group);
    }

    /**
     * Accessor for a fetch group for the specified class.
     * @param name Name of the group
     * @param cls The class
     * @return The FetchGroup
     */
    public FetchGroup getFetchGroup(String name, Class cls)
    {
        if (fetchGroupByNameClass != null)
        {
            Collection coll = (Collection) fetchGroupByNameClass.get(name);
            if (coll != null)
            {
                Iterator iter = coll.iterator();
                while (iter.hasNext())
                {
                    FetchGroupImpl grp = (FetchGroupImpl)iter.next();
                    if (grp.getFetchGroupClass() == cls)
                    {
                        return grp;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Accessor for the fetch groups for the specified name.
     * @param name Name of the group
     * @return The FetchGroup
     */
    public FetchGroup[] getFetchGroups(String name)
    {
        if (fetchGroupByNameClass != null)
        {
            Collection coll = (Collection) fetchGroupByNameClass.get(name);
            if (coll != null)
            {
                return (FetchGroup[])coll.toArray(new FetchGroup[coll.size()]);
            }
        }
        return null;
    }

    /**
     * Method to remove a dynamic FetchGroup from use by this PMF.
     * @param name Name of the group
     * @param cls The class
     */
    public void removeFetchGroup(String name, Class cls)
    {
        if (fetchGroupByNameClass != null)
        {
            Collection coll = (Collection) fetchGroupByNameClass.get(name);
            if (coll != null)
            {
                Iterator iter = coll.iterator();
                while (iter.hasNext())
                {
                    FetchGroupImpl grp = (FetchGroupImpl)iter.next();
                    if (grp.getFetchGroupClass() == cls)
                    {
                        grp.disconnectFromListeners(); // Remove the group from use
                        fetchGroupByNameClass.remove(name, grp);
                    }
                }
            }
        }
    }

    /**
     * Clear all dynamic FetchGroups from use.
     */
    public void clearFetchGroups()
    {
        if (fetchGroupByNameClass != null)
        {
            Collection fetchGroups = fetchGroupByNameClass.values();
            Iterator iter = fetchGroups.iterator();
            while (iter.hasNext())
            {
                FetchGroupImpl grp = (FetchGroupImpl)iter.next();
                grp.disconnectFromListeners(); // Remove the group from use
            }
            fetchGroupByNameClass.clear();
        }
    }
}
TOP

Related Classes of org.jpox.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.