OPENJPA-1061 merging patch provided by Jody Grassel to trunk

modified:   openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
	modified:   openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@789519 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Dick 2009-06-30 01:05:16 +00:00
parent 1fce44737b
commit 03d9e24bc6
2 changed files with 119 additions and 23 deletions

View File

@ -153,12 +153,12 @@ public class PCEnhancer {
try { try {
auxEnhancers.add(AccessController.doPrivileged( auxEnhancers.add(AccessController.doPrivileged(
J2DoPrivHelper.newInstanceAction(classes[i]))); J2DoPrivHelper.newInstanceAction(classes[i])));
} catch (Throwable t) { } catch (Throwable t) {
// aux enhancer may rely on non-existant spec classes, etc // aux enhancer may rely on non-existant spec classes, etc
} }
} }
_auxEnhancers = (AuxiliaryEnhancer[]) auxEnhancers.toArray _auxEnhancers = (AuxiliaryEnhancer[]) auxEnhancers.toArray
(new AuxiliaryEnhancer[auxEnhancers.size()]); (new AuxiliaryEnhancer[auxEnhancers.size()]);
} }
private BCClass _pc; private BCClass _pc;
@ -1138,9 +1138,15 @@ public class PCEnhancer {
addCopyKeyFieldsToObjectIdMethod(false); addCopyKeyFieldsToObjectIdMethod(false);
addCopyKeyFieldsFromObjectIdMethod(true); addCopyKeyFieldsFromObjectIdMethod(true);
addCopyKeyFieldsFromObjectIdMethod(false); addCopyKeyFieldsFromObjectIdMethod(false);
if (_meta.hasAbstractPKField() == true) {
addGetIDOwningClass();
}
addNewObjectIdInstanceMethod(true); addNewObjectIdInstanceMethod(true);
addNewObjectIdInstanceMethod(false); addNewObjectIdInstanceMethod(false);
} }
else if (_meta.hasPKFieldsFromAbstractClass()){
addGetIDOwningClass();
}
} }
/** /**
@ -2536,12 +2542,13 @@ public class PCEnhancer {
// new ObjectId (cls, oid) // new ObjectId (cls, oid)
code.anew().setType(ObjectId.class); code.anew().setType(ObjectId.class);
code.dup(); code.dup();
if(_meta.isEmbeddedOnly()) { if(_meta.isEmbeddedOnly() || _meta.hasAbstractPKField() == true) {
code.aload().setThis(); code.aload().setThis();
code.invokevirtual().setMethod(Object.class, "getClass", code.invokevirtual().setMethod(PRE + "GetIDOwningClass",
Class.class, null); Class.class, null);
}else } else {
code.classconstant().setClass(getType(_meta)); code.classconstant().setClass(getType(_meta));
}
} }
// new <oid class> (); // new <oid class> ();
@ -2549,12 +2556,13 @@ public class PCEnhancer {
code.dup(); code.dup();
if (_meta.isOpenJPAIdentity() || (obj && usesClsString == if (_meta.isOpenJPAIdentity() || (obj && usesClsString ==
Boolean.TRUE)) { Boolean.TRUE)) {
if(_meta.isEmbeddedOnly()) { if(_meta.isEmbeddedOnly() || _meta.hasAbstractPKField() == true ) {
code.aload().setThis(); code.aload().setThis();
code.invokevirtual().setMethod(Object.class, "getClass", code.invokevirtual().setMethod(PRE + "GetIDOwningClass",
Class.class, null); Class.class, null);
}else }else {
code.classconstant().setClass(getType(_meta)); code.classconstant().setClass(getType(_meta));
}
} }
if (obj) { if (obj) {
code.aload().setParam(0); code.aload().setParam(0);
@ -4613,15 +4621,27 @@ public class PCEnhancer {
public File directory = null; public File directory = null;
public boolean addDefaultConstructor = true; public boolean addDefaultConstructor = true;
public boolean tmpClassLoader = true; public boolean tmpClassLoader = true;
public boolean enforcePropertyRestrictions = false; public boolean enforcePropertyRestrictions = false;
} }
/** /**
* Plugin interface for additional enhancement. * Plugin interface for additional enhancement.
*/ */
public static interface AuxiliaryEnhancer public static interface AuxiliaryEnhancer
{ {
public void run (BCClass bc, ClassMetaData meta); public void run (BCClass bc, ClassMetaData meta);
public boolean skipEnhance(BCMethod m); public boolean skipEnhance(BCMethod m);
} }
private void addGetIDOwningClass() throws NoSuchMethodException {
BCMethod method = _pc.declareMethod(PRE + "GetIDOwningClass",
Class.class, null);
Code code = method.getCode(true);
code.classconstant().setClass(getType(_meta));
code.areturn();
code.calculateMaxStack();
code.calculateMaxLocals();
}
} }

View File

@ -208,6 +208,8 @@ public class ClassMetaData
private boolean _intercepting = false; private boolean _intercepting = false;
private Boolean _useIdClassFromParent = null; private Boolean _useIdClassFromParent = null;
private boolean _abstract = false; private boolean _abstract = false;
private Boolean _hasAbstractPKField = null;
private Boolean _hasPKFieldsFromAbstractClass = null;
/** /**
* Constructor. Supply described type and repository. * Constructor. Supply described type and repository.
@ -2593,4 +2595,78 @@ public class ClassMetaData
} }
return rval; return rval;
} }
/**
* Convenience method to determine if the pcType modeled by
* this ClassMetaData object is both abstract and declares PKFields. This
* method is used by the PCEnhancer to determine if special handling is
* required.
*
* @return
*/
public boolean hasAbstractPKField() {
if (_hasAbstractPKField != null) {
return _hasAbstractPKField.booleanValue();
}
// Default to false, set to true only if this type is abstract and
// declares a PKField.
_hasAbstractPKField = Boolean.FALSE;
if (isAbstract() == true) {
FieldMetaData[] declaredFields = getDeclaredFields();
if (declaredFields != null && declaredFields.length != 0) {
for (FieldMetaData fmd : declaredFields) {
if (fmd.isPrimaryKey()) {
_hasAbstractPKField = Boolean.TRUE;
break;
}
}
}
}
return _hasAbstractPKField.booleanValue();
}
/**
* Convenience method to determine if this type is a direct
* decendent of an abstract type declaring PKFields. Returns true if there
* are no pcTypes mapped to a table between this type and an abstract pcType
* declaring PKFields. Returns false if there no such abstract pcTypes in
* the inheritance hierarchy or if there are any pcTypes mapped to tables in
* between the type represented by this ClassMetaData object and the
* abstract pcType declaring PKFields.
*
* @return
*/
public boolean hasPKFieldsFromAbstractClass() {
if (_hasPKFieldsFromAbstractClass != null) {
return _hasPKFieldsFromAbstractClass.booleanValue();
}
// Default to FALSE, until proven true.
_hasPKFieldsFromAbstractClass = Boolean.FALSE;
FieldMetaData[] pkFields = getPrimaryKeyFields();
for (FieldMetaData fmd : pkFields) {
ClassMetaData fmdDMDA = fmd.getDeclaringMetaData();
if (fmdDMDA.isAbstract()) {
ClassMetaData cmd = getPCSuperclassMetaData();
while (cmd != fmdDMDA) {
if (fmdDMDA.isAbstract()) {
cmd = cmd.getPCSuperclassMetaData();
} else {
break;
}
}
if (cmd == fmdDMDA) {
_hasPKFieldsFromAbstractClass = Boolean.TRUE;
break;
}
}
}
return _hasPKFieldsFromAbstractClass.booleanValue();
}
} }