You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2007/12/16 21:59:37 UTC

svn commit: r604701 - in /cayenne/main/trunk/framework: cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/ cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/c...

Author: aadamchik
Date: Sun Dec 16 12:59:36 2007
New Revision: 604701

URL: http://svn.apache.org/viewvc?rev=604701&view=rev
Log:
CAY-734 Link JPA Embeddable and Embedded annotations with Cayenne runtime
(firt pass)

Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
    cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java?rev=604701&r1=604700&r2=604701&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/Embeddable.java Sun Dec 16 12:59:36 2007
@@ -24,6 +24,8 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.util.Util;
 import org.apache.cayenne.util.XMLEncoder;
 import org.apache.cayenne.util.XMLSerializable;
 
@@ -48,6 +50,23 @@
     public Embeddable(String className) {
         this.attributes = new TreeMap<String, EmbeddableAttribute>();
         this.className = className;
+    }
+
+    /**
+     * Returns Java class of the embeddable.
+     */
+    public Class<?> getJavaClass() {
+        String name = getClassName();
+
+        try {
+            return Util.getJavaClass(name);
+        }
+        catch (ClassNotFoundException e) {
+            throw new CayenneRuntimeException("Failed to load class "
+                    + name
+                    + ": "
+                    + e.getMessage(), e);
+        }
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java?rev=604701&r1=604700&r2=604701&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/bridge/DataMapConverter.java Sun Dec 16 12:59:36 2007
@@ -27,9 +27,12 @@
 import org.apache.cayenne.jpa.conf.EntityMapLoaderContext;
 import org.apache.cayenne.jpa.map.AccessType;
 import org.apache.cayenne.jpa.map.JpaAttribute;
+import org.apache.cayenne.jpa.map.JpaAttributeOverride;
 import org.apache.cayenne.jpa.map.JpaAttributes;
 import org.apache.cayenne.jpa.map.JpaBasic;
 import org.apache.cayenne.jpa.map.JpaColumn;
+import org.apache.cayenne.jpa.map.JpaEmbeddable;
+import org.apache.cayenne.jpa.map.JpaEmbedded;
 import org.apache.cayenne.jpa.map.JpaEntity;
 import org.apache.cayenne.jpa.map.JpaEntityListener;
 import org.apache.cayenne.jpa.map.JpaEntityListeners;
@@ -53,6 +56,9 @@
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.EmbeddedAttribute;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.EntityListener;
 import org.apache.cayenne.map.ObjAttribute;
@@ -147,6 +153,7 @@
 
         BaseTreeVisitor visitor = new BaseTreeVisitor();
         visitor.addChildVisitor(JpaEntity.class, new JpaEntityVisitor());
+        visitor.addChildVisitor(JpaEmbeddable.class, new JpaEmbeddableVisitor());
         visitor.addChildVisitor(JpaNamedQuery.class, new JpaNamedQueryVisitor());
         visitor.addChildVisitor(JpaPersistenceUnitMetadata.class, metadataVisitor);
         return visitor;
@@ -192,6 +199,23 @@
         return listener;
     }
 
+    Field lookupFieldInHierarchy(Class<?> beanClass, String fieldName)
+            throws SecurityException, NoSuchFieldException {
+
+        try {
+            return beanClass.getDeclaredField(fieldName);
+        }
+        catch (NoSuchFieldException e) {
+
+            Class<?> superClass = beanClass.getSuperclass();
+            if (superClass == null || superClass.getName().equals(Object.class.getName())) {
+                throw e;
+            }
+
+            return lookupFieldInHierarchy(superClass, fieldName);
+        }
+    }
+
     class JpaDefaultEntityListenerVisitor extends BaseTreeVisitor {
 
         @Override
@@ -220,6 +244,78 @@
         }
     }
 
