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

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
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy