All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.uqbar.apo.pointcut.PointCut.scala Maven / Gradle / Ivy

There is a newer version: 3.6.3
Show newest version
package com.uqbar.apo.pointcut

import javassist.CtField
import javassist.CtClass
import javassist.expr.FieldAccess
import javassist.expr.MethodCall
import scala.collection.mutable.Buffer
import javassist.ClassPool
import javassist.CtMethod
import javassist.Modifier
import com.uqbar.apo.parser.APOParser
import javassist.bytecode.Descriptor
import javassist.expr.ConstructorCall

abstract class PointCut {
  def evaluate(ctClass: CtClass): Boolean
  def hasIntercept(any: Any): Boolean
}

case class F[T](fun: (T) => Boolean, op: {def &&(fun: F[T]): F[T]
										  def ||(fun: F[T]): F[T]
										}) extends Function1[T, Boolean] {
  def apply(t: T) = fun(t)
  def &&(fun: F[T]) = op && (fun)
  def ||(fun: F[T]) = op || (fun)
}

case class FClass(fun: (CtClass) => Boolean, op: {def &&(fun: FClass): FClass
										  def ||(fun: FClass): FClass
										}) extends Function1[CtClass, Boolean] {
  def apply(t: CtClass) = fun(t)
  def &&(fun: FClass) = op && (fun)
  def ||(fun: FClass) = op || (fun)
}


trait InterceptMatchPointCut[T] extends PointCut{
  var pointcuts: F[T] = _

  override def hasIntercept(any: Any): Boolean = {
    any match {
      case t: T => if(pointcuts == null) true else pointcuts(t)
      case _ => false;
    }
  }

  def &&(func: F[T]):F[T] = { val p = pointcuts ;pointcuts = F((t: T) => { p(t) && func(t) }, this); pointcuts }
  def ||(func: F[T]):F[T] = { val p = pointcuts; pointcuts = F((t: T) => { p(t) || func(t) }, this); pointcuts }

  def filter(fun: (T) => Boolean) = if(pointcuts == null) {pointcuts = F(fun, this); pointcuts} else F(fun, this)  
}

trait FieldPointCut extends InterceptMatchPointCut[FieldAccess] {
  filter((field) => { !field.isStatic() && !field.where().getMethodInfo().toString().startsWith("$lessinit")})

  def fieldName(fun: (String) => Boolean) = filter(field => fun(field.getFieldName()))
  def field(fun: (FieldAccess) => Boolean) = filter(field => fun(field))
  def fieldType[T: Manifest] = filter(_.getField().getType().getName() == manifest[T].erasure.getName())
  def constructor() = filter(field=> { field.where().getMethodInfo().toString().startsWith("") })
}

trait MethodPointCut extends InterceptMatchPointCut[CtMethod] {
  def methodName(fun: (String) => Boolean) = filter(method => fun(method.getName()))
  def method(fun: (CtMethod) => Boolean) = filter(fun)
  def modifiers(modifiers: Int) = filter(_.getModifiers() == modifiers)
  def arguments(arguments: Class[_]*) = filter(method => {
    Descriptor.toString(method.getSignature()).startsWith(arguments.map(_.getName).mkString("(", ",", ")"))
  })

  def constructor() = filter(method => { method.getMethodInfo().toString().startsWith("") })

}

trait MethodCallPointCut extends InterceptMatchPointCut[MethodCall] {
}

trait ConstructorCallPointCut extends InterceptMatchPointCut[ConstructorCall] {
}


trait MatchPointCut extends PointCut {
  var filters: FClass = _

  def &&(func: FClass):FClass = {val f = filters; filters  = FClass((t: CtClass) => { f(t) && func(t) }, this); filters }
  def ||(func: FClass):FClass = {val f = filters; filters  = FClass((t: CtClass) => { f(t) || func(t) }, this); filters }

  protected def matchs(fun: (CtClass) => Boolean) = if(filters == null) {filters = FClass(fun, this); filters} else FClass(fun, this)

  override def evaluate(ctClass: CtClass) = if(filters!= null) filters(ctClass) else false
}

trait ClassPointCut extends MatchPointCut {
  def className(fun: (String) => Boolean) = matchs((ctClass) => fun(ctClass.getSimpleName()))
  def packageName(fun: (String) => Boolean) = matchs((ctClass) => fun(ctClass.getPackageName()))
  def superClas(className: String) = matchs((ctClass) => isSuperClass(ctClass, className))

  protected def isSuperClass(ctClass: CtClass, className: String): Boolean = {
    val superClass = ctClass.getClassPool().get(className);
    if (superClass != null) {
      ctClass.subtypeOf(superClass);
    } else {
      false
    }
  }
}

trait AnnotationPointCut extends MatchPointCut {
  def hasAnnotation(annotation: String): FClass = matchs((ctClass) => hasAnnotation(ctClass, annotation))

  protected def hasAnnotation(clazz: CtClass, annotation: String): Boolean = {
    !clazz.isAnnotation() && clazz.getAvailableAnnotations().exists(annotationProxy => {
      isImplementsAnnotation(annotationProxy.getClass().getInterfaces(), annotation)
    })
  }

  def isImplementsAnnotation[A](interfaces: Array[Class[_]], annotation: String): Boolean = {
    interfaces.exists(_.getName().equals(annotation))
  }

}
//
//  override def evaluate(ctClass: CtClass) = this.components.foldLeft(false)((c, point) => c || point.evaluate(ctClass))
//}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy