public InjectionNode generateProxy(InjectionNode injectionNode) {
    if (!aopProxiesGenerated.containsKey(injectionNode.getClassName())) {
      InjectionNode proxyInjectionNode = innerGenerateProxyCode(injectionNode);
      aopProxiesGenerated.put(injectionNode.getClassName(), proxyInjectionNode);
    }

    return aopProxiesGenerated.get(injectionNode.getClassName());
  }
 private void logInjectionNodes(InjectionNode injectionNode) {
   StringBuilder builder = new StringBuilder();
   builder.append("Injection Nodes:\n");
   InjectionNodeLogger logger = new InjectionNodeLogger(builder, injectionNode);
   while (logger.containsUnvisitedNodes()) {
     InjectionNode node = logger.next();
     node.log(logger);
     logger.append("\n");
   }
   log.debug(builder.toString());
 }
  private JInvocation buildScopeKey(InjectionNode injectionNode) {
    InjectionSignature signature = injectionNode.getTypeSignature();

    JClass injectionNodeClassRef = generationUtil.ref(injectionNode.getASTType());

    return codeModel
        .ref(ScopeKey.class)
        .staticInvoke(ScopeKey.GET_METHOD)
        .arg(injectionNodeClassRef.dotclass())
        .arg(JExpr.lit(signature.buildScopeKeySignature()));
  }
示例#4
0
  @Override
  public void analyzeType(
      InjectionNode injectionNode, ASTType concreteType, AnalysisContext context) {

    if (injectionNode.getASTType().equals(concreteType)) {
      for (Class<? extends Annotation> scopeType : scopeAspectFactoryRepository.getScopes()) {
        if (concreteType.isAnnotated(scopeType)) {
          ScopeAspectFactory scopeAspectFactory =
              scopeAspectFactoryRepository.getScopeAspectFactory(scopeType);
          injectionNode.addAspect(
              scopeAspectFactory.buildAspect(injectionNode, concreteType, context));
        }
      }
    }
  }
  @Override
  public TypedExpression buildVariable(
      InjectionBuilderContext injectionBuilderContext, InjectionNode injectionNode) {

    TypedExpression providerVar =
        injectionExpressionBuilder.buildVariable(injectionBuilderContext, providerInjectionNode);

    JExpression expression = providerVar.getExpression().invoke(PROVIDER_METHOD);

    return typedExpressionFactory.build(injectionNode.getASTType(), expression);
  }
  @Test
  public void testAnalysis() {
    AnalysisContext analysisContext = simpleAnalysisContextFactory.buildContext();
    analysisContext.getAOPRepository().put(aopAnnotationASTType, methodInterceptorASTType);

    for (ASTMethod astMethod : proxyTargetASTType.getMethods()) {
      proxyAnalyzer.analyzeMethod(
          proxyTargetInjectionNode, proxyTargetASTType, astMethod, analysisContext);
    }

    assertTrue(proxyTargetInjectionNode.containsAspect(AOPProxyAspect.class));
    AOPProxyAspect aspect = proxyTargetInjectionNode.getAspect(AOPProxyAspect.class);
    for (ASTMethod astMethod : proxyTargetASTType.getMethods()) {
      assertTrue(aspect.getMethodInterceptors().containsKey(astMethod));
      Set<InjectionNode> interceptorInjectionNodes = aspect.getMethodInterceptors().get(astMethod);
      for (InjectionNode interceptorInjectionNode : interceptorInjectionNodes) {
        assertEquals(methodInterceptorASTType, interceptorInjectionNode.getASTType());
      }
    }
  }
  @Override
  public void analyzeField(
      InjectionNode injectionNode,
      ASTType concreteType,
      ASTField astField,
      AnalysisContext context) {

    if (astField.isAnnotated(NonConfigurationInstance.class)) {
      NonConfigurationAspect aspect = buildAspect(injectionNode);
      aspect.add(injectionPointFactory.buildInjectionPoint(concreteType, astField, context));

      if (!injectionNode.containsAspect(ASTInjectionAspect.class)) {
        injectionNode.addAspect(ASTInjectionAspect.class, new ASTInjectionAspect());
      }

      injectionNode
          .getAspect(ASTInjectionAspect.class)
          .setAssignmentType(ASTInjectionAspect.InjectionAssignmentType.FIELD);
    }
  }
  private InjectionNode buildProxyInjectionNode(
      InjectionNode injectionNode,
      String proxyClassName,
      ASTInjectionAspect injectionAspect,
      ConstructorInjectionPoint proxyConstructorInjectionPoint) {
    InjectionNode proxyInjectionNode =
        new InjectionNode(new ASTProxyType(injectionNode.getASTType(), proxyClassName));

    proxyInjectionNode.getAspects().putAll(injectionNode.getAspects());

    // alter construction injection
    ASTInjectionAspect proxyInjectionAspect = new ASTInjectionAspect();
    proxyInjectionAspect.addAllFieldInjectionPoints(injectionAspect.getFieldInjectionPoints());
    proxyInjectionAspect.addAllMethodInjectionPoints(injectionAspect.getMethodInjectionPoints());
    // replace proxy constructor because of optional interceptor construction parameters
    proxyInjectionAspect.add(proxyConstructorInjectionPoint);

    proxyInjectionAspect.setAssignmentType(injectionAspect.getAssignmentType());

    proxyInjectionNode.addAspect(proxyInjectionAspect);

    return proxyInjectionNode;
  }
  public TypedExpression buildVariable(
      InjectionBuilderContext injectionBuilderContext, InjectionNode injectionNode) {

    // build provider
    JDefinedClass providerClass = providerGenerator.generateProvider(injectionNode, true);
    JExpression provider = JExpr._new(providerClass).arg(injectionBuilderContext.getScopeVar());

    // build scope call
    // <T> T getScopedObject(Class<T> clazz, Provider<T> provider);
    TypedExpression contextScopeHolderExpression =
        injectionExpressionBuilder.buildVariable(injectionBuilderContext, this.contextScopeHolder);

    JExpression cast =
        invocationHelper.coerceType(ContextScopeHolder.class, contextScopeHolderExpression);
    JExpression scopeVar = cast.invoke(ContextScopeHolder.GET_SCOPE);

    JExpression expression =
        scopeVar.invoke(Scope.GET_SCOPED_OBJECT).arg(buildScopeKey(injectionNode)).arg(provider);

    return typedExpressionFactory.build(injectionNode.getASTType(), expression);
  }
