/** * Looks up the aspect class name, based on the qualified name of the aspect. * * @param loader * @param qualifiedName * @return */ private static String lookupAspectClassName( final ClassLoader loader, final String qualifiedName) { if (qualifiedName.indexOf('/') <= 0) { // no uuid return null; } final Set definitionsBottomUp = SystemDefinitionContainer.getRegularAndVirtualDefinitionsFor(loader); // TODO: bottom up is broken now // Collections.reverse(definitionsBottomUp); for (Iterator iterator = definitionsBottomUp.iterator(); iterator.hasNext(); ) { SystemDefinition definition = (SystemDefinition) iterator.next(); for (Iterator iterator1 = definition.getAspectDefinitions().iterator(); iterator1.hasNext(); ) { AspectDefinition aspectDefinition = (AspectDefinition) iterator1.next(); if (qualifiedName.equals(aspectDefinition.getQualifiedName())) { return aspectDefinition.getClassName(); } } } return null; }
/** * 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); }
/** * Creates a new aspect container. * * @param aspectClass the aspect class */ private static AspectContainer createAspectContainer(final Class aspectClass) { AspectDefinition aspectDefinition = null; Set definitions = SystemDefinitionContainer.getRegularAndVirtualDefinitionsFor(aspectClass.getClassLoader()); for (Iterator iterator = definitions.iterator(); iterator.hasNext() && aspectDefinition == null; ) { SystemDefinition systemDefinition = (SystemDefinition) iterator.next(); for (Iterator iterator1 = systemDefinition.getAspectDefinitions().iterator(); iterator1.hasNext(); ) { AspectDefinition aspectDef = (AspectDefinition) iterator1.next(); if (aspectClass.getName().replace('/', '.').equals(aspectDef.getClassName())) { aspectDefinition = aspectDef; break; } } } if (aspectDefinition == null) { throw new Error("Could not find AspectDefinition for " + aspectClass.getName()); } String containerClassName = aspectDefinition.getContainerClassName(); try { Class containerClass; if (containerClassName == null || aspectClass.getName().equals(CFlowSystemAspect.CLASS_NAME)) { containerClass = ContextClassLoader.loadClass(aspectClass.getClassLoader(), DEFAULT_ASPECT_CONTAINER); } else { containerClass = ContextClassLoader.loadClass(aspectClass.getClassLoader(), containerClassName); } Constructor constructor = containerClass.getConstructor(new Class[] {AspectContext.class}); final AspectContext aspectContext = new AspectContext( aspectDefinition.getSystemDefinition().getUuid(), aspectClass, aspectDefinition.getName(), DeploymentModel.getDeploymentModelAsInt(aspectDefinition.getDeploymentModel()), aspectDefinition, aspectDefinition.getParameters()); final AspectContainer container = (AspectContainer) constructor.newInstance(new Object[] {aspectContext}); aspectContext.setContainer(container); return container; } catch (InvocationTargetException e) { throw new DefinitionException(e.getTargetException().toString()); } catch (NoSuchMethodException e) { throw new DefinitionException( "aspect container does not have a valid constructor [" + containerClassName + "] need to take an AspectContext instance as its only parameter: " + e.toString()); } catch (Throwable e) { StringBuffer cause = new StringBuffer(); cause.append("could not create aspect container using the implementation specified ["); cause.append(containerClassName); cause.append("] due to: "); cause.append(e.toString()); e.printStackTrace(); throw new DefinitionException(cause.toString()); } }