
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