1 22 package org.jboss.aop.instrument; 23 24 import javassist.CannotCompileException; 25 import javassist.CtClass; 26 import javassist.CtConstructor; 27 import javassist.CtField; 28 import javassist.CtMethod; 29 import javassist.CtNewMethod; 30 import javassist.Modifier; 31 import javassist.NotFoundException; 32 33 import org.jboss.aop.ClassAdvisor; 34 import org.jboss.aop.util.JavassistMethodHashing; 35 36 42 public class GeneratedAdvisorConstructionTransformer extends ConstructionTransformer 43 { 44 45 public GeneratedAdvisorConstructionTransformer(Instrumentor instrumentor) 46 { 47 super(instrumentor); 48 } 49 50 protected void generateConstructionInfoField(CtConstructor constructor, int index) throws NotFoundException, CannotCompileException 51 { 52 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 53 String ciname = addConstructionInfoField( 54 Modifier.PROTECTED, 55 genadvisor, 56 constructor, 57 index); 58 59 addJoinpoint(constructor, ciname, index); 60 61 long constructorHash = JavassistMethodHashing.constructorHash(constructor); 62 ((GeneratedAdvisorInstrumentor)instrumentor).initialiseConstructionInfoField(ciname, index, constructorHash); 63 } 64 65 private void addJoinpoint(CtConstructor constructor, String ciname, int index)throws CannotCompileException, NotFoundException 66 { 67 CtClass clazz = constructor.getDeclaringClass(); 68 CtClass joinpoint = createJoinpointClass(clazz, constructor, ciname, index); 69 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 70 CtField field = new CtField( 71 joinpoint, 72 ConstructionJoinPointGenerator.getInfoFieldName(clazz.getSimpleName(), index), 73 genadvisor); 74 field.setModifiers(Modifier.PROTECTED); 75 genadvisor.addField(field); 76 } 77 78 private CtClass createJoinpointClass(CtClass clazz, CtConstructor constructor, String ciname, int index) throws CannotCompileException, NotFoundException 79 { 80 return ConstructionJoinPointGenerator.createJoinpointBaseClass( 81 (GeneratedAdvisorInstrumentor)instrumentor, 82 clazz, 83 constructor, 84 ciname, 85 index); 86 } 87 88 89 protected void generateNotMatchedConstructionInfoField(CtConstructor constructor, int index) throws NotFoundException, CannotCompileException 90 { 91 generateConstructionInfoField(constructor, index); 92 } 93 94 protected boolean addInfoAsWeakReference() 95 { 96 return false; 97 } 98 99 public static String constructionFactory(String className) 100 { 101 if (className.indexOf('.') >= 0)throw new RuntimeException ("constructorFactory() takes a simple class name:" + className); 102 return className + "_construction_" + ClassAdvisor.NOT_TRANSFORMABLE_SUFFIX; 103 } 104 105 protected void insertInterception(CtConstructor constructor, int index) throws Exception 106 { 107 final String constructionWrapperName = constructor.getDeclaringClass().getSimpleName() + "_con_" + ClassAdvisor.NOT_TRANSFORMABLE_SUFFIX; 108 109 String body = createInterceptingWrapperBody(constructor, index); 110 CtMethod wrapper = createWrapperMethod(constructor, constructionWrapperName, body); 111 insertWrapperCallInCtor(constructor, constructionWrapperName); 112 113 } 114 115 private CtMethod createWrapperMethod(CtConstructor constructor, String wrapperName, String body)throws CannotCompileException, NotFoundException 116 { 117 final CtClass genadvisor = ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 118 CtClass[] params = constructor.getParameterTypes(); 119 CtClass[] wrapperParams = new CtClass[params.length + 1]; 120 wrapperParams[0] = constructor.getDeclaringClass(); 121 System.arraycopy(params, 0, wrapperParams, 1, params.length); 122 123 CtMethod wrapper = CtNewMethod.make( 124 CtClass.voidType, 125 wrapperName, 126 wrapperParams, 127 constructor.getExceptionTypes(), 128 body, 129 genadvisor); 130 genadvisor.addMethod(wrapper); 131 return wrapper; 132 } 133 134 private void insertWrapperCallInCtor(CtConstructor constructor, String wrapperName)throws NotFoundException, CannotCompileException 135 { 136 String wrapperCall = 137 "((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(constructor.getDeclaringClass())+ ")" + GeneratedAdvisorInstrumentor.GET_CURRENT_ADVISOR + ")." + 138 wrapperName + "(this" + ((constructor.getParameterTypes().length == 0) ? "" : ", $$") + ");"; 139 constructor.insertAfter(wrapperCall, false); 140 } 141 142 private String createInterceptingWrapperBody(CtConstructor constructor, int index)throws NotFoundException, CannotCompileException 143 { 144 String infoName = ConstructionJoinPointGenerator.getInfoFieldName(constructor.getDeclaringClass().getSimpleName(), index); 145 String generatorName = ConstructionJoinPointGenerator.getJoinPointGeneratorFieldName(constructor.getDeclaringClass().getSimpleName(), index); 146 String code = 147 "{" + 148 " if (" + infoName + " == null && " + generatorName + " != null)" + 149 " {" + 150 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 151 " }" + 152 " if (" + infoName + " != null)" + 153 " { " + 154 " " + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "($$);" + 155 " }" + 156 "}"; 157 158 return code; 159 } 160 } 161 | Popular Tags |