cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r454589 - in /incubator/cayenne/sandbox/asm-enhancer: ./ src/main/java/org/apache/cayenne/enhancer/ src/test/java/org/apache/cayenne/enhancer/
Date Tue, 10 Oct 2006 03:13:18 GMT
Author: aadamchik
Date: Mon Oct  9 20:13:17 2006
New Revision: 454589

URL: http://svn.apache.org/viewvc?view=rev&rev=454589
Log:
implementing Persistence interface properties injection

Added:
    incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
Removed:
    incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/EnhancedPojoDescriptor.java
Modified:
    incubator/cayenne/sandbox/asm-enhancer/.classpath
    incubator/cayenne/sandbox/asm-enhancer/pom.xml
    incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
    incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/AsmEnhancerTest.java
    incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java

Modified: incubator/cayenne/sandbox/asm-enhancer/.classpath
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/.classpath?view=diff&rev=454589&r1=454588&r2=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/.classpath (original)
+++ incubator/cayenne/sandbox/asm-enhancer/.classpath Mon Oct  9 20:13:17 2006
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src/test/java"/>
-	<classpathentry kind="src" path="src/main/java"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
-	<classpathentry kind="output" path="target/classes"/>
+	<classpathentry kind="src" path="src/main/java" />
+	<classpathentry kind="src" path="src/test/java" />
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" />
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" />
+	<classpathentry kind="output" path="target/classes" />
 </classpath>

Modified: incubator/cayenne/sandbox/asm-enhancer/pom.xml
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/pom.xml?view=diff&rev=454589&r1=454588&r2=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/pom.xml (original)
+++ incubator/cayenne/sandbox/asm-enhancer/pom.xml Mon Oct  9 20:13:17 2006
@@ -47,4 +47,19 @@
 			<version>3.0-incubating-SNAPSHOT</version>
 		</dependency>
 	</dependencies>
+
+	<build>
+		<plugins>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.5</source>
+					<target>1.5</target>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
 </project>

Added: incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java?view=auto&rev=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
(added)
+++ incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/ClassBuilder.java
Mon Oct  9 20:13:17 2006
@@ -0,0 +1,140 @@
+/*****************************************************************
+ *   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.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * A builder that encapsulates common class enhancement operations.
+ * 
+ * @author Andrus Adamchik
+ */
+class ClassBuilder {
+
+    private String fieldPrefix = "$cay_";
+    private ClassVisitor classVisitor;
+    private Type currentClass;
+
+    ClassBuilder(ClassVisitor classVisitor) {
+        this.classVisitor = classVisitor;
+    }
+
+    void reset(String className) {
+        // assuming no primitives or arrays
+        this.currentClass = Type.getType("L" + className + ";");
+    }
+
+    void createProperty(Class type, String name) {
+        createProperty(type, name, false);
+    }
+
+    void createProperty(Class type, String name, boolean isTransient) {
+        Type asmType = Type.getType(type);
+
+        int access = Opcodes.ACC_PROTECTED;
+        if (isTransient) {
+            access += Opcodes.ACC_TRANSIENT;
+        }
+
+        createField(name, asmType, access);
+        createGetter(name, asmType);
+        createSetter(name, asmType);
+    }
+
+    private void createSetter(String propertyName, Type asmType) {
+
+        String methodName = "set" + Character.toUpperCase(propertyName.charAt(0));
+        if (propertyName.length() > 1) {
+            methodName += propertyName.substring(1);
+        }
+
+        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, methodName, "("
+                + asmType.getDescriptor()
+                + ")V", null, null);
+        mv.visitCode();
+        Label l0 = new Label();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+
+        // TODO: other opcodes
+        if ("I".equals(asmType.getDescriptor())) {
+            mv.visitVarInsn(Opcodes.ILOAD, 1);
+        }
+        else {
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+        }
+
+        mv.visitFieldInsn(Opcodes.PUTFIELD, currentClass.getInternalName(), fieldPrefix
+                + propertyName, asmType.getDescriptor());
+        mv.visitInsn(Opcodes.RETURN);
+        Label l1 = new Label();
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", currentClass.getDescriptor(), null, l0, l1, 0);
+        mv.visitLocalVariable(propertyName, asmType.getDescriptor(), null, l0, l1, 1);
+        mv.visitMaxs(2, 2);
+        mv.visitEnd();
+    }
+
+    private void createGetter(String propertyName, Type asmType) {
+
+        String prefix = "boolean".equals(asmType.getClassName()) ? "is" : "get";
+        String methodName = prefix + Character.toUpperCase(propertyName.charAt(0));
+        if (propertyName.length() > 1) {
+            methodName += propertyName.substring(1);
+        }
+
+        MethodVisitor mv = classVisitor.visitMethod(Opcodes.ACC_PUBLIC, methodName, "()"
+                + asmType.getDescriptor(), null, null);
+        mv.visitCode();
+        Label l0 = new Label();
+        mv.visitLabel(l0);
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, currentClass.getInternalName(), fieldPrefix
+                + propertyName, asmType.getDescriptor());
+
+        // TODO: other return opcodes
+        if ("I".equals(asmType.getDescriptor())) {
+            mv.visitInsn(Opcodes.IRETURN);
+        }
+        else {
+            mv.visitInsn(Opcodes.ARETURN);
+        }
+
+        Label l1 = new Label();
+        mv.visitLabel(l1);
+        mv.visitLocalVariable("this", currentClass.getDescriptor(), null, l0, l1, 0);
+        mv.visitMaxs(1, 1);
+        mv.visitEnd();
+    }
+
+    private void createField(String propertyName, Type asmType, int access) {
+        FieldVisitor fv = classVisitor.visitField(
+                access,
+                fieldPrefix + propertyName,
+                asmType.getDescriptor(),
+                null,
+                null);
+        fv.visitEnd();
+    }
+}

