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

org.ow2.frascati.tinfi.control.intent.SCAIntentControllerTrait.scala Maven / Gradle / Ivy

The newest version!
/***
 * OW2 FraSCAti Tinfi
 * Copyright (C) 2011-2021 Inria, Univ. Lille
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact: [email protected]
 *
 * Author: Lionel Seinturier
 */

package org.ow2.frascati.tinfi.control.intent

import java.lang.annotation.Annotation
import java.lang.reflect.Method
import scala.collection.mutable.HashMap
import org.objectweb.fractal.api.Component
import org.objectweb.fractal.api.Interface
import org.objectweb.fractal.api.`type`.InterfaceType
import org.objectweb.fractal.julia.BasicControllerTrait
import org.objectweb.fractal.julia.ComponentInterface
import org.objectweb.fractal.julia.InitializationContext
import org.objectweb.fractal.julia.UseComponentTrait
import org.objectweb.fractal.juliac.runtime.ClassLoaderFcItf
import org.objectweb.fractal.juliac.runtime.ClassLoaderItf
import org.objectweb.fractal.juliac.runtime.Juliac
import org.ow2.frascati.tinfi.TinfiComponentInterceptor
import org.ow2.frascati.tinfi.TinfiRuntimeException
import org.ow2.frascati.tinfi.api.IntentHandler
import org.objectweb.fractal.juliac.commons.lang.reflect.AnnotatedElementFilter
import org.objectweb.fractal.juliac.commons.util.function.Filters
import org.objectweb.fractal.juliac.commons.lang.ClassHelper

/**
 * Trait implementing the {@link SCAIntentController} interface for scaPrimitive
 * components.
 *
 * @author Lionel Seinturier 
 * @since 1.4.5
 */
trait SCAIntentControllerTrait extends BasicControllerTrait
with UseComponentTrait
with org.ow2.frascati.tinfi.api.control.SCAIntentControllerTrait {

	private var cl: Class[_] = null

	override def initFcController( ic: InitializationContext ) = {
		cl = ic.content.asInstanceOf[Class[_]]
		super.initFcController(ic)
	}

	/**
	 * 

* Add the specified intent handler on all service methods of the current * component which satisfy the following conditions: *

* *
    *
  • the implementation method in the component class is associated with * an annotation of the specified class,
  • *
  • the annotation provides a String[] value() method,
  • *
  • one of the returned strings when calling value()is equal * to the specified value.
  • *
* * @param handler the intent handler to add * @param annotcl the searched for annotation class * @param value the searched for parameter value */ override def addFcIntentHandler[T <: Annotation]( handler: IntentHandler, annotcl: Class[T], value: String ) = { val methods = getFcMatchingMethods(annotcl,value) methods.foreach( method => { val tci = getFcInterceptor(method) val m = getFcItfMethod(method) tci.addIntentHandler(handler,m) }) } // ------------------------------------------------------------------------- // Implementation specific // ------------------------------------------------------------------------- /** *

* Return the list of methods implemented by the component class which * satisfy the following conditions: *

* *
    *
  • the method is associated with an annotation of the specified class,
  • *
  • the annotation provides a String[] value() method,
  • *
  • one of the returned strings when calling value() is * equal to the specified value.
  • *
*/ private def getFcMatchingMethods[T <: Annotation]( annotcl: Class[T], value: String ) : List[Method] = { var ret = List[Method]() // Retrieve all methods annotated with annotcl val methods = ClassHelper.getAllMethods(cl) val filter = new AnnotatedElementFilter(annotcl.getName) val ms = Filters.filter(methods,filter) ms.foreach( method => { // Retrieve the corresponding annotation val annot = method.getAnnotation(annotcl) // Check whether the annotation provides a value() method if( annot != null ) { try { val cl = annot.getClass val mvalue = cl.getMethod("value") val values = mvalue.invoke(annot).asInstanceOf[Array[String]] values.foreach( v => { if( v.equals(value) ) { ret = method :: ret } }) } catch { case e: NoSuchMethodException => // No such method value() } } }) return ret } /** * Return the interceptor for the specified component method. */ private def getFcInterceptor( method: Method ) : TinfiComponentInterceptor[_] = { if( mtcis == null ) { initFcMaps } if( ! mtcis.contains(method) ) { // Shouldn't occur val msg = "No interceptor for component method: "+method.toString throw new TinfiRuntimeException(msg) } val tci = mtcis(method) return tci } /** * Return the interface method for the specified component method. */ private def getFcItfMethod( method: Method ) : Method = { if( mms == null ) { initFcMaps } if( ! mms.contains(method) ) { // Shouldn't occur val msg = "No interface method for component method: "+method.toString() throw new TinfiRuntimeException(msg) } val m = mms(method) return m } private var mtcis: HashMap[Method,TinfiComponentInterceptor[_]] = null private var mms: HashMap[Method,Method] = null /** * Initialize the {@link #mtcis} and {@link #mms} maps. */ private def initFcMaps = { mtcis = new HashMap[Method,TinfiComponentInterceptor[_]] mms = new HashMap[Method,Method] // Retrieve all public methods of the component class val methods = cl.getMethods // Iterate on all business interfaces of the component. val itfs = weaveableC.getFcInterfaces itfs.foreach( o => { val itf = o.asInstanceOf[Interface] val name = itf.getFcItfName // Skip control interfaces if( !name.endsWith("-controller") && !name.equals("component") ) { // Retrieve the corresponding interceptor val i = itf.asInstanceOf[ComponentInterface].getFcItfImpl val tci = i.asInstanceOf[TinfiComponentInterceptor[_]] // Retrieve the interface methods val it = itf.getFcItfType().asInstanceOf[InterfaceType] val signature = it.getFcItfSignature val business = loadFcClass(signature) val ms = business.getMethods // Check if some component methods match the interface methods methods.foreach( method => { ms.foreach( m => { if( areSame(m,method) ) { mtcis += method -> tci mms += method -> m } }) }) } }) } /** * Load, with the Juliac classloader, the class whose name is specified. */ private def loadFcClass( name: String ) : Class[_] = { val boot = new Juliac().newFcInstance val loader = boot.getFcInterface(ClassLoaderFcItf.NAME).asInstanceOf[ClassLoaderItf] val cl = loader.loadClass(name) return cl } /** * Return true if the specified methods are the same: same name * and same parameters. */ private def areSame( m1: Method, m2: Method ) : Boolean = { val name1 = m1.getName val name2 = m2.getName if( ! name1.equals(name2) ) { return false } val ptypes1 = m1.getParameterTypes val ptypes2 = m2.getParameterTypes if( ptypes1.length != ptypes2.length ) { return false } for( i <- 0 until ptypes1.length ) { val ptype1 = ptypes1(i) val ptype2 = ptypes2(i) if( ! ptype1.equals(ptype2) ) { return false } } return true } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy