private InjectionNode innerGenerateProxyCode(InjectionNode injectionNode) {
    AOPProxyAspect aopProxyAspect = injectionNode.getAspect(AOPProxyAspect.class);
    JDefinedClass definedClass;
    String proxyClassName = injectionNode.getClassName() + "_AOPProxy";
    ASTInjectionAspect injectionAspect = injectionNode.getAspect(ASTInjectionAspect.class);
    ConstructorInjectionPoint constructorInjectionPoint =
        injectionAspect.getConstructorInjectionPoint();
    ConstructorInjectionPoint proxyConstructorInjectionPoint =
        new ConstructorInjectionPoint(ASTAccessModifier.PUBLIC);

    try {

      definedClass = codeModel._class(JMod.PUBLIC, proxyClassName, ClassType.CLASS);

      annotateGeneratedClass(definedClass);

      // extending injectionNode
      definedClass._extends(codeModel.ref(injectionNode.getClassName()));

      // copy constructor elements and add aop interceptors
      JMethod constructor = definedClass.constructor(JMod.PUBLIC);

      // converting exceptions into runtime exceptions
      proxyConstructorInjectionPoint.addThrows(constructorInjectionPoint.getThrowsTypes());
      for (ASTType throwType : constructorInjectionPoint.getThrowsTypes()) {
        constructor._throws(codeModel.ref(throwType.getName()));
      }

      JBlock constructorBody = constructor.body();

      List<JVar> superArguments = new ArrayList<JVar>();
      for (InjectionNode node : constructorInjectionPoint.getInjectionNodes()) {
        String paramName = namer.generateName(node);
        JVar param = constructor.param(codeModel.ref(node.getClassName()), paramName);
        superArguments.add(param);
        proxyConstructorInjectionPoint.addInjectionNode(node);
      }

      // super construction
      JInvocation constructorInvocation = constructorBody.invoke(SUPER_REF);
      for (JVar paramArgument : superArguments) {
        constructorInvocation.arg(paramArgument);
      }

      // method interceptors
      Map<ASTMethod, Map<InjectionNode, JFieldVar>> interceptorFields =
          new HashMap<ASTMethod, Map<InjectionNode, JFieldVar>>();
      for (Map.Entry<ASTMethod, Set<InjectionNode>> methodInterceptorEntry :
          aopProxyAspect.getMethodInterceptors().entrySet()) {

        buildMethodInterceptor(
            definedClass,
            proxyConstructorInjectionPoint,
            constructor,
            constructorBody,
            interceptorFields,
            methodInterceptorEntry);
      }

    } catch (JClassAlreadyExistsException e) {
      logger.error("JClassAlreadyExistsException while building AOP Proxy", e);
    } catch (ClassNotFoundException e) {
      logger.error("ClassNotFoundException while building AOP Proxy", e);
    }

    return buildProxyInjectionNode(
        injectionNode, proxyClassName, injectionAspect, proxyConstructorInjectionPoint);
  }
示例#2
0
  @Test
  public void testBackLinkAnalysis() {
    ASTType astType = astClassFactory.getType(A.class);

    InjectionNode injectionNode = analyzer.analyze(astType, astType, analysisContext);
    injectionNode.addAspect(VariableBuilder.class, variableInjectionBuilderProvider.get());

    // A -> B && A -> E
    assertEquals(1, countMethodInjectionPoints(injectionNode.getAspect(ASTInjectionAspect.class)));
    MethodInjectionPoint bInjectionPoint =
        injectionNode
            .getAspect(ASTInjectionAspect.class)
            .getGroups()
            .get(1)
            .getMethodInjectionPoints()
            .iterator()
            .next();

    assertEquals(2, bInjectionPoint.getInjectionNodes().size());
    // A -> B
    InjectionNode bInjectionNode = bInjectionPoint.getInjectionNodes().get(0);
    assertTrue(isProxyRequired(bInjectionNode));
    assertEquals(BImpl.class.getCanonicalName(), bInjectionNode.getClassName());

    // A -> E
    InjectionNode eInjectionNode = bInjectionPoint.getInjectionNodes().get(1);
    assertFalse(isProxyRequired(eInjectionNode));
    assertEquals(E.class.getCanonicalName(), eInjectionNode.getClassName());

    // B -> C
    assertEquals(1, countFieldInjectionPoints(bInjectionNode.getAspect(ASTInjectionAspect.class)));
    FieldInjectionPoint cInjectionPoint =
        bInjectionNode
            .getAspect(ASTInjectionAspect.class)
            .getGroups()
            .get(1)
            .getFieldInjectionPoints()
            .iterator()
            .next();
    InjectionNode cInjectionNode = cInjectionPoint.getInjectionNode();
    assertFalse(isProxyRequired(cInjectionNode));
    assertEquals(C.class.getCanonicalName(), cInjectionNode.getClassName());

    // B -> F
    ConstructorInjectionPoint fNonBackLinkInjectionPoint =
        bInjectionNode.getAspect(ASTInjectionAspect.class).getConstructorInjectionPoint();
    assertEquals(1, fNonBackLinkInjectionPoint.getInjectionNodes().size());
    InjectionNode fInjectionNode = fNonBackLinkInjectionPoint.getInjectionNodes().get(0);
    assertFalse(isProxyRequired(fInjectionNode));
    assertEquals(F.class.getCanonicalName(), fInjectionNode.getClassName());

    // E -> F
    ConstructorInjectionPoint fNonBackLinkInjectionPoint2 =
        eInjectionNode.getAspect(ASTInjectionAspect.class).getConstructorInjectionPoint();
    assertEquals(1, fNonBackLinkInjectionPoint2.getInjectionNodes().size());
    InjectionNode fInjectionNode2 = fNonBackLinkInjectionPoint2.getInjectionNodes().get(0);
    assertFalse(isProxyRequired(fInjectionNode2));

    // C -> D
    assertEquals(1, countFieldInjectionPoints(cInjectionNode.getAspect(ASTInjectionAspect.class)));
    FieldInjectionPoint dInjectionPoint =
        cInjectionNode
            .getAspect(ASTInjectionAspect.class)
            .getGroups()
            .get(1)
            .getFieldInjectionPoints()
            .iterator()
            .next();
    InjectionNode dInjectionNode = dInjectionPoint.getInjectionNode();
    assertFalse(isProxyRequired(dInjectionNode));
    assertEquals(D.class.getCanonicalName(), dInjectionNode.getClassName());

    // D -> B back link
    ConstructorInjectionPoint bBackLinkInjectionPoint =
        dInjectionNode.getAspect(ASTInjectionAspect.class).getConstructorInjectionPoint();
    assertEquals(1, bBackLinkInjectionPoint.getInjectionNodes().size());
    InjectionNode bBackLinkInjectionNode = bBackLinkInjectionPoint.getInjectionNodes().get(0);
    assertEquals(BImpl.class.getCanonicalName(), bBackLinkInjectionNode.getClassName());
    assertTrue(isProxyRequired(bBackLinkInjectionNode));

    // B -> F and E -> F difference
    assertNotSame(fInjectionNode, fInjectionNode2);
    assertFalse(fInjectionNode.equals(fInjectionNode2));
  }