Package org.eclipse.persistence.sessions.factories

Source Code of org.eclipse.persistence.sessions.factories.SessionFactory

/*******************************************************************************
* Copyright (c) 1998, 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/ 
package org.eclipse.persistence.sessions.factories;

import java.util.Collection;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.factories.SessionManager;


/**
* Helper class to simplify the development and generation of code that accesses
* TopLink through the SessionManager (sessions config XML).
* Responsibilities:<ul>
* <li> Lookup of a session by name using default or provided sessions config location
* <li> Support lookup of active UnitOfWork and Session in JTA environments
* <li> Hot/Re-deployment handling of applications
* <li> Detachment helpers to simplify usage within a local session bean
* </ul>
*
* Basic usage example:
* <code>
* SessionFactory = sessionFactory = new SessionFactory("session-name");
*
* ...
*
* public List read(Vector args) {
*    Session session = sessionFactory.acquireSession();
*
*    List results = (List) session.executeQuery("query-name", MyClass.class, args);
*
*    session.release();
*    return results;
* }
*
* public void write(MyClass detachedInstance) {
*    UnitOfWork uow = sessionFactory.acquireUnitOfWork();
*
*    MyClass workingCopy = (MyClass) uow.readObject(detachedInstance);
*
*    if (workingCopy == null) {
*       throw new MyException("Cannot write changes. Object does not exist");
*    }
*
*    uow.deepMergeClone(detachedInstance);
*
*    uow.commit();
* }
* </code>
*
* <b>Detachment</b>: The detach helper methods are provided to assist with the
* construction of applications. This helper class was designed for use within
* session beans (SB) and in the case of local SBs the objects returned are not
* serialized. Since EclipseLink's default behavior is to return the shared instance
* from the cache and rely on developers to only modify instances within a
* UnitOfWork this may be an issue. The client to the local session bean may
* try to modify the instance and thus corrupt the cache. By detaching the object
* the client to the session bean gets its own isolated copy that it can freely
* modify. This provides the same functionality as with a remote session bean
* and allows the developer the choice in how/when objects are detached.
* <i>Note</i>: The above code example shows how a detached instance can have
* changes made to it persisted through use of the UnitOfWork merge API.
*
* @author Doug Clarke & John Braken
* @version 10.1.3
* @since Dec 10, 2006
*/
public class SessionFactory {
    /**
     * Location for the sessions.xml file. The default here is the most common.
     * If none is provided then EclipseLink's default locations of 'sessions.xml'
     * and 'META-INF/sessions.xml' will be tried.
     */
    private String sessionXMLPath;
    private String sessionName;

    /**
     * Constructor for creating a new EclipseLinkSessionHelper instance.
     *
     * @param sessionsXMLPath - resource path of the sessions configuration xml.
     * @param sessionName - name of the session to use.
     */
    public SessionFactory(String sessionsXMLPath, String sessionName) {
        this.sessionXMLPath = sessionsXMLPath;
        this.sessionName = sessionName;
    }

    public SessionFactory(String sessionName) {
        this.sessionName = sessionName;
    }

    public String getSessionName() {
        return sessionName;
    }

    public String getSessionXMLPath() {
        return this.sessionXMLPath;
    }
   
    /**
     * The class-loader returned form this call will be used when loading the
     * EclipseLink configuration. By default this is the current thread's loader.
     * If this is not the case users can subclass this session factory and
     * override this method to provide a different loader.
     */
    protected ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    /**
     * Helper method that looks up the singleton session and ensure that
     * if the application has been hot-deployed it gets a fresh version of the
     * server.
     */
    public DatabaseSession getSharedSession() {
        return getSharedSession(true, false);
    }

    /**
     * Used in place of getSharedSession() when the calling application needs
     * access to the session prior to login or it wishes to force the session
     * configuration to be re-loaded an applied. This also makes use of the
     * current class-loader return from getClassLoader() and a SessionManager
     * class-loader check to see if the application was loaded by another
     * class-loader and is should this be refreshed as the application has been
     * hot deployed.
     */
    public DatabaseSession getSharedSession(boolean login, boolean refresh) {
        XMLSessionConfigLoader xmlLoader;

        if (getSessionXMLPath() != null) {
            xmlLoader = new XMLSessionConfigLoader(getSessionXMLPath());
        } else {
            xmlLoader = new XMLSessionConfigLoader();
        }

        return (DatabaseSession)SessionManager.getManager().getSession(xmlLoader,
                                                                       getSessionName(),
                                                                       getClassLoader(),
                                                                       login,
                                                                       refresh,
                                                                       true);
    }

    /**
     * Returns the Session active for this specified helper. If the EclipseLink
     * session does not have an external transaction controller or there is
     * not an active JTA transaction then a newly acquire client session is
     * returned on each call.
     *
     * This method also properly handles acquire a client session from a broker
     * as well as returning the shared session in the case it is a database
     * session.
     */
    public Session acquireSession() {
        Session sharedSession = getSharedSession();

        if (sharedSession.hasExternalTransactionController()) {
            UnitOfWork uow = sharedSession.getActiveUnitOfWork();
            if (uow != null) {
                return uow.getParent();
            }
        }

        if (sharedSession.isServerSession()) {
            return ((Server)sharedSession).acquireClientSession();
        }
        if (sharedSession.isSessionBroker()) {
            SessionBroker broker = (SessionBroker)sharedSession;
            if (broker.isServerSessionBroker()) {
                return broker.acquireClientSessionBroker();
            }
            return broker;
        }
        // Assume we have a database session and return it.
        return sharedSession;
    }

    /**
     * Looks up the active UnitOfWork using either the global JTA TX or acquires
     * a new one from the active session.
     */
    public UnitOfWork acquireUnitOfWork() {
        return acquireUnitOfWork(getSharedSession());
    }

    /**
     * Looks up the active UnitOfWork using either the global JTA TX or acquires
     * a new one from the active session. THis method should be used if a session
     * has already been acquired.
     */
    public UnitOfWork acquireUnitOfWork(Session session) {
        if (session.hasExternalTransactionController()) {
            return session.getActiveUnitOfWork();
        }

        return session.acquireUnitOfWork();
    }

    /**
     * Build a detached copy using a one-off UnitOfWork.
     * This simulates creation of a copy through serialization when using a
     * remote session bean if this copy process is not done the user of this
     * helper would return the shared copy from the cache that should not be
     * modified. These detachment methods *MUST* be used for local session
     * beans where the returned objects can be modified by the client.
     *
     * @param entity an existing persistent entity
     * @return a copy of the entity for use in a local client that may make changes to it
     */
    public Object detach(Object entity) {
        UnitOfWork uow =
            ((org.eclipse.persistence.internal.sessions.AbstractSession)getSharedSession()).acquireNonSynchronizedUnitOfWork(null);

        Object copy = uow.registerObject(entity);
        uow.release();

        return copy;
    }

    public Collection detach(Collection entities) {
        UnitOfWork uow =
            ((org.eclipse.persistence.internal.sessions.AbstractSession)getSharedSession()).acquireNonSynchronizedUnitOfWork(null);

        Collection copies = uow.registerAllObjects(entities);
        uow.release();

        return copies;
    }

}
TOP

Related Classes of org.eclipse.persistence.sessions.factories.SessionFactory

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.