示例#10
0
  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);
  }
示例#11
0
  private void buildMethodInterceptor(
      JDefinedClass definedClass,
      ConstructorInjectionPoint proxyConstructorInjectionPoint,
      JMethod constructor,
      JBlock constructorBody,
      Map<ASTMethod, Map<InjectionNode, JFieldVar>> interceptorFields,
      Map.Entry<ASTMethod, Set<InjectionNode>> methodInterceptorEntry)
      throws ClassNotFoundException {
    ASTMethod method = methodInterceptorEntry.getKey();

    if (method.getAccessModifier().equals(ASTAccessModifier.PRIVATE)) {
      throw new TransfuseAnalysisException("Unable to provide AOP on private methods");
    }

    if (!interceptorFields.containsKey(methodInterceptorEntry.getKey())) {
      interceptorFields.put(
          methodInterceptorEntry.getKey(), new HashMap<InjectionNode, JFieldVar>());
    }
    Map<InjectionNode, JFieldVar> injectionNodeInstanceNameMap =
        interceptorFields.get(methodInterceptorEntry.getKey());

    // setup interceptor fields
    for (InjectionNode interceptorInjectionNode : methodInterceptorEntry.getValue()) {
      String interceptorInstanceName = namer.generateName(interceptorInjectionNode);

      JFieldVar interceptorField =
          definedClass.field(
              JMod.PRIVATE,
              codeModel.ref(interceptorInjectionNode.getClassName()),
              interceptorInstanceName);

      injectionNodeInstanceNameMap.put(interceptorInjectionNode, interceptorField);

      JVar interceptorParam =
          constructor.param(
              codeModel.ref(interceptorInjectionNode.getClassName()),
              namer.generateName(interceptorInjectionNode));

      constructorBody.assign(interceptorField, interceptorParam);

      proxyConstructorInjectionPoint.addInjectionNode(interceptorInjectionNode);
    }

    JType returnType = codeModel.parseType(method.getReturnType().getName());

    JMethod methodDeclaration =
        definedClass.method(
            method.getAccessModifier().getCodeModelJMod(), returnType, method.getName());
    JBlock body = methodDeclaration.body();

    // define method parameter
    Map<ASTParameter, JVar> parameterMap = new HashMap<ASTParameter, JVar>();
    for (ASTParameter parameter : method.getParameters()) {
      parameterMap.put(
          parameter,
          methodDeclaration.param(
              JMod.FINAL,
              codeModel.ref(parameter.getASTType().getName()),
              namer.generateName(parameter.getASTType())));
    }

    // aop interceptor
    Map<InjectionNode, JFieldVar> interceptorNameMap =
        interceptorFields.get(methodInterceptorEntry.getKey());

    JArray paramArray = JExpr.newArray(codeModel.ref(Object.class));

    for (ASTParameter astParameter : method.getParameters()) {
      paramArray.add(parameterMap.get(astParameter));
    }

    JInvocation interceptorInvocation =
        buildInterceptorChain(
                definedClass,
                method,
                parameterMap,
                methodInterceptorEntry.getValue(),
                interceptorNameMap)
            .invoke("invoke");
    interceptorInvocation.arg(paramArray);

    if (method.getReturnType().equals(ASTVoidType.VOID)) {
      body.add(interceptorInvocation);
    } else {
      body._return(JExpr.cast(returnType.boxify(), interceptorInvocation));
    }
  }
示例#12
0
  private boolean isProxyRequired(InjectionNode injectionNode) {
    VirtualProxyAspect proxyAspect = injectionNode.getAspect(VirtualProxyAspect.class);

    return proxyAspect != null && proxyAspect.isProxyRequired();
  }
示例#13
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));
  }
 private NonConfigurationAspect buildAspect(InjectionNode injectionNode) {
   if (!injectionNode.containsAspect(NonConfigurationAspect.class)) {
     injectionNode.addAspect(new NonConfigurationAspect());
   }
   return injectionNode.getAspect(NonConfigurationAspect.class);
 }