package net.sourceforge.javautil.database.jpa;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.io.IInputSource;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.xml.XMLDocument;
import net.sourceforge.javautil.database.jpa.descriptor.IPersistenceUnit;
import net.sourceforge.javautil.database.jpa.descriptor.IPersistenceXML;
import net.sourceforge.javautil.database.jpa.descriptor.impl.PersistenceUnit;
import net.sourceforge.javautil.database.jpa.descriptor.impl.PersistenceXML;
import net.sourceforge.javautil.datasource.IDataSourceFactory;
/**
* Utilities related to JPA (Java Persistence Architecture).
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class JPAUtil {
/**
* @param persistenceXMLInput The file for reading the persistence xml data
*
* @see #load(PersistenceXML)
*/
public static PersistenceSetup load (IVirtualFile persistenceXMLInput, IDataSourceFactory dsFactory) {
return load(XMLDocument.read(persistenceXMLInput, PersistenceXML.class), persistenceXMLInput.getOwner(), dsFactory);
}
/**
* @param xml The loaded XML persistence configuration
* @return The setup related to the persistence xml, or null if no persistence units were defined
*/
public static PersistenceSetup load (IPersistenceXML xml, IVirtualDirectory root, IDataSourceFactory dsFactory) {
if (xml.getUnits().size() == 0) return null;
Map<String, EntityManagerFactory> factories = new LinkedHashMap<String, EntityManagerFactory>();
for (IPersistenceUnit unit : xml.getUnits()) {
String dataSource = unit.getNonJTADataSource();
if (dataSource != null) {
factories.put(unit.getName(), createFactory(
SimplePersistenceUnitInfo.getFrom(
unit, root.getURL(), PersistenceUnitTransactionType.RESOURCE_LOCAL,
dsFactory.getNonJTADataSource(unit.getNonJTADataSource()))
)
);
} else {
factories.put(unit.getName(), createFactory(
SimplePersistenceUnitInfo.getFrom(
unit, root.getURL(), PersistenceUnitTransactionType.JTA,
dsFactory.getNonJTADataSource(unit.getJTADataSource()))
)
);
}
}
return new PersistenceSetup(factories);
}
/**
* @param info The info to use for creating the EMF
* @return A new EMF based on the unit setup
*/
public static EntityManagerFactory createFactory (PersistenceUnitInfo info) {
Class<? extends PersistenceProvider> ppc = ReflectionUtil.getClass( info.getPersistenceProviderClassName() );
PersistenceProvider provider = ReflectionUtil.newInstance(ppc, new Class[0]);
return provider.createContainerEntityManagerFactory(info, new LinkedHashMap( info.getProperties() ));
}
/**
* This provides extended functionality with automatically started/committed transactions.
*
* @param factory The factory to use in order to create the extended manager
* @return An extended manager implementation
*/
public static IEntityManagerExtended createExtendedManager (EntityManagerFactory factory) {
return EntityManagerExtendedHandler.createEMProxy(new EntityManagerExtendedImpl(factory.createEntityManager()), IEntityManagerExtended.class);
}
}