You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mi...@apache.org on 2009/06/30 03:05:16 UTC
svn commit: r789519 - in
/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa:
enhance/PCEnhancer.java meta/ClassMetaData.java
Author: mikedd
Date: Tue Jun 30 01:05:16 2009
New Revision: 789519
URL: http://svn.apache.org/viewvc?rev=789519&view=rev
Log:
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
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?rev=789519&r1=789518&r2=789519&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java Tue Jun 30 01:05:16 2009
@@ -153,12 +153,12 @@
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 @@
addCopyKeyFieldsToObjectIdMethod(false);
addCopyKeyFieldsFromObjectIdMethod(true);
addCopyKeyFieldsFromObjectIdMethod(false);
+ if (_meta.hasAbstractPKField() == true) {
+ addGetIDOwningClass();
+ }
addNewObjectIdInstanceMethod(true);
addNewObjectIdInstanceMethod(false);
}
+ else if (_meta.hasPKFieldsFromAbstractClass()){
+ addGetIDOwningClass();
+ }
}
/**
@@ -2536,12 +2542,13 @@
// 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 @@
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 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();
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=789519&r1=789518&r2=789519&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Tue Jun 30 01:05:16 2009
@@ -208,6 +208,8 @@
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 @@
}
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();
+ }
+
}