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();
+    }
+
 }