1 25 26 package org.objectweb.easybeans.enhancer.interceptors; 27 28 import static org.objectweb.easybeans.deployment.annotations.InterceptorType.AROUND_INVOKE; 29 30 import java.io.File ; 31 import java.io.FileOutputStream ; 32 import java.util.ArrayList ; 33 import java.util.List ; 34 35 import org.objectweb.asm.ClassWriter; 36 import org.objectweb.asm.Label; 37 import org.objectweb.asm.MethodVisitor; 38 import org.objectweb.asm.Type; 39 import org.objectweb.easybeans.api.EasyBeansInvocationContext; 40 import org.objectweb.easybeans.deployment.annotations.InterceptorType; 41 import org.objectweb.easybeans.deployment.annotations.JClassInterceptor; 42 import org.objectweb.easybeans.deployment.annotations.JMethod; 43 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata; 44 import org.objectweb.easybeans.deployment.annotations.metadata.MethodAnnotationMetadata; 45 import org.objectweb.easybeans.enhancer.CommonClassGenerator; 46 import org.objectweb.easybeans.enhancer.lib.MethodRenamer; 47 import org.objectweb.easybeans.log.JLog; 48 import org.objectweb.easybeans.log.JLogFactory; 49 50 56 public class EasyBeansInvocationContextGenerator extends CommonClassGenerator { 57 58 62 public static final String PACKAGE_NAME_PREFIX = "org.objectweb.easybeans_gen.invocationcontext."; 63 64 68 public static final String ARG = "arg"; 69 70 74 public static final String INTERCEPTOR = "interceptor"; 75 76 79 public static final String SUFFIX_CLASS = "EasyBeansInvocationContextImpl"; 80 81 84 public static final String [] INTERFACES = new String [] {"org/objectweb/easybeans/api/EasyBeansInvocationContext"}; 85 86 89 public static final String [] PROCEED_EXCEPTIONS = new String [] {Type.getInternalName(Exception .class)}; 90 91 94 public static final String EASYBEANS_INVOCATION_CONTEXT = Type.getDescriptor(EasyBeansInvocationContext.class); 95 96 99 private static JLog logger = JLogFactory.getLog(EasyBeansInvocationContextGenerator.class); 100 101 105 private ClassAnnotationMetadata classAnnotationMetadata = null; 106 107 110 private String packageName = null; 111 112 115 private String generatedClassName = null; 116 117 121 private JMethod jMethod = null; 122 123 126 private MethodAnnotationMetadata methodAnnotationMetadata; 127 128 131 private String beanClassDesc = null; 132 133 136 private String beanClassName = null; 137 138 141 private Type beanClassType = null; 142 143 146 private String constructorDesc = null; 147 148 151 private Type[] methodArgsType = null; 152 153 156 private List <JClassInterceptor> allInterceptors = null; 157 158 161 private InterceptorType interceptorType = null; 162 163 166 private String interceptorManagerClassName = null; 167 168 171 public static final String SUFFIX_INTERCEPTOR_MANAGER = "InterceptorManager"; 172 173 178 public EasyBeansInvocationContextGenerator(final MethodAnnotationMetadata methodAnnotationMetadata, 179 final InterceptorType interceptorType) { 180 super(new ClassWriter(true)); 181 this.methodAnnotationMetadata = methodAnnotationMetadata; 182 this.classAnnotationMetadata = methodAnnotationMetadata.getClassAnnotationMetadata(); 183 this.jMethod = methodAnnotationMetadata.getJMethod(); 184 185 packageName = PACKAGE_NAME_PREFIX + classAnnotationMetadata.getClassName(); 187 188 this.interceptorType = interceptorType; 190 191 this.interceptorManagerClassName = classAnnotationMetadata.getClassName() + SUFFIX_INTERCEPTOR_MANAGER; 192 193 194 generatedClassName = packageName.replace(".", "/") + "/" + SUFFIX_CLASS; 196 generatedClassName += methodAnnotationMetadata.getJMethod().getName() + interceptorType.name().replace("_", ""); 197 generatedClassName += methodAnnotationMetadata.getJMethod().getDescriptor().hashCode(); 200 201 beanClassDesc = encodeClassDesc(classAnnotationMetadata.getClassName()); 203 beanClassName = classAnnotationMetadata.getClassName(); 204 beanClassType = Type.getType(beanClassDesc); 205 206 methodArgsType = Type.getArgumentTypes(jMethod.getDescriptor()); 208 209 allInterceptors = new ArrayList <JClassInterceptor>(); 211 if (classAnnotationMetadata.getGlobalEasyBeansInterceptors() != null) { 212 for (JClassInterceptor interceptor : classAnnotationMetadata.getGlobalEasyBeansInterceptors()) { 213 allInterceptors.add(interceptor); 214 } 215 } 216 217 if (methodAnnotationMetadata.getGlobalEasyBeansInterceptors() != null) { 219 for (JClassInterceptor interceptor : methodAnnotationMetadata.getGlobalEasyBeansInterceptors()) { 220 allInterceptors.add(interceptor); 221 } 222 } 223 224 if (methodAnnotationMetadata.getInterceptors() != null) { 226 for (JClassInterceptor interceptor : methodAnnotationMetadata.getInterceptors()) { 227 allInterceptors.add(interceptor); 228 } 229 } 230 231 if (classAnnotationMetadata.getExternalUserEasyBeansInterceptors() != null 233 && !methodAnnotationMetadata.isExcludedClassInterceptors()) { 234 List <JClassInterceptor> userInterceptorslist = 235 classAnnotationMetadata.getExternalUserEasyBeansInterceptors().get(interceptorType); 236 if (userInterceptorslist != null) { 237 for (JClassInterceptor interceptor : userInterceptorslist) { 238 allInterceptors.add(interceptor); 239 } 240 } 241 } 242 243 if (methodAnnotationMetadata.getUserEasyBeansInterceptors() != null) { 245 List <JClassInterceptor> userInterceptorslist = 246 methodAnnotationMetadata.getUserEasyBeansInterceptors().get(interceptorType); 247 if (userInterceptorslist != null) { 248 for (JClassInterceptor interceptor : userInterceptorslist) { 249 allInterceptors.add(interceptor); 250 } 251 } 252 } 253 254 if (classAnnotationMetadata.getInternalUserEasyBeansInterceptors() != null 256 && !methodAnnotationMetadata.isExcludedClassInterceptors()) { 257 List <JClassInterceptor> userInterceptorslist = 258 classAnnotationMetadata.getInternalUserEasyBeansInterceptors().get(interceptorType); 259 if (userInterceptorslist != null) { 260 for (JClassInterceptor interceptor : userInterceptorslist) { 261 allInterceptors.add(interceptor); 262 } 263 } 264 } 265 } 266 267 271 public void generate() { 272 if (logger.isDebugEnabled()) { 273 logger.debug("Generating InvocationContext for Method " + jMethod + " of class " + beanClassName); 274 } 275 276 addClassDeclaration(); 277 addAttributes(); 278 addConstructor(); 279 addStaticClassInitialization(); 280 addMethods(); 281 endClass(); 282 283 284 if (logger.isDebugEnabled()) { 285 String fName = System.getProperty("java.io.tmpdir") + File.separator 286 + generatedClassName.replace("/", ".") + ".class"; 287 logger.debug("Writing Invocation context of method " + methodAnnotationMetadata.getMethodName() + " to " 288 + fName); 289 try { 290 FileOutputStream fos = new FileOutputStream (fName); 291 fos.write(getCW().toByteArray()); 292 fos.close(); 293 } catch (Exception e) { 294 throw new RuntimeException (e); 295 } 296 } 297 } 298 299 302 public byte[] getBytes() { 303 return getCW().toByteArray(); 304 } 305 306 307 310 private void addClassDeclaration() { 311 getCW().visit(GENERATED_CLASS_VERSION, ACC_PUBLIC + ACC_SUPER, generatedClassName, null, "java/lang/Object", 313 INTERFACES); 314 } 315 316 337 private void addConstructor() { 338 339 String argsMethodDesc = ""; 341 for (Type t : methodArgsType) { 342 argsMethodDesc += t.getDescriptor(); 343 } 344 345 346 constructorDesc = "(" + beanClassDesc + argsMethodDesc + ")V"; 350 351 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "<init>", constructorDesc, null, null); 353 mv.visitCode(); 354 355 int arg = 1; 357 mv.visitVarInsn(ALOAD, 0); 358 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); 359 360 int argBean = arg++; 363 mv.visitVarInsn(ALOAD, 0); 364 mv.visitVarInsn(ALOAD, argBean); 365 mv 366 .visitFieldInsn(PUTFIELD, generatedClassName, "bean", encodeClassDesc(classAnnotationMetadata 367 .getClassName())); 368 369 370 mv.visitVarInsn(ALOAD, 0); 372 mv.visitVarInsn(ALOAD, argBean); 373 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), "getEasyBeansFactory", 374 "()Lorg/objectweb/easybeans/api/Factory;"); 375 mv.visitFieldInsn(PUTFIELD, generatedClassName, "factory", "Lorg/objectweb/easybeans/api/Factory;"); 376 377 378 mv.visitVarInsn(ALOAD, 0); 380 mv.visitVarInsn(ALOAD, argBean); 381 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), "getEasyBeansInterceptorManager", 382 "()" + encodeClassDesc(interceptorManagerClassName)); 383 mv.visitFieldInsn(PUTFIELD, generatedClassName, "interceptorManager", encodeClassDesc(interceptorManagerClassName)); 384 385 int methodArg = 0; 388 for (Type type : methodArgsType) { 389 mv.visitVarInsn(ALOAD, 0); 390 int opCode = putFieldLoadOpCode(type.getSort()); 391 mv.visitVarInsn(opCode, arg++); 392 mv.visitFieldInsn(PUTFIELD, generatedClassName, ARG + (methodArg++), type.getDescriptor()); 393 if (opCode == LLOAD || opCode == DLOAD) { 395 arg++; 396 } 397 } 398 399 400 int index = 0; 402 for (JClassInterceptor interceptor : allInterceptors) { 403 if (!interceptor.getClassName().equals(beanClassName)) { 405 mv.visitVarInsn(ALOAD, 0); 406 mv.visitVarInsn(ALOAD, 0); 407 mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptorManager", 408 encodeClassDesc(interceptorManagerClassName)); 409 String getterName = "get" + interceptor.getClassName().replace("/", ""); 410 mv.visitMethodInsn(INVOKEVIRTUAL, interceptorManagerClassName, getterName, "()" 411 + encodeClassDesc(interceptor.getClassName())); 412 mv.visitFieldInsn(PUTFIELD, generatedClassName, INTERCEPTOR + (index++), encodeClassDesc(interceptor 413 .getClassName())); 414 } 415 } 416 417 418 419 mv.visitInsn(RETURN); 421 422 mv.visitMaxs(0, 0); 424 mv.visitEnd(); 425 426 } 427 428 431 private void endClass() { 432 getCW().visitEnd(); 433 } 434 435 442 private void addAttributes() { 443 addInvocationContextAttributes(); 444 addEasyBeansInvocationContextAttributes(); 445 446 } 447 448 456 private void addMethods() { 457 addInvocationContextMethods(); 458 addEasyBeansInvocationContextMethods(); 459 addToString(); 460 461 } 462 463 466 private void addInvocationContextMethods() { 467 addInvocationContextGetParameters(); 468 addInvocationContextSetParameters(); 469 addInvocationContextGetMethod(); 470 addInvocationContextGetTarget(); 471 addInvocationContextProceed(); 472 addInvocationContextGetContextData(); 473 } 474 475 478 private void addEasyBeansInvocationContextMethods() { 479 480 addEasyBeansInvocationContextGetFactory(); 481 482 } 483 484 485 495 private void addInvocationContextGetTarget() { 496 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getTarget", "()Ljava/lang/Object;", null, null); 497 mv.visitCode(); 498 mv.visitVarInsn(ALOAD, 0); 499 mv.visitFieldInsn(GETFIELD, generatedClassName, "bean", beanClassDesc); 500 mv.visitInsn(ARETURN); 501 mv.visitMaxs(0, 0); 502 mv.visitEnd(); 503 } 504 505 506 516 private void addEasyBeansInvocationContextGetFactory() { 517 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getFactory", "()" + EASYBEANS_FACTORY, null, null); 518 mv.visitCode(); 519 mv.visitVarInsn(ALOAD, 0); 520 mv.visitFieldInsn(GETFIELD, generatedClassName, "factory", EASYBEANS_FACTORY); 521 mv.visitInsn(ARETURN); 522 mv.visitMaxs(0, 0); 523 mv.visitEnd(); 524 525 } 526 527 528 547 private void addInvocationContextGetMethod() { 548 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getMethod", "()" + JAVA_LANG_REFLECT_METHOD, null, null); 549 mv.visitCode(); 550 551 if (interceptorType == AROUND_INVOKE) { 553 554 mv.visitFieldInsn(GETSTATIC, generatedClassName, "method", JAVA_LANG_REFLECT_METHOD); 556 Label notNullParametersLabel = new Label(); 558 mv.visitJumpInsn(IFNONNULL, notNullParametersLabel); 559 560 561 Label tryLabel = new Label(); 563 mv.visitLabel(tryLabel); 564 565 mv.visitLdcInsn(beanClassType); 567 mv.visitLdcInsn(jMethod.getName()); 569 570 571 mv.visitIntInsn(BIPUSH, methodArgsType.length); 573 mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); 574 int argCount = 0; 575 for (Type type : methodArgsType) { 576 mv.visitInsn(DUP); 577 mv.visitIntInsn(BIPUSH, argCount); 578 visitClassType(type, mv); 579 mv.visitInsn(AASTORE); 580 argCount++; 581 } 582 583 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", 585 "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"); 586 587 mv.visitFieldInsn(PUTSTATIC, generatedClassName, "method", "Ljava/lang/reflect/Method;"); 589 590 591 mv.visitJumpInsn(GOTO, notNullParametersLabel); 593 594 Label firstCatchLabel = new Label(); 599 mv.visitLabel(firstCatchLabel); 600 mv.visitVarInsn(ASTORE, 1); 601 mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); 602 mv.visitInsn(DUP); 603 mv.visitLdcInsn("Cannot find method due to a security exception"); 604 mv.visitVarInsn(ALOAD, 1); 605 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", 606 "(Ljava/lang/String;Ljava/lang/Throwable;)V"); 607 mv.visitInsn(ATHROW); 608 609 610 Label secondCatchLabel = new Label(); 614 mv.visitLabel(secondCatchLabel); 615 mv.visitVarInsn(ASTORE, 1); 616 mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); 617 mv.visitInsn(DUP); 618 mv.visitLdcInsn("Cannot find the method"); 619 mv.visitVarInsn(ALOAD, 1); 620 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", 621 "(Ljava/lang/String;Ljava/lang/Throwable;)V"); 622 mv.visitInsn(ATHROW); 623 624 625 mv.visitLabel(notNullParametersLabel); 627 mv.visitFieldInsn(GETSTATIC, generatedClassName, "method", JAVA_LANG_REFLECT_METHOD); 628 mv.visitInsn(ARETURN); 629 630 mv.visitTryCatchBlock(tryLabel, firstCatchLabel, firstCatchLabel, "java/lang/SecurityException"); 632 mv.visitTryCatchBlock(tryLabel, firstCatchLabel, secondCatchLabel, "java/lang/NoSuchMethodException"); 633 } else { 634 mv.visitInsn(ACONST_NULL); 636 mv.visitInsn(ARETURN); 637 } 638 639 640 mv.visitMaxs(0, 0); 642 mv.visitEnd(); 643 644 645 } 646 663 private void addInvocationContextAttributes() { 664 665 addAttribute(ACC_PRIVATE, "bean", beanClassDesc); 668 669 addAttribute(ACC_PRIVATE, "parameters", ARRAY_OBJECTS); 672 673 addAttribute(ACC_PRIVATE + ACC_STATIC, "method", JAVA_LANG_REFLECT_METHOD); 676 677 addAttribute(ACC_PRIVATE, "interceptor", "I", new Integer (0)); 680 681 int arg = 0; 683 for (Type t : methodArgsType) { 684 addAttribute(ACC_PRIVATE, ARG + (arg++), t.getDescriptor()); 685 } 686 687 int intercpt = 0; 689 for (JClassInterceptor interceptor : allInterceptors) { 690 if (!interceptor.getClassName().equals(beanClassName)) { 692 addAttribute(ACC_PRIVATE , INTERCEPTOR + (intercpt++), encodeClassDesc(interceptor.getClassName())); 693 } 694 } 695 696 addAttribute(ACC_PRIVATE, "contextData", "Ljava/util/Map;"); 698 699 } 700 701 707 private void addStaticClassInitialization() { 708 MethodVisitor mv = getCW().visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); 709 mv.visitCode(); 710 711 mv.visitInsn(ACONST_NULL); 713 mv.visitFieldInsn(PUTSTATIC, generatedClassName, "method", JAVA_LANG_REFLECT_METHOD); 714 715 716 mv.visitInsn(RETURN); 717 mv.visitMaxs(0, 0); 718 mv.visitEnd(); 719 720 } 721 722 723 724 731 private void addEasyBeansInvocationContextAttributes() { 732 733 addAttribute(ACC_PRIVATE, "factory", EASYBEANS_FACTORY); 736 737 738 addAttribute(ACC_PRIVATE, "interceptorManager", encodeClassDesc(interceptorManagerClassName)); 741 742 } 743 744 764 private void addInvocationContextProceed() { 765 MethodVisitor mv = getCW() 766 .visitMethod(ACC_PUBLIC, "proceed", "()" + JAVA_LANG_OBJECT, null, PROCEED_EXCEPTIONS); 767 mv.visitCode(); 768 769 770 mv.visitVarInsn(ALOAD, 0); 772 mv.visitInsn(DUP); 773 mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptor", "I"); 774 mv.visitInsn(ICONST_1); 775 mv.visitInsn(IADD); mv.visitFieldInsn(PUTFIELD, generatedClassName, "interceptor", "I"); 777 778 779 780 mv.visitVarInsn(ALOAD, 0); 782 mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptor", "I"); 783 784 785 int sizeInterceptors = allInterceptors.size(); 787 788 int switchSize = sizeInterceptors + 1; 790 791 Label[] switchLabels = new Label[switchSize]; 793 for (int s = 0; s < switchSize; s++) { 794 switchLabels[s] = new Label(); 795 } 796 797 Label defaultCaseLabel = new Label(); 799 800 mv.visitTableSwitchInsn(1, switchSize, defaultCaseLabel, switchLabels); 802 803 int index = 0; 809 int interceptorIndex = 0; 810 for (JClassInterceptor interceptor : allInterceptors) { 811 mv.visitLabel(switchLabels[index]); 812 813 Type returnType = Type.getReturnType(interceptor.getJMethod().getDescriptor()); 814 815 if (interceptor.getClassName().equals(beanClassName)) { 817 mv.visitVarInsn(ALOAD, 0); 818 mv.visitFieldInsn(GETFIELD, generatedClassName, "bean", beanClassDesc); 819 mv.visitVarInsn(ALOAD, 0); 820 mv.visitMethodInsn(INVOKEVIRTUAL, beanClassName, 821 interceptor.getJMethod().getName(), interceptor.getJMethod().getDescriptor()); 822 823 returnsObject(returnType, mv); 825 } else { mv.visitVarInsn(ALOAD, 0); 827 mv.visitFieldInsn(GETFIELD, generatedClassName, INTERCEPTOR + interceptorIndex , 828 encodeClassDesc(interceptor.getClassName())); 829 mv.visitVarInsn(ALOAD, 0); 830 mv.visitMethodInsn(INVOKEVIRTUAL, interceptor.getClassName(), 831 interceptor.getJMethod().getName(), interceptor.getJMethod().getDescriptor()); 832 returnsObject(returnType, mv); 834 interceptorIndex++; 835 } 836 index++; 837 } 838 839 mv.visitLabel(switchLabels[index++]); 841 mv.visitVarInsn(ALOAD, 0); 843 mv.visitFieldInsn(GETFIELD, generatedClassName, "bean", beanClassDesc); 844 845 int indexArg = 0; 847 for (Type argType : methodArgsType) { 848 mv.visitVarInsn(ALOAD, 0); 849 mv.visitFieldInsn(GETFIELD, generatedClassName, ARG + (indexArg++), argType.getDescriptor()); 850 } 851 852 String interceptedMethod = null; 855 if (interceptorType.equals(AROUND_INVOKE)) { 856 interceptedMethod = MethodRenamer.encode(jMethod.getName()); 857 } else { 858 interceptedMethod = jMethod.getName(); 859 } 860 861 mv.visitMethodInsn(INVOKEVIRTUAL, beanClassName, interceptedMethod, jMethod.getDescriptor()); 862 Type returnType = Type.getReturnType(jMethod.getDescriptor()); 863 returnsObject(returnType, mv); 865 866 867 mv.visitLabel(defaultCaseLabel); 869 mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); 870 mv.visitInsn(DUP); 871 mv.visitLdcInsn("Problem in interceptors. Shouldn't go in the default case."); 872 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); 873 mv.visitInsn(ATHROW); 874 875 mv.visitMaxs(0, 0); 877 mv.visitEnd(); 878 } 879 880 892 public void addInvocationContextGetContextData() { 893 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getContextData", "()Ljava/util/Map;", null, null); 894 mv.visitCode(); 895 mv.visitVarInsn(ALOAD, 0); 896 mv.visitFieldInsn(GETFIELD, generatedClassName, "contextData", "Ljava/util/Map;"); 897 898 Label elseLabel = new Label(); 899 mv.visitJumpInsn(IFNONNULL, elseLabel); 900 901 mv.visitVarInsn(ALOAD, 0); 903 mv.visitTypeInsn(NEW, "java/util/HashMap"); 904 mv.visitInsn(DUP); 905 mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); 906 mv.visitFieldInsn(PUTFIELD, generatedClassName, "contextData", "Ljava/util/Map;"); 907 908 mv.visitLabel(elseLabel); 910 mv.visitVarInsn(ALOAD, 0); 911 mv.visitFieldInsn(GETFIELD, generatedClassName, "contextData", "Ljava/util/Map;"); 912 913 mv.visitInsn(ARETURN); 915 916 mv.visitMaxs(0, 0); 917 mv.visitEnd(); 918 919 920 } 921 922 935 private void addInvocationContextGetParameters() { 936 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "getParameters", "()" + ARRAY_OBJECTS, null, null); 937 mv.visitCode(); 938 939 if (interceptorType == AROUND_INVOKE) { 941 942 mv.visitVarInsn(ALOAD, 0); 944 mv.visitFieldInsn(GETFIELD, generatedClassName, "parameters", ARRAY_OBJECTS); 945 Label notNullParametersLabel = new Label(); 947 mv.visitJumpInsn(IFNONNULL, notNullParametersLabel); 948 949 mv.visitVarInsn(ALOAD, 0); 952 mv.visitIntInsn(BIPUSH, methodArgsType.length); 953 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 954 955 int argCount = 0; 957 for (Type type : methodArgsType) { 958 mv.visitInsn(DUP); 959 mv.visitIntInsn(BIPUSH, argCount); 960 mv.visitVarInsn(ALOAD, 0); 961 mv.visitFieldInsn(GETFIELD, generatedClassName, ARG + argCount, type.getDescriptor()); 962 transformPrimitiveIntoObject(type, mv); 965 mv.visitInsn(AASTORE); 966 argCount++; 967 } 968 969 mv.visitFieldInsn(PUTFIELD, generatedClassName, "parameters", ARRAY_OBJECTS); 971 972 mv.visitLabel(notNullParametersLabel); 975 mv.visitVarInsn(ALOAD, 0); 976 mv.visitFieldInsn(GETFIELD, generatedClassName, "parameters", ARRAY_OBJECTS); 977 } else { 978 mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); 980 mv.visitInsn(DUP); 981 mv.visitLdcInsn("Operation getParameters can only be applied on AroundInvoke interceptors"); 982 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); 983 mv.visitInsn(ATHROW); 984 } 985 986 mv.visitInsn(ARETURN); 988 mv.visitMaxs(0, 0); 989 mv.visitEnd(); 990 991 992 } 993 994 1018 private void addInvocationContextSetParameters() { 1019 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "setParameters", "(" + ARRAY_OBJECTS + ")V", null, null); 1020 mv.visitCode(); 1021 1022 if (interceptorType == AROUND_INVOKE) { 1024 1028 mv.visitVarInsn(ALOAD, 1); 1029 Label notNull = new Label(); 1030 mv.visitJumpInsn(IFNONNULL, notNull); 1031 mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); 1032 mv.visitInsn(DUP); 1033 mv.visitLdcInsn("Cannot set a null array."); 1034 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); 1035 mv.visitInsn(ATHROW); 1036 mv.visitLabel(notNull); 1037 1038 1043 mv.visitVarInsn(ALOAD, 1); 1044 mv.visitInsn(ARRAYLENGTH); 1045 mv.visitIntInsn(BIPUSH, methodArgsType.length); 1046 Label sizeOk = new Label(); 1047 mv.visitJumpInsn(IF_ICMPEQ, sizeOk); 1048 mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); 1049 mv.visitInsn(DUP); 1050 mv.visitLdcInsn("Invalid size of the given array. The length should be '" + methodArgsType.length + "'."); 1051 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); 1052 mv.visitInsn(ATHROW); 1053 mv.visitLabel(sizeOk); 1054 1055 mv.visitVarInsn(ALOAD, 0); 1057 mv.visitVarInsn(ALOAD, 1); 1058 mv.visitFieldInsn(PUTFIELD, generatedClassName, "parameters", ARRAY_OBJECTS); 1059 1060 1065 int argCount = 0; 1066 for (Type type : methodArgsType) { 1067 mv.visitVarInsn(ALOAD, 0); 1068 mv.visitVarInsn(ALOAD, 1); 1069 mv.visitIntInsn(BIPUSH, argCount); 1070 mv.visitInsn(AALOAD); 1071 transformObjectIntoPrimitive(type, mv); 1073 mv.visitFieldInsn(PUTFIELD, generatedClassName, ARG + argCount, type.getDescriptor()); 1075 argCount++; 1076 } 1077 } else { 1078 mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); 1080 mv.visitInsn(DUP); 1081 mv.visitLdcInsn("Operation setParameters can only be applied on AroundInvoke interceptors"); 1082 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V"); 1083 mv.visitInsn(ATHROW); 1084 } 1085 1086 mv.visitInsn(RETURN); 1087 mv.visitMaxs(0, 0); 1088 mv.visitEnd(); 1089 } 1090 1091 1092 1096 private void addToString() { 1097 MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); 1098 mv.visitCode(); 1099 1100 int localVar = 1; 1109 final int varSB = localVar++; 1110 int varCLASSNAMES = localVar++; 1111 int varCLASSNAME = localVar++; 1112 int varINDENT2 = localVar++; 1113 int varINDENT4 = localVar++; 1114 int varI = localVar++; 1115 1116 1128 1129 mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); 1130 mv.visitInsn(DUP); 1131 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); 1132 mv.visitVarInsn(ASTORE, varSB); 1133 mv.visitVarInsn(ALOAD, 0); 1134 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); 1135 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;"); 1136 mv.visitLdcInsn("\\."); 1137 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "split", "(Ljava/lang/String;)[Ljava/lang/String;"); 1138 mv.visitVarInsn(ASTORE, varCLASSNAMES); 1139 mv.visitVarInsn(ALOAD, varCLASSNAMES); 1140 mv.visitVarInsn(ALOAD, varCLASSNAMES); 1141 mv.visitInsn(ARRAYLENGTH); 1142 mv.visitInsn(ICONST_1); 1143 mv.visitInsn(ISUB); 1144 mv.visitInsn(AALOAD); 1145 mv.visitVarInsn(ASTORE, varCLASSNAME); 1146 mv.visitVarInsn(ALOAD, varSB); 1147 mv.visitVarInsn(ALOAD, varCLASSNAME); 1148 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1149 mv.visitInsn(POP); 1150 mv.visitVarInsn(ALOAD, varSB); 1151 mv.visitLdcInsn("[\n"); 1152 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1153 mv.visitInsn(POP); 1154 mv.visitLdcInsn(" "); 1155 mv.visitVarInsn(ASTORE, varINDENT2); 1156 mv.visitLdcInsn(" "); 1157 mv.visitVarInsn(ASTORE, varINDENT4); 1158 mv.visitVarInsn(ALOAD, varSB); 1159 mv.visitVarInsn(ALOAD, varINDENT2); 1160 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1161 mv.visitInsn(POP); 1162 mv.visitVarInsn(ALOAD, varSB); 1163 mv.visitLdcInsn("List of interceptors :\n"); 1164 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1165 mv.visitInsn(POP); 1166 1167 1177 int i = 1; 1178 1179 mv.visitInsn(ICONST_1); 1181 mv.visitVarInsn(ISTORE, varI); 1182 1183 if (allInterceptors != null) { 1184 for (JClassInterceptor interceptor : allInterceptors) { 1185 mv.visitVarInsn(ALOAD, varSB); 1186 mv.visitVarInsn(ALOAD, varINDENT4); 1187 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1188 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1189 mv.visitInsn(POP); 1190 1191 mv.visitVarInsn(ALOAD, varSB); 1192 mv.visitVarInsn(ILOAD, varI); 1193 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); 1194 mv.visitInsn(POP); 1195 1196 mv.visitVarInsn(ALOAD, varSB); 1197 mv.visitLdcInsn(") - "); 1198 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1199 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1200 mv.visitInsn(POP); 1201 1202 mv.visitVarInsn(ALOAD, varSB); 1204 mv.visitLdcInsn(interceptor.getClassName()); 1205 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1206 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1207 mv.visitInsn(POP); 1208 1209 mv.visitVarInsn(ALOAD, varSB); 1210 mv.visitLdcInsn("["); 1211 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1212 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1213 mv.visitInsn(POP); 1214 1215 mv.visitVarInsn(ALOAD, varSB); 1217 mv.visitLdcInsn(interceptor.getJMethod().getName()); 1218 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1219 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1220 mv.visitInsn(POP); 1221 1222 mv.visitVarInsn(ALOAD, varSB); 1223 mv.visitLdcInsn("]\n"); 1224 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1225 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1226 mv.visitInsn(POP); 1227 1228 i++; 1229 mv.visitIincInsn(varI, 1); 1231 } 1232 1238 mv.visitVarInsn(ALOAD, varSB); 1239 mv.visitVarInsn(ALOAD, varINDENT2); 1240 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1241 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1242 mv.visitInsn(POP); 1243 1244 mv.visitVarInsn(ALOAD, varSB); 1245 mv.visitLdcInsn("Current interceptor : "); 1246 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1247 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1248 mv.visitInsn(POP); 1249 1250 mv.visitVarInsn(ALOAD, varSB); 1251 mv.visitVarInsn(ALOAD, 0); 1252 mv.visitFieldInsn(GETFIELD, generatedClassName, "interceptor", "I"); 1253 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); 1254 mv.visitInsn(POP); 1255 1256 mv.visitVarInsn(ALOAD, varSB); 1257 mv.visitLdcInsn("/"); 1258 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1259 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1260 mv.visitInsn(POP); 1261 1262 mv.visitVarInsn(ALOAD, varSB); 1263 mv.visitLdcInsn(String.valueOf(allInterceptors.size())); 1264 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1265 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1266 mv.visitInsn(POP); 1267 1268 } else { 1269 1273 mv.visitVarInsn(ALOAD, varSB); 1274 mv.visitVarInsn(ALOAD, varINDENT2); 1275 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1276 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1277 mv.visitInsn(POP); 1278 1279 mv.visitVarInsn(ALOAD, varSB); 1280 mv.visitLdcInsn("No interceptors : "); 1281 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1282 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1283 mv.visitInsn(POP); 1284 } 1285 1286 1291 mv.visitVarInsn(ALOAD, varSB); 1292 mv.visitLdcInsn("\n"); 1293 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1294 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1295 mv.visitInsn(POP); 1296 1297 mv.visitVarInsn(ALOAD, varSB); 1298 mv.visitLdcInsn("]"); 1299 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", 1300 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); 1301 mv.visitInsn(POP); 1302 1303 mv.visitVarInsn(ALOAD, varSB); 1304 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); 1305 mv.visitInsn(ARETURN); 1306 1307 mv.visitMaxs(0, 0); 1308 mv.visitEnd(); 1309 1310 } 1311 1312 1315 public MethodAnnotationMetadata getMethodAnnotationMetadata() { 1316 return methodAnnotationMetadata; 1317 } 1318 1319 1322 public String getGeneratedClassName() { 1323 return generatedClassName; 1324 } 1325 1326 1329 public String getConstructorDesc() { 1330 return constructorDesc; 1331 } 1332 1333 1336 public List <JClassInterceptor> getAllInterceptors() { 1337 return allInterceptors; 1338 } 1339 1340} 1341 | Popular Tags |