You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2009/12/08 22:51:27 UTC
svn commit: r888586 - in /openjpa/branches/1.2.x:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/
openjpa-kernel/src/main/java/org/apache/openjpa/conf/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-kernel/src/main/java/org/ap...
Author: curtisr7
Date: Tue Dec 8 21:51:26 2009
New Revision: 888586
URL: http://svn.apache.org/viewvc?rev=888586&view=rev
Log:
OPENJPA-250: Committing to 1.2.x. Submitted by Patrick Linskey, Simon Droscher, and Rick Curtis.
Modified:
openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
Modified: openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original)
+++ openjpa/branches/1.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Tue Dec 8 21:51:26 2009
@@ -143,7 +143,15 @@
/**
* Representation of the database schema.
*/
- public synchronized SchemaGroup getSchemaGroup() {
+ public SchemaGroup getSchemaGroup() {
+ if(_locking){
+ synchronized(this){
+ if (_schema == null)
+ _schema = ((JDBCConfiguration) getConfiguration()).
+ getSchemaFactoryInstance().readSchema();
+ return _schema;
+ }
+ }
if (_schema == null)
_schema = ((JDBCConfiguration) getConfiguration()).
getSchemaFactoryInstance().readSchema();
@@ -153,33 +161,59 @@
/**
* Representation of the database schema.
*/
- public synchronized void setSchemaGroup(SchemaGroup schema) {
- _schema = schema;
+ public void setSchemaGroup(SchemaGroup schema) {
+ if (_locking) {
+ synchronized (this) {
+ _schema = schema;
+ }
+ } else {
+ _schema = schema;
+ }
}
/**
* Installs mapping strategies on components.
*/
- public synchronized StrategyInstaller getStrategyInstaller() {
- if (_installer == null)
- _installer = new RuntimeStrategyInstaller(this);
- return _installer;
+ public StrategyInstaller getStrategyInstaller() {
+ if (_locking) {
+ synchronized (this) {
+ if (_installer == null)
+ _installer = new RuntimeStrategyInstaller(this);
+ return _installer;
+ }
+ } else {
+ if (_installer == null)
+ _installer = new RuntimeStrategyInstaller(this);
+ return _installer;
+ }
}
/**
* Installs mapping strategies on components.
*/
- public synchronized void setStrategyInstaller(StrategyInstaller installer) {
- _installer = installer;
+ public void setStrategyInstaller(StrategyInstaller installer) {
+ if (_locking) {
+ synchronized (this) {
+ _installer = installer;
+ }
+ } else {
+ _installer = installer;
+ }
}
/**
* Return the query result mapping for the given name.
*/
- public synchronized QueryResultMapping getQueryResultMapping(Class cls,
+ public QueryResultMapping getQueryResultMapping(Class cls,
String name, ClassLoader envLoader, boolean mustExist) {
- QueryResultMapping res = getQueryResultMappingInternal(cls, name,
- envLoader);
+ QueryResultMapping res = null;
+ if (_locking) {
+ synchronized (this) {
+ res = getQueryResultMappingInternal(cls, name, envLoader);
+ }
+ } else {
+ res = getQueryResultMappingInternal(cls, name, envLoader);
+ }
if (res == null && mustExist)
throw new MetaDataException(_loc.get("no-query-res", cls, name));
return res;
@@ -219,26 +253,49 @@
/**
* Return all cached query result mappings.
*/
- public synchronized QueryResultMapping[] getQueryResultMappings() {
- Collection values = _results.values();
- return (QueryResultMapping[]) values.toArray
- (new QueryResultMapping[values.size()]);
+ public QueryResultMapping[] getQueryResultMappings() {
+ if (_locking) {
+ synchronized (this) {
+ Collection values = _results.values();
+ return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+ }
+ } else {
+ Collection values = _results.values();
+ return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+ }
}
/**
* Return the cached query result mapping with the given name, or null if
* none.
*/
- public synchronized QueryResultMapping getCachedQueryResultMapping
+ public QueryResultMapping getCachedQueryResultMapping
(Class cls, String name) {
- return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+ if (_locking) {
+ synchronized (this) {
+ return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+ }
+ } else {
+ return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+ }
}
/**
* Add a query result mapping.
*/
- public synchronized QueryResultMapping addQueryResultMapping(Class cls,
+ public QueryResultMapping addQueryResultMapping(Class cls,
String name) {
+ if (_locking) {
+ return addQueryResultMappingLocking(cls, name);
+ } else {
+ return addQueryResultMappingInternal(cls, name);
+ }
+ }
+ private synchronized QueryResultMapping addQueryResultMappingLocking(Class cls, String name) {
+ return addQueryResultMappingInternal(cls, name);
+ }
+
+ private QueryResultMapping addQueryResultMappingInternal(Class cls, String name) {
QueryResultMapping res = new QueryResultMapping(name, this);
res.setDefiningType(cls);
_results.put(getQueryResultKey(res), res);
@@ -248,19 +305,33 @@
/**
* Remove a query result mapping.
*/
- public synchronized boolean removeQueryResultMapping
+ public boolean removeQueryResultMapping
(QueryResultMapping res) {
- return _results.remove(getQueryResultKey(res)) != null;
+ if (_locking) {
+ synchronized (this) {
+ return _results.remove(getQueryResultKey(res)) != null;
+ }
+ } else {
+ return _results.remove(getQueryResultKey(res)) != null;
+ }
}
/**
* Remove a query result mapping.
*/
- public synchronized boolean removeQueryResultMapping(Class cls,
+ public boolean removeQueryResultMapping(Class cls,
String name) {
- if (name == null)
- return false;
- return _results.remove(getQueryResultKey(cls, name)) != null;
+ if (_locking) {
+ synchronized (this) {
+ if (name == null)
+ return false;
+ return _results.remove(getQueryResultKey(cls, name)) != null;
+ }
+ } else {
+ if (name == null)
+ return false;
+ return _results.remove(getQueryResultKey(cls, name)) != null;
+ }
}
/**
@@ -300,10 +371,18 @@
mustExist);
}
- public synchronized void clear() {
- super.clear();
- _schema = null;
- _results.clear();
+ public void clear() {
+ if (_locking) {
+ synchronized (this) {
+ super.clear();
+ _schema = null;
+ _results.clear();
+ }
+ } else {
+ super.clear();
+ _schema = null;
+ _results.clear();
+ }
}
protected void prepareMapping(ClassMetaData meta) {
Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Tue Dec 8 21:51:26 2009
@@ -126,7 +126,7 @@
public BooleanValue multithreaded;
public StringValue mapping;
public PluginValue metaFactoryPlugin;
- public ObjectValue metaRepositoryPlugin;
+ public MetaDataRepositoryValue metaRepositoryPlugin;
public ObjectValue lockManagerPlugin;
public ObjectValue inverseManagerPlugin;
public ObjectValue savepointManagerPlugin;
@@ -303,7 +303,7 @@
mapping = addString("Mapping");
metaFactoryPlugin = addPlugin("MetaDataFactory", false);
- metaRepositoryPlugin = (ObjectValue)
+ metaRepositoryPlugin = (MetaDataRepositoryValue)
addValue(new MetaDataRepositoryValue());
connectionFactory = addObject("ConnectionFactory");
Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java Tue Dec 8 21:51:26 2009
@@ -256,7 +256,7 @@
* Load the configured persistent classes list. Performed automatically
* whenever a broker is created.
*/
- private void loadPersistentTypes(ClassLoader envLoader) {
+ public void loadPersistentTypes(ClassLoader envLoader) {
// if we've loaded the persistent types and the class name list
// is empty, then we can simply return. Note that there is a
// potential threading scenario in which _persistentTypesLoaded is
Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataRepository.java Tue Dec 8 21:51:26 2009
@@ -20,6 +20,7 @@
import java.io.Serializable;
import java.security.AccessController;
+import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -37,8 +38,8 @@
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.DynamicPersistenceCapable;
import org.apache.openjpa.enhance.PCRegistry;
-import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.PCRegistry.RegisterClassListener;
import org.apache.openjpa.event.LifecycleEventManager;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
@@ -46,11 +47,14 @@
import org.apache.openjpa.lib.util.Closeable;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.MultiClassLoader;
+import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.lib.util.StringDistance;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.MetaDataException;
import org.apache.openjpa.util.OpenJPAId;
+
import serp.util.Strings;
/**
@@ -63,6 +67,8 @@
public class MetaDataRepository
implements PCRegistry.RegisterClassListener, Configurable, Closeable,
MetaDataModes, Serializable {
+
+ protected boolean _locking = true;
/**
* Constant to not validate any metadata.
@@ -105,18 +111,18 @@
// cache of parsed metadata, oid class to class, and interface class
// to metadatas
- private final Map _metas = new HashMap();
- private final Map _oids = Collections.synchronizedMap(new HashMap());
- private final Map _impls = Collections.synchronizedMap(new HashMap());
- private final Map _ifaces = Collections.synchronizedMap(new HashMap());
- private final Map _queries = new HashMap();
- private final Map _seqs = new HashMap();
- private final Map _aliases = Collections.synchronizedMap(new HashMap());
- private final Map _pawares = Collections.synchronizedMap(new HashMap());
- private final Map _nonMapped = Collections.synchronizedMap(new HashMap());
+ private Map _metas = new HashMap();
+ private Map _oids = Collections.synchronizedMap(new HashMap());
+ private Map _impls = Collections.synchronizedMap(new HashMap());
+ private Map _ifaces = Collections.synchronizedMap(new HashMap());
+ private Map _queries = new HashMap();
+ private Map _seqs = new HashMap();
+ private Map _aliases = Collections.synchronizedMap(new HashMap());
+ private Map _pawares = Collections.synchronizedMap(new HashMap());
+ private Map _nonMapped = Collections.synchronizedMap(new HashMap());
// map of classes to lists of their subclasses
- private final Map _subs = Collections.synchronizedMap(new HashMap());
+ private Map _subs = Collections.synchronizedMap(new HashMap());
// xml mapping
protected final XMLMetaData[] EMPTY_XMLMETAS;
@@ -147,6 +153,9 @@
new LifecycleEventManager.ListenerList(3);
private boolean _reorderMetaDataResolution = false;
+ protected boolean _preload = false;
+ protected boolean _preloadComplete = false;
+ private static final String PRELOAD_STR = "Preload";
/**
* Default constructor. Configure via {@link Configurable}.
@@ -275,6 +284,70 @@
}
/**
+ * Sets whether this repository will load all MetaData for all known persistent classes at
+ * initialization and remove all locking. Defaults to false.
+ */
+ public void setPreload(boolean p) {
+ _preload = p;
+ }
+
+ /**
+ * Returns a boolean indicating whether this repository will load all MetaData for all known
+ * persistent classes at initialization.
+ */
+ public boolean getPreload() {
+ return _preload;
+ }
+
+ /**
+ * If the openjpa.MetaDataRepository plugin value Preload=true is set, this method will load all
+ * MetaData for all persistent classes and will remove locking from this class.
+ * <p>
+ *
+ */
+ public synchronized void preload() {
+ if (_preload == false) {
+ return;
+ }
+ // If pooling EMFs, this method may be invoked more than once. Only perform this work once.
+ if (_preloadComplete == true) {
+ return;
+ }
+
+ MultiClassLoader multi = AccessController.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
+ multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+ multi.addClassLoader(AccessController.doPrivileged(J2DoPrivHelper
+ .getClassLoaderAction(MetaDataRepository.class)));
+
+ Set<String> classes = getPersistentTypeNames(false, multi);
+ if (classes == null || classes.size() == 0) {
+ throw new MetaDataException(_loc.get("repos-initializeEager-none"));
+ }
+ if (_log.isTraceEnabled() == true) {
+ _log.trace(_loc.get("repos-initializeEager-found", classes));
+ }
+
+ List<Class> loaded = new ArrayList<Class>();
+ for (String c : classes) {
+ try {
+ Class<?> cls = AccessController.doPrivileged((J2DoPrivHelper.getForNameAction(c, true, multi)));
+ loaded.add(cls);
+ // This call may be unnecessary?
+ _factory.load(cls, MODE_ALL, multi);
+ } catch (PrivilegedActionException pae) {
+ throw new MetaDataException(_loc.get("repos-initializeEager-error"), pae);
+ }
+ }
+ resolveAll(multi);
+
+ // Hook in this class as a listener and process registered classes list to populate _aliases list.
+ PCRegistry.addRegisterClassListener(this);
+ processRegisteredClasses(multi);
+ _locking = false;
+ _preloadComplete = true;
+ }
+
+ /**
* Return the metadata for the given class.
*
* @param cls the class to retrieve metadata for
@@ -282,7 +355,17 @@
* @param mustExist if true, throws a {@link MetaDataException}
* if no metadata is found
*/
- public synchronized ClassMetaData getMetaData(Class cls,
+ public ClassMetaData getMetaData(Class cls, ClassLoader envLoader, boolean mustExist) {
+ if (_locking) {
+ return getMetaDataLocking(cls, envLoader, mustExist);
+ } else {
+ return getMetaDataInternal(cls, envLoader, mustExist);
+ }
+ }
+ private synchronized ClassMetaData getMetaDataLocking(Class cls, ClassLoader envLoader, boolean mustExist) {
+ return getMetaDataInternal(cls, envLoader, mustExist);
+ }
+ private ClassMetaData getMetaDataInternal(Class cls,
ClassLoader envLoader, boolean mustExist) {
if (cls != null &&
DynamicPersistenceCapable.class.isAssignableFrom(cls))
@@ -403,14 +486,24 @@
* @since 1.1.0
*/
public Collection getAliasNames() {
- Collection aliases = new HashSet();
+ if (_locking) {
+ return getAliasNamesLocking();
+ } else {
+ return getAliasNamesInternal();
+ }
+ }
+
+ private Collection getAliasNamesLocking() {
synchronized (_aliases) {
- for (Iterator iter = _aliases.entrySet().iterator();
- iter.hasNext(); ) {
- Map.Entry e = (Map.Entry) iter.next();
- if (e.getValue() != null)
- aliases.add(e.getKey());
- }
+ return getAliasNamesInternal();
+ }
+ }
+ private final Collection getAliasNamesInternal() {
+ Collection aliases = new HashSet();
+ for (Iterator iter = _aliases.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry e = (Map.Entry) iter.next();
+ if (e.getValue() != null)
+ aliases.add(e.getKey());
}
return aliases;
}
@@ -749,7 +842,17 @@
/**
* Return all the metadata instances currently in the repository.
*/
- public synchronized ClassMetaData[] getMetaDatas() {
+ public ClassMetaData[] getMetaDatas() {
+ if (_locking) {
+ return getMetaDatasLocking();
+ } else {
+ return getMetaDatasInternal();
+ }
+ }
+ private synchronized ClassMetaData[] getMetaDatasLocking() {
+ return getMetaDatasInternal();
+ }
+ private ClassMetaData[] getMetaDatasInternal() {
// prevent concurrent mod errors when resolving one metadata
// introduces others
ClassMetaData[] metas = (ClassMetaData[]) _metas.values().
@@ -803,13 +906,22 @@
// synchronize on this rather than the map, because all other methods
// that access _metas are synchronized on this
- synchronized (this) {
- if (_pawares.containsKey(cls))
- throw new MetaDataException(_loc.get("pc-and-aware", cls));
- _metas.put(cls, meta);
+ if (_locking) {
+ metasPutLocking(cls, meta);
+ } else {
+ metasPutInternal(cls, meta);
}
+
return meta;
}
+ private synchronized void metasPutLocking(Class cls, ClassMetaData meta){
+ metasPutInternal(cls, meta);
+ }
+ private void metasPutInternal(Class cls, ClassMetaData meta){
+ if (_pawares.containsKey(cls))
+ throw new MetaDataException(_loc.get("pc-and-aware", cls));
+ _metas.put(cls, meta);
+ }
/**
* Create a new class metadata instance.
@@ -927,7 +1039,17 @@
*
* @return true if removed, false if not in this repository
*/
- public synchronized boolean removeMetaData(Class cls) {
+ public boolean removeMetaData(Class cls) {
+ if(_locking){
+ return removeMetaDataLocking(cls);
+ }else{
+ return removeMetaDataInternal(cls);
+ }
+ }
+ private synchronized boolean removeMetaDataLocking(Class cls) {
+ return removeMetaDataInternal(cls);
+ }
+ private boolean removeMetaDataInternal(Class cls) {
if (cls == null)
return false;
if (_metas.remove(cls) != null) {
@@ -943,24 +1065,42 @@
* Add the given metadata as declared interface implementation.
*/
void addDeclaredInterfaceImpl(ClassMetaData meta, Class iface) {
+ if (_locking) {
+ addDeclaredInterfaceImplLocking(meta, iface);
+ } else {
+ addDeclaredInterfaceImplInternal(meta, iface);
+ }
+ }
+ void addDeclaredInterfaceImplLocking(ClassMetaData meta, Class iface) {
synchronized (_impls) {
- Collection vals = (Collection) _impls.get(iface);
-
- // check to see if the superclass already declares to avoid dups
- if (vals != null) {
- ClassMetaData sup = meta.getPCSuperclassMetaData();
- for (; sup != null; sup = sup.getPCSuperclassMetaData())
- if (vals.contains(sup.getDescribedType()))
- return;
- }
- addToCollection(_impls, iface, meta.getDescribedType(), false);
+ addDeclaredInterfaceImplInternal(meta, iface);
}
}
-
+ private void addDeclaredInterfaceImplInternal(ClassMetaData meta, Class iface) {
+ Collection vals = (Collection) _impls.get(iface);
+ // check to see if the superclass already declares to avoid dups
+ if (vals != null) {
+ ClassMetaData sup = meta.getPCSuperclassMetaData();
+ for (; sup != null; sup = sup.getPCSuperclassMetaData())
+ if (vals.contains(sup.getDescribedType()))
+ return;
+ }
+ addToCollection(_impls, iface, meta.getDescribedType(), false);
+ }
/**
* Set the implementation for the given managed interface.
*/
- synchronized void setInterfaceImpl(ClassMetaData meta, Class impl) {
+ void setInterfaceImpl(ClassMetaData meta, Class impl) {
+ if(_locking){
+ setInterfaceImplLocking(meta, impl);
+ }else{
+ setInterfaceImplInternal(meta, impl);
+ }
+ }
+ private synchronized void setInterfaceImplLocking(ClassMetaData meta, Class impl) {
+ setInterfaceImplInternal(meta, impl);
+ }
+ private void setInterfaceImplInternal(ClassMetaData meta, Class impl) {
if (!meta.isManagedInterface())
throw new MetaDataException(_loc.get("not-managed-interface",
meta, impl));
@@ -1096,19 +1236,12 @@
// get impls of given interface / abstract class
loadRegisteredClassMetaData(envLoader);
Collection vals = (Collection) _impls.get(cls);
- ClassMetaData meta;
Collection mapped = null;
if (vals != null) {
- synchronized (vals) {
- for (Iterator itr = vals.iterator(); itr.hasNext();) {
- meta = getMetaData((Class) itr.next(), envLoader, true);
- if (meta.isMapped()
- || meta.getMappedPCSubclassMetaDatas().length > 0) {
- if (mapped == null)
- mapped = new ArrayList(vals.size());
- mapped.add(meta);
- }
- }
+ if (_locking) {
+ mapped = getImplementorMetaDatasLocking(vals, envLoader, mustExist);
+ } else {
+ mapped = getImplementorMetaDatasInternal(vals, envLoader, mustExist);
}
}
@@ -1119,6 +1252,22 @@
return (ClassMetaData[]) mapped.toArray(newClassMetaDataArray
(mapped.size()));
}
+ private Collection getImplementorMetaDatasLocking(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+ synchronized (classes) {
+ return getImplementorMetaDatasInternal(classes, envLoader, mustExist);
+ }
+ }
+ private Collection getImplementorMetaDatasInternal(Collection<Class> classes, ClassLoader envLoader, boolean mustExist) {
+ Collection mapped = new ArrayList(classes.size());
+ ClassMetaData meta = null;
+ for (Iterator itr = classes.iterator(); itr.hasNext();) {
+ meta = getMetaData((Class) itr.next(), envLoader, true);
+ if (meta.isMapped() || meta.getMappedPCSubclassMetaDatas().length > 0) {
+ mapped.add(meta);
+ }
+ }
+ return mapped;
+ }
/**
* Gets the metadata corresponding to the given persistence-aware class.
@@ -1135,12 +1284,21 @@
* @return empty array if no class has been registered as pers-aware
*/
public NonPersistentMetaData[] getPersistenceAwares() {
+ if (_locking) {
+ return getPersistenceAwaresLocking();
+ } else {
+ return getPersistenceAwaresInternal();
+ }
+ }
+ private NonPersistentMetaData[] getPersistenceAwaresLocking() {
synchronized (_pawares) {
+ return getPersistenceAwaresInternal();
+ }
+ }
+ private NonPersistentMetaData[] getPersistenceAwaresInternal() {
if (_pawares.isEmpty())
return EMPTY_NON_PERSISTENT;
- return (NonPersistentMetaData[])_pawares.values().toArray
- (new NonPersistentMetaData[_pawares.size()]);
- }
+ return (NonPersistentMetaData[]) _pawares.values().toArray(new NonPersistentMetaData[_pawares.size()]);
}
/**
@@ -1151,17 +1309,26 @@
public NonPersistentMetaData addPersistenceAware(Class cls) {
if (cls == null)
return null;
- synchronized(this) {
+ if (_locking) {
+ return addPersistenceAwareLocking(cls);
+ } else {
+ return addPersistenceAwareInternal(cls);
+ }
+ }
+
+ private synchronized NonPersistentMetaData addPersistenceAwareLocking(Class cls) {
+ return addPersistenceAwareInternal(cls);
+ }
+
+ private NonPersistentMetaData addPersistenceAwareInternal(Class cls) {
if (_pawares.containsKey(cls))
return (NonPersistentMetaData)_pawares.get(cls);
if (getCachedMetaData(cls) != null)
throw new MetaDataException(_loc.get("pc-and-aware", cls));
- NonPersistentMetaData meta = new NonPersistentMetaData(cls, this,
- NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
+ NonPersistentMetaData meta = new NonPersistentMetaData(cls, this, NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
_pawares.put(cls, meta);
return meta;
}
- }
/**
* Remove a persitence-aware class from the repository
@@ -1188,12 +1355,21 @@
* @return empty array if no non-mapped interface has been registered.
*/
public NonPersistentMetaData[] getNonMappedInterfaces() {
+ if(_locking){
+ return getNonMappedInterfacesLocking();
+ }else{
+ return getNonMappedInterfacesInternal();
+ }
+ }
+ private NonPersistentMetaData[] getNonMappedInterfacesLocking() {
synchronized (_nonMapped) {
+ return getNonMappedInterfacesInternal();
+ }
+ }
+ private NonPersistentMetaData[] getNonMappedInterfacesInternal() {
if (_nonMapped.isEmpty())
return EMPTY_NON_PERSISTENT;
- return (NonPersistentMetaData[])_nonMapped.values().toArray
- (new NonPersistentMetaData[_nonMapped.size()]);
- }
+ return (NonPersistentMetaData[]) _nonMapped.values().toArray(new NonPersistentMetaData[_nonMapped.size()]);
}
/**
@@ -1206,7 +1382,17 @@
return null;
if (!iface.isInterface())
throw new MetaDataException(_loc.get("not-non-mapped", iface));
- synchronized(this) {
+ if(_locking){
+ return addNonMappedInterfaceLocking(iface);
+ }else{
+ return addNonMappedInterfaceInternal(iface);
+ }
+ }
+ private synchronized NonPersistentMetaData addNonMappedInterfaceLocking(Class iface) {
+ return addNonMappedInterfaceInternal(iface);
+ }
+
+ private NonPersistentMetaData addNonMappedInterfaceInternal(Class iface) {
if (_nonMapped.containsKey(iface))
return (NonPersistentMetaData)_nonMapped.get(iface);
if (getCachedMetaData(iface) != null)
@@ -1216,7 +1402,6 @@
_nonMapped.put(iface, meta);
return meta;
}
- }
/**
* Remove a non-mapped interface from the repository
@@ -1231,10 +1416,21 @@
* Clear the cache of parsed metadata. This method also clears the
* internal {@link MetaDataFactory MetaDataFactory}'s cache.
*/
- public synchronized void clear() {
+ public void clear() {
if (_log.isTraceEnabled())
_log.trace(_loc.get("clear-repos", this));
-
+
+ if (_locking) {
+ clearLocking();
+ } else {
+ clearInternal();
+ }
+ }
+ private synchronized void clearLocking(){
+ clearInternal();
+ }
+ private void clearInternal(){
+ // Recreating these datastructures is probably faster than calling clear. Future change?
_metas.clear();
_oids.clear();
_subs.clear();
@@ -1247,7 +1443,6 @@
_pawares.clear();
_nonMapped.clear();
}
-
/**
* Return the set of configured persistent classes, or null if the user
* did not configure any.
@@ -1256,8 +1451,18 @@
* in the classpath if no classes are configured explicitly
* @param envLoader the class loader to use, or null for default
*/
- public synchronized Set getPersistentTypeNames(boolean devpath,
+ public Set getPersistentTypeNames(boolean devpath,
ClassLoader envLoader) {
+ if (_locking) {
+ return getPersistentTypeNamesLocking(devpath, envLoader);
+ } else {
+ return getPersistentTypeNamesInternal(devpath, envLoader);
+ }
+ }
+ private synchronized Set getPersistentTypeNamesLocking(boolean devpath, ClassLoader envLoader) {
+ return getPersistentTypeNamesInternal(devpath, envLoader);
+ }
+ private Set getPersistentTypeNamesInternal(boolean devpath, ClassLoader envLoader) {
return _factory.getPersistentTypeNames(devpath, envLoader);
}
@@ -1273,15 +1478,26 @@
* @param envLoader the class loader to use, or null for default
* @return the loaded classes, or empty collection if none
*/
- public synchronized Collection loadPersistentTypes(boolean devpath,
+ public Collection loadPersistentTypes(boolean devpath,
ClassLoader envLoader) {
+ if (_locking) {
+ return loadPersistentTypesLocking(devpath, envLoader);
+ } else {
+ return loadPersistentTypesInternal(devpath, envLoader);
+ }
+ }
+
+ private synchronized Collection loadPersistentTypesLocking(boolean devpath, ClassLoader envLoader) {
+ return loadPersistentTypesInternal(devpath, envLoader);
+ }
+
+ private Collection loadPersistentTypesInternal(boolean devpath, ClassLoader envLoader) {
Set names = getPersistentTypeNames(devpath, envLoader);
if (names == null || names.isEmpty())
return Collections.EMPTY_LIST;
// attempt to load classes so that they get processed
- ClassLoader clsLoader = _conf.getClassResolverInstance().
- getClassLoader(getClass(), envLoader);
+ ClassLoader clsLoader = _conf.getClassResolverInstance().getClassLoader(getClass(), envLoader);
List classes = new ArrayList(names.size());
Class cls;
for (Iterator itr = names.iterator(); itr.hasNext();) {
@@ -1349,7 +1565,11 @@
public void register(Class cls) {
// buffer registered classes until an oid metadata request is made,
// at which point we'll parse everything in the buffer
+ if (_locking) {
synchronized (_registered) {
+ _registered.add(cls);
+ }
+ } else {
_registered.add(cls);
}
}
@@ -1379,7 +1599,12 @@
// copy into new collection to avoid concurrent mod errors on reentrant
// registrations
Class[] reg;
- synchronized (_registered) {
+ if (_locking) {
+ synchronized (_registered) {
+ reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
+ _registered.clear();
+ }
+ } else {
reg = (Class[]) _registered.toArray(new Class[_registered.size()]);
_registered.clear();
}
@@ -1408,7 +1633,11 @@
}
}
if (failed != null) {
- synchronized (_registered) {
+ if(_locking){
+ synchronized (_registered) {
+ _registered.addAll(failed);
+ }
+ }else{
_registered.addAll(failed);
}
}
@@ -1428,16 +1657,10 @@
// update subclass lists; synchronize on this because accessing _metas
// requires it
Class leastDerived = cls;
- synchronized (this) {
- ClassMetaData meta;
- for (Class anc = cls;
- (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
- addToCollection(_subs, anc, cls, true);
- meta = (ClassMetaData) _metas.get(anc);
- if (meta != null)
- meta.clearSubclassCache();
- leastDerived = anc;
- }
+ if (_locking) {
+ leastDerived = calcualteLeastDerivedLocking(cls);
+ } else {
+ leastDerived = calcualteLeastDerivedInternal(cls);
}
// update oid mappings if this is a base concrete class
@@ -1467,25 +1690,67 @@
// update mappings from interfaces and non-pc superclasses to
// pc implementing types
- synchronized (_impls) {
+ if (_locking) {
+ synchronized (_impls) {
+ updateImpls(cls, leastDerived, cls);
+ }
+ } else {
updateImpls(cls, leastDerived, cls);
}
// set alias for class
String alias = PCRegistry.getTypeAlias(cls);
if (alias != null) {
- synchronized (_aliases) {
- List classList = (List) _aliases.get(alias);
- if (classList == null) {
- classList = new ArrayList(3);
- _aliases.put(alias, classList);
- }
- if (!classList.contains(cls))
- classList.add(cls);
+ if(_locking){
+ setAliasForClassLocking(alias, cls);
+ }else{
+ setAliasForClassInternal(alias, cls);
}
}
}
-
+ /**
+ * Private worker method for use by processRegisterClasses.
+ */
+ private void setAliasForClassLocking(String alias, Class cls){
+ synchronized(_aliases){
+ setAliasForClassInternal(alias, cls);
+ }
+ }
+ /**
+ * Private worker method for use by processRegisterClasses.
+ */
+ private void setAliasForClassInternal(String alias, Class cls){
+ List classList = (List) _aliases.get(alias);
+ if (classList == null) {
+ classList = new ArrayList(3);
+ _aliases.put(alias, classList);
+ }
+ if (!classList.contains(cls))
+ classList.add(cls);
+ }
+ /**
+ * Private worker method for use by processRegisterClasses.
+ */
+ private synchronized Class calcualteLeastDerivedLocking(Class cls){
+ return calcualteLeastDerivedInternal(cls);
+ }
+ /**
+ * Private worker method for use by processRegisterClasses.
+ */
+ private Class calcualteLeastDerivedInternal(Class cls){
+ Class leastDerived = cls;
+ ClassMetaData meta;
+ for (Class anc = cls; (anc = PCRegistry.getPersistentSuperclass(anc)) != null;) {
+ addToCollection(_subs, anc, cls, true);
+ meta = (ClassMetaData) _metas.get(anc);
+ if (meta != null)
+ meta.clearSubclassCache();
+ leastDerived = anc;
+ }
+
+ return leastDerived;
+ }
+
/**
* Update the list of implementations of base classes and interfaces.
*/
@@ -1535,7 +1800,18 @@
*/
private void addToCollection(Map map, Class key, Class value,
boolean inheritance) {
+ if(_locking){
+ addToCollectionLocking(map, key, value, inheritance);
+ }else{
+ addToCollectionInternal(map, key, value, inheritance);
+ }
+ }
+ private void addToCollectionLocking(Map map, Class key, Class value, boolean inheritance) {
synchronized (map) {
+ addToCollectionInternal(map, key, value, inheritance);
+ }
+ }
+ private void addToCollectionInternal(Map map, Class key, Class value, boolean inheritance) {
Collection coll = (Collection) map.get(key);
if (coll == null) {
if (inheritance) {
@@ -1548,7 +1824,6 @@
}
coll.add(value);
}
- }
///////////////////////////////
// Configurable implementation
@@ -1567,6 +1842,16 @@
initializeMetaDataFactory();
if (_implGen == null)
_implGen = new InterfaceImplGenerator(this);
+ if (_preload == true) {
+ _oids = new HashMap();
+ _impls = new HashMap();
+ _ifaces = new HashMap();
+ _aliases = new HashMap();
+ _pawares = new HashMap();
+ _nonMapped = new HashMap();
+ _subs = new HashMap();
+ // Wait till we're done loading MetaData to remove lock.
+ }
}
private void initializeMetaDataFactory() {
@@ -1585,8 +1870,20 @@
/**
* Return query metadata for the given class, name, and classloader.
*/
- public synchronized QueryMetaData getQueryMetaData(Class cls, String name,
+ public QueryMetaData getQueryMetaData(Class cls, String name,
ClassLoader envLoader, boolean mustExist) {
+ if(_locking){
+ return getQueryMetaDataLocking(cls, name, envLoader, mustExist);
+ }else{
+ return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+ }
+ }
+ private synchronized QueryMetaData getQueryMetaDataLocking(Class cls, String name, ClassLoader envLoader,
+ boolean mustExist) {
+ return getQueryMetaDataInternal(cls, name, envLoader, mustExist);
+ }
+
+ private QueryMetaData getQueryMetaDataInternal(Class cls, String name, ClassLoader envLoader, boolean mustExist) {
QueryMetaData meta = getQueryMetaDataInternal(cls, name, envLoader);
if (meta == null) {
// load all the metadatas for all the known classes so that
@@ -1597,12 +1894,10 @@
if (meta == null && mustExist) {
if (cls == null) {
- throw new MetaDataException(_loc.get
- ("no-named-query-null-class",
- getPersistentTypeNames(false, envLoader), name));
+ throw new MetaDataException(_loc.get("no-named-query-null-class", getPersistentTypeNames(false,
+ envLoader), name));
} else {
- throw new MetaDataException(_loc.get("no-named-query",
- cls, name));
+ throw new MetaDataException(_loc.get("no-named-query", cls, name));
}
}
@@ -1655,26 +1950,45 @@
/**
* Return the cached query metadata.
*/
- public synchronized QueryMetaData[] getQueryMetaDatas() {
- return (QueryMetaData[]) _queries.values().toArray
- (new QueryMetaData[_queries.size()]);
+ public QueryMetaData[] getQueryMetaDatas() {
+ if (_locking) {
+ synchronized (this) {
+ return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+ }
+ } else {
+ return (QueryMetaData[]) _queries.values().toArray(new QueryMetaData[_queries.size()]);
+ }
}
/**
* Return the cached query metadata for the given name.
*/
- public synchronized QueryMetaData getCachedQueryMetaData(Class cls,
+ public QueryMetaData getCachedQueryMetaData(Class cls,
String name) {
- return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+ if (_locking) {
+ synchronized (this) {
+ return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+ }
+ } else {
+ return (QueryMetaData) _queries.get(getQueryKey(cls, name));
+ }
}
/**
* Add a new query metadata to the repository and return it.
*/
- public synchronized QueryMetaData addQueryMetaData(Class cls, String name) {
- QueryMetaData meta = newQueryMetaData(cls, name);
- _queries.put(getQueryKey(meta), meta);
- return meta;
+ public QueryMetaData addQueryMetaData(Class cls, String name) {
+ if (_locking) {
+ synchronized (this) {
+ QueryMetaData meta = newQueryMetaData(cls, name);
+ _queries.put(getQueryKey(meta), meta);
+ return meta;
+ }
+ }else{
+ QueryMetaData meta = newQueryMetaData(cls, name);
+ _queries.put(getQueryKey(meta), meta);
+ return meta;
+ }
}
/**
@@ -1689,19 +2003,35 @@
/**
* Remove the given query metadata from the repository.
*/
- public synchronized boolean removeQueryMetaData(QueryMetaData meta) {
- if (meta == null)
- return false;
- return _queries.remove(getQueryKey(meta)) != null;
+ public boolean removeQueryMetaData(QueryMetaData meta) {
+ if(_locking){
+ synchronized (this) {
+ if (meta == null)
+ return false;
+ return _queries.remove(getQueryKey(meta)) != null;
+ }
+ }else{
+ if (meta == null)
+ return false;
+ return _queries.remove(getQueryKey(meta)) != null;
+ }
}
/**
* Remove query metadata for the given class name if in the repository.
*/
- public synchronized boolean removeQueryMetaData(Class cls, String name) {
- if (name == null)
- return false;
- return _queries.remove(getQueryKey(cls, name)) != null;
+ public boolean removeQueryMetaData(Class cls, String name) {
+ if (_locking) {
+ synchronized (this) {
+ if (name == null)
+ return false;
+ return _queries.remove(getQueryKey(cls, name)) != null;
+ }
+ } else {
+ if (name == null)
+ return false;
+ return _queries.remove(getQueryKey(cls, name)) != null;
+ }
}
/**
@@ -1733,7 +2063,19 @@
/**
* Return sequence metadata for the given name and classloader.
*/
- public synchronized SequenceMetaData getSequenceMetaData(String name,
+ public SequenceMetaData getSequenceMetaData(String name,
+ ClassLoader envLoader, boolean mustExist) {
+ if(_locking){
+ return getSequenceMetaDataLocking(name, envLoader, mustExist);
+ }else{
+ return getSequenceMetaDataInternal(name, envLoader, mustExist);
+ }
+ }
+ private synchronized SequenceMetaData getSequenceMetaDataLocking(String name,
+ ClassLoader envLoader, boolean mustExist) {
+ return getSequenceMetaDataInternal(name, envLoader, mustExist);
+ }
+ private SequenceMetaData getSequenceMetaDataInternal(String name,
ClassLoader envLoader, boolean mustExist) {
SequenceMetaData meta = getSequenceMetaDataInternal(name, envLoader);
if (meta == null && SequenceMetaData.NAME_SYSTEM.equals(name)) {
@@ -1806,26 +2148,44 @@
/**
* Return the cached sequence metadata.
*/
- public synchronized SequenceMetaData[] getSequenceMetaDatas() {
- return (SequenceMetaData[]) _seqs.values().toArray
- (new SequenceMetaData[_seqs.size()]);
+ public SequenceMetaData[] getSequenceMetaDatas() {
+ if (_locking) {
+ synchronized (this) {
+ return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+ }
+ } else {
+ return (SequenceMetaData[]) _seqs.values().toArray(new SequenceMetaData[_seqs.size()]);
+ }
}
/**
* Return the cached a sequence metadata for the given name.
*/
- public synchronized SequenceMetaData getCachedSequenceMetaData(
- String name) {
- return (SequenceMetaData) _seqs.get(name);
+ public SequenceMetaData getCachedSequenceMetaData(String name) {
+ if (_locking) {
+ synchronized (this) {
+ return (SequenceMetaData) _seqs.get(name);
+ }
+ } else {
+ return (SequenceMetaData) _seqs.get(name);
+ }
}
/**
* Add a new sequence metadata to the repository and return it.
*/
- public synchronized SequenceMetaData addSequenceMetaData(String name) {
- SequenceMetaData meta = newSequenceMetaData(name);
- _seqs.put(name, meta);
- return meta;
+ public SequenceMetaData addSequenceMetaData(String name) {
+ if (_locking) {
+ synchronized (this) {
+ SequenceMetaData meta = newSequenceMetaData(name);
+ _seqs.put(name, meta);
+ return meta;
+ }
+ } else {
+ SequenceMetaData meta = newSequenceMetaData(name);
+ _seqs.put(name, meta);
+ return meta;
+ }
}
/**
@@ -1838,44 +2198,76 @@
/**
* Remove the given sequence metadata from the repository.
*/
- public synchronized boolean removeSequenceMetaData(SequenceMetaData meta) {
- if (meta == null)
- return false;
- return _seqs.remove(meta.getName()) != null;
+ public boolean removeSequenceMetaData(SequenceMetaData meta) {
+ if (_locking) {
+ synchronized (this) {
+ if (meta == null)
+ return false;
+ return _seqs.remove(meta.getName()) != null;
+ }
+ } else {
+ if (meta == null)
+ return false;
+ return _seqs.remove(meta.getName()) != null;
+ }
}
/**
* Remove sequence metadata for the name if in the repository.
*/
- public synchronized boolean removeSequenceMetaData(String name) {
- if (name == null)
- return false;
- return _seqs.remove(name) != null;
+ public boolean removeSequenceMetaData(String name) {
+ if (_locking) {
+ synchronized (this) {
+ if (name == null)
+ return false;
+ return _seqs.remove(name) != null;
+ }
+ }else{
+ if (name == null)
+ return false;
+ return _seqs.remove(name) != null;
+ }
}
/**
* Add the given system lifecycle listener.
*/
- public synchronized void addSystemListener(Object listener) {
- // copy to avoid issues with ListenerList and avoid unncessary
- // locking on the list during runtime
- LifecycleEventManager.ListenerList listeners = new
- LifecycleEventManager.ListenerList(_listeners);
- listeners.add(listener);
- _listeners = listeners;
+ public void addSystemListener(Object listener) {
+ if (_locking) {
+ synchronized (this) {
+ // copy to avoid issues with ListenerList and avoid unncessary
+ // locking on the list during runtime
+ LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+ listeners.add(listener);
+ _listeners = listeners;
+ }
+ } else {
+ LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
+ listeners.add(listener);
+ _listeners = listeners;
+ }
}
/**
* Remove the given system lifecycle listener.
*/
- public synchronized boolean removeSystemListener(Object listener) {
+ public boolean removeSystemListener(Object listener) {
+ if (_locking) {
+ return removeSystemListenerLocking(listener);
+ } else {
+ return removeSystemListenerInternal(listener);
+ }
+ }
+ private synchronized boolean removeSystemListenerLocking(Object listener) {
+ return removeSystemListenerInternal(listener);
+ }
+ private boolean removeSystemListenerInternal(Object listener) {
if (!_listeners.contains(listener))
return false;
// copy to avoid issues with ListenerList and avoid unncessary
// locking on the list during runtime
- LifecycleEventManager.ListenerList listeners = new
- LifecycleEventManager.ListenerList(_listeners);
+ LifecycleEventManager.ListenerList listeners = new LifecycleEventManager.ListenerList(_listeners);
listeners.remove(listener);
_listeners = listeners;
return true;
@@ -1891,7 +2283,17 @@
/**
* Free the resources used by this repository. Closes all user sequences.
*/
- public synchronized void close() {
+ public void close() {
+ if(_locking){
+ closeLocking();
+ }else{
+ closeInternal();
+ }
+ }
+ private synchronized void closeLocking() {
+ closeInternal();
+ }
+ private void closeInternal() {
SequenceMetaData[] smds = getSequenceMetaDatas();
for (int i = 0; i < smds.length; i++)
smds[i].close();
@@ -1931,7 +2333,17 @@
* @param fmd
* @return XML metadata
*/
- public synchronized XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+ public XMLMetaData getXMLMetaData(FieldMetaData fmd) {
+ if(_locking){
+ return getXMLMetaDataLocking(fmd);
+ }else{
+ return getXMLMetaDataInternal(fmd);
+ }
+ }
+ private synchronized XMLMetaData getXMLMetaDataLocking(FieldMetaData fmd) {
+ return getXMLMetaDataInternal(fmd);
+ }
+ private XMLMetaData getXMLMetaDataInternal(FieldMetaData fmd) {
Class cls = fmd.getDeclaredType();
// check if cached before
XMLMetaData xmlmeta = (XMLClassMetaData) _xmlmetas.get(cls);
@@ -1957,7 +2369,11 @@
// synchronize on this rather than the map, because all other methods
// that access _xmlmetas are synchronized on this
+ if(_locking){
synchronized (this) {
+ _xmlmetas.put(type, meta);
+ }
+ }else{
_xmlmetas.put(type, meta);
}
return meta;
@@ -1992,6 +2408,17 @@
public XMLFieldMetaData newXMLFieldMetaData(Class type, String name) {
return new XMLFieldMetaData(type, name);
}
+
+ /**
+ * This helper method returns true if Options paramater has the property Preload
+ * set to true.
+ */
+ public static boolean needsPreload(Options o) {
+ if (o.getBooleanProperty(PRELOAD_STR) == true) {
+ return true;
+ }
+ return false;
+ }
/**
* Analyzes the list of ClassMetaData in the supplied list for any which has foreign keys to other ClassMetaData
@@ -2090,7 +2517,6 @@
return returnList;
}
-
/**
* Linked list node class for managing any foreign keys in the identity of a ClassMetaData instance.
*
Modified: openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties (original)
+++ openjpa/branches/1.2.x/openjpa-kernel/src/main/resources/org/apache/openjpa/meta/localizer.properties Tue Dec 8 21:51:26 2009
@@ -324,3 +324,8 @@
cmd-discover-cycle: A cycle was detected while resolving the identity \
references for type "{0}". The original process buffer ordering \
will be used.
+repos-initializeEager-none: No persistent metadata found for loading during initialization. \
+ The persistent classes must be listed in persistence unit configuration to be loaded during initialization.
+repos-initializeEager-found: The following classes are being preloaded "{0}".
+repos-initializeEager-error: Unexpected error during early loading of entity metadata during initialization. \
+ See nested stacktrace for details.
Modified: openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java (original)
+++ openjpa/branches/1.2.x/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/J2DoPrivHelper.java Tue Dec 8 21:51:26 2009
@@ -905,9 +905,9 @@
*
* @return MultiClassLoader
*/
- public static final PrivilegedAction newMultiClassLoaderAction() {
+ public static final PrivilegedAction<MultiClassLoader> newMultiClassLoaderAction() {
return new PrivilegedAction() {
- public Object run() {
+ public MultiClassLoader run() {
return new MultiClassLoader();
}
};
Modified: openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java?rev=888586&r1=888585&r2=888586&view=diff
==============================================================================
--- openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java (original)
+++ openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java Tue Dec 8 21:51:26 2009
@@ -20,24 +20,30 @@
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
+import java.security.AccessController;
import java.security.ProtectionDomain;
import java.util.Map;
+
import javax.persistence.EntityManager;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import org.apache.openjpa.conf.BrokerValue;
+import org.apache.openjpa.conf.MetaDataRepositoryValue;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
import org.apache.openjpa.enhance.PCClassFileTransformer;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
import org.apache.openjpa.kernel.Bootstrap;
import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.ConfigurationProvider;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.meta.MetaDataModes;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.util.ClassResolver;
@@ -79,6 +85,8 @@
return null;
BrokerFactory factory = getBrokerFactory(cp, poolValue, null);
+ preloadMetaDataRepository(factory);
+
return JPAFacadeHelper.toEntityManagerFactory(factory);
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
@@ -153,6 +161,7 @@
_loc.get("transformer-registration-error", pui));
}
}
+ preloadMetaDataRepository(factory);
return JPAFacadeHelper.toEntityManagerFactory(factory);
} catch (Exception e) {
throw PersistenceExceptions.toPersistenceException(e);
@@ -177,6 +186,30 @@
protected OpenJPAConfiguration newConfigurationImpl() {
return new OpenJPAConfigurationImpl();
}
+
+ /**
+ * Private worker method that will call to the MetaDataRepository to preload if the provided
+ * BrokerFactory is configured to do so.
+ */
+ private void preloadMetaDataRepository(BrokerFactory factory){
+ // We need to wait to preload until after we get back a fully configured/instantiated
+ // BrokerFactory. This is because it is possible that someone has extended OpenJPA
+ // functions and they need to be allowed time to configure themselves before we go off and
+ // start instanting configurable objects (ie:openjpa.MetaDataRepository). Don't catch
+ // any exceptions here because we want to fail-fast.
+ OpenJPAConfiguration conf = factory.getConfiguration();
+ Options o = Configurations.parseProperties(Configurations.getProperties(conf.getMetaDataRepository()));
+ if (MetaDataRepository.needsPreload(o) == true) {
+ MetaDataRepository mdr = conf.getMetaDataRepositoryInstance();
+ mdr.setValidate(MetaDataRepository.VALIDATE_RUNTIME, true);
+ mdr.setResolve(MetaDataRepository.MODE_MAPPING_INIT, true);
+
+ // Load persistent classes and hook in subclasser
+ ((AbstractBrokerFactory) factory).loadPersistentTypes((ClassLoader) AccessController
+ .doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()));
+ mdr.preload();
+ }
+ }
/**
* Java EE 5 class transformer.