+    class JpaEmbeddedVisitor extends NestedVisitor {
+
+        @Override
+        Object createObject(ProjectPath path) {
+            JpaEmbedded jpaEmbedded = (JpaEmbedded) path.getObject();
+
+            ObjEntity parentCayenneEntity = (ObjEntity) targetPath.getObject();
+
+            EmbeddedAttribute embedded = new EmbeddedAttribute(jpaEmbedded.getName());
+            embedded.setType(jpaEmbedded.getPropertyDescriptor().getType().getName());
+
+            for (JpaAttributeOverride override : jpaEmbedded.getAttributeOverrides()) {
+                embedded.addAttributeOverride(override.getName(), override
+                        .getColumn()
+                        .getName());
+            }
+            parentCayenneEntity.addAttribute(embedded);
+
+            return embedded;
+        }
+    }
+
+    class JpaEmbeddedBasicVisitor extends NestedVisitor {
+
+        @Override
+        Object createObject(ProjectPath path) {
+            JpaBasic jpaBasic = (JpaBasic) path.getObject();
+
+            Embeddable embeddable = (Embeddable) targetPath.getObject();
+
+            EmbeddableAttribute attribute = new EmbeddableAttribute(jpaBasic.getName());
+            attribute.setType(getAttributeType(path, jpaBasic.getName()).getName());
+            attribute.setDbAttributeName(jpaBasic.getColumn().getName());
+
+            embeddable.addAttribute(attribute);
+            return attribute;
+        }
+
+        Class<?> getAttributeType(ProjectPath path, String name) {
+            AccessType access = null;
+
+            JpaManagedClass entity = path.firstInstanceOf(JpaManagedClass.class);
+            access = entity.getAccess();
+
+            if (access == null) {
+                JpaEntityMap map = path.firstInstanceOf(JpaEntityMap.class);
+                access = map.getAccess();
+            }
+
+            Class<?> objectClass = targetPath
+                    .firstInstanceOf(Embeddable.class)
+                    .getJavaClass();
+
+            try {
+                if (access == AccessType.FIELD) {
+                    return lookupFieldInHierarchy(objectClass, name).getType();
+                }
+                else {
+                    return new PropertyDescriptor(name, objectClass).getPropertyType();
+                }
+            }
+            catch (Exception e) {
+                throw new JpaProviderException("Error resolving attribute '"
+                        + name
+                        + "', access type:"
+                        + access
+                        + ", class: "
+                        + objectClass.getName(), e);
+            }
+        }
+    }
+
     class JpaBasicVisitor extends NestedVisitor {
 
         @Override
@@ -271,23 +367,6 @@
             }
         }
 
-        Field lookupFieldInHierarchy(Class<?> beanClass, String fieldName)
-                throws SecurityException, NoSuchFieldException {
-
-            try {
-                return beanClass.getDeclaredField(fieldName);
-            }
-            catch (NoSuchFieldException e) {
-
-                Class<?> superClass = beanClass.getSuperclass();
-                if (superClass == null
-                        || superClass.getName().equals(Object.class.getName())) {
-                    throw e;
-                }
-
-                return lookupFieldInHierarchy(superClass, fieldName);
-            }
-        }
     }
 
     class JpaVersionVisitor extends JpaBasicVisitor {
@@ -313,6 +392,12 @@
         @Override
         public boolean onStartNode(ProjectPath path) {
             JpaColumn jpaColumn = (JpaColumn) path.getObject();
+
+            // skip embeddable columns
+            if (path.firstInstanceOf(JpaEmbeddable.class) != null) {
+                return false;
+            }
+
             JpaAttribute attribute = (JpaAttribute) path.getObjectParent();
 
             DbAttribute dbAttribute = new DbAttribute(jpaColumn.getName());
@@ -464,6 +549,27 @@
         }
     }
 
