1 21 package oracle.toplink.essentials.internal.weaving; 23 24 import java.util.*; 26 27 import oracle.toplink.libraries.asm.*; 29 import oracle.toplink.libraries.asm.attrs.RuntimeVisibleAnnotations; 30 import oracle.toplink.libraries.asm.attrs.Annotation; 31 32 40 41 public class TopLinkClassWeaver extends ClassAdapter implements Constants { 42 43 public static final String VHI_CLASSNAME = 44 "oracle.toplink.essentials.indirection.ValueHolderInterface"; 45 public static final String VH_SHORT_SIGNATURE = 46 "oracle/toplink/essentials/indirection/ValueHolder"; 47 public static final String VHI_SHORT_SIGNATURE = 48 "oracle/toplink/essentials/indirection/ValueHolderInterface"; 49 public static final String VHI_SIGNATURE = 50 "L" + VHI_SHORT_SIGNATURE +";"; 51 public static final String TW_SHORT_SIGNATURE = 52 "oracle/toplink/essentials/internal/weaving/TopLinkWeaved"; 53 54 protected ClassDetails classDetails; 55 public boolean alreadyWeaved = false; 56 public boolean weavedVH = false; 57 58 public TopLinkClassWeaver(ClassWriter classWriter, ClassDetails classDetails) { 59 super(classWriter); 60 this.classDetails = classDetails; 61 } 62 63 70 public void addValueHolder(AttributeDetails attributeDetails){ 71 String attribute = attributeDetails.getAttributeName(); 72 RuntimeVisibleAnnotations annotations = null; 73 if (attributeDetails.getMapping().getGetMethodName() == null || attributeDetails.getMapping().getGetMethodName().equals("")){ 74 annotations = getTransientAnnotation(); 75 } 76 weavedVH = true; 77 cv.visitField(ACC_PRIVATE, "_toplink_" + attribute + "_vh", "Loracle/toplink/essentials/indirection/ValueHolderInterface;", null, annotations); 78 } 79 80 88 public void addGetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails){ 89 String attribute = attributeDetails.getAttributeName(); 90 String className = classDetails.getClassName(); 91 CodeVisitor cv_get_VH = cv.visitMethod(ACC_PUBLIC, "_toplink_get" + attribute + "_vh", "()" + VHI_SIGNATURE, null, null); 93 cv_get_VH.visitVarInsn(ALOAD, 0); 94 cv_get_VH.visitFieldInsn(GETFIELD, className, "_toplink_" + attribute + "_vh", "Loracle/toplink/essentials/indirection/ValueHolderInterface;"); 95 cv_get_VH.visitInsn(ARETURN); 96 cv_get_VH.visitMaxs(0, 0); 97 } 98 99 107 public void addSetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails){ 108 String attribute = attributeDetails.getAttributeName(); 109 String className = classDetails.getClassName(); 110 CodeVisitor cv_set_value = cv.visitMethod(ACC_PUBLIC, "_toplink_set" + attribute + "_vh", "(Loracle/toplink/essentials/indirection/ValueHolderInterface;)V", null, null); 112 cv_set_value.visitVarInsn(ALOAD, 0); 113 cv_set_value.visitVarInsn(ALOAD, 1); 114 cv_set_value.visitFieldInsn(PUTFIELD, className, "_toplink_" + attribute + "_vh", "Loracle/toplink/essentials/indirection/ValueHolderInterface;"); 115 cv_set_value.visitInsn(RETURN); 116 cv_set_value.visitMaxs(0, 0); 117 } 118 119 130 public void addSetterMethodForFieldAccess(ClassDetails classDetails, AttributeDetails attributeDetails){ 131 String attribute = attributeDetails.getAttributeName(); 132 CodeVisitor cv_set = cv.visitMethod(ACC_PUBLIC, "_toplink_set" + attribute, "(L" + attributeDetails.getReferenceClass().replace('.','/') + ";)V", null, null); 133 cv_set.visitVarInsn(ALOAD, 0); 134 cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_toplink_" + attribute + "_vh", TopLinkClassWeaver.VHI_SIGNATURE); 135 cv_set.visitVarInsn(ALOAD, 1); 136 cv_set.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "setValue", "(Ljava/lang/Object;)V"); 137 cv_set.visitVarInsn(ALOAD, 0); 138 cv_set.visitVarInsn(ALOAD, 1); 139 cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, "L" + attributeDetails.getReferenceClass().replace('.','/') + ";"); 140 cv_set.visitInsn(RETURN); 141 cv_set.visitMaxs(0 ,0); 142 } 143 144 155 public void addGetterMethodForFieldAccess(ClassDetails classDetails, AttributeDetails attributeDetails){ 156 String attribute = attributeDetails.getAttributeName(); 157 158 CodeVisitor cv_get = cv.visitMethod(ACC_PUBLIC, "_toplink_get" + attribute, "()L" + attributeDetails.getReferenceClass().replace('.','/') + ";", null, null); 159 cv_get.visitVarInsn(ALOAD, 0); 160 cv_get.visitVarInsn(ALOAD, 0); 161 cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), "_toplink_" + attribute + "_vh", TopLinkClassWeaver.VHI_SIGNATURE); 162 cv_get.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;"); 163 cv_get.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClass().replace('.','/')); 164 cv_get.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, "L" + attributeDetails.getReferenceClass().replace('.','/') + ";"); 165 cv_get.visitVarInsn(ALOAD, 0); 166 cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), attribute, "L" + attributeDetails.getReferenceClass().replace('.','/') + ";"); 167 cv_get.visitInsn(ARETURN); 168 cv_get.visitMaxs(0, 0); 169 } 170 171 private RuntimeVisibleAnnotations getTransientAnnotation(){ 172 RuntimeVisibleAnnotations attrs = new RuntimeVisibleAnnotations(); 173 Annotation transientAnnotation = new Annotation("Ljavax/persistence/Transient;"); 174 attrs.annotations.add(transientAnnotation); 175 return attrs; 176 } 177 178 public void visit(int version, int access, String name, String superName, 180 String [] interfaces, String sourceFile) { 181 182 for (int i = 0; i < interfaces.length; i++) { 184 String s = interfaces[i]; 185 if (TW_SHORT_SIGNATURE.equals(s)) { 186 alreadyWeaved = true; 187 break; 188 } 189 } 190 191 if (!alreadyWeaved) { 192 int len = 1 + interfaces.length; 193 String [] newInterfaces = new String [len]; 194 System.arraycopy(interfaces, 0, newInterfaces, 0, interfaces.length); 195 newInterfaces[interfaces.length] = TW_SHORT_SIGNATURE; 197 super.visit(version, access, name, superName, newInterfaces, 198 sourceFile); 199 } else { 200 super.visit(version, access, name, superName, interfaces, sourceFile); 201 } 202 203 } 204 205 209 public CodeVisitor visitMethod(int access, String methodName, String desc, 210 String [] exceptions, Attribute attrs) { 211 212 if (!alreadyWeaved) { 213 return new TopLinkMethodWeaver(this, methodName, desc, cv.visitMethod(access, methodName, desc, exceptions, attrs)); 214 } else { 215 return super.visitMethod(access, methodName, desc, exceptions, attrs); 216 } 217 } 218 219 public void visitAttribute(Attribute attr) { 220 if (!alreadyWeaved) { 221 cv.visitAttribute(attr); 222 } else { 223 super.visitAttribute(attr); 224 } 225 } 226 227 public void visitEnd() { 228 if (!alreadyWeaved) { 229 CodeVisitor cv_weavedValueHolders = cv.visitMethod(ACC_PUBLIC, 232 "weavedValueHolders", "()Z", null, null); 233 if (classDetails.weavedValueHolders()) { 234 cv_weavedValueHolders.visitInsn(ICONST_1); 235 } else { 236 cv_weavedValueHolders.visitInsn(ICONST_0); 237 } 238 cv_weavedValueHolders.visitInsn(IRETURN); 239 cv_weavedValueHolders.visitMaxs(0, 0); 240 } 241 242 for (Iterator i = classDetails.getAttributesMap().values().iterator();i.hasNext();) { 244 AttributeDetails attributeDetails = (AttributeDetails)i.next(); 245 if (attributeDetails.weaveValueHolders()) { 246 247 if (!alreadyWeaved && !attributeDetails.isAttributeOnSuperClass()){ 252 addValueHolder(attributeDetails); 253 addGetterMethodForValueHolder(classDetails, attributeDetails); 254 addSetterMethodForValueHolder(classDetails, attributeDetails); 255 256 if (attributeDetails.getMapping().usesIndirection() && attributeDetails.isMappedWithAttributeAccess()){ 258 addSetterMethodForFieldAccess(classDetails, attributeDetails); 259 addGetterMethodForFieldAccess(classDetails, attributeDetails); 260 } 261 } 262 263 } 264 } 265 super.visitEnd(); 266 } 267 } 268 | Popular Tags |