/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.amber.manager;
import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.sql.DataSource;
import com.caucho.amber.AmberRuntimeException;
import com.caucho.amber.cfg.EntityMappingsConfig;
import com.caucho.amber.cfg.MappedSuperclassConfig;
import com.caucho.amber.gen.AmberEnhancer;
import com.caucho.amber.gen.AmberGenerator;
import com.caucho.amber.type.EmbeddableType;
import com.caucho.amber.type.EntityType;
import com.caucho.amber.type.ListenerType;
import com.caucho.amber.type.MappedSuperclassType;
import com.caucho.bytecode.JClassWrapper;
import com.caucho.config.Config;
import com.caucho.config.ConfigException;
import com.caucho.config.LineConfigException;
import com.caucho.config.Names;
import com.caucho.config.inject.BeanBuilder;
import com.caucho.config.inject.InjectManager;
import com.caucho.config.inject.CurrentLiteral;
import com.caucho.config.program.ConfigProgram;
import com.caucho.env.jpa.EntityManagerFactoryProxy;
import com.caucho.env.jpa.EntityManagerJtaProxy;
import com.caucho.env.jpa.ConfigPersistence;
import com.caucho.env.jpa.ConfigPersistenceUnit;
import com.caucho.loader.DynamicClassLoader;
import com.caucho.loader.Environment;
import com.caucho.loader.EnvironmentClassLoader;
import com.caucho.loader.EnvironmentListener;
import com.caucho.loader.EnvironmentLocal;
import com.caucho.loader.enhancer.EnhancerManager;
import com.caucho.loader.enhancer.ScanClass;
import com.caucho.loader.enhancer.ScanClassAllow;
import com.caucho.loader.enhancer.ScanListener;
import com.caucho.loader.enhancer.ScanMatch;
import com.caucho.util.*;
import com.caucho.vfs.*;
/**
* Environment-based container.
*/
public class AmberContainer implements ScanListener, EnvironmentListener {
private static final L10N L = new L10N(AmberContainer.class);
private static final Logger log = Logger.getLogger(AmberContainer.class
.getName());
private static final EnvironmentLocal<AmberContainer> _localContainer
= new EnvironmentLocal<AmberContainer>();
private EnvironmentClassLoader _parentLoader;
private ClassLoader _tempLoader;
// private EnhancingClassLoader _enhancedLoader;
private AmberContainer _parentAmberContainer;
private AmberEnhancer _enhancer;
private DataSource _dataSource;
private DataSource _readDataSource;
private DataSource _xaDataSource;
private boolean _createDatabaseTables;
private ArrayList<ConfigProgram> _unitDefaultList
= new ArrayList<ConfigProgram>();
private HashMap<String, ArrayList<ConfigProgram>> _unitDefaultMap
= new HashMap<String, ArrayList<ConfigProgram>>();
private ArrayList<ConfigPersistenceUnit> _unitConfigList
= new ArrayList<ConfigPersistenceUnit>();
private HashMap<String, AmberPersistenceUnit> _unitMap
= new HashMap<String, AmberPersistenceUnit>();
private HashMap<String, EntityManagerFactory> _factoryMap
= new HashMap<String, EntityManagerFactory>();
private HashMap<String, EntityManager> _persistenceContextMap
= new HashMap<String, EntityManager>();
private HashMap<String, EmbeddableType> _embeddableMap
= new HashMap<String, EmbeddableType>();
private HashMap<String, EntityType> _entityMap
= new HashMap<String, EntityType>();
private HashMap<String, MappedSuperclassType> _mappedSuperclassMap
= new HashMap<String, MappedSuperclassType>();
private HashMap<String, ListenerType> _defaultListenerMap
= new HashMap<String, ListenerType>();
private HashMap<String, ArrayList<ListenerType>> _entityListenerMap
= new HashMap<String, ArrayList<ListenerType>>();
private Throwable _exception;
private HashMap<String, Throwable> _embeddableExceptionMap
= new HashMap<String, Throwable>();
private HashMap<String, Throwable> _entityExceptionMap
= new HashMap<String, Throwable>();
private HashMap<String, Throwable> _listenerExceptionMap
= new HashMap<String, Throwable>();
private HashMap<Path, RootContext> _persistenceRootMap
= new HashMap<Path, RootContext>();
private ArrayList<RootContext> _pendingRootList
= new ArrayList<RootContext>();
private ArrayList<AmberPersistenceUnit> _pendingUnitList
= new ArrayList<AmberPersistenceUnit>();
private ArrayList<LazyEntityManagerFactory> _pendingFactoryList
= new ArrayList<LazyEntityManagerFactory>();
private HashSet<URL> _persistenceURLSet = new HashSet<URL>();
private ArrayList<String> _pendingClasses = new ArrayList<String>();
private AmberContainer(ClassLoader loader)
{
_parentAmberContainer = _localContainer.get(loader);
_parentLoader = Environment.getEnvironmentClassLoader(loader);
_localContainer.set(this, _parentLoader);
_tempLoader = _parentLoader.getNewTempClassLoader();
_enhancer = new AmberEnhancer(this);
EnhancerManager.create(_parentLoader).addClassEnhancer(_enhancer);
if (_parentAmberContainer != null)
copyContainerDefaults(_parentAmberContainer);
_parentLoader.addScanListener(this);
Environment.addEnvironmentListener(this, _parentLoader);
try {
if (_parentLoader instanceof DynamicClassLoader)
((DynamicClassLoader) _parentLoader).make();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Returns the local container.
*/
public static AmberContainer create()
{
return create(Thread.currentThread().getContextClassLoader());
}
/**
* Returns the local container.
*/
public static AmberContainer create(ClassLoader loader)
{
synchronized (_localContainer) {
AmberContainer container = _localContainer.getLevel(loader);
if (container == null) {
container = new AmberContainer(loader);
_localContainer.set(container, loader);
}
return container;
}
}
/**
* Returns the local container.
*/
public static AmberContainer getCurrent()
{
return getCurrent(Thread.currentThread().getContextClassLoader());
}
/**
* Returns the current environment container.
*/
public static AmberContainer getCurrent(ClassLoader loader)
{
synchronized (_localContainer) {
return _localContainer.get(loader);
}
}
/**
* Sets the primary data source.
*/
public void setDataSource(DataSource dataSource)
{
_dataSource = dataSource;
}
/**
* Gets the primary data source.
*/
public DataSource getDataSource()
{
return _dataSource;
}
/**
* Sets the read data source.
*/
public void setReadDataSource(DataSource dataSource)
{
_readDataSource = dataSource;
}
/**
* Gets the read data source.
*/
public DataSource getReadDataSource()
{
return _readDataSource;
}
/**
* Sets the xa data source.
*/
public void setXADataSource(DataSource dataSource)
{
_xaDataSource = dataSource;
}
/**
* Gets the XA data source.
*/
public DataSource getXADataSource()
{
return _xaDataSource;
}
/**
* True if database tables should be created automatically.
*/
public boolean getCreateDatabaseTables()
{
return _createDatabaseTables;
}
/**
* True if database tables should be created automatically.
*/
public void setCreateDatabaseTables(boolean isCreate)
{
_createDatabaseTables = isCreate;
}
/**
* Returns the parent loader
*/
public ClassLoader getParentClassLoader()
{
return _parentLoader;
}
/**
* Returns the parent loader
*/
public ClassLoader getEnhancedLoader()
{
return _parentLoader;
}
/**
* Returns the enhancer.
*/
public AmberGenerator getGenerator()
{
return _enhancer;
}
/**
* Returns the persistence unit JNDI context.
*/
public static String getPersistenceUnitJndiPrefix()
{
return "java:comp/env/persistence/_amber_PersistenceUnit/";
}
/**
* Adds a persistence-unit default
*/
public void addPersistenceUnitDefault(ConfigProgram program)
{
_unitDefaultList.add(program);
}
/**
* Returns the persistence-unit default list.
*/
public ArrayList<ConfigProgram> getPersistenceUnitDefaultList()
{
return _unitDefaultList;
}
/**
* Adds a persistence-unit default
*/
public void addPersistenceUnitProxy(String name,
ArrayList<ConfigProgram> program)
{
ArrayList<ConfigProgram> oldProgram = _unitDefaultMap.get(name);
if (oldProgram == null)
oldProgram = new ArrayList<ConfigProgram>();
oldProgram.addAll(program);
_unitDefaultMap.put(name, oldProgram);
}
public ArrayList<ConfigProgram> getProxyProgram(String name)
{
return _unitDefaultMap.get(name);
}
/**
* Returns the persistence unit JNDI context.
*/
public static String getPersistenceContextJndiPrefix()
{
// return "java:comp/env/persistence/PersistenceContext/";
return "java:comp/env/persistence/";
}
/**
* Returns the JClassLoader.
*/
public ClassLoader getTempClassLoader()
{
return _tempLoader;
}
public Class loadTempClass(String name) throws ClassNotFoundException
{
return Class.forName(name, false, getTempClassLoader());
}
private void copyContainerDefaults(AmberContainer parent)
{
_dataSource = parent._dataSource;
_xaDataSource = parent._xaDataSource;
_readDataSource = parent._readDataSource;
_createDatabaseTables = parent._createDatabaseTables;
}
public void init()
{
}
/**
* Returns the EmbeddableType for an introspected class.
*/
public EmbeddableType getEmbeddable(String className)
{
Throwable e = _embeddableExceptionMap.get(className);
if (e != null)
throw new AmberRuntimeException(e);
else if (_exception != null) {
throw new AmberRuntimeException(_exception);
}
return _embeddableMap.get(className);
}
/**
* Returns the EntityType for an introspected class.
*/
public EntityType getEntity(String className)
{
Throwable e = _entityExceptionMap.get(className);
if (e != null)
throw new AmberRuntimeException(e);
else if (_exception != null) {
throw new AmberRuntimeException(_exception);
}
return _entityMap.get(className);
}
/**
* Returns the MappedSuperclassType for an introspected class.
*/
public MappedSuperclassType getMappedSuperclass(String className)
{
Throwable e = _entityExceptionMap.get(className);
if (e != null)
throw new AmberRuntimeException(e);
else if (_exception != null) {
throw new AmberRuntimeException(_exception);
}
MappedSuperclassType type = _mappedSuperclassMap.get(className);
return type;
}
/**
* Returns the default ListenerType for an introspected class.
*/
public ListenerType getDefaultListener(String className)
{
if (true)
return null;
Throwable e = _listenerExceptionMap.get(className);
if (e != null)
throw new AmberRuntimeException(e);
else if (_exception != null) {
throw new AmberRuntimeException(_exception);
}
return _defaultListenerMap.get(className);
}
/**
* Returns the entity ListenerType for an introspected class.
*/
public ListenerType getEntityListener(String className)
{
if (true)
return null;
Throwable e = _listenerExceptionMap.get(className);
if (e != null)
throw new AmberRuntimeException(e);
else if (_exception != null) {
throw new AmberRuntimeException(_exception);
}
ArrayList<ListenerType> listenerList;
for (Map.Entry<String, ArrayList<ListenerType>> entry : _entityListenerMap
.entrySet()) {
listenerList = entry.getValue();
if (listenerList == null)
continue;
for (ListenerType listener : listenerList) {
if (className.equals(listener.getBeanClass().getName()))
return listener;
}
}
return null;
}
/**
* Returns the listener for an introspected class.
*/
public ListenerType getListener(String className)
{
if (true)
return null;
ListenerType listener = getDefaultListener(className);
if (listener == null)
listener = getEntityListener(className);
return listener;
}
/**
* Returns the entity listeners for an entity.
*/
public ArrayList<ListenerType> getEntityListeners(String entityClassName)
{
return null;
// return _entityListenerMap.get(entityClassName);
}
/**
* Adds an entity for an introspected class.
*/
public void addEntityException(String className, Throwable e)
{
_entityExceptionMap.put(className, e);
}
/**
* Adds an entity for an introspected class.
*/
public void addException(Throwable e)
{
if (_exception == null) {
_exception = e;
Environment.setConfigException(e);
}
}
public Throwable getConfigException()
{
return _exception;
}
/**
* Adds an embeddable for an introspected class.
*/
public void addEmbeddable(String className, EmbeddableType type)
{
_embeddableMap.put(className, type);
}
/**
* Adds an entity for an introspected class.
*/
public void addEntity(String className, EntityType type)
{
_entityMap.put(className, type);
}
/**
* Adds a mapped superclass for an introspected class.
*/
public void addMappedSuperclass(String className, MappedSuperclassType type)
{
_mappedSuperclassMap.put(className, type);
}
/**
* Adds a default listener.
*/
public void addDefaultListener(String className, ListenerType type)
{
_defaultListenerMap.put(className, type);
}
/**
* Adds an entity listener.
*/
public void addEntityListener(String entityClassName,
ListenerType listenerType)
{
ArrayList<ListenerType> listenerList
= _entityListenerMap.get(entityClassName);
if (listenerList == null) {
listenerList = new ArrayList<ListenerType>();
_entityListenerMap.put(entityClassName, listenerList);
}
listenerList.add(listenerType);
}
/**
* Initialize the entity homes.
*/
public void initEntityHomes()
{
throw new UnsupportedOperationException();
}
public EntityManagerFactory createEntityManagerFactory(PersistenceUnitInfo info)
{
Path path = Vfs.lookup(info.getPersistenceUnitRootUrl());
addPersistenceUnit(path);
String name = info.getPersistenceUnitName();
configurePersistenceRoot(info);
AmberPersistenceUnit pUnit = createPersistenceUnit(name);
return getEntityManagerFactory(name);
}
public AmberPersistenceUnit createPersistenceUnit(String name)
{
AmberPersistenceUnit unit = _unitMap.get(name);
if (unit == null) {
unit = new AmberPersistenceUnit(this, name);
_unitMap.put(unit.getName(), unit);
}
return unit;
}
public void start()
{
// configurePersistenceRoots();
startPersistenceUnits();
}
public AmberPersistenceUnit getPersistenceUnit(String name)
{
if (_exception != null)
throw new AmberRuntimeException(_exception);
return _unitMap.get(name);
}
public EntityManagerFactory getEntityManagerFactory(String name)
{
if (_exception != null)
throw new AmberRuntimeException(_exception);
EntityManagerFactory factory = _factoryMap.get(name);
if (factory != null)
return factory;
/*
if (_pendingRootList.size() > 0)
configurePersistenceRoots();
*/
factory = _factoryMap.get(name);
if (factory != null)
return factory;
AmberPersistenceUnit amberUnit = _unitMap.get(name);
if (amberUnit != null) {
factory = new AmberEntityManagerFactory(amberUnit);
_factoryMap.put(name, factory);
return factory;
}
if ("".equals(name) && _factoryMap.size() == 1)
return _factoryMap.values().iterator().next();
if ("".equals(name) && _unitMap.size() == 1) {
amberUnit = _unitMap.values().iterator().next();
factory = new AmberEntityManagerFactory(amberUnit);
_factoryMap.put(name, factory);
return factory;
}
if (_parentAmberContainer != null)
return _parentAmberContainer.getEntityManagerFactory(name);
else
return null;
}
public EntityManager getPersistenceContext(String name)
{
if (_exception != null)
throw new AmberRuntimeException(_exception);
if ("".equals(name) && _unitConfigList.size() > 0)
name = _unitConfigList.get(0).getName();
EntityManager context = _persistenceContextMap.get(name);
if (context != null)
return context;
/*
if (_pendingRootList.size() > 0)
configurePersistenceRoots();
*/
if ("".equals(name) && _unitConfigList.size() > 0)
name = _unitConfigList.get(0).getName();
context = _persistenceContextMap.get(name);
if (context != null)
return context;
AmberPersistenceUnit amberUnit = _unitMap.get(name);
if (amberUnit != null) {
context = new EntityManagerProxy(amberUnit);
_persistenceContextMap.put(name, context);
return context;
}
return null;
}
public EntityManager getExtendedPersistenceContext(String name)
{
if (_exception != null)
throw new AmberRuntimeException(_exception);
if ("".equals(name) && _unitConfigList.size() > 0)
name = _unitConfigList.get(0).getName();
/*
if (_pendingRootList.size() > 0)
configurePersistenceRoots();
*/
if ("".equals(name) && _unitConfigList.size() > 0)
name = _unitConfigList.get(0).getName();
AmberPersistenceUnit amberUnit = _unitMap.get(name);
if (amberUnit != null) {
return new EntityManagerExtendedProxy(amberUnit);
}
return null;
}
/**
* Adds a persistence root.
*/
public void addPersistenceUnit(Path root)
{
if (_persistenceRootMap.get(root) != null)
return;
RootContext context = new RootContext(root);
_persistenceRootMap.put(root, context);
_pendingRootList.add(context);
}
private Class loadProvider(URL url)
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = null;
try {
is = url.openStream();
ReadStream in = Vfs.openRead(is);
String line;
while ((line = in.readLine()) != null) {
line = line.trim();
if (! "".equals(line) && ! line.startsWith("#")) {
return Class.forName(line, false, loader);
}
}
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
} finally {
IoUtil.close(is);
}
return null;
}
private void configurePersistenceRoot(PersistenceUnitInfo info)
{
URL rootUrl = info.getPersistenceUnitRootUrl();
String pUnitName = info.getPersistenceUnitName();
Path root = Vfs.lookup(rootUrl);
try {
Path ormXml = root.lookup("META-INF/orm.xml");
EntityMappingsConfig entityMappings
= configureMappingFile(root, ormXml);
// HashMap<String, JClass> classMap = new HashMap<String, JClass>();
try {
if (log.isLoggable(Level.CONFIG))
log.config("Amber PersistenceUnit[" + pUnitName + "] configuring " + rootUrl);
ArrayList<String> classes = new ArrayList<String>();
if (! info.excludeUnlistedClasses()) {
/*
for (String className : rootContext.getClassNameList())
lookupClass(className, classMap, entityMappings);
*/
// unitConfig.addAllClasses(classMap);
}
ArrayList<EntityMappingsConfig> entityMappingsList
= new ArrayList<EntityMappingsConfig>();
if (entityMappings != null)
entityMappingsList.add(entityMappings);
/*
// jpa/0s2n: <jar-file>
for (String fileName : unitConfig.getJarFiles()) {
JarPath jarFile;
Path parent = root;
if (root instanceof JarPath) {
parent = ((JarPath) root).getContainer().getParent();
}
jarFile = JarPath.create(parent.lookup(fileName));
classMap.clear();
unitConfig.addAllClasses(classMap);
}
*/
// jpa/0s2l: custom mapping-file.
/*
for (String fileName : unitConfig.getMappingFiles()) {
Path mappingFile = root.lookup(fileName);
EntityMappingsConfig mappingFileConfig
= configureMappingFile(root, mappingFile);
if (mappingFileConfig != null) {
entityMappingsList.add(mappingFileConfig);
classMap.clear();
unitConfig.addAllClasses(classMap);
}
}
*/
AmberPersistenceUnit unit = init(info);
_pendingUnitList.add(unit);
_unitMap.put(unit.getName(), unit);
} catch (Exception e) {
addException(e);
log.log(Level.WARNING, e.toString(), e);
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw ConfigException.create(e);
}
}
private AmberPersistenceUnit init(PersistenceUnitInfo info)
throws Exception
{
String name = info.getPersistenceUnitName();
AmberPersistenceUnit unit
= new AmberPersistenceUnit(this, name);
unit.setJPA(true);
if (info.getJtaDataSource() != null)
unit.setJtaDataSource(info.getJtaDataSource());
if (info.getNonJtaDataSource() != null)
unit.setNonJtaDataSource(info.getNonJtaDataSource());
// unit.setEntityMappingsList(entityMappings);
unit.init();
ClassLoader tempLoader = info.getNewTempClassLoader();
for (String className : info.getManagedClassNames()) {
Class type = Class.forName(className, false, tempLoader);
unit.addEntityClass(className, type);//JClassWrapper.create(type));
}
unit.generate();
return unit;
}
/**
* Adds the URLs for the classpath.
*/
public void startPersistenceUnits()
{
Thread thread = Thread.currentThread();
ClassLoader oldLoader = thread.getContextClassLoader();
try {
// jpa/1630
// thread.setContextClassLoader(_tempLoader);
thread.setContextClassLoader(_parentLoader);
ArrayList<AmberPersistenceUnit> unitList
= new ArrayList<AmberPersistenceUnit>(_pendingUnitList);
_pendingUnitList.clear();
ArrayList<LazyEntityManagerFactory> lazyEmfList = new ArrayList<LazyEntityManagerFactory>(
_pendingFactoryList);
_pendingFactoryList.clear();
for (LazyEntityManagerFactory lazyEmf : lazyEmfList) {
lazyEmf.init();
}
for (AmberPersistenceUnit unit : unitList) {
unit.initEntityHomes();
}
} finally {
thread.setContextClassLoader(oldLoader);
}
}
//
// private
//
// Configures the default orm.xml or mapping files specified with
// mapping-file tags within a persistence-unit.
//
private EntityMappingsConfig configureMappingFile(Path root, Path xmlFile)
throws Exception
{
EntityMappingsConfig entityMappings = null;
if (xmlFile.exists()) {
InputStream is = xmlFile.openRead();
entityMappings = new EntityMappingsConfig();
entityMappings.setRoot(root);
new Config().configure(entityMappings, is,
"com/caucho/amber/cfg/mapping-30.rnc");
}
return entityMappings;
}
private void lookupClass(String className, HashMap<String, Class> classMap,
EntityMappingsConfig entityMappings) throws Exception
{
Class type = loadTempClass(className);
if (type != null) {
boolean isEntity = type.getAnnotation(javax.persistence.Entity.class) != null;
boolean isEmbeddable
= type.getAnnotation(javax.persistence.Embeddable.class) != null;
boolean isMappedSuperclass
= type.getAnnotation(javax.persistence.MappedSuperclass.class) != null;
MappedSuperclassConfig mappedSuperclassOrEntityConfig = null;
if (entityMappings != null) {
mappedSuperclassOrEntityConfig =
entityMappings.getEntityConfig(className);
if (mappedSuperclassOrEntityConfig == null)
mappedSuperclassOrEntityConfig
= entityMappings.getMappedSuperclass(className);
}
if (isEntity || isEmbeddable || isMappedSuperclass
|| (mappedSuperclassOrEntityConfig != null)) {
classMap.put(className, type);
}
}
}
//
// ScanListener
//
/**
* Since Amber enhances it's priority 0
*/
public int getScanPriority()
{
return 0;
}
/**
* Returns true if the root is a valid scannable root.
*/
@Override
public boolean isRootScannable(Path root, String packageRoot)
{
if (! root.lookup("META-INF/persistence.xml").canRead())
return false;
RootContext context = _persistenceRootMap.get(root);
if (context == null) {
context = new RootContext(root);
_pendingRootList.add(context);
_persistenceRootMap.put(root, context);
}
if (context.isScanComplete())
return false;
else {
if (log.isLoggable(Level.FINER))
log.finer(this + " scanning " + root);
context.setScanComplete(true);
return true;
}
}
@Override
public ScanClass scanClass(Path root, String packageRoot,
String className, int modifiers)
{
if (Modifier.isInterface(modifiers))
return null;
else if (Modifier.isAbstract(modifiers))
return null;
else if (Modifier.isFinal(modifiers))
return null;
else if (!Modifier.isPublic(modifiers))
return null;
else
return ScanClassAllow.ALLOW;
}
@Override
public boolean isScanMatchAnnotation(CharBuffer annotationName)
{
if (annotationName.matches("javax.persistence.Entity"))
return true;
else if (annotationName.matches("javax.persistence.Embeddable"))
return true;
else if (annotationName.matches("javax.persistence.MappedSuperclass"))
return true;
else
return false;
}
/**
* Callback to note the class matches
*/
public void classMatchEvent(EnvironmentClassLoader loader, Path root,
String className)
{
RootContext context = _persistenceRootMap.get(root);
if (context == null) {
context = new RootContext(root);
_persistenceRootMap.put(root, context);
_pendingRootList.add(context);
}
context.addClassName(className);
}
//
// EnvironmentListener
//
/**
* Handles the environment config phase
*/
public void environmentConfigure(EnvironmentClassLoader loader)
{
// configurePersistenceRoots();
}
/**
* Handles the environment config phase
*/
public void environmentBind(EnvironmentClassLoader loader)
{
// configurePersistenceRoots();
}
/**
* Handles the case where the environment is starting (after init).
*/
public void environmentStart(EnvironmentClassLoader loader)
{
start();
}
/**
* Handles the case where the environment is stopping
*/
public void environmentStop(EnvironmentClassLoader loader)
{
}
public String toString()
{
return "AmberContainer[" + _parentLoader.getId() + "]";
}
class LazyEntityManagerFactory {
private final ConfigPersistenceUnit _unit;
private final PersistenceProvider _provider;
private final Map _props;
LazyEntityManagerFactory(ConfigPersistenceUnit unit,
PersistenceProvider provider, Map props)
{
_unit = unit;
_provider = provider;
_props = props;
}
void init()
{
/*
synchronized (AmberContainer.this) {
String unitName = _unit.getName();
EntityManagerFactory factory = _factoryMap.get(unitName);
if (factory == null) {
factory = _provider.createContainerEntityManagerFactory(_unit, _props);
if (factory == null)
throw new ConfigException(L.l(
"'{0}' must return an EntityManagerFactory",
_provider.getClass().getName()));
if (log.isLoggable(Level.FINE)) {
log.fine(L.l("Amber creating persistence unit '{0}' created with provider '{1}'",
unitName, _provider.getClass().getName()));
}
_factoryMap.put(unitName, factory);
}
}
*/
}
}
}