DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Rodolfo has posted 3 posts at DZone. View Full User Profile

An Excerpt From "Managing Cross-Cutting Concerns Using Mixin Composition And AOP" From Jonas Boner

12.11.2008
| 1928 views |
  • submit to reddit
        // A little scala script with the AOP part of his post at

// http://java.dzone.com/articles/real-world-scala-managing-cros

// 1 - add aspectjweaver.jar to your classpath 
// 2 - paste this code to jbtest2.scala 
// 3 - scalac -target:jvm-1.5 -d classes jbtest2.scala
// 4 - scala -classpath classes;%classpath% jbtest2
// 5 - have some fun ! Thanks Jonas 


// jbtest2.scala
import org.aspectj.weaver.tools.PointcutParser 
import org.aspectj.weaver.tools.PointcutExpression
import java.lang.annotation.Annotation
import java.lang.reflect.InvocationHandler 
import java.lang.reflect.Proxy
import java.lang.reflect.Method

object jbtest2 {

  def main(args: Array[String]) = {

    println("hello ") 

    var foo = ManagedComponentFactory.createComponent[Foo](
        classOf[Foo],
	new ManagedComponentProxy(new FooImpl) with LoggingInterceptor with TransactionInterceptor)

    foo.foo("foo")
    foo.bar("bar")

    println("bye ") 
  
 } 

}

case class Invocation(val method: Method, val args: Array[AnyRef], val target: AnyRef) {
  def invoke: AnyRef = method.invoke(target, args:_*)
  override def toString: String = "Invocation [method: " + method.getName + ", args: " + args + ", target: " + target + "]"
  override def hashCode(): Int = { 3 }
  override def equals(that: Any): Boolean = { true }
}

trait Interceptor {
  protected val parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution()
  protected def matches(pointcut: PointcutExpression, invocation: Invocation): Boolean = {
    pointcut.matchesMethodExecution(invocation.method).alwaysMatches ||
    invocation.target.getClass.getDeclaredMethods.exists(pointcut.matchesMethodExecution(_).alwaysMatches) ||
    false
  }
  protected def matches(annotationClass: Class[T] forSome {type T <: Annotation}, invocation: Invocation): Boolean = {
    invocation.method.isAnnotationPresent(annotationClass) ||
    invocation.target.getClass.isAnnotationPresent(annotationClass) ||
    false
  }
  def invoke(invocation: Invocation): AnyRef
}

object ManagedComponentFactory {
  def createComponent[T](intf: Class[T] forSome {type T}, proxy: ManagedComponentProxy): T =
    Proxy.newProxyInstance(
      proxy.target.getClass.getClassLoader,
      Array(intf),
      proxy).asInstanceOf[T]
}

class ManagedComponentProxy(val target: AnyRef) extends InvocationHandler {
  def invoke(proxy: AnyRef, m: Method, args: Array[AnyRef]): AnyRef = invoke(Invocation(m, args, target))
  def invoke(invocation: Invocation): AnyRef = invocation.invoke
}

trait Foo {
    @Deprecated 
    def foo(msg: String)
    def bar(msg: String)
  }

class FooImpl extends Foo {
    val bar: Bar = new BarImpl
    def foo(msg: String) = println("msg: " + msg)
    def bar(msg: String) = bar.bar(msg)
}

trait Bar {
    def bar(msg: String)
}

class BarImpl extends Bar {
    def bar(msg: String) = println("msg: " + msg)
}

trait LoggingInterceptor extends Interceptor {

    val loggingPointcut = parser.parsePointcutExpression("execution(* *.foo(..))")

    abstract override def invoke(invocation: Invocation): AnyRef =
      if (matches(loggingPointcut , invocation)) {
        println("=====> Enter: " + invocation.method.getName + " @ " + invocation.target.getClass.getName)
        val result = super.invoke(invocation)
        println("=====> Exit: " + invocation.method.getName + " @ " + invocation.target.getClass.getName)
        result
      } else super.invoke(invocation)
}

trait TransactionInterceptor extends Interceptor {

    // using Deprecated annotation instead of javax.ejb.TransactionAttribute just to have less jars to set up   
    val matchingDeprecatedAnnotation = classOf[java.lang.Deprecated]

    abstract override def invoke(invocation: Invocation): AnyRef =
      if (matches(matchingDeprecatedAnnotation, invocation)) {
        println("=====> interceptor begin")
        try {
          // val result = super.doStuff 
		  val result = super.invoke(invocation)
          println("=====> interceptor commit")
          result
        } catch {
          case e: Exception =>
            println("=====> interceptor rollback since we got an exception")
        }
      } else super.invoke(invocation)
}