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 2006/10/13 02:33:35 UTC

svn commit: r463528 - in /incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src: main/java/org/apache/cayenne/enhancer/ test/java/org/apache/cayenne/enhancer/

Author: aadamchik
Date: Thu Oct 12 17:33:33 2006
New Revision: 463528

URL: http://svn.apache.org/viewvc?view=rev&rev=463528
Log:
CAY-682: Generic Cayenne POJO enhancer
Adding support for int setters

Modified:
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/PersistentAccessorVisitor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/SetterVisitor.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactoryTest.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockPojo1.java

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/AccessorVisitor.java Thu Oct 12 17:33:33 2006
@@ -24,6 +24,7 @@
 import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
 
 /**
  * An enhancer that adds interceptor code to the getters and setters.
@@ -62,11 +63,17 @@
         super(cw);
     }
 
-    protected MethodVisitor visitGetter(MethodVisitor mv, String property) {
+    protected MethodVisitor visitGetter(
+            MethodVisitor mv,
+            String property,
+            Type propertyType) {
         return mv;
     }
 
-    protected MethodVisitor visitSetter(MethodVisitor mv, String property) {
+    protected MethodVisitor visitSetter(
+            MethodVisitor mv,
+            String property,
+            Type propertyType) {
         return mv;
     }
 
@@ -80,17 +87,26 @@
 
         MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
 
-        // TODO: andrus, 10/8/2006 - check method sig for real... just checking
-        // the name is not enough
+        // TODO: andrus, 10/8/2006 - what other signature checks do we need to do?
 
-        String getProperty = AccessorVisitor.propertyNameForGetter(name);
-        if (getProperty != null) {
-            return visitGetter(mv, getProperty);
-        }
+        Type returnType = Type.getReturnType(desc);
+        Type[] args = Type.getArgumentTypes(desc);
 
-        String setProperty = AccessorVisitor.propertyNameForSetter(name);
-        if (setProperty != null) {
-            return visitSetter(mv, setProperty);
+        // possible setter
+        if ("V".equals(returnType.getDescriptor())) {
+            if (args.length == 1) {
+                String setProperty = AccessorVisitor.propertyNameForSetter(name);
+                if (setProperty != null) {
+                    return visitSetter(mv, setProperty, args[0]);
+                }
+            }
+        }
+        // possible getter
+        else if (args.length == 0) {
+            String getProperty = AccessorVisitor.propertyNameForGetter(name);
+            if (getProperty != null) {
+                return visitGetter(mv, getProperty, returnType);
+            }
         }
 
         return mv;

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/PersistentAccessorVisitor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/PersistentAccessorVisitor.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/PersistentAccessorVisitor.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/PersistentAccessorVisitor.java Thu Oct 12 17:33:33 2006
@@ -21,6 +21,7 @@
 import org.apache.cayenne.map.ObjEntity;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
 
 /**
  * Accessor enhancer that enhances getters and setters mapped in a given {@link ObjEntity}.
@@ -47,24 +48,34 @@
             String signature,
             String superName,
             String[] interfaces) {
-        
+
         helper.reset(name);
         super.visit(version, access, name, signature, superName, interfaces);
     }
 
     @Override
-    protected MethodVisitor visitGetter(MethodVisitor mv, String property) {
-        return (entity.getAttribute(property) != null) ? new GetterVisitor(
-                mv,
-                helper,
-                property) : mv;
+    protected MethodVisitor visitGetter(
+            MethodVisitor mv,
+            String property,
+            Type propertyType) {
+
+        if (entity.getAttribute(property) != null) {
+            return new GetterVisitor(mv, helper, property);
+        }
+
+        return mv;
     }
 
     @Override
-    protected MethodVisitor visitSetter(MethodVisitor mv, String property) {
-        return (entity.getAttribute(property) != null) ? new SetterVisitor(
-                mv,
-                helper,
-                property) : mv;
+    protected MethodVisitor visitSetter(
+            MethodVisitor mv,
+            String property,
+            Type propertyType) {
+
+        if (entity.getAttribute(property) != null) {
+            return new SetterVisitor(mv, helper, property, propertyType);
+        }
+
+        return mv;
     }
 }

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/SetterVisitor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/SetterVisitor.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/SetterVisitor.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/main/java/org/apache/cayenne/enhancer/SetterVisitor.java Thu Oct 12 17:33:33 2006
@@ -33,12 +33,14 @@
 
     private EnhancementHelper helper;
     private String propertyName;
+    private Type propertyType;
 
-    public SetterVisitor(MethodVisitor mv, EnhancementHelper helper,
-            String propertyName) {
+    public SetterVisitor(MethodVisitor mv, EnhancementHelper helper, String propertyName,
+            Type propertyType) {
         super(mv);
         this.helper = helper;
         this.propertyName = propertyName;
+        this.propertyType = propertyType;
     }
 
     @Override
@@ -47,6 +49,7 @@
 
         String field = helper.getPropertyField("objectContext");
         Type objectContextType = Type.getType(ObjectContext.class);
+        String propertyDescriptor = propertyType.getDescriptor();
 
         mv.visitVarInsn(Opcodes.ALOAD, 0);
         mv.visitFieldInsn(
@@ -63,14 +66,32 @@
                 field,
                 objectContextType.getDescriptor());
         mv.visitVarInsn(Opcodes.ALOAD, 0);
-        mv.visitLdcInsn("attribute1");
+        mv.visitLdcInsn(propertyName);
         mv.visitVarInsn(Opcodes.ALOAD, 0);
+
         mv.visitFieldInsn(
                 Opcodes.GETFIELD,
                 helper.getCurrentClass().getInternalName(),
                 propertyName,
-                "Ljava/lang/String;");
-        mv.visitVarInsn(Opcodes.ALOAD, 1);
+                propertyDescriptor);
+
+        if ("I".equals(propertyDescriptor)) {
+            mv.visitMethodInsn(
+                    Opcodes.INVOKESTATIC,
+                    "java/lang/Integer",
+                    "valueOf",
+                    "(I)Ljava/lang/Integer;");
+            mv.visitVarInsn(Opcodes.ILOAD, 1);
+            mv.visitMethodInsn(
+                    Opcodes.INVOKESTATIC,
+                    "java/lang/Integer",
+                    "valueOf",
+                    "(I)Ljava/lang/Integer;");
+        }
+        else {
+            mv.visitVarInsn(Opcodes.ALOAD, 1);
+        }
+
         mv
                 .visitMethodInsn(
                         Opcodes.INVOKEINTERFACE,

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactoryTest.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactoryTest.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactoryTest.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/CayenneEnhancerVisitorFactoryTest.java Thu Oct 12 17:33:33 2006
@@ -57,8 +57,10 @@
         enhancedPropertyMap.put(C1, c1);
 
         ObjAttribute a1 = new ObjAttribute("attribute1");
+        ObjAttribute a2 = new ObjAttribute("attribute2");
         ObjEntity e = new ObjEntity("E1");
         e.addAttribute(a1);
+        e.addAttribute(a2);
         e.setClassName(C1);
         DataMap map = new DataMap("x");
         map.addObjEntity(e);
@@ -189,7 +191,7 @@
         assertEquals("attribute1", prepared[1]);
     }
 
-    public void testSetterIntercepted() throws Exception {
+    public void testStringSetterIntercepted() throws Exception {
 
         Class e1Class = Class.forName(C1, true, loader);
         assertNotNull(e1Class);
@@ -244,5 +246,60 @@
         assertEquals("attribute1", change[1]);
         assertEquals("x", change[2]);
         assertEquals("y", change[3]);
+    }
+
+    public void testIntSetterIntercepted() throws Exception {
+
+        Class e1Class = Class.forName(C1, true, loader);
+
+        Object o = e1Class.newInstance();
+
+        // attempt calling on detached object - must not fail
+        Method getAttribute2 = e1Class.getDeclaredMethod("getAttribute2", (Class[]) null);
+        Method setAttribute2 = e1Class.getDeclaredMethod("setAttribute2", new Class[] {
+            Integer.TYPE
+        });
+
+        assertEquals(new Integer(0), getAttribute2.invoke(o, (Object[]) null));
+        setAttribute2.invoke(o, new Object[] {
+            new Integer(3)
+        });
+        assertEquals(new Integer(3), getAttribute2.invoke(o, (Object[]) null));
+
+        // now call on attached object
+        final Object[] change = new Object[4];
+        ObjectContext context = new MockObjectContext() {
+
+            @Override
+            public void propertyChanged(
+                    Persistent object,
+                    String property,
+                    Object oldValue,
+                    Object newValue) {
+                change[0] = object;
+                change[1] = property;
+                change[2] = oldValue;
+                change[3] = newValue;
+            }
+        };
+
+        Method setObjectContext = e1Class.getDeclaredMethod(
+                "setObjectContext",
+                new Class[] {
+                    ObjectContext.class
+                });
+
+        setObjectContext.invoke(o, new Object[] {
+            context
+        });
+
+        setAttribute2.invoke(o, new Object[] {
+            new Integer(4)
+        });
+        assertEquals(new Integer(4), getAttribute2.invoke(o, (Object[]) null));
+        assertSame(o, change[0]);
+        assertEquals("attribute2", change[1]);
+        assertEquals(new Integer(3), change[2]);
+        assertEquals(new Integer(4), change[3]);
     }
 }

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockEnhancedPojo.java Thu Oct 12 17:33:33 2006
@@ -37,6 +37,9 @@
     protected transient ObjectContext $cay_objectContext;
 
     protected String attribute1;
+    protected int attribute2;
+    protected double attribute3;
+    protected byte[] attribute4;
 
     public String getAttribute1() {
         if ($cay_objectContext != null) {
@@ -55,6 +58,63 @@
         }
 
         this.attribute1 = attribute1;
+    }
+
+    public int getAttribute2() {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.prepareForAccess(this, "attribute2");
+        }
+        return attribute2;
+    }
+
+    public void setAttribute2(int attribute2) {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.propertyChanged(
+                    this,
+                    "attribute2",
+                    Integer.valueOf(this.attribute2),
+                    Integer.valueOf(attribute2));
+        }
+        
+        this.attribute2 = attribute2;
+    }
+
+    public double getAttribute3() {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.prepareForAccess(this, "attribute3");
+        }
+        return attribute3;
+    }
+
+    public void setAttribute3(double attribute3) {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.propertyChanged(
+                    this,
+                    "attribute3",
+                    Double.valueOf(this.attribute3),
+                    Double.valueOf(attribute3));
+        }
+        
+        this.attribute3 = attribute3;
+    }
+
+    public byte[] getAttribute4() {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.prepareForAccess(this, "attribute4");
+        }
+        return attribute4;
+    }
+
+    public void setAttribute4(byte[] attribute4) {
+        if ($cay_objectContext != null) {
+            $cay_objectContext.propertyChanged(
+                    this,
+                    "attribute4",
+                    this.attribute4,
+                    attribute4);
+        }
+        
+        this.attribute4 = attribute4;
     }
 
     public int getPersistenceState() {

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockPojo1.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockPojo1.java?view=diff&rev=463528&r1=463527&r2=463528
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockPojo1.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.5/src/test/java/org/apache/cayenne/enhancer/MockPojo1.java Thu Oct 12 17:33:33 2006
@@ -21,6 +21,9 @@
 public class MockPojo1 {
 
     protected String attribute1;
+    protected int attribute2;
+    protected double attribute3;
+    protected byte[] attribute4;
 
     public String getAttribute1() {
         return attribute1;
@@ -28,5 +31,29 @@
 
     public void setAttribute1(String attribute1) {
         this.attribute1 = attribute1;
+    }
+
+    public int getAttribute2() {
+        return attribute2;
+    }
+
+    public void setAttribute2(int attribute2) {
+        this.attribute2 = attribute2;
+    }
+
+    public double getAttribute3() {
+        return attribute3;
+    }
+
+    public void setAttribute3(double attribute3) {
+        this.attribute3 = attribute3;
+    }
+
+    public byte[] getAttribute4() {
+        return attribute4;
+    }
+
+    public void setAttribute4(byte[] attribute4) {
+        this.attribute4 = attribute4;
     }
 }