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