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/22 21:14:40 UTC
svn commit: r606484 - in /cayenne/main/trunk/framework:
cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/
cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/
cayenne-jpa-unpublished/src/main/java/org/apache/cayenn...
Author: aadamchik
Date: Sat Dec 22 12:14:39 2007
New Revision: 606484
URL: http://svn.apache.org/viewvc?rev=606484&view=rev
Log:
CAY-858 A more sound enhancer algorithm that intercepts access to persistent fields
(a related enhancer improvement - will create fault tracking variables based on the mapping metadata, instead of attempting to analyze the class on the fly... this results in a much more robust and controllable behavior)
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayennePojoVisitor.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PojoVisitor.java
- copied, changed from r606412, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PersistentInterfaceVisitor.java
cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaPojoVisitor.java
Removed:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PersistentInterfaceVisitor.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java
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-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/JpaAttributes.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java?rev=606484&r1=606483&r2=606484&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java Sat Dec 22 12:14:39 2007
@@ -90,8 +90,6 @@
if (isEnhancedProperty(property)) {
if (isLazyFaulted(property)) {
- // inject fault flag field
- helper.createField(Boolean.TYPE, "faultResolved_" + property, true);
return new GetterVisitor(mv, helper, property, true);
}
else {
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=606484&r1=606483&r2=606484&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 Sat Dec 22 12:14:39 2007
@@ -28,7 +28,7 @@
import org.objectweb.asm.commons.SerialVersionUIDAdder;
/**
- * A factory of enhacing visitors.
+ * EnhancerVisitorFactory implementation based on Cayenne mapping.
*
* @since 3.0
* @author Andrus Adamchik
@@ -65,7 +65,7 @@
if (entity != null) {
// create enhancer chain
- PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
+ PojoVisitor e1 = new CayennePojoVisitor(out, entity);
PersistentAccessorVisitor e2 = new PersistentAccessorVisitor(e1, entity);
// this ensures that both enhanced and original classes have compatible
@@ -79,8 +79,6 @@
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
Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayennePojoVisitor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayennePojoVisitor.java?rev=606484&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayennePojoVisitor.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/CayennePojoVisitor.java Sat Dec 22 12:14:39 2007
@@ -0,0 +1,43 @@
+/*****************************************************************
+ * 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 java.util.Collection;
+
+import org.apache.cayenne.map.ObjEntity;
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class CayennePojoVisitor extends PojoVisitor {
+
+ protected ObjEntity entity;
+
+ CayennePojoVisitor(ClassVisitor visitor, ObjEntity entity) {
+ super(visitor);
+ this.entity = entity;
+ }
+
+ @Override
+ protected Collection<String> getLazilyFaultedProperties() {
+ return entity.getRelationshipMap().keySet();
+ }
+}
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=606484&r1=606483&r2=606484&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 Sat Dec 22 12:14:39 2007
@@ -58,11 +58,19 @@
return fieldPrefix + propertyName;
}
+ /**
+ * Resets helper to process a given class. Must be called repeatedly before each class
+ * is processed.
+ */
public void reset(String className) {
// assuming no primitives or arrays
this.currentClass = Type.getType("L" + className + ";");
}
+ /**
+ * Appends an interface to a String array of interfaces, returning the resulting
+ * expanded array.
+ */
public String[] addInterface(String[] interfaces, Class<?> newInterface) {
String name = Type.getInternalName(newInterface);
Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PojoVisitor.java (from r606412, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PersistentInterfaceVisitor.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PojoVisitor.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PojoVisitor.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PersistentInterfaceVisitor.java&r1=606412&r2=606484&rev=606484&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PersistentInterfaceVisitor.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/enhancer/PojoVisitor.java Sat Dec 22 12:14:39 2007
@@ -18,6 +18,8 @@
****************************************************************/
package org.apache.cayenne.enhancer;
+import java.util.Collection;
+
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.Persistent;
@@ -26,19 +28,19 @@
import org.objectweb.asm.Type;
/**
- * Enhances classes passed through the visitor to add {@link Persistent} interface to
- * them, and fields and methods to support its implementation.
+ * Enhances classes passed through the visitor, ensuring that the resulting class
+ * implements {@link Persistent} interface as well as supports lazy faulting.
*
* @since 3.0
* @author Andrus Adamchik
*/
-public class PersistentInterfaceVisitor extends ClassAdapter {
+public abstract class PojoVisitor extends ClassAdapter {
static String ENHANCED_INTERFACE_SIG = Type.getInternalName(Persistent.class);
protected EnhancementHelper helper;
- public PersistentInterfaceVisitor(ClassVisitor visitor) {
+ public PojoVisitor(ClassVisitor visitor) {
super(visitor);
this.helper = new EnhancementHelper(this);
}
@@ -65,15 +67,19 @@
helper.reset(name);
interfaces = helper.addInterface(interfaces, Persistent.class);
-
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitEnd() {
- // per ASM docs, 'visitEnd' is the only correct place to add class members
helper.createProperty(ObjectId.class, "objectId");
helper.createProperty(ObjectContext.class, "objectContext", true);
helper.createProperty(Integer.TYPE, "persistenceState");
+
+ for (String property : getLazilyFaultedProperties()) {
+ helper.createField(Boolean.TYPE, "faultResolved_" + property, true);
+ }
}
+
+ protected abstract Collection<String> getLazilyFaultedProperties();
}
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=606484&r1=606483&r2=606484&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 Sat Dec 22 12:14:39 2007
@@ -20,7 +20,7 @@
import org.apache.cayenne.enhancer.EmbeddableVisitor;
import org.apache.cayenne.enhancer.EnhancerVisitorFactory;
-import org.apache.cayenne.enhancer.PersistentInterfaceVisitor;
+import org.apache.cayenne.enhancer.PojoVisitor;
import org.apache.cayenne.jpa.map.JpaEmbeddable;
import org.apache.cayenne.jpa.map.JpaEntity;
import org.apache.cayenne.jpa.map.JpaEntityMap;
@@ -28,9 +28,10 @@
import org.objectweb.asm.commons.SerialVersionUIDAdder;
/**
- * Class enhancer used for JPA.
+ * EnhancerVisitorFactory implementation based on JPA mapping.
*
* @author Andrus Adamchik
+ * @since 3.0
*/
public class JpaEnhancerVisitorFactory implements EnhancerVisitorFactory {
@@ -48,12 +49,11 @@
if (entity != null) {
// create enhancer chain
- PersistentInterfaceVisitor e1 = new PersistentInterfaceVisitor(out);
+ PojoVisitor e1 = new JpaPojoVisitor(out, entity);
JpaAccessorVisitor e2 = new JpaAccessorVisitor(e1, entity);
// this ensures that both enhanced and original classes have compatible
- // serialized
- // format even if no serialVersionUID is defined by the user
+ // serialized format even if no serialVersionUID is defined by the user
SerialVersionUIDAdder e3 = new SerialVersionUIDAdder(e2);
return e3;
@@ -61,10 +61,9 @@
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
Added: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaPojoVisitor.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaPojoVisitor.java?rev=606484&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaPojoVisitor.java (added)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/enhancer/JpaPojoVisitor.java Sat Dec 22 12:14:39 2007
@@ -0,0 +1,44 @@
+/*****************************************************************
+ * 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.jpa.enhancer;
+
+import java.util.Collection;
+
+import org.apache.cayenne.enhancer.PojoVisitor;
+import org.apache.cayenne.jpa.map.JpaManagedClass;
+import org.objectweb.asm.ClassVisitor;
+
+/**
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class JpaPojoVisitor extends PojoVisitor {
+
+ protected JpaManagedClass managedClass;
+
+ JpaPojoVisitor(ClassVisitor visitor, JpaManagedClass managedClass) {
+ super(visitor);
+ this.managedClass = managedClass;
+ }
+
+ @Override
+ protected Collection<String> getLazilyFaultedProperties() {
+ return managedClass.getAttributes().getLazyAttributeNames();
+ }
+}
Modified: cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaAttributes.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaAttributes.java?rev=606484&r1=606483&r2=606484&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaAttributes.java (original)
+++ cayenne/main/trunk/framework/cayenne-jpa-unpublished/src/main/java/org/apache/cayenne/jpa/map/JpaAttributes.java Sat Dec 22 12:14:39 2007
@@ -21,6 +21,8 @@
import java.util.ArrayList;
import java.util.Collection;
+import javax.persistence.FetchType;
+
import org.apache.cayenne.util.TreeNodeChild;
import org.apache.cayenne.util.XMLEncoder;
import org.apache.cayenne.util.XMLSerializable;
@@ -94,6 +96,52 @@
encoder.indent(-1);
encoder.println("</attributes>");
+ }
+
+ /**
+ * Returns the names of attributes that are fetched lazily.
+ */
+ public Collection<String> getLazyAttributeNames() {
+ Collection<String> lazyAttributes = new ArrayList<String>();
+
+ if (basicAttributes != null) {
+ for (JpaBasic attribute : basicAttributes) {
+ if (attribute.getFetch() == FetchType.LAZY) {
+ lazyAttributes.add(attribute.getName());
+ }
+ }
+ }
+
+ // TODO: andrus 12/22/2007 - since Cayenne fetches all relationships lazily unless
+ // query specifies a prefetch, for now we'll treat all relationships as LAZY (even
+ // though JPA defines all one-to-one relationships as EAGER). To be JPA compliant
+ // we need to change that at some point...
+
+ if (oneToOneRelationships != null) {
+ for (JpaOneToOne attribute : oneToOneRelationships) {
+ lazyAttributes.add(attribute.getName());
+ }
+ }
+
+ if (oneToManyRelationships != null) {
+ for (JpaOneToMany attribute : oneToManyRelationships) {
+ lazyAttributes.add(attribute.getName());
+ }
+ }
+
+ if (manyToOneRelationships != null) {
+ for (JpaManyToOne attribute : manyToOneRelationships) {
+ lazyAttributes.add(attribute.getName());
+ }
+ }
+
+ if (manyToManyRelationships != null) {
+ for (JpaManyToMany attribute : manyToManyRelationships) {
+ lazyAttributes.add(attribute.getName());
+ }
+ }
+
+ return lazyAttributes;
}
public JpaAttribute getAttribute(String name) {