mirror of https://github.com/apache/openjpa.git
Supports for interface query alias metadata
as well as refactoring persistence-aware metadata into non-persistent metadata to support non-managed interfaces git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@442363 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
da1961910b
commit
1defd23037
|
@ -660,7 +660,8 @@ public class MappingTool
|
||||||
ClassMapping mapping = repos.getMapping(cls, null, false);
|
ClassMapping mapping = repos.getMapping(cls, null, false);
|
||||||
if (mapping != null)
|
if (mapping != null)
|
||||||
return mapping;
|
return mapping;
|
||||||
if (!validate || repos.getPersistenceAware(cls) != null)
|
if (!validate || cls.isInterface() ||
|
||||||
|
repos.getPersistenceAware(cls) != null)
|
||||||
return null;
|
return null;
|
||||||
throw new MetaDataException(_loc.get("no-meta", cls));
|
throw new MetaDataException(_loc.get("no-meta", cls));
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,10 +120,11 @@ public class ExtentImpl
|
||||||
_broker.getClassLoader(), false);
|
_broker.getClassLoader(), false);
|
||||||
|
|
||||||
ClassMetaData[] metas;
|
ClassMetaData[] metas;
|
||||||
if (meta != null && (meta.isMapped() || (_subs
|
if (meta != null && (!_subs || !meta.isManagedInterface())
|
||||||
|
&& (meta.isMapped() || (_subs
|
||||||
&& meta.getMappedPCSubclassMetaDatas().length > 0)))
|
&& meta.getMappedPCSubclassMetaDatas().length > 0)))
|
||||||
metas = new ClassMetaData[]{ meta };
|
metas = new ClassMetaData[]{ meta };
|
||||||
else if (meta == null && _subs)
|
else if (_subs && (meta == null || meta.isManagedInterface()))
|
||||||
metas = repos.getImplementorMetaDatas(_type,
|
metas = repos.getImplementorMetaDatas(_type,
|
||||||
_broker.getClassLoader(), false);
|
_broker.getClassLoader(), false);
|
||||||
else
|
else
|
||||||
|
|
|
@ -657,11 +657,11 @@ public class QueryImpl
|
||||||
ClassMetaData[] metas;
|
ClassMetaData[] metas;
|
||||||
if (_class == null || _storeQuery.supportsAbstractExecutors())
|
if (_class == null || _storeQuery.supportsAbstractExecutors())
|
||||||
metas = new ClassMetaData[]{ meta };
|
metas = new ClassMetaData[]{ meta };
|
||||||
else if (meta != null && (_subclasses || meta.isMapped()))
|
else if (_subclasses && (meta == null || meta.isManagedInterface()))
|
||||||
metas = new ClassMetaData[]{ meta };
|
|
||||||
else if (_subclasses)
|
|
||||||
metas = repos.getImplementorMetaDatas(_class,
|
metas = repos.getImplementorMetaDatas(_class,
|
||||||
_broker.getClassLoader(), true);
|
_broker.getClassLoader(), true);
|
||||||
|
else if (meta != null && (_subclasses || meta.isMapped()))
|
||||||
|
metas = new ClassMetaData[]{ meta };
|
||||||
else
|
else
|
||||||
metas = StoreQuery.EMPTY_METAS;
|
metas = StoreQuery.EMPTY_METAS;
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ public class ClassMetaData
|
||||||
private Boolean _embedded = null;
|
private Boolean _embedded = null;
|
||||||
private Boolean _interface = null;
|
private Boolean _interface = null;
|
||||||
private Class _impl = null;
|
private Class _impl = null;
|
||||||
|
private Map _ifaceMap = new HashMap();
|
||||||
private int _identity = ID_UNKNOWN;
|
private int _identity = ID_UNKNOWN;
|
||||||
private int _idStrategy = ValueStrategies.NONE;
|
private int _idStrategy = ValueStrategies.NONE;
|
||||||
private int _accessType = ACCESS_UNKNOWN;
|
private int _accessType = ACCESS_UNKNOWN;
|
||||||
|
@ -694,6 +695,37 @@ public class ClassMetaData
|
||||||
public void setInterfaceImpl(Class impl) {
|
public void setInterfaceImpl(Class impl) {
|
||||||
_impl = impl;
|
_impl = impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias properties from the given interface during queries to
|
||||||
|
* the local field.
|
||||||
|
*/
|
||||||
|
public void setInterfacePropertyAlias(Class iface, String orig,
|
||||||
|
String local) {
|
||||||
|
synchronized (_ifaceMap) {
|
||||||
|
Map fields = (Map) _ifaceMap.get(iface);
|
||||||
|
if (fields == null) {
|
||||||
|
fields = new HashMap();
|
||||||
|
_ifaceMap.put(iface, fields);
|
||||||
|
}
|
||||||
|
if (fields.containsKey(orig))
|
||||||
|
throw new MetaDataException(_loc.get("duplicate-iface-alias",
|
||||||
|
this, orig, local));
|
||||||
|
fields.put(orig, local);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get local field alias for the given interface property.
|
||||||
|
*/
|
||||||
|
public String getInterfacePropertyAlias(Class iface, String orig) {
|
||||||
|
synchronized (_ifaceMap) {
|
||||||
|
Map fields = (Map) _ifaceMap.get(iface);
|
||||||
|
if (fields == null)
|
||||||
|
return null;
|
||||||
|
return (String) fields.get(orig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of fields that use impl or intermediate data, in
|
* Return the number of fields that use impl or intermediate data, in
|
||||||
|
@ -2194,6 +2226,10 @@ public class ClassMetaData
|
||||||
fg = addDeclaredFetchGroup(fgs[i].getName());
|
fg = addDeclaredFetchGroup(fgs[i].getName());
|
||||||
fg.copy(fgs[i]);
|
fg.copy(fgs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy iface re-mapping
|
||||||
|
_ifaceMap.clear();
|
||||||
|
_ifaceMap.putAll(meta._ifaceMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -83,8 +83,8 @@ public class MetaDataRepository
|
||||||
public static final int VALIDATE_RUNTIME = 8;
|
public static final int VALIDATE_RUNTIME = 8;
|
||||||
|
|
||||||
protected static final Class[] EMPTY_CLASSES = new Class[0];
|
protected static final Class[] EMPTY_CLASSES = new Class[0];
|
||||||
protected static final PersistenceAwareClass[] EMPTY_PAWARE_CLASSES =
|
protected static final NonPersistentMetaData[] EMPTY_NON_PERSISTENT =
|
||||||
new PersistenceAwareClass[0];
|
new NonPersistentMetaData[0];
|
||||||
protected final ClassMetaData[] EMPTY_METAS;
|
protected final ClassMetaData[] EMPTY_METAS;
|
||||||
protected final FieldMetaData[] EMPTY_FIELDS;
|
protected final FieldMetaData[] EMPTY_FIELDS;
|
||||||
protected final Order[] EMPTY_ORDERS;
|
protected final Order[] EMPTY_ORDERS;
|
||||||
|
@ -110,6 +110,7 @@ public class MetaDataRepository
|
||||||
private final Map _seqs = new HashMap();
|
private final Map _seqs = new HashMap();
|
||||||
private final Map _aliases = Collections.synchronizedMap(new HashMap());
|
private final Map _aliases = Collections.synchronizedMap(new HashMap());
|
||||||
private final Map _pawares = Collections.synchronizedMap(new HashMap());
|
private final Map _pawares = Collections.synchronizedMap(new HashMap());
|
||||||
|
private final Map _nonMapped = Collections.synchronizedMap(new HashMap());
|
||||||
|
|
||||||
// map of classes to lists of their subclasses
|
// map of classes to lists of their subclasses
|
||||||
private final Map _subs = Collections.synchronizedMap(new HashMap());
|
private final Map _subs = Collections.synchronizedMap(new HashMap());
|
||||||
|
@ -886,6 +887,7 @@ public class MetaDataRepository
|
||||||
meta, impl));
|
meta, impl));
|
||||||
_ifaces.put(meta.getDescribedType(), impl);
|
_ifaces.put(meta.getDescribedType(), impl);
|
||||||
_metas.put(impl, meta);
|
_metas.put(impl, meta);
|
||||||
|
addDeclaredInterfaceImpl(meta, meta.getDescribedType());
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized InterfaceImplGenerator getImplGenerator() {
|
synchronized InterfaceImplGenerator getImplGenerator() {
|
||||||
|
@ -1034,56 +1036,112 @@ public class MetaDataRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the persistence-aware class corresponding to the given class. Can
|
* Gets the metadata corresponding to the given persistence-aware class.
|
||||||
* be null, if the given class is not registered as persistence-aware with
|
* Returns null, if the given class is not registered as
|
||||||
* this receiver.
|
* persistence-aware.
|
||||||
*/
|
*/
|
||||||
public PersistenceAwareClass getPersistenceAware(Class cls) {
|
public NonPersistentMetaData getPersistenceAware(Class cls) {
|
||||||
return (PersistenceAwareClass)_pawares.get(cls);
|
return (NonPersistentMetaData)_pawares.get(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the registered persistence-aware classes.
|
* Gets all the metadatas for persistence-aware classes
|
||||||
*
|
*
|
||||||
* @return empty array if no class has been registered
|
* @return empty array if no class has been registered as pers-aware
|
||||||
*/
|
*/
|
||||||
public PersistenceAwareClass[] getPersistenceAwares() {
|
public NonPersistentMetaData[] getPersistenceAwares() {
|
||||||
synchronized (_pawares) {
|
synchronized (_pawares) {
|
||||||
if (_pawares.isEmpty())
|
if (_pawares.isEmpty())
|
||||||
return EMPTY_PAWARE_CLASSES;
|
return EMPTY_NON_PERSISTENT;
|
||||||
return (PersistenceAwareClass[])_pawares.values().toArray
|
return (NonPersistentMetaData[])_pawares.values().toArray
|
||||||
(new PersistenceAwareClass[_pawares.size()]);
|
(new NonPersistentMetaData[_pawares.size()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given class as persitence-aware.
|
* Add the given class as persistence-aware.
|
||||||
*
|
*
|
||||||
* @param cls non-null and must not alreaddy be added as persitence-capable
|
* @param cls non-null and must not alreaddy be added as persitence-capable
|
||||||
*/
|
*/
|
||||||
public PersistenceAwareClass addPersistenceAware(Class cls) {
|
public NonPersistentMetaData addPersistenceAware(Class cls) {
|
||||||
if (cls == null)
|
if (cls == null)
|
||||||
return null;
|
return null;
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
if (_pawares.containsKey(cls))
|
if (_pawares.containsKey(cls))
|
||||||
return (PersistenceAwareClass)_pawares.get(cls);
|
return (NonPersistentMetaData)_pawares.get(cls);
|
||||||
if (getCachedMetaData(cls) != null)
|
if (getCachedMetaData(cls) != null)
|
||||||
throw new MetaDataException(_loc.get("pc-and-aware", cls));
|
throw new MetaDataException(_loc.get("pc-and-aware", cls));
|
||||||
PersistenceAwareClass result = new PersistenceAwareClass(cls, this);
|
NonPersistentMetaData meta = new NonPersistentMetaData(cls, this,
|
||||||
_pawares.put(cls, result);
|
NonPersistentMetaData.TYPE_PERSISTENCE_AWARE);
|
||||||
return result;
|
_pawares.put(cls, meta);
|
||||||
|
return meta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a persitence-aware class from this receiver.
|
* Remove a persitence-aware class from the repository
|
||||||
*
|
*
|
||||||
* @return true if removed, false if not contained in this receiver
|
* @return true if removed
|
||||||
*/
|
*/
|
||||||
public boolean removePersistenceAware(Class cls) {
|
public boolean removePersistenceAware(Class cls) {
|
||||||
return _pawares.remove(cls) != null;
|
return _pawares.remove(cls) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the metadata corresponding to the given non-mapped interface.
|
||||||
|
* Returns null, if the given interface is not registered as
|
||||||
|
* persistence-aware.
|
||||||
|
*/
|
||||||
|
public NonPersistentMetaData getNonMappedInterface(Class iface) {
|
||||||
|
return (NonPersistentMetaData)_nonMapped.get(iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the corresponding metadatas for all registered, non-mapped
|
||||||
|
* interfaces
|
||||||
|
*
|
||||||
|
* @return empty array if no non-mapped interface has been registered.
|
||||||
|
*/
|
||||||
|
public NonPersistentMetaData[] getNonMappedInterfaces() {
|
||||||
|
synchronized (_nonMapped) {
|
||||||
|
if (_nonMapped.isEmpty())
|
||||||
|
return EMPTY_NON_PERSISTENT;
|
||||||
|
return (NonPersistentMetaData[])_nonMapped.values().toArray
|
||||||
|
(new NonPersistentMetaData[_nonMapped.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given non-mapped interface to the repository.
|
||||||
|
*
|
||||||
|
* @param iface the non-mapped interface
|
||||||
|
*/
|
||||||
|
public NonPersistentMetaData addNonMappedInterface(Class iface) {
|
||||||
|
if (iface == null)
|
||||||
|
return null;
|
||||||
|
synchronized(this) {
|
||||||
|
if (!iface.isInterface())
|
||||||
|
throw new MetaDataException(_loc.get("not-non-mapped", iface));
|
||||||
|
if (_nonMapped.containsKey(iface))
|
||||||
|
return (NonPersistentMetaData)_nonMapped.get(iface);
|
||||||
|
if (getCachedMetaData(iface) != null)
|
||||||
|
throw new MetaDataException(_loc.get("non-mapped-pc", iface));
|
||||||
|
NonPersistentMetaData meta = new NonPersistentMetaData(iface, this,
|
||||||
|
NonPersistentMetaData.TYPE_NON_MAPPED_INTERFACE);
|
||||||
|
_nonMapped.put(iface, meta);
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a non-mapped interface from the repository
|
||||||
|
*
|
||||||
|
* @return true if removed
|
||||||
|
*/
|
||||||
|
public boolean removeNonMappedInterface(Class iface) {
|
||||||
|
return _nonMapped.remove(iface) != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the cache of parsed metadata. This method also clears the
|
* Clear the cache of parsed metadata. This method also clears the
|
||||||
* internal {@link MetaDataFactory MetaDataFactory}'s cache.
|
* internal {@link MetaDataFactory MetaDataFactory}'s cache.
|
||||||
|
@ -1102,6 +1160,7 @@ public class MetaDataRepository
|
||||||
_factory.clear();
|
_factory.clear();
|
||||||
_aliases.clear();
|
_aliases.clear();
|
||||||
_pawares.clear();
|
_pawares.clear();
|
||||||
|
_nonMapped.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1317,7 +1376,7 @@ public class MetaDataRepository
|
||||||
* Update the list of implementations of base classes and interfaces.
|
* Update the list of implementations of base classes and interfaces.
|
||||||
*/
|
*/
|
||||||
private void updateImpls(Class cls, Class leastDerived, Class check) {
|
private void updateImpls(Class cls, Class leastDerived, Class check) {
|
||||||
if (_factory.getDefaults().isDeclaredInterfacePersistent())
|
if (!_factory.getDefaults().isDeclaredInterfacePersistent())
|
||||||
return;
|
return;
|
||||||
// allow users to query on common non-pc superclasses
|
// allow users to query on common non-pc superclasses
|
||||||
Class sup = check.getSuperclass();
|
Class sup = check.getSuperclass();
|
||||||
|
|
|
@ -10,20 +10,25 @@ import org.apache.openjpa.lib.xml.Commentable;
|
||||||
*
|
*
|
||||||
* @author Pinaki Poddar
|
* @author Pinaki Poddar
|
||||||
*/
|
*/
|
||||||
public class PersistenceAwareClass
|
public class NonPersistentMetaData
|
||||||
implements Comparable, SourceTracker, Commentable, MetaDataContext {
|
implements Comparable, SourceTracker, Commentable, MetaDataContext {
|
||||||
|
public static final int TYPE_PERSISTENCE_AWARE = 1;
|
||||||
|
public static final int TYPE_NON_MAPPED_INTERFACE = 2;
|
||||||
|
|
||||||
private final MetaDataRepository _repos;
|
private final MetaDataRepository _repos;
|
||||||
private final Class _class;
|
private final Class _class;
|
||||||
|
private final int _type;
|
||||||
|
|
||||||
private File _srcFile = null;
|
private File _srcFile = null;
|
||||||
private int _srcType = SRC_OTHER;
|
private int _srcType = SRC_OTHER;
|
||||||
private String[] _comments = null;
|
private String[] _comments = null;
|
||||||
private int _listIndex = -1;
|
private int _listIndex = -1;
|
||||||
|
|
||||||
protected PersistenceAwareClass(Class cls, MetaDataRepository repos) {
|
protected NonPersistentMetaData(Class cls, MetaDataRepository repos,
|
||||||
|
int type) {
|
||||||
_repos = repos;
|
_repos = repos;
|
||||||
_class = cls;
|
_class = cls;
|
||||||
|
_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +44,13 @@ public class PersistenceAwareClass
|
||||||
public Class getDescribedType() {
|
public Class getDescribedType() {
|
||||||
return _class;
|
return _class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of metadata.
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index in which this class was listed in the metadata. Defaults to
|
* The index in which this class was listed in the metadata. Defaults to
|
||||||
|
@ -85,13 +97,14 @@ public class PersistenceAwareClass
|
||||||
_comments = comments;
|
_comments = comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(Object other) {
|
public int compareTo(Object o) {
|
||||||
if (other == this)
|
if (o == this)
|
||||||
return 0;
|
return 0;
|
||||||
if (!(other instanceof PersistenceAwareClass))
|
if (!(o instanceof NonPersistentMetaData))
|
||||||
return 1;
|
return 1;
|
||||||
return _class.getName().compareTo(((PersistenceAwareClass) other).
|
NonPersistentMetaData other = (NonPersistentMetaData) o;
|
||||||
getDescribedType().getName());
|
if (_type != other.getType())
|
||||||
|
return _type - other.getType();
|
||||||
|
return _class.getName().compareTo(other.getDescribedType().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -259,8 +259,13 @@ bad-fg-inclue: Attempt to include non-existent fetch group "{1}" in fetch \
|
||||||
group "{0}".
|
group "{0}".
|
||||||
unknown-fg: Attempt to add fetch group "{0}" to type field "{1}" failed. \
|
unknown-fg: Attempt to add fetch group "{0}" to type field "{1}" failed. \
|
||||||
This fetch group has not been defined.
|
This fetch group has not been defined.
|
||||||
|
duplicate-iface-alias: Cannot alias interface "{0}" property "{1}" to local \
|
||||||
|
field "{2}" as the property has already been aliased.
|
||||||
pc-and-aware: Attempt to register "{0}" as a persistence-aware class failed. \
|
pc-and-aware: Attempt to register "{0}" as a persistence-aware class failed. \
|
||||||
The same class has been registered as persistence-capable already.=======
|
The same class has been registered as persistence-capable already.
|
||||||
|
not-non-mapped: Type "{0}" cannot be a non-mapped interface as the class is \
|
||||||
|
not an interface
|
||||||
|
non-mapped-pc: A non-mapped interface cannot also be mapped.
|
||||||
no-metadatafactory: No configuration properties were found. If you are \
|
no-metadatafactory: No configuration properties were found. If you are \
|
||||||
using Ant, please see the <properties> or <propertiesFile> attributes \
|
using Ant, please see the <properties> or <propertiesFile> attributes \
|
||||||
of the task''s nested <config> element.
|
of the task''s nested <config> element.
|
||||||
|
|
Loading…
Reference in New Issue