package net.sourceforge.javautil.database.jpa;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import net.sourceforge.javautil.classloader.impl.ClassContext;
import net.sourceforge.javautil.classloader.impl.StandardClassLoaderHeiarchy;
import net.sourceforge.javautil.classloader.resolver.IClassPackage;
import net.sourceforge.javautil.classloader.resolver.ClassPackageContext;
import net.sourceforge.javautil.classloader.resolver.IClassPackageDependencyReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageResolver;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageDependencyReferenceImpl;
import net.sourceforge.javautil.classloader.source.ClassSourceUtil;
import net.sourceforge.javautil.classloader.source.CompositeClassSource;
import net.sourceforge.javautil.classloader.util.ClassPackageUtil;
import net.sourceforge.javautil.common.ReflectionUtil;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.database.jpa.descriptor.IPersistenceUnit;
/**
* A simple unit info implementation.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: SimplePersistenceUnitInfo.java 2297 2010-06-16 00:13:14Z ponderator $
*/
public class SimplePersistenceUnitInfo implements PersistenceUnitInfo {
public static SimplePersistenceUnitInfo getFrom (IPersistenceUnit unit, URL rootURL, PersistenceUnitTransactionType type, DataSource dataSource) {
try {
SimplePersistenceUnitInfo info = new SimplePersistenceUnitInfo(unit.getName(), unit.getProvider(), rootURL);
info.type = type;
info.dataSource = dataSource;
info.excludeUnlistedClasses = unit.isExcludedUnlistedClasses() != null ? unit.isExcludedUnlistedClasses() : false;
for (String jarFile : unit.getJarFiles()) {
info.jarFileURLS.add( new URL(jarFile) );
}
info.managedClassNames.addAll(unit.getClasses());
info.mappingFiles.addAll(unit.getMappingFiles());
info.settings.putAll( unit.getProperties() );
return info;
} catch (MalformedURLException e) {
throw ThrowableManagerRegistry.caught(e);
}
}
protected final String name;
protected final String providerClassName;
protected final URL rootURL;
protected PersistenceUnitTransactionType type = PersistenceUnitTransactionType.RESOURCE_LOCAL;
protected Properties settings = new Properties();
protected DataSource dataSource;
protected boolean excludeUnlistedClasses = false;
protected List<URL> jarFileURLS = new ArrayList<URL>();
protected List<String> managedClassNames = new ArrayList<String>();
protected List<String> mappingFiles = new ArrayList<String>();
protected List<ClassTransformer> transformers = new ArrayList<ClassTransformer>();
protected ClassContext classContext;
public SimplePersistenceUnitInfo(String name, String providerClassName, URL rootURL) {
this.rootURL = rootURL;
this.name = name;
this.providerClassName = providerClassName;
}
public void addTransformer(ClassTransformer transformer) {
this.transformers.add(transformer);
}
public ClassLoader getClassLoader() {
if (this.classContext == null) {
this.classContext = this.createClassContext();
}
return this.classContext;
}
public ClassLoader getNewTempClassLoader() {
return this.createClassContext();
}
public boolean excludeUnlistedClasses() { return this.excludeUnlistedClasses; }
public List<URL> getJarFileUrls() { return this.jarFileURLS; }
/**
* This facilitate adding {@link #getJarFileUrls()} by means of the {@link IClassPackage} framework. This
* requires that a {@link ClassPackageContext#getResolver()} be setup.
*
* @param groupId The group id of the package
* @param artifactId The artifact id of the package
* @param version The version of the package
*/
public void add (String groupId, String artifactId, String version) {
IClassPackageResolver resolver = ClassPackageContext.getPackageResolver();
if (resolver == null) throw new IllegalStateException("No class package context resolver available, this feature is disabled");
IClassPackageDependencyReference ref = new ClassPackageDependencyReferenceImpl(groupId, artifactId, version, null);
IClassPackage pkg = ClassPackageUtil.get(resolver, ref, true);
if (pkg == null) throw new IllegalArgumentException("Could not resolve: " + ref);
this.getJarFileUrls().add(pkg.getMainJarSource().getURL());
}
public List<String> getManagedClassNames() { return this.managedClassNames; }
public List<String> getMappingFileNames() { return this.mappingFiles; }
public DataSource getJtaDataSource() {
return type == PersistenceUnitTransactionType.RESOURCE_LOCAL ? null : this.dataSource;
}
public DataSource getNonJtaDataSource() {
return type == PersistenceUnitTransactionType.JTA ? null : this.dataSource;
}
public String getPersistenceProviderClassName() { return this.providerClassName; }
public String getPersistenceUnitName() { return this.name; }
public URL getPersistenceUnitRootUrl() { return this.rootURL; }
public Properties getProperties() { return this.settings; }
public PersistenceUnitTransactionType getTransactionType() { return this.type; }
public SimplePersistenceUnitInfo setSettings(Properties settings) { this.settings = settings; return this; }
public SimplePersistenceUnitInfo setDataSource(DataSource dataSource) { this.dataSource = dataSource; return this; }
public SimplePersistenceUnitInfo setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
this.excludeUnlistedClasses = excludeUnlistedClasses;
return this;
}
public SimplePersistenceUnitInfo setType(PersistenceUnitTransactionType type) { this.type = type; return this; }
/**
* @return The class context for this unit, including any specified transformers
*/
protected ClassContext createClassContext () {
return new ClassContext(new StandardClassLoaderHeiarchy(), this.createClassSource())
.setTransformer(new PersistenceClassTransformer(this.transformers.toArray(new ClassTransformer[this.transformers.size()])));
}
/**
* @return The composite class including the {@link #rootURL} and any {@link #jarFileURLS}
*/
protected CompositeClassSource createClassSource () {
CompositeClassSource ccl = new CompositeClassSource();
ccl.add( ClassSourceUtil.getFor( this.rootURL ) );
return ccl;
}
}