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;
}
}