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

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

The newest version!
package org.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 org.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 - 2025 Weber Informatics LLC | Privacy Policy