1 21 package oracle.toplink.essentials.internal.weaving; 23 24 import oracle.toplink.libraries.asm.*; 26 27 import java.util.Iterator ; 28 29 43 44 public class TopLinkMethodWeaver extends CodeAdapter implements Constants { 45 46 protected TopLinkClassWeaver tcw; 47 protected String methodName; 48 private String methodDescriptor = null; 49 50 private boolean methodStarted = false; 52 53 private boolean constructorInitializationDone = false; 55 56 public TopLinkMethodWeaver(TopLinkClassWeaver tcw, String methodName, String methodEscriptor, 57 CodeVisitor cv) { 58 59 super(cv); 60 this.tcw = tcw; 61 this.methodName = methodName; 62 this.methodDescriptor = methodDescriptor; 63 } 64 65 77 public void weaveAttributesIfRequired(int opcode, String owner, String name, String desc){ 78 AttributeDetails attributeDetails = (AttributeDetails)tcw.classDetails.getAttributeDetailsFromClassOrSuperClass(name); 79 if (attributeDetails == null || !attributeDetails.isMappedWithAttributeAccess()){ 80 super.visitFieldInsn(opcode, owner, name, desc); 81 return; 82 } 83 if (opcode == GETFIELD) { 84 if (attributeDetails != null) { 85 cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_toplink_get" + name, "()L" + attributeDetails.getReferenceClass().replace('.','/') + ";"); 86 } else { 87 super.visitFieldInsn(opcode, owner, name, desc); 88 } 89 } else if (opcode == PUTFIELD) { 90 if (attributeDetails != null) { 91 cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_toplink_set" + name, "(L" + attributeDetails.getReferenceClass().replace('.','/') + ";)V"); 92 } else { 93 super.visitFieldInsn(opcode, owner, name, desc); 94 } 95 } else { 96 super.visitFieldInsn(opcode, owner, name, desc); 97 } 98 } 99 100 107 public void weaveConstructorIfRequired(int opcode, String owner, String name, String desc){ 108 if (!constructorInitializationDone && ("<init>".equals(methodName)||"<cinit>".equals(methodName))) { 109 if (opcode == INVOKESPECIAL && name.startsWith("<init>")) { 112 ClassDetails details = tcw.classDetails; 113 Iterator attributes = details.getAttributesMap().keySet().iterator(); 114 while (attributes.hasNext()){ 115 String key = (String )attributes.next(); 116 117 AttributeDetails attribute = (AttributeDetails)details.getAttributesMap().get(key); 118 if (attribute.weaveValueHolders() && !attribute.isCollectionMapping() && !attribute.isAttributeOnSuperClass()){ 119 super.visitVarInsn(ALOAD, 0); 120 super.visitTypeInsn(NEW, "oracle/toplink/essentials/indirection/ValueHolder"); 121 super.visitInsn(DUP); 122 super.visitMethodInsn(INVOKESPECIAL, "oracle/toplink/essentials/indirection/ValueHolder", "<init>", "()V"); 123 super.visitFieldInsn(PUTFIELD, details.className, "_toplink_" + attribute.attributeName + "_vh", "Loracle/toplink/essentials/indirection/ValueHolderInterface;"); 124 } 125 } 126 } 127 constructorInitializationDone = true; 128 } 129 } 130 131 146 public void addValueHolderReferencesIfRequired(){ 147 if (methodStarted){ 148 return; 149 } 150 AttributeDetails attributeDetails = (AttributeDetails)tcw.classDetails.getGetterMethodToAttributeDetails().get(methodName); 151 if (attributeDetails != null && !attributeDetails.isAttributeOnSuperClass()){ 152 cv.visitVarInsn(ALOAD, 0); 153 cv.visitVarInsn(ALOAD, 0); 154 cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", TopLinkClassWeaver.VHI_SIGNATURE); 155 cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;"); 156 cv.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClass().replace('.','/')); 157 cv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClass().replace('.','/') + ";)V"); 158 } else { 159 attributeDetails = (AttributeDetails)tcw.classDetails.getSetterMethodToAttributeDetails().get(methodName); 160 if (attributeDetails != null){ 161 cv.visitVarInsn(ALOAD, 0); 162 cv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_toplink_" + attributeDetails.getAttributeName() + "_vh", "Loracle/toplink/essentials/indirection/ValueHolderInterface;"); 163 cv.visitVarInsn(ALOAD, 1); 164 cv.visitMethodInsn(INVOKEINTERFACE, TopLinkClassWeaver.VHI_SHORT_SIGNATURE, "setValue", "(Ljava/lang/Object;)V"); 165 } 166 } 167 } 168 169 public void visitInsn (final int opcode) { 170 addValueHolderReferencesIfRequired(); 171 methodStarted = true; 172 super.visitInsn(opcode); 173 } 174 175 public void visitIntInsn (final int opcode, final int operand) { 176 addValueHolderReferencesIfRequired(); 177 methodStarted = true; 178 cv.visitIntInsn(opcode, operand); 179 } 180 181 public void visitVarInsn (final int opcode, final int var) { 182 addValueHolderReferencesIfRequired(); 183 methodStarted = true; 184 cv.visitVarInsn(opcode, var); 185 } 186 187 public void visitTypeInsn (final int opcode, final String desc) { 188 addValueHolderReferencesIfRequired(); 189 methodStarted = true; 190 cv.visitTypeInsn(opcode, desc); 191 } 192 193 public void visitFieldInsn (final int opcode, final String owner, final String name, final String desc){ 194 addValueHolderReferencesIfRequired(); 195 methodStarted = true; 196 weaveAttributesIfRequired(opcode, owner, name, desc); 197 } 198 199 public void visitMethodInsn (final int opcode, final String owner, final String name, final String desc){ 200 addValueHolderReferencesIfRequired(); 201 methodStarted = true; 202 super.visitMethodInsn(opcode, owner, name, desc); 203 weaveConstructorIfRequired(opcode, owner, name, desc); 204 } 205 206 public void visitJumpInsn (final int opcode, final Label label) { 207 addValueHolderReferencesIfRequired(); 208 methodStarted = true; 209 cv.visitJumpInsn(opcode, label); 210 } 211 212 public void visitLabel (final Label label) { 213 cv.visitLabel(label); 214 } 215 216 public void visitLdcInsn (final Object cst) { 217 addValueHolderReferencesIfRequired(); 218 methodStarted = true; 219 cv.visitLdcInsn(cst); 220 } 221 222 public void visitIincInsn (final int var, final int increment) { 223 addValueHolderReferencesIfRequired(); 224 methodStarted = true; 225 cv.visitIincInsn(var, increment); 226 } 227 228 public void visitTableSwitchInsn (final int min, final int max, final Label dflt, final Label labels[]){ 229 addValueHolderReferencesIfRequired(); 230 methodStarted = true; 231 cv.visitTableSwitchInsn(min, max, dflt, labels); 232 } 233 234 public void visitLookupSwitchInsn (final Label dflt, final int keys[], final Label labels[]){ 235 addValueHolderReferencesIfRequired(); 236 methodStarted = true; 237 cv.visitLookupSwitchInsn(dflt, keys, labels); 238 } 239 240 public void visitMultiANewArrayInsn (final String desc, final int dims) { 241 addValueHolderReferencesIfRequired(); 242 methodStarted = true; 243 cv.visitMultiANewArrayInsn(desc, dims); 244 } 245 246 public void visitTryCatchBlock (final Label start, final Label end,final Label handler, final String type){ 247 addValueHolderReferencesIfRequired(); 248 methodStarted = true; 249 cv.visitTryCatchBlock(start, end, handler, type); 250 } 251 252 public void visitMaxs (final int maxStack, final int maxLocals) { 253 addValueHolderReferencesIfRequired(); 254 methodStarted = true; 255 cv.visitMaxs(0, 0); 256 } 257 258 public void visitLocalVariable (final String name, final String desc, final Label start, final Label end, final int index){ 259 addValueHolderReferencesIfRequired(); 260 methodStarted = true; 261 cv.visitLocalVariable(name, desc, start, end, index); 262 } 263 264 public void visitLineNumber (final int line, final Label start) { 265 cv.visitLineNumber(line, start); 266 } 267 268 public void visitAttribute (final Attribute attr) { 269 addValueHolderReferencesIfRequired(); 270 methodStarted = true; 271 cv.visitAttribute(attr); 272 } 273 274 275 protected AttributeDetails weaveValueHolders(ClassDetails startingDetails, 277 String fieldName) { 278 279 if (startingDetails == null) { 280 return null; 281 } else { 282 AttributeDetails attributeDetails = (AttributeDetails)startingDetails.getAttributesMap().get(fieldName); 283 if (attributeDetails != null && attributeDetails.weaveValueHolders()) { 284 return attributeDetails; 285 } else { 286 return weaveValueHolders(startingDetails.getSuperClassDetails(), 287 fieldName); 288 } 289 } 290 } 291 } 292 | Popular Tags |