mirror of
https://github.com/apache/openjpa.git
synced 2025-02-21 01:15:30 +00:00
Support for managed interfaces
git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@439383 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c39b7141ce
commit
423b0a418a
@ -90,8 +90,9 @@ public class PCEnhancer {
|
||||
|
||||
public static final int ENHANCE_NONE = 0;
|
||||
public static final int ENHANCE_AWARE = 2 << 0;
|
||||
public static final int ENHANCE_PC = 2 << 1;
|
||||
public static final int ENHANCE_OID = 2 << 2;
|
||||
public static final int ENHANCE_INTERFACE = 2 << 1;
|
||||
public static final int ENHANCE_PC = 2 << 2;
|
||||
public static final int ENHANCE_OID = 2 << 3;
|
||||
|
||||
private static final String PRE = "pc";
|
||||
private static final Class PCTYPE = PersistenceCapable.class;
|
||||
@ -127,7 +128,7 @@ public class PCEnhancer {
|
||||
* Constructor. Supply configuration and type to enhance.
|
||||
*/
|
||||
public PCEnhancer(OpenJPAConfiguration conf, Class type) {
|
||||
this(conf, new Project().loadClass(type), null);
|
||||
this(conf, new Project().loadClass(type), (MetaDataRepository) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,6 +164,17 @@ public class PCEnhancer {
|
||||
_meta = _repos.getMetaData(type.getType(), null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Supply configuration, type, and metadata.
|
||||
*/
|
||||
public PCEnhancer(OpenJPAConfiguration conf, BCClass type,
|
||||
ClassMetaData meta) {
|
||||
_pc = type;
|
||||
_log = conf.getLog(OpenJPAConfiguration.LOG_ENHANCE);
|
||||
_repos = meta.getRepository();
|
||||
_meta = meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bytecode representation of the class being manipulated.
|
||||
*/
|
||||
@ -266,6 +278,10 @@ public class PCEnhancer {
|
||||
_log.trace(_loc.get("enhance-start", _pc.getType()));
|
||||
|
||||
try {
|
||||
// if managed interface, skip
|
||||
if (_pc.isInterface())
|
||||
return ENHANCE_INTERFACE;
|
||||
|
||||
// check if already enhanced
|
||||
Class[] interfaces = _pc.getDeclaredInterfaceTypes();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
@ -612,13 +628,13 @@ public class PCEnhancer {
|
||||
String prefix = (get) ? PRE + "Get" : PRE + "Set";
|
||||
methodName = prefix + name;
|
||||
if (get) {
|
||||
mi.setMethod(owner.getDescribedType().getName(),
|
||||
mi.setMethod(getType(owner).getName(),
|
||||
methodName, typeName, new String[]
|
||||
{ owner.getDescribedType().getName() });
|
||||
{ getType(owner).getName() });
|
||||
} else {
|
||||
mi.setMethod(owner.getDescribedType().getName(),
|
||||
mi.setMethod(getType(owner).getName(),
|
||||
methodName, "void", new String[]
|
||||
{ owner.getDescribedType().getName(), typeName });
|
||||
{ getType(owner).getName(), typeName });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -659,6 +675,10 @@ public class PCEnhancer {
|
||||
if (owner.getName().equals(Object.class.getName()))
|
||||
return null;
|
||||
|
||||
// managed interface
|
||||
if (_meta != null && _meta.getDescribedType().isInterface())
|
||||
return _meta;
|
||||
|
||||
return _repos.getMetaData(owner, null, false);
|
||||
}
|
||||
|
||||
@ -722,8 +742,9 @@ public class PCEnhancer {
|
||||
// super.pcClearFields ()
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
code.aload().setThis();
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass(),
|
||||
PRE + "ClearFields", void.class, null);
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()), PRE + "ClearFields", void.class,
|
||||
null);
|
||||
}
|
||||
|
||||
FieldMetaData[] fmds = _meta.getDeclaredFields();
|
||||
@ -849,7 +870,8 @@ public class PCEnhancer {
|
||||
// return <fields> + <superclass>.pcGetManagedFieldCount ()
|
||||
code.constant().setValue(_meta.getDeclaredFields().length);
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
code.invokestatic().setMethod(_meta.getPCSuperclass().getName(),
|
||||
code.invokestatic().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()).getName(),
|
||||
PRE + "GetManagedFieldCount", int.class.getName(), null);
|
||||
code.iadd();
|
||||
}
|
||||
@ -1039,14 +1061,15 @@ public class PCEnhancer {
|
||||
loadManagedInstance(code, false);
|
||||
String[] args;
|
||||
if (copy) {
|
||||
args = new String[]{ _meta.getPCSuperclass().getName(),
|
||||
int.class.getName() };
|
||||
args = new String[]{ getType(_meta.getPCSuperclassMetaData()).
|
||||
getName(), int.class.getName() };
|
||||
code.aload().setParam(0);
|
||||
} else
|
||||
args = new String[]{ int.class.getName() };
|
||||
code.iload().setParam(fieldNumber);
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass().
|
||||
getName(), name, void.class.getName(), args);
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()).getName(), name,
|
||||
void.class.getName(), args);
|
||||
code.vreturn();
|
||||
} else
|
||||
throwException(code, IllegalArgumentException.class);
|
||||
@ -1442,7 +1465,8 @@ public class PCEnhancer {
|
||||
loadManagedInstance(code, false);
|
||||
for (int i = 0; i < args.length; i++)
|
||||
code.aload().setParam(i);
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass().getName(),
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()).getName(),
|
||||
PRE + "CopyKeyFieldsToObjectId", void.class.getName(), args);
|
||||
}
|
||||
|
||||
@ -1535,7 +1559,8 @@ public class PCEnhancer {
|
||||
loadManagedInstance(code, false);
|
||||
for (int i = 0; i < args.length; i++)
|
||||
code.aload().setParam(i);
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass().getName(),
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()).getName(),
|
||||
PRE + "CopyKeyFieldsFromObjectId", void.class.getName(), args);
|
||||
}
|
||||
|
||||
@ -1729,14 +1754,14 @@ public class PCEnhancer {
|
||||
// new ObjectId (cls, oid)
|
||||
code.anew().setType(ObjectId.class);
|
||||
code.dup();
|
||||
code.classconstant().setClass(_meta.getDescribedType());
|
||||
code.classconstant().setClass(getType(_meta));
|
||||
}
|
||||
|
||||
// new <oid class> ();
|
||||
code.anew().setType(oidType);
|
||||
code.dup();
|
||||
if (_meta.isOpenJPAIdentity() || (obj && usesClsString == Boolean.TRUE))
|
||||
code.classconstant().setClass(_meta.getDescribedType());
|
||||
code.classconstant().setClass(getType(_meta));
|
||||
if (obj) {
|
||||
code.aload().setParam(0);
|
||||
code.checkcast().setType(String.class);
|
||||
@ -1926,12 +1951,14 @@ public class PCEnhancer {
|
||||
Code code = getOrCreateClassInitCode(true);
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
// pcInheritedFieldCount = <superClass>.pcGetManagedFieldCount()
|
||||
code.invokestatic().setMethod(_meta.getPCSuperclass().getName(),
|
||||
code.invokestatic().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()).getName(),
|
||||
PRE + "GetManagedFieldCount", int.class.getName(), null);
|
||||
code.putstatic().setField(INHERIT, int.class);
|
||||
|
||||
// pcPCSuperclass = <superClass>;
|
||||
code.classconstant().setClass(_meta.getPCSuperclass());
|
||||
code.classconstant().setClass(getType(_meta.
|
||||
getPCSuperclassMetaData()));
|
||||
code.putstatic().setField(SUPER, Class.class);
|
||||
}
|
||||
|
||||
@ -2961,7 +2988,7 @@ public class PCEnhancer {
|
||||
// readUnmanaged (in);
|
||||
loadManagedInstance(code, false);
|
||||
code.aload().setParam(0);
|
||||
code.invokevirtual().setMethod(_meta.getDescribedType(),
|
||||
code.invokevirtual().setMethod(getType(_meta),
|
||||
PRE + "ReadUnmanaged", void.class, inargs);
|
||||
|
||||
if (detachedState) {
|
||||
@ -3013,8 +3040,9 @@ public class PCEnhancer {
|
||||
if (parentDetachable) {
|
||||
loadManagedInstance(code, false);
|
||||
code.aload().setParam(0);
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass(),
|
||||
PRE + "ReadUnmanaged", void.class, inargs);
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()), PRE + "ReadUnmanaged", void.class,
|
||||
inargs);
|
||||
}
|
||||
|
||||
// read declared unmanaged serializable fields
|
||||
@ -3091,7 +3119,7 @@ public class PCEnhancer {
|
||||
Code code = meth.getCode(true);
|
||||
|
||||
// super.writeExternal (out);
|
||||
Class sup = _meta.getDescribedType().getSuperclass();
|
||||
Class sup = getType(_meta).getSuperclass();
|
||||
if (!parentDetachable && Externalizable.class.isAssignableFrom(sup)) {
|
||||
loadManagedInstance(code, false);
|
||||
code.aload().setParam(0);
|
||||
@ -3102,7 +3130,7 @@ public class PCEnhancer {
|
||||
// writeUnmanaged (out);
|
||||
loadManagedInstance(code, false);
|
||||
code.aload().setParam(0);
|
||||
code.invokevirtual().setMethod(_meta.getDescribedType(),
|
||||
code.invokevirtual().setMethod(getType(_meta),
|
||||
PRE + "WriteUnmanaged", void.class, outargs);
|
||||
|
||||
JumpInstruction go2 = null;
|
||||
@ -3169,8 +3197,9 @@ public class PCEnhancer {
|
||||
if (parentDetachable) {
|
||||
loadManagedInstance(code, false);
|
||||
code.aload().setParam(0);
|
||||
code.invokespecial().setMethod(_meta.getPCSuperclass(),
|
||||
PRE + "WriteUnmanaged", void.class, outargs);
|
||||
code.invokespecial().setMethod(getType(_meta.
|
||||
getPCSuperclassMetaData()), PRE + "WriteUnmanaged", void.class,
|
||||
outargs);
|
||||
}
|
||||
|
||||
// write declared unmanaged serializable fields
|
||||
@ -3316,7 +3345,7 @@ public class PCEnhancer {
|
||||
// static void pcSet<field> (XXX inst, <fieldtype> value)
|
||||
BCField field = _pc.getDeclaredField(fmd.getName());
|
||||
setter = _pc.declareMethod(PRE + "Set" + fmd.getName(), void.class,
|
||||
new Class[]{ _meta.getDescribedType(), fmd.getDeclaredType() });
|
||||
new Class[]{ getType(_meta), fmd.getDeclaredType() });
|
||||
setter.setAccessFlags(field.getAccessFlags()
|
||||
& ~Constants.ACCESS_TRANSIENT & ~Constants.ACCESS_VOLATILE);
|
||||
setter.setStatic(true);
|
||||
@ -3337,6 +3366,17 @@ public class PCEnhancer {
|
||||
return setter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the concrete type for the given class, i.e. impl for managed
|
||||
* interfaces
|
||||
*/
|
||||
public Class getType(ClassMetaData meta) {
|
||||
if (meta.getInterfaceImpl() != null)
|
||||
return meta.getInterfaceImpl();
|
||||
return meta.getDescribedType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Move code-related attributes from one method to another.
|
||||
*/
|
||||
@ -3479,6 +3519,8 @@ public class PCEnhancer {
|
||||
status = enhancer.run();
|
||||
if (status == ENHANCE_NONE)
|
||||
log.info(_loc.get("enhance-norun"));
|
||||
else if (status == ENHANCE_INTERFACE)
|
||||
log.info(_loc.get("enhance-interface"));
|
||||
else if (status == ENHANCE_AWARE) {
|
||||
log.info(_loc.get("enhance-aware"));
|
||||
enhancer.record();
|
||||
|
@ -2494,6 +2494,9 @@ public class BrokerImpl
|
||||
|
||||
PersistenceCapable copy;
|
||||
PCState state;
|
||||
Class type = meta.getDescribedType();
|
||||
if (type.isInterface())
|
||||
type = meta.getInterfaceImpl();
|
||||
if (obj != null) {
|
||||
// give copy and the original instance the same state manager
|
||||
// so that we can copy fields from one to the other
|
||||
@ -2512,8 +2515,7 @@ public class BrokerImpl
|
||||
// copy the instance. we do this even if it doesn't already
|
||||
// have a state manager in case it is later assigned to a
|
||||
// PC field; at that point it's too late to copy
|
||||
copy = PCRegistry.newInstance(meta.getDescribedType(),
|
||||
copySM, false);
|
||||
copy = PCRegistry.newInstance(type, copySM, false);
|
||||
int[] fields = new int[meta.getFields().length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
fields[i] = i;
|
||||
@ -2527,8 +2529,7 @@ public class BrokerImpl
|
||||
pc.pcReplaceStateManager(null);
|
||||
}
|
||||
} else {
|
||||
copy = PCRegistry.newInstance(meta.getDescribedType(), sm,
|
||||
false);
|
||||
copy = PCRegistry.newInstance(type, sm, false);
|
||||
if ((_flags & FLAG_ACTIVE) != 0 && !_optimistic)
|
||||
state = PCState.ECLEAN;
|
||||
else
|
||||
@ -3986,8 +3987,11 @@ public class BrokerImpl
|
||||
public Object newInstance(Class cls) {
|
||||
assertOpen();
|
||||
|
||||
//### JDO2
|
||||
if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers()))
|
||||
if (cls.isInterface()) {
|
||||
ClassMetaData meta = _conf.getMetaDataRepositoryInstance().
|
||||
getMetaData(cls, _loader, true);
|
||||
cls = meta.getInterfaceImpl();
|
||||
} else if (Modifier.isAbstract(cls.getModifiers()))
|
||||
throw new UnsupportedOperationException(_loc.get
|
||||
("new-abstract", cls).getMessage());
|
||||
|
||||
|
@ -241,6 +241,8 @@ public class StateManagerImpl
|
||||
}
|
||||
_meta = sub;
|
||||
}
|
||||
if (cls.isInterface())
|
||||
cls = _meta.getInterfaceImpl();
|
||||
|
||||
PersistenceCapable inst = PCRegistry.newInstance(cls, this, _oid, true);
|
||||
if (inst == null) {
|
||||
|
@ -41,6 +41,7 @@ public abstract class AbstractMetaDataDefaults
|
||||
|
||||
private int _access = ClassMetaData.ACCESS_FIELD;
|
||||
private boolean _ignore = true;
|
||||
private boolean _interface = true;
|
||||
private boolean _pcRegistry = true;
|
||||
private int _callback = CALLBACK_RETHROW;
|
||||
|
||||
@ -170,7 +171,8 @@ public abstract class AbstractMetaDataDefaults
|
||||
*/
|
||||
private void populateFromReflection(ClassMetaData meta) {
|
||||
Member[] members;
|
||||
if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD)
|
||||
boolean iface = meta.getDescribedType().isInterface();
|
||||
if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD && !iface)
|
||||
members = meta.getDescribedType().getDeclaredFields();
|
||||
else
|
||||
members = meta.getDescribedType().getDeclaredMethods();
|
||||
@ -263,6 +265,14 @@ public abstract class AbstractMetaDataDefaults
|
||||
protected abstract boolean isDefaultPersistent(ClassMetaData meta,
|
||||
Member member, String name);
|
||||
|
||||
public void setDeclaredInterfacePersistent(boolean pers) {
|
||||
_interface = pers;
|
||||
}
|
||||
|
||||
public boolean isDeclaredInterfacePersistent() {
|
||||
return _interface;
|
||||
}
|
||||
|
||||
public Member getBackingMember(FieldMetaData fmd) {
|
||||
if (fmd == null)
|
||||
return null;
|
||||
@ -321,6 +331,10 @@ public abstract class AbstractMetaDataDefaults
|
||||
new String[]{ name, clsName, "get" + capName, "is" + capName }));
|
||||
}
|
||||
|
||||
public Class getUnimplementedExceptionType() {
|
||||
return UnsupportedOperationException.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method; returns true if the given class appears to be
|
||||
* user-defined.
|
||||
|
@ -140,6 +140,8 @@ public class ClassMetaData
|
||||
private Boolean _openjpaId = null;
|
||||
private Boolean _extent = null;
|
||||
private Boolean _embedded = null;
|
||||
private Boolean _interface = null;
|
||||
private Class _impl = null;
|
||||
private int _identity = -1;
|
||||
private int _idStrategy = ValueStrategies.NONE;
|
||||
private int _accessType = ACCESS_UNKNOWN;
|
||||
@ -215,9 +217,8 @@ public class ClassMetaData
|
||||
* an embedded value changes its declared type.
|
||||
*/
|
||||
protected void setDescribedType(Class type) {
|
||||
if (type.isInterface())
|
||||
throw new MetaDataException(_loc.get("interface", type));
|
||||
if ("java.lang.Enum".equals(type.getSuperclass().getName()))
|
||||
if (type.getSuperclass() != null && "java.lang.Enum".equals
|
||||
(type.getSuperclass().getName()))
|
||||
throw new MetaDataException(_loc.get("enum", type));
|
||||
_type = type;
|
||||
}
|
||||
@ -669,6 +670,38 @@ public class ClassMetaData
|
||||
_embedded = (embed) ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the type is a managed interface.
|
||||
*/
|
||||
public boolean isManagedInterface() {
|
||||
if (!_type.isInterface())
|
||||
return false;
|
||||
return _interface == null ? false : _interface.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the type is a managed interface
|
||||
*/
|
||||
public void setManagedInterface(boolean managedInterface) {
|
||||
if (!_type.isInterface())
|
||||
throw new MetaDataException(_loc.get("not-interface", _type));
|
||||
_interface = managedInterface ? Boolean.TRUE : Boolean.FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the managed interface implementor if any.
|
||||
*/
|
||||
public Class getInterfaceImpl() {
|
||||
return _impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the managed interface implementor class.
|
||||
*/
|
||||
public void setInterfaceImpl(Class impl) {
|
||||
_impl = impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of fields that use impl or intermediate data, in
|
||||
* order to create a compacted array for storage of said data.
|
||||
@ -1481,7 +1514,19 @@ public class ClassMetaData
|
||||
log.trace(_loc.get((embed) ? "resolve-embed-meta" : "resolve-meta",
|
||||
this + "@" + System.identityHashCode(this)));
|
||||
|
||||
if (runtime && !PersistenceCapable.class.isAssignableFrom(_type))
|
||||
if (_type.isInterface()) {
|
||||
if (!embed && _interface != Boolean.TRUE)
|
||||
throw new MetaDataException(_loc.get("interface", _type));
|
||||
|
||||
if (runtime) {
|
||||
_impl = _repos.getImplGenerator().createImpl(this);
|
||||
if (!embed)
|
||||
_repos.setInterfaceImpl(this, _impl);
|
||||
}
|
||||
}
|
||||
|
||||
if (runtime && !_type.isInterface() &&
|
||||
!PersistenceCapable.class.isAssignableFrom(_type))
|
||||
throw new MetaDataException(_loc.get("not-enhanced", _type));
|
||||
|
||||
// are we the target of an embedded value?
|
||||
@ -2113,6 +2158,8 @@ public class ClassMetaData
|
||||
_objectId = meta.getObjectIdType();
|
||||
_extent = (meta.getRequiresExtent()) ? Boolean.TRUE : Boolean.FALSE;
|
||||
_embedded = (meta.isEmbeddedOnly()) ? Boolean.TRUE : Boolean.FALSE;
|
||||
_interface = (meta.isManagedInterface()) ? Boolean.TRUE : Boolean.FALSE;
|
||||
_impl = meta.getInterfaceImpl();
|
||||
_identity = meta.getIdentityType();
|
||||
_idStrategy = meta.getIdentityStrategy();
|
||||
_seqName = meta.getIdentitySequenceName();
|
||||
|
@ -62,8 +62,14 @@ class InheritanceComparator
|
||||
|
||||
int i1 = levels(c1);
|
||||
int i2 = levels(c2);
|
||||
if (i1 == i2)
|
||||
if (i1 == i2) {
|
||||
// sort simple interfaces as well as simple order test will fail.
|
||||
if (c1.isAssignableFrom(o2.getClass()))
|
||||
return -1;
|
||||
if (c2.isAssignableFrom(o1.getClass()))
|
||||
return 1;
|
||||
return c1.getName().compareTo(c2.getName());
|
||||
}
|
||||
return i1 - i2;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,12 @@ public interface MetaDataDefaults
|
||||
*/
|
||||
public void setIgnoreNonPersistent(boolean ignore);
|
||||
|
||||
/**
|
||||
* Whether declared interfaces of a class are treated as persistent
|
||||
* types. Defaults to true.
|
||||
*/
|
||||
public boolean isDeclaredInterfacePersistent();
|
||||
|
||||
/**
|
||||
* Populate the given metadata with default settings.
|
||||
*
|
||||
@ -61,4 +67,10 @@ public interface MetaDataDefaults
|
||||
* Return the backing member for the given field metadata.
|
||||
*/
|
||||
public Member getBackingMember(FieldMetaData field);
|
||||
|
||||
/**
|
||||
* Return a runtime exception class to throw for un-implemented
|
||||
* managed interface methods.
|
||||
*/
|
||||
public Class getUnimplementedExceptionType();
|
||||
}
|
||||
|
@ -25,7 +25,11 @@ public class MetaDataInheritanceComparator
|
||||
extends InheritanceComparator {
|
||||
|
||||
protected Class toClass(Object elem) {
|
||||
return (elem == null) ? null
|
||||
: ((ClassMetaData) elem).getDescribedType();
|
||||
if (elem == null)
|
||||
return null;
|
||||
ClassMetaData meta = (ClassMetaData) elem;
|
||||
if (meta.getInterfaceImpl() != null)
|
||||
return meta.getInterfaceImpl();
|
||||
return meta.getDescribedType();
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ public class MetaDataRepository
|
||||
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());
|
||||
@ -116,6 +117,7 @@ public class MetaDataRepository
|
||||
private OpenJPAConfiguration _conf = null;
|
||||
private Log _log = null;
|
||||
private MetaDataFactory _factory = null;
|
||||
private InterfaceImplGenerator _implGen = null;
|
||||
private int _resMode = MODE_META | MODE_MAPPING;
|
||||
private int _sourceMode = MODE_META | MODE_MAPPING | MODE_QUERY;
|
||||
private int _validate = VALIDATE_META | VALIDATE_UNENHANCED;
|
||||
@ -541,6 +543,18 @@ public class MetaDataRepository
|
||||
} else
|
||||
sup = sup.getSuperclass();
|
||||
}
|
||||
if (meta.getDescribedType().isInterface()) {
|
||||
Class[] sups = meta.getDescribedType().getInterfaces();
|
||||
for (int i = 0; i < sups.length; i++) {
|
||||
supMeta = getMetaData(sups[i], meta.getEnvClassLoader(),
|
||||
false);
|
||||
if (supMeta != null) {
|
||||
meta.setPCSuperclass(sup);
|
||||
meta.setPCSuperclassMetaData(supMeta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_log.isTraceEnabled())
|
||||
_log.trace(_loc.get("assigned-sup", meta,
|
||||
meta.getPCSuperclass()));
|
||||
@ -845,12 +859,41 @@ public class MetaDataRepository
|
||||
if (cls == null)
|
||||
return false;
|
||||
if (_metas.remove(cls) != null) {
|
||||
Class impl = (Class) _ifaces.remove(cls);
|
||||
if (impl != null)
|
||||
_metas.remove(impl);
|
||||
_count--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given metadata as declared interface implementation.
|
||||
*/
|
||||
public void addDeclaredInterfaceImpl(ClassMetaData meta, Class iface) {
|
||||
synchronized (_impls) {
|
||||
addToCollection(_impls, iface, meta.getDescribedType(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the implementation for the given managed interface.
|
||||
*/
|
||||
synchronized void setInterfaceImpl(ClassMetaData meta, Class impl) {
|
||||
if (!meta.isManagedInterface())
|
||||
throw new MetaDataException(_loc.get("not-managed-interface",
|
||||
meta, impl));
|
||||
_ifaces.put(meta.getDescribedType(), impl);
|
||||
_metas.put(impl, meta);
|
||||
}
|
||||
|
||||
synchronized InterfaceImplGenerator getImplGenerator() {
|
||||
if (_implGen == null)
|
||||
_implGen = new InterfaceImplGenerator(this);
|
||||
return _implGen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the least-derived class metadata for the given application
|
||||
* identity object.
|
||||
@ -1274,6 +1317,8 @@ public class MetaDataRepository
|
||||
* Update the list of implementations of base classes and interfaces.
|
||||
*/
|
||||
private void updateImpls(Class cls, Class leastDerived, Class check) {
|
||||
if (_factory.getDefaults().isDeclaredInterfacePersistent())
|
||||
return;
|
||||
// allow users to query on common non-pc superclasses
|
||||
Class sup = check.getSuperclass();
|
||||
if (leastDerived == cls && sup != null && sup != Object.class) {
|
||||
|
@ -104,10 +104,18 @@ public class NoneMetaDataFactory
|
||||
public void setIgnoreNonPersistent(boolean ignore) {
|
||||
}
|
||||
|
||||
public boolean isDeclaredInterfacePersistent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void populate(ClassMetaData meta, int access) {
|
||||
}
|
||||
|
||||
public Member getBackingMember(FieldMetaData fmd) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Class getUnimplementedExceptionType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -257,8 +257,11 @@ public class ApplicationIds {
|
||||
// to the original oid values, then copy its key fields to a new
|
||||
// oid instance
|
||||
if (!Modifier.isAbstract(meta.getDescribedType().getModifiers())) {
|
||||
PersistenceCapable pc = PCRegistry.newInstance
|
||||
(meta.getDescribedType(), null, oid, false);
|
||||
Class type = meta.getDescribedType();
|
||||
if (meta.getInterfaceImpl() != null)
|
||||
type = meta.getInterfaceImpl();
|
||||
PersistenceCapable pc = PCRegistry.newInstance(type, null, oid,
|
||||
false);
|
||||
Object copy = pc.pcNewObjectIdInstance();
|
||||
pc.pcCopyKeyFieldsToObjectId(copy);
|
||||
return copy;
|
||||
|
@ -24,6 +24,7 @@ enhance-running-oids: Enhancer running on oid: {0}
|
||||
enhance-aware: The class does not have metadata - enhanced as persistence-aware.
|
||||
enhance-norun: The class is already persistence capable - no enhancement \
|
||||
performed.
|
||||
enhance-interface: The class is a managed interface - no enhancement performed.
|
||||
enhance-usage: Usage: java org.apache.openjpa.enhance.PCEnhancer\n\
|
||||
\t[-properties/-p <properties file or resource>]\n\
|
||||
\t[-<property name> <property value>]*\n\
|
||||
|
@ -4,8 +4,8 @@ unloaded-detached: Attempt to access an unloaded field of detached instance \
|
||||
"{0}".
|
||||
meta-unknownid: Cannot manipulate identity of type "{0}": it''s identity type \
|
||||
is unknown.
|
||||
new-abstract: Cannot create an instance of "{0}": abstract classes and \
|
||||
interfaces are not yet supported.
|
||||
new-abstract: Cannot create an instance of "{0}": abstract classes are not \
|
||||
yet supported.
|
||||
bad-new-query: Attempt to construct a query from an extent or class. You must \
|
||||
pass a (possibly null) query string or template to the query factory \
|
||||
method when creating the query.
|
||||
|
@ -18,6 +18,8 @@ clear-repos: Clearing metadata repository "{0}".
|
||||
process-registered: Processing registered persistence-capable class "{0}".
|
||||
assigned-sup: Set persistence-capable superclass of "{0}" to "{1}".
|
||||
found-pcs: Found {0} classes with metadata in {1} milliseconds.
|
||||
not-managed-interface: Cannot set type "{1}" as interface "{0}" implementor. \
|
||||
"{0}" is not a managed interface.
|
||||
unmanaged-sup-field: Superclass field "{0}" is mapped in the metadata for \
|
||||
subclass "{1}", but is not a persistent field.
|
||||
bad-discover-class: The class "{0}" listed in the openjpa.MetaDataFactory \
|
||||
@ -180,7 +182,10 @@ bad-update-strategy: "{0}" declares a read only value of "{1}". \
|
||||
bad-update-strategy-hint: "{0}" declares a read only value of \
|
||||
"{1}". This is not a recognized strategy, though it closely resembles \
|
||||
the standard strategy "{2}". Available strategies are: {3}
|
||||
interface: Type "{0}" is an interface and therefore cannot be made persistent.
|
||||
not-interface: Can't set type "{0}" to be a managed interface as it is not \
|
||||
and interface.
|
||||
interface: The type "{0}" is an unmanaged interface and therefore cannot be \
|
||||
made persistent.
|
||||
enum: Type "{0}" is an enumeration and therefore cannot be made persistent.
|
||||
bad-drop: The metadata for some of the following classes may not have \
|
||||
been dropped: {0}
|
||||
|
Loading…
x
Reference in New Issue
Block a user