Modified: incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java?view=diff&rev=454589&r1=454588&r2=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
(original)
+++ incubator/cayenne/sandbox/asm-enhancer/src/main/java/org/apache/cayenne/enhancer/PersistentClassVisitor.java
Mon Oct  9 20:13:17 2006
@@ -20,12 +20,11 @@
 
 import java.util.Collection;
 
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ObjectId;
 import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
 
 /**
  * ASM-based visitor that turns a pojo class into enahnced persistent object.
@@ -34,12 +33,13 @@
  */
 class PersistentClassVisitor extends ClassAdapter {
 
-    private String className;
     private Collection<String> enhancedProperties;
+    private ClassBuilder builder;
 
     PersistentClassVisitor(ClassVisitor visitor, Collection<String> enhancedProperties)
{
         super(visitor);
         this.enhancedProperties = enhancedProperties;
+        this.builder = new ClassBuilder(this);
     }
 
     /**
@@ -54,12 +54,12 @@
             String superName,
             String[] interfaces) {
 
-        this.className = name;
-
         super.visit(version, access, name, signature, superName, interfaces);
 
-        injectPersistenceFields();
-        injectPersistenceMethods();
+        builder.reset(name);
+        builder.createProperty(ObjectId.class, "objectId");
+        builder.createProperty(ObjectContext.class, "objectContext", true);
+        builder.createProperty(Integer.TYPE, "persistenceState");
     }
 
     /**
@@ -78,67 +78,16 @@
         // TODO: andrus, 10/8/2006 - check method sig for real... just checking
         // the name is not enough
 
-        String getProperty = EnhancerUtil.propertyNameForGetter(name);
-        if (getProperty != null && enhancedProperties.contains(getProperty)) {
-            return new PersistentGetterVisitor(mv, className, getProperty);
-        }
-
-        String setProperty = EnhancerUtil.propertyNameForSetter(name);
-        if (setProperty != null && enhancedProperties.contains(setProperty)) {
-            return new PersistentSetterVisitor(mv, className, setProperty);
-        }
+        // String getProperty = EnhancerUtil.propertyNameForGetter(name);
+        // if (getProperty != null && enhancedProperties.contains(getProperty)) {
+        // return new PersistentGetterVisitor(mv, className, getProperty);
+        // }
+        //
+        // String setProperty = EnhancerUtil.propertyNameForSetter(name);
+        // if (setProperty != null && enhancedProperties.contains(setProperty)) {
+        // return new PersistentSetterVisitor(mv, className, setProperty);
+        // }
 
         return mv;
-    }
-
-    private void injectPersistenceFields() {
-        FieldVisitor fv = visitField(
-                Opcodes.ACC_PROTECTED,
-                EnhancedPojoDescriptor.OBJECT_ID_FIELD,
-                "Lorg/apache/cayenne/ObjectId;",
-                null,
-                null);
-        fv.visitEnd();
-
-        fv = visitField(
-                Opcodes.ACC_PROTECTED,
-                EnhancedPojoDescriptor.PERSISTENCE_STATE_FIELD,
-                "I",
-                null,
-                null);
-        fv.visitEnd();
-
-        fv = visitField(
-                Opcodes.ACC_PROTECTED + Opcodes.ACC_TRANSIENT,
-                EnhancedPojoDescriptor.OBJECT_CONTEXT_FIELD,
-                "Lorg/apache/cayenne/ObjectContext;",
-                null,
-                null);
-        fv.visitEnd();
-    }
-
-    private void injectPersistenceMethods() {
-
-        MethodVisitor mv = visitMethod(
-                Opcodes.ACC_PUBLIC,
-                "getObjectContext",
-                "()Lorg/apache/cayenne/ObjectContext;",
-                null,
-                null);
-        mv.visitCode();
-        Label l0 = new Label();
-        mv.visitLabel(l0);
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitFieldInsn(
-                Opcodes.GETFIELD,
-                className,
-                EnhancedPojoDescriptor.OBJECT_CONTEXT_FIELD,
-                "Lorg/apache/cayenne/ObjectContext;");
-        mv.visitInsn(Opcodes.ARETURN);
-        Label l1 = new Label();
-        mv.visitLabel(l1);
-        mv.visitLocalVariable("this", className, null, l0, l1, 0);
-        mv.visitMaxs(1, 1);
-        mv.visitEnd();
     }
 }

Modified: incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/AsmEnhancerTest.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/AsmEnhancerTest.java?view=diff&rev=454589&r1=454588&r2=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/AsmEnhancerTest.java
(original)
+++ incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/AsmEnhancerTest.java
Mon Oct  9 20:13:17 2006
@@ -1,6 +1,7 @@
 package org.apache.cayenne.enhancer;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -15,7 +16,7 @@
 
 public class AsmEnhancerTest extends TestCase {
 
-    public static final String C1 = "org.apache.cayenne.jpa.enhancer.MockPojo1";
+    public static final String C1 = "org.apache.cayenne.enhancer.MockPojo1";
 
     protected ClassLoader loader;
 
@@ -39,27 +40,48 @@
         assertNotNull(e1Class);
         assertEquals(C1, e1Class.getName());
 
-        Field objectContext = e1Class
-                .getDeclaredField(EnhancedPojoDescriptor.OBJECT_CONTEXT_FIELD);
+        Field objectContext = e1Class.getDeclaredField("$cay_objectContext");
         assertTrue(ObjectContext.class.isAssignableFrom(objectContext.getType()));
         assertTrue(!Modifier.isStatic(objectContext.getModifiers()));
         assertTrue(Modifier.isProtected(objectContext.getModifiers()));
         assertTrue(!Modifier.isFinal(objectContext.getModifiers()));
         assertTrue(Modifier.isTransient(objectContext.getModifiers()));
 
-        Field persistenceState = e1Class
-                .getDeclaredField(EnhancedPojoDescriptor.PERSISTENCE_STATE_FIELD);
+        Field persistenceState = e1Class.getDeclaredField("$cay_persistenceState");
         assertTrue(Integer.TYPE.isAssignableFrom(persistenceState.getType()));
         assertTrue(!Modifier.isStatic(persistenceState.getModifiers()));
         assertTrue(Modifier.isProtected(persistenceState.getModifiers()));
         assertTrue(!Modifier.isFinal(persistenceState.getModifiers()));
         assertTrue(!Modifier.isTransient(persistenceState.getModifiers()));
 
-        Field objectId = e1Class.getDeclaredField(EnhancedPojoDescriptor.OBJECT_ID_FIELD);
+        Field objectId = e1Class.getDeclaredField("$cay_objectId");
         assertTrue(ObjectId.class.isAssignableFrom(objectId.getType()));
         assertTrue(!Modifier.isStatic(objectId.getModifiers()));
         assertTrue(Modifier.isProtected(objectId.getModifiers()));
         assertTrue(!Modifier.isFinal(objectId.getModifiers()));
         assertTrue(!Modifier.isTransient(objectId.getModifiers()));
+    }
+
+    public void testPersistentPropertiesInjected() throws Exception {
+        Class e1Class = Class.forName(C1, true, loader);
+        assertNotNull(e1Class);
+        assertEquals(C1, e1Class.getName());
+
+        Method getObjectContext = e1Class.getDeclaredMethod(
+                "getObjectContext",
+                (Class[]) null);
+        Method setObjectContext = e1Class.getDeclaredMethod(
+                "setObjectContext",
+                new Class[] {
+                    ObjectContext.class
+                });
+
+        Object o = e1Class.newInstance();
+        assertNull(getObjectContext.invoke(o, (Object[]) null));
+        ObjectContext oc = new MockObjectContext();
+        setObjectContext.invoke(o, new Object[] {
+            oc
+        });
+        assertSame(oc, getObjectContext.invoke(o, (Object[]) null));
     }
 }

Modified: incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java?view=diff&rev=454589&r1=454588&r2=454589
==============================================================================
--- incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
(original)
+++ incubator/cayenne/sandbox/asm-enhancer/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
Mon Oct  9 20:13:17 2006
@@ -23,6 +23,12 @@
 import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.Persistent;
 
+/**
+ * This class in combination with the ASM Eclipse plugin is used as a reference for
+ * building parts of the ASM enhancer.
+ * 
+ * @author Andrus Adamchik
+ */
 public class MockEnhancedPojo implements Persistent {
 
     protected ObjectId $cay_objectId;
@@ -56,10 +62,6 @@
 
     public void setPersistenceState(int persistenceState) {
         this.$cay_persistenceState = persistenceState;
-
-        if (persistenceState == PersistenceState.TRANSIENT) {
-            this.$cay_objectContext = null;
-        }
     }
 
     public ObjectContext getObjectContext() {



Mime
View raw message