+    class JpaEmbeddableVisitor extends NestedVisitor {
+
+        JpaEmbeddableVisitor() {
+
+            BaseTreeVisitor attributeVisitor = new BaseTreeVisitor();
+
+            JpaEmbeddedBasicVisitor basicVisitor = new JpaEmbeddedBasicVisitor();
+            basicVisitor.addChildVisitor(JpaColumn.class, new JpaColumnVisitor());
+            attributeVisitor.addChildVisitor(JpaBasic.class, basicVisitor);
+            addChildVisitor(JpaAttributes.class, attributeVisitor);
+        }
+
+        @Override
+        Object createObject(ProjectPath path) {
+            JpaEmbeddable jpaEmbeddable = (JpaEmbeddable) path.getObject();
+            Embeddable embeddable = new Embeddable(jpaEmbeddable.getClassName());
+            ((DataMap) targetPath.getObject()).addEmbeddable(embeddable);
+            return embeddable;
+        }
+    }
+
     class JpaEntityVisitor extends NestedVisitor {
 
         JpaEntityVisitor() {
@@ -489,6 +595,9 @@
             basicVisitor.addChildVisitor(JpaColumn.class, new JpaColumnVisitor());
             attributeVisitor.addChildVisitor(JpaBasic.class, basicVisitor);
 
+            JpaEmbeddedVisitor embeddedVisitor = new JpaEmbeddedVisitor();
+            attributeVisitor.addChildVisitor(JpaEmbedded.class, embeddedVisitor);
+
             JpaVersionVisitor versionVisitor = new JpaVersionVisitor();
             versionVisitor.addChildVisitor(JpaColumn.class, new JpaColumnVisitor());
             attributeVisitor.addChildVisitor(JpaVersion.class, versionVisitor);
@@ -497,7 +606,7 @@
             idVisitor.addChildVisitor(JpaColumn.class, new JpaIdColumnVisitor());
             attributeVisitor.addChildVisitor(JpaId.class, idVisitor);
 
-            // TODO: andrus 8/6/2006 - handle Embedded, EmbeddedId, AttributeOverride
+            // TODO: andrus 8/6/2006 - handle EmbeddedId, AttributeOverride
 
             addChildVisitor(JpaAttributes.class, attributeVisitor);
             addChildVisitor(JpaTable.class, new JpaTableVisitor());
@@ -681,9 +790,10 @@
                 try {
 
                     // query class is not enhanced, so use normal class loader
-                    Class<?> cayenneQueryClass = Class.forName(hint.getValue(), true, Thread
-                            .currentThread()
-                            .getContextClassLoader());
+                    Class<?> cayenneQueryClass = Class.forName(
+                            hint.getValue(),
+                            true,
+                            Thread.currentThread().getContextClassLoader());
 
                     if (!JpaIndirectQuery.class.isAssignableFrom(cayenneQueryClass)) {
                         recordConflict(path, "Unknown type for Cayenne query '"

Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java?rev=604701&r1=604700&r2=604701&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/conf/EntityMapDefaultsProcessor.java Sun Dec 16 12:59:36 2007
@@ -35,6 +35,7 @@
 import org.apache.cayenne.jpa.map.JpaBasic;
 import org.apache.cayenne.jpa.map.JpaClassDescriptor;
 import org.apache.cayenne.jpa.map.JpaColumn;
+import org.apache.cayenne.jpa.map.JpaEmbeddable;
 import org.apache.cayenne.jpa.map.JpaEntity;
 import org.apache.cayenne.jpa.map.JpaEntityMap;
 import org.apache.cayenne.jpa.map.JpaId;
@@ -193,6 +194,26 @@
         }
     }
 
+    class EmbeddableBasicVisitor extends BaseTreeVisitor {
+
+        EmbeddableBasicVisitor() {
+            addChildVisitor(JpaColumn.class, new ColumnVisitor());
+        }
+
+        @Override
+        public boolean onStartNode(ProjectPath path) {
+            JpaBasic jpaBasic = (JpaBasic) path.getObject();
+            if (jpaBasic.getColumn() == null) {
+                JpaColumn column = new JpaColumn(AnnotationPrototypes.getColumn());
+                column.setName(jpaBasic.getName());
+                column.setNullable(jpaBasic.isOptional());
+                jpaBasic.setColumn(column);
+            }
+
+            return true;
+        }
+    }
+
     class BasicVisitor extends BaseTreeVisitor {
 
         BasicVisitor() {
@@ -311,6 +332,7 @@
         EntityMapVisitor() {
             addChildVisitor(JpaEntity.class, new EntityVisitor());
             addChildVisitor(JpaMappedSuperclass.class, new MappedSuperclassVisitor());
+            addChildVisitor(JpaEmbeddable.class, new EmbeddableVisitor());
         }
 
         @Override
@@ -323,6 +345,15 @@
             entityMap.setAccess(AccessType.FIELD);
 
             return true;
+        }
+    }
+
+    final class EmbeddableVisitor extends BaseTreeVisitor {
+
+        EmbeddableVisitor() {
+            BaseTreeVisitor attributeVisitor = new BaseTreeVisitor();
+            attributeVisitor.addChildVisitor(JpaBasic.class, new EmbeddableBasicVisitor());
+            addChildVisitor(JpaAttributes.class, attributeVisitor);
         }
     }