}
ctClass.instrument(
new ExprEditor() {
public void edit(MethodCall methodCall) throws CannotCompileException {
try {
CtBehavior where;
try {
where = methodCall.where();
} catch (RuntimeException e) {
// <clinit> access leads to a bug in Javassist
where = ctClass.getClassInitializer();
}
// filter caller methods
if (methodFilterCaller(where)) {
return;
}
// get the callee method name, signature and class name
CtMethod calleeMethod = methodCall.getMethod();
String calleeClassName = methodCall.getClassName();
// filter callee classes
if (!definition.inIncludePackage(calleeClassName)) {
return;
}
// filter callee methods
if (methodFilterCallee(calleeMethod)) {
return;
}
JavassistClassInfoRepository classInfoRepository = JavassistClassInfoRepository
.getRepository(context.getLoader());
// TODO: callee side class info is NOT used, make use of it
ClassInfo calleeSideClassInfo = classInfoRepository.getClassInfo(calleeClassName);
if (calleeSideClassInfo == null) {
calleeSideClassInfo = JavassistClassInfo.getClassInfo(
ctClass.getClassPool().get(calleeClassName),
context.getLoader()
);
}
// create the caller method info, used for 'within' and 'withincode'
MemberInfo withinMemberInfo = null;
if (where instanceof CtMethod) {
withinMemberInfo = JavassistMethodInfo.getMethodInfo(
(CtMethod)where,
context.getLoader()
);
} else if (where instanceof CtConstructor) {
withinMemberInfo =
JavassistConstructorInfo.getConstructorInfo(
(CtConstructor)where,
context.getLoader()
);
}
// create the callee method info
MethodInfo calleeSideMethodInfo = JavassistMethodInfo.getMethodInfo(
methodCall.getMethod(),
context.getLoader()
);
ExpressionContext ctx = new ExpressionContext(
PointcutType.CALL, calleeSideMethodInfo,
withinMemberInfo
);
if (definition.hasPointcut(ctx) || definition.hasCflowPointcut(ctx)) {
// check the callee class is not the same as target class, if that is the case
// then we have have class loaded and set in the ___AW_clazz already
String declaringClassMethodName = TransformationUtil.STATIC_CLASS_FIELD;
CtMethod method = methodCall.getMethod();
CtClass declaringClass = method.getDeclaringClass();
if (!declaringClass.getName().replace('/', '.').equals(
where.getDeclaringClass()
.getName()
.replace('/', '.')
)) {
declaringClassMethodName = addCalleeMethodDeclaringClassField(ctClass, method);
}
// call the wrapper method instead of the callee method
StringBuffer body = new StringBuffer();
StringBuffer callBody = new StringBuffer();
callBody.append(TransformationUtil.JOIN_POINT_MANAGER_FIELD);
callBody.append('.');
callBody.append(TransformationUtil.PROCEED_WITH_CALL_JOIN_POINT_METHOD);
callBody.append('(');
callBody.append(TransformationUtil.calculateHash(method));
callBody.append(',');
callBody.append(klass.getJoinPointIndex());
callBody.append(", args, ");
callBody.append(TransformationUtil.STATIC_CLASS_FIELD);
if (Modifier.isStatic(where.getModifiers())) {
callBody.append(", nullObject, ");
} else {
callBody.append(", this, ");
}
callBody.append("declaringClass, $0, \"");
callBody.append(where.getName());
callBody.append("\",\"");
callBody.append(where.getSignature());
callBody.append("\",");
callBody.append(TransformationUtil.JOIN_POINT_TYPE_METHOD_CALL);
callBody.append(");");
body.append('{');
if (method.getParameterTypes().length > 0) {
body.append("Object[] args = $args; ");
} else {
body.append("Object[] args = null; ");
}
body.append("Class declaringClass = ");
body.append(declaringClassMethodName);
body.append("; ");
if (Modifier.isStatic(where.getModifiers())) {
body.append("Object nullObject = null;");
}
if (methodCall.getMethod().getReturnType() == CtClass.voidType) {
body.append("$_ = ").append(callBody.toString()).append("}");
} else if (!methodCall.getMethod().getReturnType().isPrimitive()) {