Package org.aspectj.weaver.reflect

Source Code of org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator

/* *******************************************************************
* Copyright (c) 2005 Contributors.
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0
* which accompanies this distribution and is available at
* http://eclipse.org/legal/epl-v10.html
* Contributors:
*   Adrian Colyer      Initial implementation
* ******************************************************************/
package org.aspectj.weaver.reflect;

import java.lang.reflect.Member;

import org.aspectj.util.FuzzyBoolean;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.And;
import org.aspectj.weaver.ast.Call;
import org.aspectj.weaver.ast.FieldGetCall;
import org.aspectj.weaver.ast.HasAnnotation;
import org.aspectj.weaver.ast.ITestVisitor;
import org.aspectj.weaver.ast.Instanceof;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Not;
import org.aspectj.weaver.ast.Or;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.ast.Var;
import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
import org.aspectj.weaver.patterns.ExposedState;
import org.aspectj.weaver.tools.DefaultMatchingContext;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.ShadowMatch;

/**
* @author colyer
* Implementation of ShadowMatch for reflection based worlds.
*/
public class ShadowMatchImpl implements ShadowMatch {

  private FuzzyBoolean match;
  private ExposedState state;
  private Test residualTest;
  private PointcutParameter[] params;
  private Member withinCode;
  private Member subject;
  private Class withinType;
  private MatchingContext matchContext = new DefaultMatchingContext();
 
  public ShadowMatchImpl(FuzzyBoolean match, Test test, ExposedState state, PointcutParameter[] params) {
    this.match = match;
    this.residualTest = test;
    this.state = state;
    this.params = params;
  }
 
  public void setWithinCode(Member aMember) { this.withinCode = aMember; }
  public void setSubject(Member aMember) { this.subject = aMember; }
  public void setWithinType(Class aClass) { this.withinType = aClass; }
   
  public boolean alwaysMatches() {
    return match.alwaysTrue();
  }

  public boolean maybeMatches() {
    return match.maybeTrue();
  }

  public boolean neverMatches() {
    return match.alwaysFalse();
  }

  public JoinPointMatch matchesJoinPoint(Object thisObject, Object targetObject, Object[] args) {
    if (neverMatches()) return JoinPointMatchImpl.NO_MATCH;
    if (new RuntimeTestEvaluator(residualTest,thisObject,targetObject,args,this.matchContext).matches()) {
      return new JoinPointMatchImpl(getPointcutParameters(thisObject,targetObject,args));
    } else {
      return JoinPointMatchImpl.NO_MATCH;
    }
  }
 
  /* (non-Javadoc)
   * @see org.aspectj.weaver.tools.ShadowMatch#setMatchingContext(org.aspectj.weaver.tools.MatchingContext)
   */
  public void setMatchingContext(MatchingContext aMatchContext) {
    this.matchContext = aMatchContext;
  }

  private PointcutParameter[] getPointcutParameters(Object thisObject, Object targetObject, Object[] args) {
    Var[] vars = state.vars;
    PointcutParameterImpl[] bindings = new PointcutParameterImpl[params.length];
    for (int i = 0; i < bindings.length; i++) {
      bindings[i] = new PointcutParameterImpl(params[i].getName(),params[i].getType());
      bindings[i].setBinding(((ReflectionVar)vars[i]).getBindingAtJoinPoint(thisObject, targetObject, args,subject,withinCode,withinType));
    }
    return bindings;
  }

  private static class RuntimeTestEvaluator implements ITestVisitor {

    private boolean matches = true;
    private final Test test;
    private final Object thisObject;
    private final Object targetObject;
    private final Object[] args;
    private final MatchingContext matchContext;
   
   
    public RuntimeTestEvaluator(Test aTest,Object thisObject, Object targetObject, Object[] args, MatchingContext context) {
      this.test = aTest;
      this.thisObject = thisObject;
      this.targetObject = targetObject;
      this.args = args;
      this.matchContext = context;
    }
   
    public boolean matches() {
      test.accept(this);
      return matches;
    }
   
    public void visit(And e) {
      boolean leftMatches =
        new RuntimeTestEvaluator(e.getLeft(),thisObject,targetObject,args,matchContext).matches();
      if (!leftMatches) {
        matches = false;
      } else {
        matches = new RuntimeTestEvaluator(e.getRight(),thisObject,targetObject,args,matchContext).matches();
      }     
    }

    public void visit(Instanceof i) {
      ReflectionVar v = (ReflectionVar) i.getVar();
      Object value = v.getBindingAtJoinPoint(thisObject,targetObject, args);
      World world = v.getType().getWorld();
      ResolvedType desiredType = i.getType().resolve(world);
      ResolvedType actualType = world.resolve(value.getClass().getName());
      matches = desiredType.isAssignableFrom(actualType);
    }
   
    public void visit(MatchingContextBasedTest matchingContextTest) {
      matches = matchingContextTest.matches(this.matchContext);
    }

    public void visit(Not not) {
      matches = ! new RuntimeTestEvaluator(not.getBody(),thisObject,targetObject,args,matchContext).matches();
    }

    public void visit(Or or) {
      boolean leftMatches =
        new RuntimeTestEvaluator(or.getLeft(),thisObject,targetObject,args,matchContext).matches();
      if (leftMatches) {
        matches = true;
      } else {
        matches = new RuntimeTestEvaluator(or.getRight(),thisObject,targetObject,args,matchContext).matches();
      }
    }

    public void visit(Literal literal) {
      if (literal == Literal.FALSE) {
        matches = false;
      } else {
        matches = true;
      }
    }

    public void visit(Call call) {
      throw new UnsupportedOperationException("Can't evaluate call test at runtime");
    }

    public void visit(FieldGetCall fieldGetCall) {
      throw new UnsupportedOperationException("Can't evaluate fieldGetCall test at runtime");     
    }

    public void visit(HasAnnotation hasAnnotation) {
      ReflectionVar v = (ReflectionVar) hasAnnotation.getVar();
      Object value = v.getBindingAtJoinPoint(thisObject,targetObject, args);
      World world = v.getType().getWorld();
      ResolvedType actualVarType = world.resolve(value.getClass().getName());
      ResolvedType requiredAnnotationType = hasAnnotation.getAnnotationType().resolve(world);
      matches = actualVarType.hasAnnotation(requiredAnnotationType);
    }
   
  }

}
TOP

Related Classes of org.aspectj.weaver.reflect.ShadowMatchImpl$RuntimeTestEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.