/** * Transforms the call side pointcuts. * * @param context the transformation context * @param klass the class set. */ public void transform(final Context context, final Klass klass) throws NotFoundException, CannotCompileException { List definitions = SystemDefinitionContainer.getDefinitionsContext(); m_joinPointIndex = TransformationUtil.getJoinPointIndex(klass.getCtClass()); // TODO thread safe reentrant for (Iterator it = definitions.iterator(); it.hasNext(); ) { final SystemDefinition definition = (SystemDefinition) it.next(); final CtClass ctClass = klass.getCtClass(); final ClassMetaData classMetaData = context.getMetaDataMaker().createClassMetaData(ctClass); // filter caller classes if (classFilter(definition, classMetaData, ctClass)) { continue; } ctClass.instrument( new ExprEditor() { public void edit(MethodCall methodCall) throws CannotCompileException { try { CtBehavior where = null; 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; } // create the class meta-data ClassMetaData calleeSideClassMetaData; try { calleeSideClassMetaData = context .getMetaDataMaker() .createClassMetaData(context.getClassPool().get(calleeClassName)); } catch (NotFoundException e) { // TODO - AV - 20040507 small fix for test.aopc. that use on the fly generated // classes if (calleeClassName.equals(ctClass.getName())) { calleeSideClassMetaData = classMetaData; } else { throw new WrappedRuntimeException(e); } } // create the method meta-data MethodMetaData calleeSideMethodMetaData = JavassistMetaDataMaker.createMethodMetaData(methodCall.getMethod()); // is this a caller side method pointcut? if (definition.isPickedOutByCallPointcut( calleeSideClassMetaData, calleeSideMethodMetaData)) { // // TODO: should this caller data be passed to the // join point? It is possible. // String callerMethodName = callerBehaviour.getName(); // String callerMethodSignature = // callerBehaviour.getSignature(); // CtClass[] callerMethodParameterTypes = // callerBehaviour.getParameterTypes(); // int callerMethodModifiers = // callerBehaviour.getModifiers(); // 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(m_joinPointIndex); callBody.append(", args"); callBody.append(", $0, declaringClassMethodName, "); 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 declaringClassMethodName = "); body.append(declaringClassMethodName); body.append("; "); if (methodCall.getMethod().getReturnType() == CtClass.voidType) { body.append("$_ = ").append(callBody.toString()).append("}"); } else if (!methodCall.getMethod().getReturnType().isPrimitive()) { body.append("$_ = ($r)"); body.append(callBody.toString()); body.append("}"); } else { String localResult = TransformationUtil.ASPECTWERKZ_PREFIX + "res"; body.append("Object ").append(localResult).append(" = "); body.append(callBody.toString()); body.append("if (").append(localResult).append(" != null)"); body.append("$_ = ($r) ").append(localResult).append("; else "); body.append("$_ = "); body.append( JavassistHelper.getDefaultPrimitiveValue( methodCall.getMethod().getReturnType())); body.append("; }"); } methodCall.replace(body.toString()); context.markAsAdvised(); m_joinPointIndex++; } } catch (NotFoundException nfe) { nfe.printStackTrace(); // TODO: should we swallow this exception? } } }); } TransformationUtil.setJoinPointIndex(klass.getCtClass(), m_joinPointIndex); }