/*******************************************************************************
* Copyright (c) 1998, 2008 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.internal.jpa;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
/**
* <p>
* <b>Purpose</b>: Provides the implementation for the EntityManager Factory.
* <p>
* <b>Description</b>: This class will store a reference to the active ServerSession. When a request
* is made for an EntityManager an new EntityManager is created with the ServerSession and returned.
* The primary consumer of these EntityManager is assumed to be either the Container. There is
* one EntityManagerFactory per deployment.
* @see javax.persistence.EntityManager
* @see org.eclipse.persistence.jpa.JpaEntityManager
* @see org.eclipse.persistence.jpa.EntityManagerFactory
*
* @author gyorke
* @since TopLink 10.1.3 EJB 3.0 Preview
*/
public class EntityManagerFactoryImpl implements EntityManagerFactory {
// This stores a reference to the ServerSession for this deployment.
protected ServerSession serverSession;
protected EntityManagerSetupImpl setupImpl;
protected boolean isOpen = true;
protected Map properties;
/**
* Will return an instance of the Factory. Should only be called by EclipseLink.
* @param serverSession
*/
public EntityManagerFactoryImpl(ServerSession serverSession){
this.serverSession = serverSession;
}
public EntityManagerFactoryImpl(EntityManagerSetupImpl setupImpl, Map properties){
this.setupImpl = setupImpl;
this.properties = properties;
}
/**
* INTERNAL:
* Returns the ServerSession that the Factory will be using and initializes it if it is not available.
* This method makes use of the partially constructed session stored in our setupImpl and
* completes its construction
*/
public synchronized ServerSession getServerSession(){
if (serverSession == null){
ClassLoader realLoader = setupImpl.getPersistenceUnitInfo().getClassLoader();
// the call top setupImpl.deploy() finishes the session creation
serverSession = setupImpl.deploy(realLoader, properties);
}
return this.serverSession;
}
/**
* Closes this factory, releasing any resources that might be held by this factory. After
* invoking this method, all methods on the instance will throw an
* {@link IllegalStateException}, except for {@link #isOpen}, which will return
* <code>false</code>.
*/
public synchronized void close(){
verifyOpen();
isOpen = false;
setupImpl.undeploy();
}
/**
* Indicates whether or not this factory is open. Returns <code>true</code> until a call
* to {@link #close} is made.
*/
public boolean isOpen(){
return isOpen;
}
/**
* PUBLIC:
* Returns an EntityManager for this deployment
*/
public EntityManager createEntityManager() {
return createEntityManagerImpl(false);
}
/**
* PUBLIC:
* Returns an EntityManager for this deployment
*/
public EntityManager createEntityManager(Map properties) {
return createEntityManagerImpl(properties, false);
}
protected EntityManagerImpl createEntityManagerImpl(boolean extended) {
return createEntityManagerImpl(null, extended);
}
protected synchronized EntityManagerImpl createEntityManagerImpl(Map properties, boolean extended) {
verifyOpen();
if (!getServerSession().isConnected()) {
getServerSession().login();
}
return createEntityManagerImplInternal(properties, extended);
}
//TODO change the way create works to deal with how the specification works with persistence contexts
protected EntityManagerImpl createEntityManagerImplInternal(Map properties, boolean extended) {
return new EntityManagerImpl(this, properties, false, extended);
}
protected void verifyOpen(){
if (!isOpen){
throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
}
}
protected void finalize() throws Throwable {
if(isOpen()) {
close();
}
}
/**
* The method return user defined property passed in from EntityManagerFactory.
*/
public Object getProperty(String name) {
if(name==null){
return null;
}
return this.getServerSession().getProperty(name);
}
}