org.ow2.frascati.tinfi.control.component.ComponentContextTrait.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.component
import java.lang.reflect.Constructor
import java.util.ArrayList
import java.util.Collection
import org.oasisopen.sca.ComponentContext
import org.oasisopen.sca.RequestContext
import org.oasisopen.sca.ServiceReference
import org.objectweb.fractal.api.Component
import org.objectweb.fractal.api.Interface
import org.objectweb.fractal.api.NoSuchInterfaceException
import org.objectweb.fractal.api.`type`.InterfaceType
import org.objectweb.fractal.julia.BasicControllerTrait
import org.objectweb.fractal.julia.UseComponentTrait
import org.objectweb.fractal.juliac.runtime.Juliac
import org.ow2.frascati.tinfi.TinfiComponentOutInterface
import org.ow2.frascati.tinfi.TinfiRuntimeException
import org.ow2.frascati.tinfi.api.control.SCAPropertyController
import org.ow2.frascati.tinfi.control.content.SCAExtendedContentController
import org.ow2.frascati.tinfi.control.content.UseSCAContentControllerTrait
import org.ow2.frascati.tinfi.control.property.UseSCAPropertyControllerTrait
import org.ow2.frascati.tinfi.oasis.ServiceReferenceImpl
/**
* Trait implementing the {@link ComponentContext} control interface.
*
* @author Lionel
* @since 1.4.5
*/
trait ComponentContextTrait extends BasicControllerTrait
with UseComponentTrait with UseSCAPropertyControllerTrait
with UseSCAContentControllerTrait with ComponentContext {
def getURI : String = throw new UnsupportedOperationException
def cast[B]( target: B ) : ServiceReference[B] = {
if( ! target.isInstanceOf[ServiceReference[_]] ) {
val msg = "Not a reference: "+target
throw new IllegalArgumentException(msg)
}
val ci = target.asInstanceOf[ServiceReference[_]]
val businessInterface = ci.getBusinessInterface
val service = ci.getService
// Create a ServiceReference
val signature = businessInterface.getName
val clname = Juliac.JULIAC_GENERATED+'.'+signature+"FcSR"
val cl = Class.forName(clname)
val ctrs = cl.getConstructors
val ctr = ctrs(0)
val params = new Array[Object](2)
params(0) = businessInterface
params(1) = service.asInstanceOf[Object]
val sr = ctr.newInstance(businessInterface,service.asInstanceOf[Object])
return sr.asInstanceOf[ServiceReference[B]]
}
def getService[B]( businessInterface:Class[B], referenceName: String ): B = {
val fcCltItf = getFcCltItf(businessInterface,referenceName)
/*
* Do not return "fcCltItf". The idea is that the object returned by
* this method must implement the business interface while yet being
* able to execute the control logic (such as pushing conversations on
* the conversation stack) when invoked. This control logic is
* implemented by the generated subclasses of ServiceReferenceImpl.
*/
val tco = fcCltItf.asInstanceOf[TinfiComponentOutInterface[B]]
val sr = tco.getServiceReference.asInstanceOf[B]
return sr
}
def getServiceReference[B]( businessInterface: Class[B], referenceName: String )
: ServiceReference[B] = {
val service = getFcCltItf(businessInterface,referenceName)
val sr = new ServiceReferenceImpl[B](businessInterface,service)
return sr
}
def getServiceReferences[B]( businessInterface: Class[B], referenceName: String )
: Collection[ServiceReference[B]] = {
val services = getFcCltColItf(businessInterface,referenceName)
val srs = new ArrayList[ServiceReference[B]]
services.foreach( service => {
val sr = new ServiceReferenceImpl[B](businessInterface,service)
srs.add(sr)
})
return srs
}
def getServices[B]( businessInterface: Class[B], referenceName: String )
: Collection[B] = {
val fcCltItfs = getFcCltColItf(businessInterface,referenceName)
// Same comment as in getService()
val services = new ArrayList[B]
fcCltItfs.foreach( fcCltItf => {
val tco = fcCltItf.asInstanceOf[TinfiComponentOutInterface[B]]
val sr = tco.getServiceReference
services.add(sr.asInstanceOf[B])
})
return services
}
def getProperty[B]( typ: Class[B], propertyName: String ) : B = {
if( ! weaveableSCAPC.containsPropertyName(propertyName) ) {
val msg = "No such property: "+propertyName
throw new IllegalArgumentException(msg)
}
val value = weaveableSCAPC.getValue(propertyName)
try {
val ret = value.asInstanceOf[B]
return ret
} catch {
case cce:ClassCastException =>
val msg = "Property "+propertyName+" is not of type "+typ.getName
throw new IllegalArgumentException(msg)
}
}
def createSelfReference[B]( businessInterface: Class[B] )
: ServiceReference[B] = {
val service = getFcSrvItf(businessInterface)
val sr = new ServiceReferenceImpl[B](businessInterface,service)
return sr
}
def createSelfReference[B](
businessInterface: Class[B], serviceName: String ) :
ServiceReference[B] = {
val service = getFcSrvItf(businessInterface,serviceName)
val sr = new ServiceReferenceImpl[B](businessInterface,service)
return sr
}
def getRequestContext: RequestContext = {
def rc = weaveableSCACC.getRequestContext
return rc
}
// -------------------------------------------------------------------------
// Implementation specific
// -------------------------------------------------------------------------
/**
* Return the Fractal server interface provided by this component which
* implements the specified business interface type.
*
* @param cl the business interface class
* @return the corresponding Fractal server interface
* @throws TinfiRuntimeException if no such Fractal server interface exists
*/
private def getFcSrvItf[B]( cl: Class[B] ) : B = {
def itfs = weaveableC.getFcInterfaces.asInstanceOf[Array[Interface]]
itfs.foreach( itf => {
val it = itf.getFcItfType.asInstanceOf[InterfaceType]
if( ! it.isFcClientItf ) {
val itfClass = itf.getClass
if( cl.isAssignableFrom(itfClass) ) {
return itf.asInstanceOf[B]
}
}
})
val msg = "No such default service"
throw new TinfiRuntimeException(msg)
}
/**
* Return the Fractal server interface provided by this component whose name
* is specified and which implements the specified business interface type.
*
* @param cl the business interface class
* @param name the interface name
* @return the corresponding Fractal server interface
* @throws TinfiRuntimeException if no such Fractal server interface exists
*/
private def getFcSrvItf[B]( cl: Class[B], name: String ) : B = {
var itf:Interface = weaveableC.getFcInterface(name).asInstanceOf[Interface]
val it = itf.getFcItfType.asInstanceOf[InterfaceType]
if( it.isFcClientItf ) {
val msg = "No such service: "+name
throw new TinfiRuntimeException(msg)
}
val itfClass = itf.getClass
if( ! cl.isAssignableFrom(itfClass) ) {
val msg = "Service can not be casted to: "+cl.getName
throw new TinfiRuntimeException(msg)
}
return itf.asInstanceOf[B]
}
/**
* Return the Fractal client interface required by this component whose name
* is specified and which implements the specified business interface type.
*
* @param cl the business interface class
* @param name the interface name
* @return the corresponding Fractal client interface
* @throws TinfiRuntimeException if no such Fractal client interface exists
*/
private def getFcCltItf[B]( cl: Class[B], name: String ) : B = {
var itf = weaveableC.getFcInterface(name).asInstanceOf[Interface]
val it = itf.getFcItfType.asInstanceOf[InterfaceType]
if( ! it.isFcClientItf ) {
val msg = "No such reference: "+name
throw new TinfiRuntimeException(msg)
}
val itfClass = itf.getClass
if( ! cl.isAssignableFrom(itfClass) ) {
val msg = "Reference can not be casted to: "+cl.getName
throw new TinfiRuntimeException(msg)
}
return itf.asInstanceOf[B]
}
/**
* Return the Fractal client interfaces required by this component whose
* name is specified and which implements the specified business interface
* type.
*
* @param cl the business interface class
* @param name the interface name
* @return the corresponding Fractal client collection interfaces
* @throws TinfiRuntimeException if no such Fractal client interface exists
*/
private def getFcCltColItf[B]( cl: Class[B], name: String ) : List[B] = {
var ret = List[B]()
val itfs = weaveableC.getFcInterfaces.asInstanceOf[Array[Object]]
itfs.foreach( o => {
val itf = o.asInstanceOf[Interface]
val itfname = itf.getFcItfName
if( itfname.startsWith(name) ) {
val it = itf.getFcItfType.asInstanceOf[InterfaceType]
if( ! it.isFcClientItf ) {
val msg = "No such reference: "+name
throw new TinfiRuntimeException(msg)
}
val itfClass = itf.getClass
if( ! cl.isAssignableFrom(itfClass) ) {
val msg = "Reference can not be casted to: "+cl.getName
throw new TinfiRuntimeException(msg)
}
ret = itf.asInstanceOf[B] :: ret
}
})
return ret.toList
}
}