/*
* JBoss, Home of Professional Open Source.
* Copyright 2012, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.jpa.config;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
import org.jboss.jandex.Index;
import org.jipijapa.plugin.spi.PersistenceUnitMetadata;
import org.jipijapa.plugin.spi.TempClassLoaderFactory;
/**
* Represents the persistence unit definition
*
* @author Scott Marlow (based on work by Bill Burke)
*/
public class PersistenceUnitMetadataImpl implements PersistenceUnitMetadata {
// required: name of the persistent unit
private volatile String name;
// required: name of the persistent unit scoped to deployment file
private volatile String scopedName;
// optional: jndi name of non-jta datasource
private volatile String nonJtaDataSourceName;
// optional: jndi name of jta datasource
private volatile String jtaDataSourceName;
private volatile DataSource jtaDatasource;
private volatile DataSource nonJtaDataSource;
// optional: provider classname (must implement javax.persistence.spi.PersistenceProvider)
private volatile String provider;
// optional: specifies if EntityManagers will be JTA (default) or RESOURCE_LOCAL
private volatile PersistenceUnitTransactionType transactionType;
// optional: collection of individually named managed entity classes
private volatile List<String> classes = new ArrayList<String>(1);
// optional:
private final List<String> packages = new ArrayList<String>(1);
// optional: collection of jar file names that contain entity classes
private volatile List<String> jarFiles = new ArrayList<String>(1);
private volatile List<URL> jarFilesUrls = new ArrayList<URL>();
private volatile URL persistenceUnitRootUrl;
// optional: collection of orm.xml style entity mapping files
private volatile List<String> mappingFiles = new ArrayList<String>(1);
// collection of properties for the persistence provider
private volatile Properties props = new Properties();
// optional: specifies whether to include entity classes in the root folder containing the persistence unit.
private volatile boolean excludeUnlistedClasses;
// optional: validation mode can be "auto", "callback", "none".
private volatile ValidationMode validationMode;
// optional: version of the JPA specification
private volatile String version;
// transformers will be written to when the JPA persistence provider adds their transformer.
// there should be very few calls to add transformers but potentially many calls to get the
// transformer list (once per application class loaded).
private final List<ClassTransformer> transformers = new CopyOnWriteArrayList<ClassTransformer>();
private volatile SharedCacheMode sharedCacheMode;
private volatile ClassLoader classloader;
private volatile TempClassLoaderFactory tempClassLoaderFactory;
private volatile ClassLoader cachedTempClassLoader;
private volatile Map<URL, Index> annotationIndex;
@Override
public void setPersistenceUnitName(String name) {
this.name = name;
}
@Override
public String getPersistenceUnitName() {
return name;
}
@Override
public void setScopedPersistenceUnitName(String scopedName) {
this.scopedName = scopedName;
}
@Override
public String getScopedPersistenceUnitName() {
return scopedName;
}
@Override
public void setPersistenceProviderClassName(String provider) {
if (provider != null && provider.endsWith(".class")) {
this.provider = provider.substring(0, provider.length() - 6);
}
this.provider = provider;
}
@Override
public String getPersistenceProviderClassName() {
return provider;
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return transactionType;
}
@Override
public DataSource getJtaDataSource() {
return jtaDatasource;
}
@Override
public void setJtaDataSource(DataSource jtaDataSource) {
this.jtaDatasource = jtaDataSource;
}
@Override
public void setNonJtaDataSource(DataSource nonJtaDataSource) {
this.nonJtaDataSource = nonJtaDataSource;
}
@Override
public DataSource getNonJtaDataSource() {
return nonJtaDataSource;
}
@Override
public void setJtaDataSourceName(String jtaDatasource) {
this.jtaDataSourceName = jtaDatasource;
}
@Override
public String getJtaDataSourceName() {
return jtaDataSourceName;
}
@Override
public void setNonJtaDataSourceName(String nonJtaDatasource) {
this.nonJtaDataSourceName = nonJtaDatasource;
}
@Override
public String getNonJtaDataSourceName() {
return this.nonJtaDataSourceName;
}
@Override
public void setPersistenceUnitRootUrl(URL persistenceUnitRootUrl) {
this.persistenceUnitRootUrl = persistenceUnitRootUrl;
}
@Override
public URL getPersistenceUnitRootUrl() {
return persistenceUnitRootUrl;
}
@Override
public void setAnnotationIndex(Map<URL, Index> indexes) {
annotationIndex = indexes;
}
@Override
public Map<URL, Index> getAnnotationIndex() {
return annotationIndex;
}
@Override
public List<String> getManagedClassNames() {
return classes;
}
@Override
public void setManagedClassNames(List<String> classes) {
this.classes = classes;
}
@Override
public boolean excludeUnlistedClasses() {
return excludeUnlistedClasses;
}
@Override
public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) {
this.excludeUnlistedClasses = excludeUnlistedClasses;
}
@Override
public void setTransactionType(PersistenceUnitTransactionType transactionType) {
this.transactionType = transactionType;
}
@Override
public void setMappingFiles(List<String> mappingFiles) {
this.mappingFiles = mappingFiles;
}
@Override
public List<String> getMappingFileNames() {
return mappingFiles;
}
@Override
public List<URL> getJarFileUrls() {
return jarFilesUrls;
}
@Override
public void setJarFileUrls(List<URL> jarFilesUrls) {
this.jarFilesUrls = jarFilesUrls;
}
@Override
public List<String> getJarFiles() {
return jarFiles;
}
@Override
public void setJarFiles(List<String> jarFiles) {
this.jarFiles = jarFiles;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("PersistenceUnitMetadataImpl(version=")
.append(version)
.append(") [\n")
.append("\tname: ").append(name).append("\n")
.append("\tjtaDataSource: ").append(jtaDataSourceName).append("\n")
.append("\tnonJtaDataSource: ").append(nonJtaDataSourceName).append("\n")
.append("\ttransactionType: ").append(transactionType).append("\n")
.append("\tprovider: ").append(provider).append("\n")
.append("\tclasses[\n");
if (classes != null) {
for (String elt : classes) {
sb.append("\t\t").append(elt);
}
}
sb.append("\t]\n")
.append("\tpackages[\n");
if (packages != null) {
for (String elt : packages) {
sb.append("\t\t").append(elt).append("\n");
}
}
sb.append("\t]\n")
.append("\tmappingFiles[\n");
if (mappingFiles != null) {
for (String elt : mappingFiles) {
sb.append("\t\t").append(elt).append("\n");
}
}
sb.append("\t]\n")
.append("\tjarFiles[\n");
if (jarFiles != null) {
for (String elt : jarFiles) {
sb.append("\t\t").append(elt).append("\n");
}
}
sb.append("\t]\n");
if (validationMode != null) {
sb.append("\tvalidation-mode: ").append(validationMode).append("\n");
}
if (sharedCacheMode != null) {
sb.append("\tshared-cache-mode: ").append(sharedCacheMode).append("\n");
}
sb.append("\tproperties[\n");
if (props != null) {
for (Entry<Object, Object> elt : props.entrySet()) {
sb.append("\t\t").append(elt.getKey()).append(": ").append(elt.getValue()).append("\n");
}
}
sb.append("\t]").append("]");
return sb.toString();
}
@Override
public void setValidationMode(ValidationMode validationMode) {
this.validationMode = validationMode;
}
@Override
public ValidationMode getValidationMode() {
return validationMode;
}
@Override
public void setProperties(Properties props) {
this.props = props;
}
@Override
public Properties getProperties() {
return props;
}
@Override
public void setPersistenceXMLSchemaVersion(String version) {
this.version = version;
}
@Override
public String getPersistenceXMLSchemaVersion() {
return version;
}
@Override
public void setClassLoader(ClassLoader cl) {
classloader = cl;
}
/**
* Return a classloader that the provider can use to load the entity classes.
* <p/>
* Note from JPA 8.2:
* All persistence classes defined at the level of the Java EE EAR must be accessible to other Java EE
* components in the application—i.e. loaded by the application classloader—such that if the same entity
* class is referenced by two different Java EE components (which may be using different persistence
* units), the referenced class is the same identical class.
*
* @return
*/
@Override
public ClassLoader getClassLoader() {
return classloader;
}
@Override
public List<ClassTransformer> getTransformers() {
return transformers;
}
@Override
public void addTransformer(ClassTransformer classTransformer) {
transformers.add(classTransformer);
}
@Override
public void setTempClassLoaderFactory(TempClassLoaderFactory tempClassloaderFactory) {
this.tempClassLoaderFactory = tempClassloaderFactory;
cachedTempClassLoader = null; // always clear the cached temp classloader when a new tempClassloaderFactory is set.
}
@Override
public ClassLoader cacheTempClassLoader() {
if(cachedTempClassLoader == null && tempClassLoaderFactory != null) {
cachedTempClassLoader = tempClassLoaderFactory.createNewTempClassLoader();
}
return cachedTempClassLoader;
}
@Override
public ClassLoader getNewTempClassLoader() {
return tempClassLoaderFactory != null ?
tempClassLoaderFactory.createNewTempClassLoader() : null;
}
@Override
public SharedCacheMode getSharedCacheMode() {
return sharedCacheMode;
}
@Override
public void setSharedCacheMode(SharedCacheMode sharedCacheMode) {
this.sharedCacheMode = sharedCacheMode;
}
}