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 23:19:41 UTC
svn commit: r604721 - in /cayenne/main/trunk/framework:
cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/
cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/
cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/r...
Author: aadamchik
Date: Sun Dec 16 14:19:40 2007
New Revision: 604721
URL: http://svn.apache.org/viewvc?rev=604721&view=rev
Log:
CAY-734 Link JPA Embeddable and Embedded annotations with Cayenne runtime
(first cut of the Embeddable enhancer)
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EmbeddableVisitor.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactory.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EnhancementHelper.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/FieldAccessor.java
cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/Provider.java
cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaEnhancerVisitorFactory.java
cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactory.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactory.java Sun Dec 16 14:19:40 2007
@@ -21,6 +21,7 @@
import java.util.HashMap;
import java.util.Map;
+import org.apache.cayenne.map.Embeddable;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
import org.objectweb.asm.ClassVisitor;
@@ -35,6 +36,7 @@
public class CayenneEnhancerVisitorFactory implements EnhancerVisitorFactory {
protected Map<String, ObjEntity> entitiesByClass;
+ protected Map<String, Embeddable> embeddablesByClass;
public CayenneEnhancerVisitorFactory(EntityResolver entityResolver) {
indexEntities(entityResolver);
@@ -46,25 +48,47 @@
// manually
this.entitiesByClass = new HashMap<String, ObjEntity>();
- for (Object object : entityResolver.getObjEntities()) {
- ObjEntity entity = (ObjEntity) object;
+ for (ObjEntity entity : entityResolver.getObjEntities()) {
entitiesByClass.put(entity.getClassName(), entity);
}
+
+ this.embeddablesByClass = new HashMap<String, Embeddable>();
+ for (Embeddable embeddable : entityResolver.getEmbeddables()) {
+ embeddablesByClass.put(embeddable.getClassName(), embeddable);
+ }
}
public ClassVisitor createVisitor(String className, ClassVisitor out) {
- ObjEntity entity = entitiesByClass.get(className.replace('/', '.'));
- if (entity == null) {
- return null;
+ String key = className.replace('/', '.');
+
+ ObjEntity entity = entitiesByClass.get(key);
+ if (entity != null) {
+
+ // create enhancer chain
+ PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
+ PersistentAccessorVisitor e2 = new PersistentAccessorVisitor(e1, entity);
+
+ // this ensures that both enhanced and original classes have compatible
+ // serialized
+ // format even if no serialVersionUID is defined by the user
+ SerialVersionUIDAdder e3 = new SerialVersionUIDAdder(e2);
+ return e3;
+ }
+
+ Embeddable embeddable = embeddablesByClass.get(key);
+ if (embeddable != null) {
+ // create enhancer chain
+ EmbeddableVisitor e1 = new EmbeddableVisitor(out);
+
+ // TODO: andrus 12/16/2007 - setter visitor...
+
+ // this ensures that both enhanced and original classes have compatible
+ // serialized
+ // format even if no serialVersionUID is defined by the user
+ SerialVersionUIDAdder e2 = new SerialVersionUIDAdder(e1);
+ return e2;
}
- // create enhancer chain
- PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
- PersistentAccessorVisitor e2 = new PersistentAccessorVisitor(e1, entity);
-
- // this ensures that both enhanced and original classes have compatible serialized
- // format even if no serialVersionUID is defined by the user
- SerialVersionUIDAdder e3 = new SerialVersionUIDAdder(e2);
- return e3;
+ return null;
}
}
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EmbeddableVisitor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EmbeddableVisitor.java?rev=604721&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EmbeddableVisitor.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EmbeddableVisitor.java Sun Dec 16 14:19:40 2007
@@ -0,0 +1,46 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.enhancer;
+
+import org.apache.cayenne.Persistent;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * Enhances classes passed through the visitor to add embeddable fields and methods needed
+ * by Cayenne.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class EmbeddableVisitor extends ClassAdapter {
+
+ protected EnhancementHelper helper;
+
+ public EmbeddableVisitor(ClassVisitor visitor) {
+ super(visitor);
+ this.helper = new EnhancementHelper(this);
+ }
+
+ @Override
+ public void visitEnd() {
+ helper.createProperty(Persistent.class, "owner");
+ helper.createProperty(String.class, "embeddedProperty");
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EnhancementHelper.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EnhancementHelper.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EnhancementHelper.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/EnhancementHelper.java Sun Dec 16 14:19:40 2007
@@ -63,7 +63,7 @@
this.currentClass = Type.getType("L" + className + ";");
}
- public String[] addInterface(String[] interfaces, Class newInterface) {
+ public String[] addInterface(String[] interfaces, Class<?> newInterface) {
String name = Type.getInternalName(newInterface);
if (interfaces == null || interfaces.length == 0) {
@@ -83,7 +83,7 @@
* Creates a new protected field in the current class. Field name will be
* automatically prefixed by "$cay_".
*/
- public void createField(Class fieldType, String name) {
+ public void createField(Class<?> fieldType, String name) {
createField(fieldType, name, false);
}
@@ -91,7 +91,7 @@
* Creates a new protected field in the current class. Field name will be
* automatically prefixed by "$cay_".
*/
- public void createField(Class fieldType, String name, boolean isTransient) {
+ public void createField(Class<?> fieldType, String name, boolean isTransient) {
Type asmType = Type.getType(fieldType);
int access = Opcodes.ACC_PROTECTED;
if (isTransient) {
@@ -101,11 +101,11 @@
createField(name, asmType, access);
}
- public void createProperty(Class propertyType, String name) {
+ public void createProperty(Class<?> propertyType, String name) {
createProperty(propertyType, name, false);
}
- public void createProperty(Class propertyType, String name, boolean isTransient) {
+ public void createProperty(Class<?> propertyType, String name, boolean isTransient) {
Type asmType = Type.getType(propertyType);
int access = Opcodes.ACC_PROTECTED;
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java Sun Dec 16 14:19:40 2007
@@ -273,6 +273,18 @@
return c;
}
+
+ /**
+ * @since 3.0
+ */
+ public Collection<Embeddable> getEmbeddables() {
+ CompositeCollection c = new CompositeCollection();
+ for (DataMap map : getDataMaps()) {
+ c.addComposited(map.getEmbeddables());
+ }
+
+ return c;
+ }
public Collection<Procedure> getProcedures() {
CompositeCollection c = new CompositeCollection();
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/FieldAccessor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/FieldAccessor.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/FieldAccessor.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/FieldAccessor.java Sun Dec 16 14:19:40 2007
@@ -36,7 +36,7 @@
protected Field field;
protected Object nullValue;
- public FieldAccessor(Class objectClass, String propertyName, Class propertyType) {
+ public FieldAccessor(Class<?> objectClass, String propertyName, Class<?> propertyType) {
// sanity check
if (objectClass == null) {
throw new IllegalArgumentException("Null objectClass");
@@ -93,7 +93,7 @@
* Finds a field for the property, ensuring that direct access via reflection is
* possible.
*/
- protected Field prepareField(Class beanClass, String propertyName, Class propertyType) {
+ protected Field prepareField(Class<?> beanClass, String propertyName, Class<?> propertyType) {
Field field;
// locate field
@@ -144,7 +144,7 @@
/**
* Recursively looks for a named field in a class hierarchy.
*/
- protected Field lookupFieldInHierarchy(Class beanClass, String fieldName)
+ protected Field lookupFieldInHierarchy(Class<?> beanClass, String fieldName)
throws SecurityException, NoSuchFieldException {
// TODO: support property names following other common naming patterns, such as
@@ -155,7 +155,7 @@
}
catch (NoSuchFieldException e) {
- Class superClass = beanClass.getSuperclass();
+ Class<?> superClass = beanClass.getSuperclass();
if (superClass == null || superClass.getName().equals(Object.class.getName())) {
throw e;
}
Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/Provider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/Provider.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/Provider.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/Provider.java Sun Dec 16 14:19:40 2007
@@ -203,7 +203,7 @@
public synchronized EntityManagerFactory createContainerEntityManagerFactory(
PersistenceUnitInfo unit,
Map map) {
-
+
if (logger.isInfoEnabled() && map != null) {
logger.info("Extra container PersistenceUnitInfo properties: " + map);
}
@@ -235,11 +235,11 @@
// add transformer before DataMapConverter starts loading the classes via app
// class loader
+ ClassFileTransformer enhancer = new Enhancer(new JpaEnhancerVisitorFactory(
+ loader.getEntityMap()));
Map<String, JpaClassDescriptor> managedClasses = loader
.getEntityMap()
.getMangedClasses();
- ClassFileTransformer enhancer = new Enhancer(new JpaEnhancerVisitorFactory(
- managedClasses));
unit.addTransformer(new UnitClassTransformer(managedClasses, loader
.getContext()
.getTempClassLoader(), enhancer));
@@ -327,16 +327,16 @@
*/
protected void loadSchema(DataSource dataSource, DbAdapter adapter, DataMap map) {
- Collection tables = map.getDbEntities();
+ Collection<DbEntity> tables = map.getDbEntities();
if (tables.isEmpty()) {
return;
}
- // sniff a first table precense
+ // sniff a first table presence
// TODO: andrus 9/1/2006 - should we make this check a part of DbGenerator (and
// query - a part of DbAdapter)?
- DbEntity table = (DbEntity) tables.iterator().next();
+ DbEntity table = tables.iterator().next();
try {
Connection c = dataSource.getConnection();
Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaEnhancerVisitorFactory.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaEnhancerVisitorFactory.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaEnhancerVisitorFactory.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaEnhancerVisitorFactory.java Sun Dec 16 14:19:40 2007
@@ -18,11 +18,12 @@
****************************************************************/
package org.apache.cayenne.jpa.enhancer;
-import java.util.Map;
-
+import org.apache.cayenne.enhancer.EmbeddableVisitor;
import org.apache.cayenne.enhancer.EnhancerVisitorFactory;
import org.apache.cayenne.enhancer.PersistentInterfaceVisitor;
-import org.apache.cayenne.jpa.map.JpaClassDescriptor;
+import org.apache.cayenne.jpa.map.JpaEmbeddable;
+import org.apache.cayenne.jpa.map.JpaEntity;
+import org.apache.cayenne.jpa.map.JpaEntityMap;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.commons.SerialVersionUIDAdder;
@@ -33,29 +34,46 @@
*/
public class JpaEnhancerVisitorFactory implements EnhancerVisitorFactory {
- private Map<String, JpaClassDescriptor> managedClasses;
+ private JpaEntityMap entityMap;
- public JpaEnhancerVisitorFactory(Map<String, JpaClassDescriptor> managedClasses) {
- this.managedClasses = managedClasses;
+ public JpaEnhancerVisitorFactory(JpaEntityMap entityMap) {
+ this.entityMap = entityMap;
}
public ClassVisitor createVisitor(String className, ClassVisitor out) {
- JpaClassDescriptor descriptor = managedClasses.get(className.replace('/', '.'));
- if (descriptor == null) {
- return null;
- }
- // from here the code is copied essentially verbatim
- // from CayenneEnhancerVisitorFactory.
+ String key = className.replace('/', '.');
+
+ JpaEntity entity = entityMap.entityForClass(key);
+ if (entity != null) {
+
+ // create enhancer chain
+ PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
+ JpaAccessorVisitor e2 = new JpaAccessorVisitor(e1, entity
+ .getClassDescriptor());
+
+ // this ensures that both enhanced and original classes have compatible
+ // serialized
+ // format even if no serialVersionUID is defined by the user
+ SerialVersionUIDAdder e3 = new SerialVersionUIDAdder(e2);
- // create enhancer chain
- PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
- JpaAccessorVisitor e2 = new JpaAccessorVisitor(e1, descriptor);
-
- // this ensures that both enhanced and original classes have compatible serialized
- // format even if no serialVersionUID is defined by the user
- SerialVersionUIDAdder e3 = new SerialVersionUIDAdder(e2);
+ return e3;
+ }
+
+ JpaEmbeddable embeddable = entityMap.embeddableForClass(key);
+ if (embeddable != null) {
+ // create enhancer chain
+ EmbeddableVisitor e1 = new EmbeddableVisitor(out);
+
+ // TODO: andrus 12/16/2007 - setter visitor...
+
+ // this ensures that both enhanced and original classes have compatible
+ // serialized
+ // format even if no serialVersionUID is defined by the user
+ SerialVersionUIDAdder e2 = new SerialVersionUIDAdder(e1);
+ return e2;
+ }
- return e3;
+ return null;
}
}
Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java?rev=604721&r1=604720&r2=604721&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaEntityMap.java Sun Dec 16 14:19:40 2007
@@ -173,16 +173,12 @@
if (entities != null) {
for (JpaEntity object : entities) {
- // TODO: andrus, 5/1/2006 - need not enhance entities extending mapped
- // superclasses
managedClasses.put(object.getClassName(), object.getClassDescriptor());
}
}
if (embeddables != null) {
for (JpaEmbeddable object : embeddables) {
- // TODO: andrus, 5/1/2006 - need not enhance entities extending mapped
- // superclasses
managedClasses.put(object.getClassName(), object.getClassDescriptor());
}
}
@@ -193,7 +189,7 @@
/**
* Returns a JpaEntity describing a given persistent class.
*/
- public JpaEntity entityForClass(Class entityClass) {
+ public JpaEntity entityForClass(Class<?> entityClass) {
if (entityClass == null) {
throw new IllegalArgumentException("Null entity class");
@@ -209,6 +205,10 @@
if (entityClassName == null) {
throw new IllegalArgumentException("Null entity class name");
}
+
+ if(entities == null) {
+ return null;
+ }
for (JpaEntity entity : entities) {
if (entityClassName.equals(entity.getClassName())) {
@@ -218,6 +218,40 @@
return null;
}
+
+ /**
+ * Returns a JpaEmbeddable describing a given embeddable class.
+ */
+ public JpaEmbeddable embeddableForClass(Class<?> embeddableClass) {
+
+ if (embeddableClass == null) {
+ throw new IllegalArgumentException("Null embeddable class");
+ }
+
+ return embeddableForClass(embeddableClass.getName());
+ }
+
+ /**
+ * Returns a JpaEmbeddable describing a given embeddable class.
+ */
+ public JpaEmbeddable embeddableForClass(String embeddableClassName) {
+ if (embeddableClassName == null) {
+ throw new IllegalArgumentException("Null embeddable class name");
+ }
+
+ if(embeddables == null) {
+ return null;
+ }
+
+ for (JpaEmbeddable embeddable : embeddables) {
+ if (embeddableClassName.equals(embeddable.getClassName())) {
+ return embeddable;
+ }
+ }
+
+ return null;
+ }
+
public AccessType getAccess() {
return access;