Exemplo n.º 1
0
  /**
   * 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);
  }
Exemplo n.º 3
0
  /**
   * 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());
    }
  }