/* */ package org.jboss.aop.instrument;
/* */
/* */ import java.lang.ref.WeakReference;
/* */ import java.lang.reflect.Constructor;
/* */ import java.lang.reflect.Method;
/* */ import javassist.CannotCompileException;
/* */ import javassist.CtClass;
/* */ import javassist.CtConstructor;
/* */ import javassist.CtField;
/* */ import javassist.CtMethod;
/* */ import javassist.CtNewConstructor;
/* */ import javassist.CtNewMethod;
/* */ import javassist.NotFoundException;
/* */ import org.jboss.aop.ConByMethodInfo;
/* */ import org.jboss.aop.GeneratedClassAdvisor;
/* */ import org.jboss.aop.JoinPointInfo;
/* */ import org.jboss.aop.advice.AdviceMethodProperties;
/* */ import org.jboss.aop.joinpoint.ConstructorCallByMethod;
/* */ import org.jboss.aop.joinpoint.ConstructorCalledByMethodInvocation;
/* */ import org.jboss.aop.joinpoint.JoinPointBean;
/* */ import org.jboss.aop.util.ReflectToJavassist;
/* */
/* */ public class ConByMethodJoinPointGenerator extends JoinPointGenerator
/* */ {
/* */ public static final String JOINPOINT_CLASS_PREFIX = "JoinPoint_CByM_";
/* */ public static final String JOINPOINT_FIELD_PREFIX = "joinpoint_CByM_";
/* 55 */ private static final Class JOINPOINT_TYPE = ConstructorCallByMethod.class;
/* 56 */ private static final Class INVOCATION_TYPE = ConstructorCalledByMethodInvocation.class;
/* */ private static final CtClass INVOCATION_CT_TYPE;
/* */ private boolean hasCallingObject;
/* */ private WeakReference<Class<?>> returnType;
/* */
/* */ public ConByMethodJoinPointGenerator(GeneratedClassAdvisor advisor, JoinPointInfo info)
/* */ {
/* 75 */ super(advisor, info, getParameters((ConByMethodInfo)info), ((ConByMethodInfo)info).getConstructor().getParameterTypes().length, false);
/* */
/* 78 */ this.hasCallingObject = (!java.lang.reflect.Modifier.isStatic(((ConByMethodInfo)info).getCallingMethod().getModifiers()));
/* 79 */ this.returnType = new WeakReference(((ConByMethodInfo)info).getCalledClass());
/* */ }
/* */
/* */ private static JoinPointGenerator.JoinPointParameters getParameters(ConByMethodInfo info)
/* */ {
/* 84 */ if (javassist.Modifier.isStatic(info.getCallingMethod().getModifiers()))
/* */ {
/* 86 */ return JoinPointGenerator.JoinPointParameters.ONLY_ARGS;
/* */ }
/* 88 */ return JoinPointGenerator.JoinPointParameters.CALLER_ARGS;
/* */ }
/* */
/* */ protected void initialiseJoinPointNames(JoinPointInfo info)
/* */ {
/* 93 */ ConByMethodInfo cinfo = (ConByMethodInfo)info;
/* 94 */ this.joinpointClassName = getGeneratedJoinPointClassName(callingMethodHash(cinfo), calledClass(cinfo), calledConHash(cinfo));
/* */
/* 99 */ this.joinpointFieldName = getGeneratedJoinPointFieldName(callingMethodHash(cinfo), calledClass(cinfo), calledConHash(cinfo));
/* */ }
/* */
/* */ private long callingMethodHash(ConByMethodInfo info)
/* */ {
/* 108 */ return info.getCallingMethodHash();
/* */ }
/* */
/* */ private String calledClass(ConByMethodInfo info)
/* */ {
/* 113 */ return info.getCalledClass().getName();
/* */ }
/* */
/* */ private long calledConHash(ConByMethodInfo info)
/* */ {
/* 118 */ return info.getCalledConHash();
/* */ }
/* */
/* */ protected boolean isVoid()
/* */ {
/* 123 */ return false;
/* */ }
/* */
/* */ protected Class getReturnClassType()
/* */ {
/* 128 */ return (Class)this.returnType.get();
/* */ }
/* */
/* */ protected AdviceMethodProperties getAdviceMethodProperties(JoinPointBean joinPoint, JoinPointGenerator.AdviceSetup setup)
/* */ {
/* 133 */ ConstructorCallByMethod call = (ConstructorCallByMethod)joinPoint;
/* 134 */ Constructor ctor = call.getConstructor();
/* 135 */ AdviceMethodProperties properties = new AdviceMethodProperties(joinPoint, setup.getAspectClass(), setup.getAdviceName(), JOINPOINT_TYPE, INVOCATION_TYPE, ctor.getDeclaringClass(), ctor.getGenericParameterTypes(), ctor.getParameterTypes(), ctor.getGenericExceptionTypes(), call.getCalledClass(), false, call.getCallingClass(), hasCallingObject());
/* */
/* 149 */ return properties;
/* */ }
/* */
/* */ protected boolean isCaller()
/* */ {
/* 154 */ return true;
/* */ }
/* */
/* */ protected boolean hasCallingObject()
/* */ {
/* 159 */ return this.hasCallingObject;
/* */ }
/* */
/* */ protected boolean hasTargetObject()
/* */ {
/* 164 */ return false;
/* */ }
/* */
/* */ protected void overrideDispatchMethods(CtClass superClass, CtClass clazz, JoinPointInfo newInfo) throws CannotCompileException, NotFoundException
/* */ {
/* 169 */ super.overrideDispatchMethods(superClass, clazz, (ConByMethodInfo)newInfo);
/* */ }
/* */
/* */ protected static CtClass createJoinpointBaseClass(GeneratedAdvisorInstrumentor instrumentor, long callingHash, boolean hasCallingObject, CtClass callingClass, CtConstructor targetCtor, String classname, long calledHash, String ciname)
/* */ throws NotFoundException, CannotCompileException
/* */ {
/* 182 */ BaseClassGenerator generator = new BaseClassGenerator(instrumentor, callingClass, callingHash, hasCallingObject, classname, targetCtor, calledHash, ciname);
/* 183 */ return generator.generate();
/* */ }
/* */
/* */ protected static String getGeneratedJoinPointClassName(long callingHash, String classname, long calledHash)
/* */ {
/* 188 */ return "JoinPoint_CByM_" + CallerTransformer.getUniqueInvocationFieldname(callingHash, classname, calledHash);
/* */ }
/* */
/* */ protected static String getGeneratedJoinPointFieldName(long callingHash, String classname, long calledHash)
/* */ {
/* 193 */ return "joinpoint_CByM_" + CallerTransformer.getUniqueInvocationFieldname(callingHash, classname, calledHash);
/* */ }
/* */
/* */ static
/* */ {
/* */ try
/* */ {
/* 62 */ INVOCATION_CT_TYPE = ReflectToJavassist.classToJavassist(INVOCATION_TYPE);
/* */ }
/* */ catch (NotFoundException e)
/* */ {
/* 66 */ throw new RuntimeException(e);
/* */ }
/* */ }
/* */
/* */ private static class BaseClassGenerator
/* */ {
/* */ GeneratedAdvisorInstrumentor instrumentor;
/* */ CtClass callingClass;
/* */ long callingHash;
/* */ boolean hasCallingObject;
/* */ String classname;
/* */ CtClass targetClass;
/* */ CtConstructor targetCtor;
/* */ long calledHash;
/* */ String ciname;
/* */ CtClass jp;
/* */ CtClass[] params;
/* */ CtClass constructorInfoClass;
/* */
/* */ BaseClassGenerator(GeneratedAdvisorInstrumentor instrumentor, CtClass callingClass, long callingHash, boolean hasCallingObject, String classname, CtConstructor targetCtor, long calledHash, String ciname)
/* */ throws NotFoundException
/* */ {
/* 222 */ this.instrumentor = instrumentor;
/* 223 */ this.callingClass = callingClass;
/* 224 */ this.callingHash = callingHash;
/* 225 */ this.hasCallingObject = hasCallingObject;
/* 226 */ this.classname = classname;
/* 227 */ this.targetClass = instrumentor.forName(classname);
/* 228 */ this.targetCtor = targetCtor;
/* 229 */ this.calledHash = calledHash;
/* 230 */ this.ciname = ciname;
/* 231 */ this.params = targetCtor.getParameterTypes();
/* 232 */ this.constructorInfoClass = instrumentor.forName(CallerTransformer.CON_BY_METHOD_INFO_CLASS_NAME);
/* */ }
/* */
/* */ protected CtClass generate() throws CannotCompileException, NotFoundException
/* */ {
/* 237 */ this.jp = setupClass();
/* 238 */ OptimizedBehaviourInvocations.addArgumentFieldsAndAccessors(this.instrumentor.getClassPool(), this.jp, this.params, false);
/* */
/* 240 */ addTypedCallingField();
/* 241 */ addInvokeJoinpointMethod();
/* 242 */ addMethodInfoField();
/* 243 */ addPublicConstructor();
/* 244 */ addProtectedConstructors();
/* 245 */ addDispatchMethods();
/* */
/* 247 */ TransformerCommon.compileOrLoadClass(this.callingClass, this.jp);
/* 248 */ return this.jp;
/* */ }
/* */
/* */ private CtClass setupClass()
/* */ throws NotFoundException, CannotCompileException
/* */ {
/* 254 */ String className = ConByMethodJoinPointGenerator.getGeneratedJoinPointClassName(this.callingHash, this.targetClass.getName(), this.calledHash);
/* */
/* 257 */ this.jp = TransformerCommon.makeNestedClass(this.callingClass, className, true, 9, ConByMethodJoinPointGenerator.INVOCATION_CT_TYPE);
/* 258 */ JoinPointGenerator.addUntransformableInterface(this.instrumentor, this.jp);
/* 259 */ return this.jp;
/* */ }
/* */
/* */ private void addTypedCallingField() throws CannotCompileException
/* */ {
/* 264 */ CtField callingField = new CtField(this.callingClass, "typedCallingObject", this.jp);
/* 265 */ this.jp.addField(callingField);
/* 266 */ callingField.setModifiers(4);
/* */ }
/* */
/* */ private void addPublicConstructor()
/* */ throws CannotCompileException
/* */ {
/* 276 */ CtConstructor publicConstructor = CtNewConstructor.make(new CtClass[] { this.constructorInfoClass }, new CtClass[0], "{super($1, null, $1.getInterceptors()); this.info = $1;}", this.jp);
/* */
/* 282 */ this.jp.addConstructor(publicConstructor);
/* */ }
/* */
/* */ protected void addProtectedConstructors()
/* */ throws CannotCompileException
/* */ {
/* 291 */ int offset = this.hasCallingObject ? 2 : 1;
/* 292 */ CtClass[] ctorParams1 = new CtClass[this.params.length + offset];
/* 293 */ CtClass[] ctorParams2 = new CtClass[offset];
/* */ CtClass tmp37_34 = this.jp; ctorParams2[0] = tmp37_34; ctorParams1[0] = tmp37_34;
/* 295 */ if (this.hasCallingObject)
/* */ {
/* */ CtClass tmp55_52 = this.callingClass; ctorParams2[1] = tmp55_52; ctorParams1[1] = tmp55_52;
/* */ }
/* 299 */ System.arraycopy(this.params, 0, ctorParams1, offset, this.params.length);
/* */
/* 301 */ StringBuffer body = new StringBuffer();
/* 302 */ body.append("{");
/* 303 */ body.append(" this($1.info);");
/* */
/* 305 */ if (this.hasCallingObject)
/* */ {
/* 307 */ body.append(" super.").append("callingObject");
/* 308 */ body.append("=$").append(offset).append(';');
/* 309 */ body.append(" this.").append("typedCallingObject");
/* 310 */ body.append("=$").append(offset).append(';');
/* */ }
/* */
/* 313 */ StringBuffer setArguments = new StringBuffer();
/* 314 */ for (int i = offset; i < ctorParams1.length; i++)
/* */ {
/* 316 */ setArguments.append(" arg" + (i - offset) + " = $" + (i + 1) + ";");
/* */ }
/* 318 */ setArguments.append("}");
/* */
/* 320 */ CtConstructor protectedConstructor = CtNewConstructor.make(ctorParams1, new CtClass[0], body.toString() + setArguments.toString(), this.jp);
/* */
/* 325 */ protectedConstructor.setModifiers(4);
/* 326 */ this.jp.addConstructor(protectedConstructor);
/* 327 */ if (this.params.length > 0)
/* */ {
/* 329 */ protectedConstructor = CtNewConstructor.make(ctorParams2, new CtClass[0], body.toString() + "}", this.jp);
/* */
/* 334 */ protectedConstructor.setModifiers(4);
/* 335 */ this.jp.addConstructor(protectedConstructor);
/* */ }
/* */ }
/* */
/* */ private CtClass[] getInvokeJoinPointParams()
/* */ {
/* 341 */ if (this.hasCallingObject)
/* */ {
/* 343 */ CtClass[] invokeParams = null;
/* 344 */ invokeParams = new CtClass[this.params.length + 1];
/* 345 */ invokeParams[0] = this.callingClass;
/* 346 */ System.arraycopy(this.params, 0, invokeParams, 1, this.params.length);
/* 347 */ return invokeParams;
/* */ }
/* 349 */ return this.params;
/* */ }
/* */
/* */ private CtMethod addInvokeJoinpointMethod()
/* */ throws CannotCompileException, NotFoundException
/* */ {
/* 358 */ CtMethod invokeJoinpointMethod = CtNewMethod.make(this.targetClass, "invokeJoinpoint", getInvokeJoinPointParams(), JoinPointGenerator.THROWS_THROWABLE, null, this.jp);
/* */
/* 365 */ invokeJoinpointMethod.setModifiers(4);
/* 366 */ this.jp.addMethod(invokeJoinpointMethod);
/* 367 */ return invokeJoinpointMethod;
/* */ }
/* */
/* */ private void addMethodInfoField() throws CannotCompileException
/* */ {
/* 372 */ CtField infoField = new CtField(this.constructorInfoClass, "info", this.jp);
/* 373 */ infoField.setModifiers(4);
/* 374 */ this.jp.addField(infoField);
/* */ }
/* */
/* */ private void addDispatchMethods() throws CannotCompileException, NotFoundException
/* */ {
/* 379 */ OptimizedConstructorInvocations.addDispatch(this.jp, "dispatch", this.targetCtor);
/* 380 */ if ((this.hasCallingObject) || (this.params.length > 0))
/* */ {
/* 382 */ addInvokeJoinPointDispatchMethod();
/* */ }
/* */
/* 385 */ addInvokeTargetMethod();
/* */ }
/* */
/* */ private void addInvokeJoinPointDispatchMethod()
/* */ throws CannotCompileException, NotFoundException
/* */ {
/* 392 */ int offset = this.hasCallingObject ? 1 : 0;
/* 393 */ StringBuffer parameters = new StringBuffer("(");
/* 394 */ for (int i = 0; i < this.params.length; i++)
/* */ {
/* 396 */ if (i > 0) parameters.append(", ");
/* 397 */ parameters.append("$" + (i + offset + 1));
/* */ }
/* 399 */ parameters.append(")");
/* */
/* 401 */ String body = "{ " + this.targetClass.getName() + " obj = new " + this.targetClass.getName() + parameters + ";" + " setTargetObject(obj);" + " return obj;" + "}";
/* */
/* 408 */ CtClass[] params = getInvokeJoinPointParams();
/* */ try
/* */ {
/* 411 */ CtMethod dispatch = CtNewMethod.make(this.targetClass, "dispatch", params, this.targetCtor.getExceptionTypes(), body, this.jp);
/* */
/* 418 */ dispatch.setModifiers(4);
/* 419 */ this.jp.addMethod(dispatch);
/* */ }
/* */ catch (CannotCompileException e)
/* */ {
/* 423 */ throw new RuntimeException("Could not compile code " + body + " for method " + JoinPointGenerator.getMethodString(this.jp, "dispatch", params), e);
/* */ }
/* */ }
/* */
/* */ private void addInvokeTargetMethod() throws CannotCompileException, NotFoundException
/* */ {
/* 429 */ CtMethod template = ConByMethodJoinPointGenerator.INVOCATION_CT_TYPE.getDeclaredMethod("invokeTarget");
/* */
/* 431 */ String body = "{return dispatch();}";
/* */
/* 433 */ CtMethod invokeTarget = CtNewMethod.make(template.getReturnType(), template.getName(), template.getParameterTypes(), template.getExceptionTypes(), body, this.jp);
/* */
/* 440 */ this.jp.addMethod(invokeTarget);
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.aop.instrument.ConByMethodJoinPointGenerator
* JD-Core Version: 0.6.0
*/