1 19 package org.apache.cayenne.enhancer; 20 21 import org.apache.cayenne.ObjectContext; 22 import org.objectweb.asm.Label; 23 import org.objectweb.asm.MethodAdapter; 24 import org.objectweb.asm.MethodVisitor; 25 import org.objectweb.asm.Opcodes; 26 import org.objectweb.asm.Type; 27 28 32 public class SetterVisitor extends MethodAdapter { 33 34 private EnhancementHelper helper; 35 private String propertyName; 36 private Type propertyType; 37 38 public SetterVisitor(MethodVisitor mv, EnhancementHelper helper, String propertyName, 39 Type propertyType) { 40 super(mv); 41 this.helper = helper; 42 this.propertyName = propertyName; 43 this.propertyType = propertyType; 44 } 45 46 @Override 47 public void visitCode() { 48 super.visitCode(); 49 50 String field = helper.getPropertyField("objectContext"); 51 Type objectContextType = Type.getType(ObjectContext.class); 52 String propertyDescriptor = propertyType.getDescriptor(); 53 54 mv.visitVarInsn(Opcodes.ALOAD, 0); 55 mv.visitFieldInsn( 56 Opcodes.GETFIELD, 57 helper.getCurrentClass().getInternalName(), 58 field, 59 objectContextType.getDescriptor()); 60 Label l1 = new Label(); 61 mv.visitJumpInsn(Opcodes.IFNULL, l1); 62 mv.visitVarInsn(Opcodes.ALOAD, 0); 63 mv.visitFieldInsn( 64 Opcodes.GETFIELD, 65 helper.getCurrentClass().getInternalName(), 66 field, 67 objectContextType.getDescriptor()); 68 mv.visitVarInsn(Opcodes.ALOAD, 0); 69 mv.visitLdcInsn(propertyName); 70 mv.visitVarInsn(Opcodes.ALOAD, 0); 71 72 mv.visitFieldInsn( 73 Opcodes.GETFIELD, 74 helper.getCurrentClass().getInternalName(), 75 propertyName, 76 propertyDescriptor); 77 78 if (!visitPrimitiveConversion(propertyDescriptor)) { 79 mv.visitVarInsn(Opcodes.ALOAD, 1); 80 } 81 82 mv 83 .visitMethodInsn( 84 Opcodes.INVOKEINTERFACE, 85 objectContextType.getInternalName(), 86 "propertyChanged", 87 "(Lorg/apache/cayenne/Persistent;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"); 88 mv.visitLabel(l1); 89 } 90 91 protected boolean visitPrimitiveConversion(String propertyDescriptor) { 92 if (propertyDescriptor.length() != 1) { 93 return false; 94 } 95 96 switch (propertyDescriptor.charAt(0)) { 97 case 'I': 98 mv.visitMethodInsn( 99 Opcodes.INVOKESTATIC, 100 "java/lang/Integer", 101 "valueOf", 102 "(I)Ljava/lang/Integer;"); 103 mv.visitVarInsn(Opcodes.ILOAD, 1); 104 mv.visitMethodInsn( 105 Opcodes.INVOKESTATIC, 106 "java/lang/Integer", 107 "valueOf", 108 "(I)Ljava/lang/Integer;"); 109 return true; 110 case 'D': 111 mv.visitMethodInsn( 112 Opcodes.INVOKESTATIC, 113 "java/lang/Double", 114 "valueOf", 115 "(D)Ljava/lang/Double;"); 116 mv.visitVarInsn(Opcodes.DLOAD, 1); 117 mv.visitMethodInsn( 118 Opcodes.INVOKESTATIC, 119 "java/lang/Double", 120 "valueOf", 121 "(D)Ljava/lang/Double;"); 122 return true; 123 case 'F': 124 mv.visitMethodInsn( 125 Opcodes.INVOKESTATIC, 126 "java/lang/Float", 127 "valueOf", 128 "(F)Ljava/lang/Float;"); 129 mv.visitVarInsn(Opcodes.FLOAD, 1); 130 mv.visitMethodInsn( 131 Opcodes.INVOKESTATIC, 132 "java/lang/Float", 133 "valueOf", 134 "(F)Ljava/lang/Float;"); 135 return true; 136 case 'Z': 137 mv.visitMethodInsn( 138 Opcodes.INVOKESTATIC, 139 "java/lang/Boolean", 140 "valueOf", 141 "(Z)Ljava/lang/Boolean;"); 142 mv.visitVarInsn(Opcodes.ILOAD, 1); 143 mv.visitMethodInsn( 144 Opcodes.INVOKESTATIC, 145 "java/lang/Boolean", 146 "valueOf", 147 "(Z)Ljava/lang/Boolean;"); 148 return true; 149 case 'J': 150 mv.visitMethodInsn( 151 Opcodes.INVOKESTATIC, 152 "java/lang/Long", 153 "valueOf", 154 "(J)Ljava/lang/Long;"); 155 mv.visitVarInsn(Opcodes.LLOAD, 1); 156 mv.visitMethodInsn( 157 Opcodes.INVOKESTATIC, 158 "java/lang/Long", 159 "valueOf", 160 "(J)Ljava/lang/Long;"); 161 return true; 162 case 'B': 163 mv.visitMethodInsn( 164 Opcodes.INVOKESTATIC, 165 "java/lang/Byte", 166 "valueOf", 167 "(B)Ljava/lang/Byte;"); 168 mv.visitVarInsn(Opcodes.ILOAD, 1); 169 mv.visitMethodInsn( 170 Opcodes.INVOKESTATIC, 171 "java/lang/Byte", 172 "valueOf", 173 "(B)Ljava/lang/Byte;"); 174 return true; 175 case 'C': 176 mv.visitMethodInsn( 177 Opcodes.INVOKESTATIC, 178 "java/lang/Character", 179 "valueOf", 180 "(C)Ljava/lang/Character;"); 181 mv.visitVarInsn(Opcodes.ILOAD, 1); 182 mv.visitMethodInsn( 183 Opcodes.INVOKESTATIC, 184 "java/lang/Character", 185 "valueOf", 186 "(C)Ljava/lang/Character;"); 187 return true; 188 case 'S': 189 mv.visitMethodInsn( 190 Opcodes.INVOKESTATIC, 191 "java/lang/Short", 192 "valueOf", 193 "(S)Ljava/lang/Short;"); 194 mv.visitVarInsn(Opcodes.ILOAD, 1); 195 mv.visitMethodInsn( 196 Opcodes.INVOKESTATIC, 197 "java/lang/Short", 198 "valueOf", 199 "(S)Ljava/lang/Short;"); 200 return true; 201 default: 202 return false; 203 } 204 } 205 } 206 | Popular Tags |