Commit c8f1a75c authored by Lionel Seinturier's avatar Lionel Seinturier

Intent handler on control interfaces (feature requested by Philippe.)

Associated tests.
parent 80bb0bae
......@@ -6,8 +6,9 @@ Tinfi 0.6
* new example mixing SCA and OSGi components
* move to Juliac 2.1.6
* bug fix for @EagerInit (reported by Nicolas D.)
* SCA intent handler control interface: method level granularity for adding,
listing and removing an intent handler (feature requested by Philippe)
* SCA intent handler controller (features requested by Philippe)
* method level granularity for adding, listing and removing an intent handler
* intent handler on control interfaces
Tinfi 0.4.4
......
......@@ -122,7 +122,11 @@ extends AbstractInterceptorSourceCodeGenerator {
mv.visitln(" stack.push(rq);");
// Proceed with the call to the delegate
mv.visitln(" "+it.getFcItfSignature()+" _impl = ("+it.getFcItfSignature()+") getFcContent();");
mv.visit (" ");
mv.visit (it.getFcItfSignature());
mv.visit (" _impl = (");
mv.visit (it.getFcItfSignature());
mv.visitln(") getContent();");
// Begin of try/finally block
mv.visitln(" try {");
......
......@@ -72,18 +72,11 @@ extends AbstractInterceptorSourceCodeGenerator {
}
/**
* Return true if some code must be generated by the current source file
* generator.
* Return <code>true</code> if some code must be generated by the current
* source code generator.
*/
public boolean match() {
// Skip control interfaces
String itname = it.getFcItfName();
if( itname.equals("component") || itname.endsWith("-controller") ) {
return false;
}
// Match all other interfaces (business server and client)
// Match all interfaces, including control ones
return true;
}
......@@ -258,7 +251,7 @@ extends AbstractInterceptorSourceCodeGenerator {
@Override
public void generateMethodInitFcController( MethodSourceCodeVisitor mv, UnifiedClass proxycl ) {
mv.visitln(" initFcIntentHandlersMap(METHODS);");
mv.visitln(" initIntentHandlersMap(METHODS);");
mv.visitln(" super.initFcController(ic);");
}
......
......@@ -53,7 +53,7 @@ public class HelloWorldTestCase {
IllegalLifeCycleException, NoSuchInterfaceException,
java.lang.InstantiationException {
// Instanciate the HelloWorld composite
// Instantiate the HelloWorld composite
Component root = TinfiDomain.getComponent("example.hw.HelloWorld");
// Retrieve the client and server components
......@@ -92,7 +92,10 @@ public class HelloWorldTestCase {
IntentHandler h2 = TinfiDomain.getService("example.hw.handler.PolicySetDebug2",IntentHandler.class,"h");
/*
* Register the intent handlers with the server component.
* Register the intent handlers with the server component. The h1 intent
* handler is registered with all interfaces of the component. The h2
* intent handler is registered with all methods of the component
* implementation annotated with @PolicySets("debug2").
*/
SCAIntentController ic = (SCAIntentController) server.getFcInterface(SCAIntentController.NAME);
Fractal.getLifeCycleController(server).stopFc();
......@@ -135,7 +138,10 @@ public class HelloWorldTestCase {
IntentHandler h2 = TinfiDomain.getService("example.hw.handler.PolicySetDebug2",IntentHandler.class,"h");
/*
* Register the intent handlers with the server component.
* Register the intent handlers with the server component. The h1 intent
* handler is registered with all interfaces of the component. The h2
* intent handler is registered with all methods of the component
* implementation annotated with @PolicySets("debug2").
*/
SCAIntentController ic = (SCAIntentController) server.getFcInterface(SCAIntentController.NAME);
Fractal.getLifeCycleController(server).stopFc();
......@@ -178,10 +184,13 @@ public class HelloWorldTestCase {
/*
* Create the intent handler component.
*/
IntentHandler h1 = TinfiDomain.getService("example.hw.handler.PolicySetDebug1",IntentHandler.class,"h");
IntentHandler h1 =
TinfiDomain.getService(
"example.hw.handler.PolicySetDebug1",IntentHandler.class,"h");
/*
* Register the intent handler with the client component.
* Register the intent handler with the s interface of the client
* component.
*/
SCAIntentController ic = (SCAIntentController) client.getFcInterface(SCAIntentController.NAME);
Fractal.getLifeCycleController(client).stopFc();
......
......@@ -65,10 +65,51 @@ implements SCABasicIntentController {
Map<String,TinfiComponentInterceptor> interceptors = getFcInterceptors();
Collection<TinfiComponentInterceptor> tcis = interceptors.values();
for (TinfiComponentInterceptor tci : tcis) {
tci.addFcIntentHandler(handler);
tci.addIntentHandler(handler);
}
}
/**
* Add the specified intent handler on all interfaces (business or control)
* which match the specified interface filter.
*
* @param handler the intent handler to add
* @param filter the interface filter
* @throw IllegalLifeCycleException if the component is not stopped
* @since 0.6
*/
public void addFcIntentHandler( IntentHandler handler, InterfaceFilter filter ) {
Object[] itfs = _this_weaveableOptC.getFcInterfaces();
for (Object o : itfs) {
Interface itf = (Interface) o;
boolean accept = filter.accept(itf);
if( ! accept ) {
// Skip interfaces which are not accepted
continue;
}
String name = itf.getFcItfName();
Object i = ((ComponentInterface)itf).getFcItfImpl();
if( ! (i instanceof TinfiComponentInterceptor) ) {
/*
* Shouldn't occur. Since this controller is associated with a
* scaPrimitive or scaComposite component, all business
* interceptors extend TinfiComponentInterceptor.
*/
String msg =
"Interface "+name+
" was expected to delegate to an object implementing"+
" TinfiComponentInterceptor";
throw new TinfiRuntimeException(msg);
}
TinfiComponentInterceptor tci = (TinfiComponentInterceptor) i;
tci.addIntentHandler(handler);
}
}
/**
* Add the specified intent handler on the interface (service or reference)
* whose name is specified.
......@@ -88,7 +129,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
tci.addFcIntentHandler(handler);
tci.addIntentHandler(handler);
}
/**
......@@ -112,7 +153,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
tci.addFcIntentHandler(handler,method);
tci.addIntentHandler(handler,method);
}
/**
......@@ -133,7 +174,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
List<IntentHandler> handlers = tci.listFcIntentHandler(); // Already a copy
List<IntentHandler> handlers = tci.listIntentHandler(); // Already a copy
return handlers;
}
......@@ -157,7 +198,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
List<IntentHandler> handlers = tci.listFcIntentHandler(method); // Already a copy
List<IntentHandler> handlers = tci.listIntentHandler(method); // Already a copy
return handlers;
}
......@@ -172,7 +213,7 @@ implements SCABasicIntentController {
Map<String,TinfiComponentInterceptor> interceptors = getFcInterceptors();
Collection<TinfiComponentInterceptor> tcis = interceptors.values();
for (TinfiComponentInterceptor tci : tcis) {
tci.removeFcIntentHandler(handler);
tci.removeIntentHandler(handler);
}
}
......@@ -195,7 +236,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
tci.removeFcIntentHandler(handler);
tci.removeIntentHandler(handler);
}
/**
......@@ -220,7 +261,7 @@ implements SCABasicIntentController {
}
TinfiComponentInterceptor tci = interceptors.get(name);
tci.removeFcIntentHandler(handler,method);
tci.removeIntentHandler(handler,method);
}
......
......@@ -129,7 +129,7 @@ implements Controller, SCAIntentController {
TinfiComponentInterceptor tci = getFcInterceptor(method);
Method m = getFcItfMethod(method);
try {
tci.addFcIntentHandler(handler,m);
tci.addIntentHandler(handler,m);
}
catch (NoSuchMethodException e) {
/*
......
......@@ -56,7 +56,14 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
public void initFcController( InitializationContext ic )
throws InstantiationException {
owner = (Component) ic.getInterface("component");
Interceptor owner = (Interceptor) ic.getInterface("component");
/*
* Skip the intent interceptor which is installed on all control
* interfaces, including "component".
*/
this.owner = (Component) owner.getFcItfDelegate();
}
@Override
......@@ -96,6 +103,11 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
// Management of intents handlers
// -----------------------------------------------------------------------
/*
* The Fc string in method names has been removed to avoid name clashes when
* adding intent handlers on the SCAIntentController interface.
*/
/**
* The map of intent handlers associated with each component method managed
* by this interceptor. This map is queried by generated subclasses.
......@@ -108,7 +120,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* Initialize the intent handlers map by adding an empty entry for each
* specified method.
*/
protected void initFcIntentHandlersMap( Method[] methods ) {
protected void initIntentHandlersMap( Method[] methods ) {
intentHandlersMap = new HashMap<Method,List<IntentHandler>>();
for (Method method : methods) {
List<IntentHandler> handlers = new ArrayList<IntentHandler>();
......@@ -120,7 +132,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* Add the specified intent handler for all component methods managed by
* this interceptor.
*/
public void addFcIntentHandler( IntentHandler handler ) {
public void addIntentHandler( IntentHandler handler ) {
for (Map.Entry<Method,List<IntentHandler>> entry : intentHandlersMap.entrySet()) {
List<IntentHandler> handlers = entry.getValue();
handlers.add(handler);
......@@ -134,7 +146,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* if the specified method is not a component method managed by this
* interceptor
*/
public void addFcIntentHandler( IntentHandler handler, Method method )
public void addIntentHandler( IntentHandler handler, Method method )
throws NoSuchMethodException {
if( ! intentHandlersMap.containsKey(method) ) {
......@@ -150,7 +162,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
*
* @since 0.4.4
*/
public List<IntentHandler> listFcIntentHandler() {
public List<IntentHandler> listIntentHandler() {
List<IntentHandler> all = new ArrayList<IntentHandler>();
for (Map.Entry<Method,List<IntentHandler>> entry : intentHandlersMap.entrySet()) {
List<IntentHandler> handlers = entry.getValue();
......@@ -168,7 +180,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* interceptor
* @since 0.4.4
*/
public List<IntentHandler> listFcIntentHandler( Method method )
public List<IntentHandler> listIntentHandler( Method method )
throws NoSuchMethodException {
if( ! intentHandlersMap.containsKey(method) ) {
......@@ -185,7 +197,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* Remove the specified intent handler for all component methods managed by
* this interceptor.
*/
public void removeFcIntentHandler( IntentHandler handler ) {
public void removeIntentHandler( IntentHandler handler ) {
for (Map.Entry<Method,List<IntentHandler>> entry : intentHandlersMap.entrySet()) {
List<IntentHandler> handlers = entry.getValue();
handlers.remove(handler);
......@@ -199,7 +211,7 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
* if the specified method is not a component method managed by this
* interceptor
*/
public void removeFcIntentHandler( IntentHandler handler, Method method )
public void removeIntentHandler( IntentHandler handler, Method method )
throws NoSuchMethodException {
if( ! intentHandlersMap.containsKey(method) ) {
......@@ -228,11 +240,17 @@ public abstract class TinfiComponentInterceptor implements Interceptor {
return stack;
}
/*
* The Fc string in this method name has been removed to avoid name clashes
* when adding intent handlers on the SCAContentController interface which
* defines a getFcContent method.
*/
/**
* Query the content controller to retrieve the content instance
* corresponding to the current scope policy.
*/
protected Object getFcContent() {
protected Object getContent() {
SCAContentController cc = getFcSCAContentCtrlItf();
try {
Object content = cc.getFcContent();
......
/***
* OW2 FraSCAti Tinfi
* Copyright (C) 2009 INRIA, USTL
*
* 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: frascati@ow2.org
*
* Author: Lionel Seinturier
*/
package org.ow2.frascati.tinfi.control.intent;
import org.objectweb.fractal.api.Interface;
/**
* A filter for {@link Interface}s.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
* @since 0.6
*/
public interface InterfaceFilter {
/**
* Test whether the specified {@link Interface} should be included.
*
* @param itf the {@link Interface} to be tested
* @return if <code>itf</code> should be included
*/
public boolean accept( Interface itf );
}
......@@ -59,6 +59,18 @@ public interface SCABasicIntentController {
public void addFcIntentHandler( IntentHandler handler )
throws IllegalLifeCycleException;
/**
* Add the specified intent handler on all interfaces (business or control)
* which match the specified interface filter.
*
* @param handler the intent handler to add
* @param filter the interface filter
* @throw IllegalLifeCycleException if the component is not stopped
* @since 0.6
*/
public void addFcIntentHandler( IntentHandler handler, InterfaceFilter filter )
throws IllegalLifeCycleException;
/**
* Add the specified intent handler on the service or reference interface
* whose name is specified.
......
......@@ -28,14 +28,15 @@ import java.lang.reflect.Method;
import junit.framework.TestCase;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.Interface;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.factory.InstantiationException;
import org.objectweb.fractal.util.Fractal;
import org.ow2.frascati.tinfi.control.intent.IntentHandler;
import org.ow2.frascati.tinfi.control.intent.InterfaceFilter;
import org.ow2.frascati.tinfi.control.intent.SCAIntentController;
/**
* Class for testing the SCA Intent Controller.
*
......@@ -75,14 +76,14 @@ public class SCAIntentControllerTestCase extends TestCase {
}
/**
* Add the intent handler on all interfaces of a component.
* Add the intent handler on all services and references of a component.
*/
public void testAllInterfaces()
public void testAllServicesAndReferences()
throws IllegalLifeCycleException, NoSuchInterfaceException {
Fractal.getLifeCycleController(comp).stopFc();
ic.addFcIntentHandler(h);
Fractal.getLifeCycleController(comp).startFc();
Fractal.getLifeCycleController(comp).startFc();
itf.runAnnotatedMethod();
int count = countItf.getCount();
......@@ -101,7 +102,7 @@ public class SCAIntentControllerTestCase extends TestCase {
Fractal.getLifeCycleController(comp).stopFc();
ic.addFcIntentHandler(h,"r");
Fractal.getLifeCycleController(comp).startFc();
Fractal.getLifeCycleController(comp).startFc();
itf.runAnnotatedMethod();
int count = countItf.getCount();
......@@ -125,7 +126,7 @@ public class SCAIntentControllerTestCase extends TestCase {
Fractal.getLifeCycleController(comp).stopFc();
ic.addFcIntentHandler(h,"r",m);
Fractal.getLifeCycleController(comp).startFc();
Fractal.getLifeCycleController(comp).startFc();
itf.runAnnotatedMethod();
int count = countItf.getCount();
......@@ -135,4 +136,56 @@ public class SCAIntentControllerTestCase extends TestCase {
count = countItf.getCount();
assertEquals(2,count);
}
/**
* Add the intent handler on all the name controller.
*/
public void testNameController()
throws IllegalLifeCycleException, NoSuchInterfaceException {
Fractal.getLifeCycleController(comp).stopFc();
ic.addFcIntentHandler(
h,
new InterfaceFilter(){
public boolean accept( Interface itf ) {
String name = itf.getFcItfName();
return name.equals("name-controller");
}
}
);
Fractal.getLifeCycleController(comp).startFc();
Fractal.getNameController(comp).getFcName();
int count = countItf.getCount();
assertEquals(2,count);
}
/**
* Add the intent handler on all interfaces (business and control.)
*/
public void testAllInterfaces()
throws IllegalLifeCycleException, NoSuchInterfaceException {
Fractal.getLifeCycleController(comp).stopFc();
ic.addFcIntentHandler(
h,
new InterfaceFilter(){
public boolean accept( Interface itf ) {
return true;
}
}
);
Fractal.getLifeCycleController(comp).startFc();
/*
* 23. That's the count. counter is incremented before and after
* invocations on interface methods. The oddness of the value is due to
* the fact that just after having added the intent handler the counter
* is incremented when addFcIntentHandler returns (it has not been
* incremented in the before part.)
*/
int count = countItf.getCount();
assertEquals(23,count);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment