org.ow2.frascati.tinfi.control.intent.SCABasicIntentControllerTrait.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.reflect.Method
import org.objectweb.fractal.api.Component
import org.objectweb.fractal.api.Interface
import org.objectweb.fractal.api.NoSuchInterfaceException
import org.objectweb.fractal.julia.BasicControllerTrait
import org.objectweb.fractal.julia.ComponentInterface
import org.objectweb.fractal.julia.UseComponentTrait
import org.ow2.frascati.tinfi.TinfiComponentInterceptor
import org.ow2.frascati.tinfi.TinfiRuntimeException
import org.ow2.frascati.tinfi.api.IntentHandler
import org.ow2.frascati.tinfi.api.InterfaceFilter
import org.ow2.frascati.tinfi.api.InterfaceMethodFilter
/**
* Trait implementing the functionalities of the {@link SCAIntentController}
* interface shared by the scaPrimitive and scaComposite components.
*
* @author Lionel Seinturier
* @since 1.4.5
*/
trait SCABasicIntentControllerTrait extends BasicControllerTrait
with UseComponentTrait
with org.ow2.frascati.tinfi.api.control.SCAIntentControllerTrait {
override def addFcIntentHandler( handler: IntentHandler ) = {
val interceptors = getFcInterceptors
interceptors.keys.foreach( name => {
// Skip control interface
if( !name.endsWith("-controller") && !name.equals("component") ) {
val tci = interceptors(name)
tci.addIntentHandler(handler)
}
})
}
override def addFcIntentHandler(
handler: IntentHandler, filter: InterfaceFilter ) = {
val itfs = weaveableC.getFcInterfaces
itfs.foreach( o => {
val itf = o.asInstanceOf[Interface]
val accept = filter.accept(itf)
if(accept) {
val i = itf.asInstanceOf[ComponentInterface].getFcItfImpl
if( ! i.isInstanceOf[TinfiComponentInterceptor[_]] ) {
/*
* Shouldn't occur. All interceptors extend
* TinfiComponentInterceptor.
*/
val name = itf.getFcItfName
val msg =
"Interface "+name+
" was expected to delegate to an object implementing"+
" TinfiComponentInterceptor"
throw new TinfiRuntimeException(msg)
}
val tci = i.asInstanceOf[TinfiComponentInterceptor[_]]
tci.addIntentHandler(handler)
}
})
}
override def addFcIntentHandler( handler: IntentHandler, filter: InterfaceMethodFilter ) = {
val itfs = weaveableC.getFcInterfaces
itfs.foreach( o => {
val itf = o.asInstanceOf[Interface]
val i = itf.asInstanceOf[ComponentInterface].getFcItfImpl
if( ! i.isInstanceOf[TinfiComponentInterceptor[_]] ) {
/*
* Shouldn't occur. All interceptors extend
* TinfiComponentInterceptor.
*/
val name = itf.getFcItfName
val msg =
"Interface "+name+
" was expected to delegate to an object implementing"+
" TinfiComponentInterceptor"
throw new TinfiRuntimeException(msg)
}
val tci = i.asInstanceOf[TinfiComponentInterceptor[_]]
val methods = tci.getMethods
methods.foreach( method => {
val accept = filter.accept(itf,method)
if(accept) {
tci.addIntentHandler(handler,method)
}
})
})
}
override def addFcIntentHandler( handler: IntentHandler, name: String ) = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
tci.addIntentHandler(handler)
}
override def addFcIntentHandler(
handler: IntentHandler, name: String, method: Method ) = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
tci.addIntentHandler(handler,method)
}
override def listFcIntentHandler( name: String ) : java.util.List[IntentHandler] = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
val handlers = tci.listIntentHandler // Already a copy
return handlers
}
override def listFcIntentHandler( name: String, method: Method ) : java.util.List[IntentHandler] = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
val handlers = tci.listIntentHandler(method) // Already a copy
return handlers
}
override def removeFcIntentHandler( handler: IntentHandler ) = {
val interceptors = getFcInterceptors
val tcis = interceptors.values
tcis.foreach( tci => {
tci.removeIntentHandler(handler)
})
}
override def removeFcIntentHandler( handler: IntentHandler, name: String ) = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
tci.removeIntentHandler(handler)
}
override def removeFcIntentHandler(
handler: IntentHandler, name: String, method: Method ) = {
val interceptors = getFcInterceptors
if( ! interceptors.contains(name) ) {
throw new NoSuchInterfaceException(name)
}
val tci = interceptors(name)
tci.removeIntentHandler(handler,method)
}
// -------------------------------------------------------------------------
// Implementation specific
// -------------------------------------------------------------------------
/**
* Return the interceptors associated with the business interfaces of the
* current component.
*/
private def getFcInterceptors : Map[String,TinfiComponentInterceptor[_]] = {
/*
* I used to cache the interceptors map in a field. Philippe noticed
* that this may be problematic for multiple references since additional
* references may be bound after that the map has been computed.
*
* The solution is not to cache interceptors. The loss in performance
* should not be that important.
*/
val interceptors = new scala.collection.mutable.HashMap[String,TinfiComponentInterceptor[_]]
val itfs = weaveableC.getFcInterfaces
itfs.foreach( o => {
val itf = o.asInstanceOf[Interface]
val name = itf.getFcItfName
val i = itf.asInstanceOf[ComponentInterface].getFcItfImpl
if( i.isInstanceOf[TinfiComponentInterceptor[_]] ) {
val tci = i.asInstanceOf[TinfiComponentInterceptor[_]]
interceptors += name -> tci
}
})
return interceptors.toMap
}
}