Commit e9b0328f authored by Lionel Seinturier's avatar Lionel Seinturier

New @Start and @Stop annotations for triggering actions when a component is...

New @Start and @Stop annotations for triggering actions when a component is started and stopped (requested by Philippe and Jonathan.)
parent 4271c594
......@@ -4,6 +4,8 @@ Tinfi 1.3
* support inherited non public field injection point in component
implementations (requested by Philippe)
* remove @EagerDestroy
* new @Start and @Stop annotations for triggering actions when a component is
started and stopped (requested by Philippe and Jonathan)
Tinfi 1.2.1
......
......@@ -24,8 +24,5 @@ runtime/oo-dyn/
Having a generic initializer should bypass this difficulty.
runtime-oo/
* remove the @EagerDestroy annotation which is misleading wrt @EagerInit which
is a class annotation whereas @EagerDestroy is a method annotation and create
@Start and @Stop method annotations
* support polymorphic setter methods in POJOs (see p12 of "SCA Service Component
Architecture Java Component Implementation Specification")
......@@ -26,6 +26,8 @@ package org.ow2.frascati.tinfi;
import org.osoa.sca.annotations.Destroy;
import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Reference;
import org.ow2.frascati.tinfi.annotations.Start;
import org.ow2.frascati.tinfi.annotations.Stop;
/**
* Root class for component implementations used for testing the {@link
......@@ -37,6 +39,8 @@ public class ScopeImpl implements ScopeItf {
public static int initcounter = 0;
public static int destroycounter = 0;
public static int startcounter = 0;
public static int stopcounter = 0;
@Init
public void init() {
......@@ -48,6 +52,16 @@ public class ScopeImpl implements ScopeItf {
destroycounter++;
}
@Start
public void start() {
startcounter++;
}
@Stop
public void stop() {
stopcounter++;
}
@Reference
public void setC( ScopeItf c ) {
this.c = c;
......
......@@ -161,14 +161,11 @@ public class SCAIntentControllerTestCase {
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.)
* 22. That's the count. counter is incremented before and after
* invocations on interface methods.
*/
int count = countItf.getCount();
Assert.assertEquals(23,count);
Assert.assertEquals(22,count);
}
/**
......
......@@ -120,6 +120,34 @@ public class ScopeTestCase {
0, ScopeImpl.destroycounter);
}
/**
* @since 1.3
*/
@Test
public void testScopeCompositeStartStop() throws Exception {
ScopeImpl.startcounter = 0;
ScopeImpl.stopcounter = 0;
String adl = getClass().getPackage().getName()+".ScopeComposite";
// getComponent(String) starts the component
Component c = TinfiDomain.getComponent(adl);
Assert.assertEquals(1,ScopeImpl.startcounter);
Assert.assertEquals(0,ScopeImpl.stopcounter);
Fractal.getLifeCycleController(c).stopFc();
Assert.assertEquals(1,ScopeImpl.startcounter);
Assert.assertEquals(1,ScopeImpl.stopcounter);
Fractal.getLifeCycleController(c).startFc();
Assert.assertEquals(2,ScopeImpl.startcounter);
Assert.assertEquals(1,ScopeImpl.stopcounter);
Fractal.getLifeCycleController(c).stopFc();
Assert.assertEquals(2,ScopeImpl.startcounter);
Assert.assertEquals(2,ScopeImpl.stopcounter);
}
@Test
public void testScopeRequest() throws Exception {
......
......@@ -334,6 +334,62 @@ implements Controller, SCAContentController {
*/
sm.getFcContent();
}
/**
* Invoke the @{@link org.ow2.frascati.tinfi.annotations.Start} annotated
* method on all current content instances associated with the component.
*
* @throws ContentInstantiationException
* in case of exception when invoking the method
* @since 1.3
*/
public void start() throws ContentInstantiationException {
if( ccmd.startMethod == null ) {
return;
}
Object[] contents = sm.getFcCurrentContents();
for (Object content : contents) {
try {
ccmd.startMethod.invoke(content);
}
catch (IllegalAccessException e) {
throw new ContentInstantiationException(e);
}
catch (InvocationTargetException e) {
throw new ContentInstantiationException(e);
}
}
}
/**
* Invoke the @{@link org.ow2.frascati.tinfi.annotations.Stop} annotated
* method on all current content instances associated with the component.
*
* @throws ContentInstantiationException
* in case of exception when invoking the method
* @since 1.3
*/
public void stop() throws ContentInstantiationException {
if( ccmd.stopMethod == null ) {
return;
}
Object[] contents = sm.getFcCurrentContents();
for (Object content : contents) {
try {
ccmd.stopMethod.invoke(content);
}
catch (IllegalAccessException e) {
throw new ContentInstantiationException(e);
}
catch (InvocationTargetException e) {
throw new ContentInstantiationException(e);
}
}
}
/**
* Return <code>true</code> if the specified property is declared by the
......
......@@ -21,45 +21,51 @@
* Author: Lionel Seinturier
*/
package org.ow2.frascati.tinfi.control.content;
package org.ow2.frascati.tinfi.control.lifecycle;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.julia.control.lifecycle.ChainedIllegalLifeCycleException;
import org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator;
import org.ow2.frascati.tinfi.control.content.ContentInstantiationException;
import org.ow2.frascati.tinfi.control.content.SCAContentController;
/**
* Mixin layer to be included in the lifecycle controller for managing the
* EagerInit and EagerDestroy policy.
* EagerInit policy, the Start and the Stop policy.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
*/
public abstract class LifeCycleEagerMixin implements LifeCycleCoordinator {
public abstract class SCALifeCycleMixin {
// -------------------------------------------------------------------------
// Private constructor
// -------------------------------------------------------------------------
private LifeCycleEagerMixin() {}
private SCALifeCycleMixin() {}
// -------------------------------------------------------------------------
// Implementation of the LifeCycleCoordinator interface
// -------------------------------------------------------------------------
public boolean setFcStarted() throws IllegalLifeCycleException {
/*
* Notify the SCA content controller that the component has been
* started. This gives the opportunity to eager initialize the component
* if the @EagerInit annotation has been set.
*/
public void setFcContentState( boolean started )
throws IllegalLifeCycleException {
/*
* Do not propagate to super layers. We do not want to execute the code
* defined in ContainerLifeCycleMixin#setFcContentState(boolean).
*/
try {
_this_weaveableSCACC.eagerInit();
if(started) {
_this_weaveableSCACC.eagerInit();
_this_weaveableSCACC.start();
}
else {
_this_weaveableSCACC.stop();
}
}
catch( ContentInstantiationException ie ) {
throw new ChainedIllegalLifeCycleException(ie,null,"");
}
return _super_setFcStarted();
}
......@@ -67,9 +73,6 @@ public abstract class LifeCycleEagerMixin implements LifeCycleCoordinator {
// Fields and methods required by the mixin class in the base class
// -------------------------------------------------------------------------
public abstract boolean _super_setFcStarted() throws IllegalLifeCycleException;
public abstract boolean _super_setFcStopped() throws IllegalLifeCycleException;
/**
* The {@link SCAContentController} interface of the component to which
* this controller object belongs.
......
......@@ -85,7 +85,7 @@
)
# LifeCycleController implementation (for primitive or composite components)
# uses LifeCycleEagerMixin to notify the SCA content controller of start/stop events
# uses SCALifeCycleMixin to notify the SCA content controller of start/stop events
(sca-lifecycle-controller-impl
((org.objectweb.fractal.julia.asm.MixinClassGenerator
SCALifeCycleControllerImpl
......@@ -98,7 +98,7 @@
# to notify the encapsulated component (if present) when its state changes:
org.objectweb.fractal.julia.control.lifecycle.ContainerLifeCycleMixin
org.ow2.frascati.tinfi.control.content.UseSCAContentControllerMixin
org.ow2.frascati.tinfi.control.content.LifeCycleEagerMixin
org.ow2.frascati.tinfi.control.lifecycle.SCALifeCycleMixin
))
)
......
/***
* OW2 FraSCAti Tinfi
* Copyright (C) 2010 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.annotations;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotation for component implementation methods to be invoked when the
* component is started.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
* @since 1.3
*/
@Target(METHOD)
@Retention(RUNTIME)
public @interface Start {
// Indeed nothing
}
\ No newline at end of file
/***
* OW2 FraSCAti Tinfi
* Copyright (C) 2010 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.annotations;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotation for component implementation methods to be invoked when the
* component is stopped.
*
* @author Lionel Seinturier <Lionel.Seinturier@univ-lille1.fr>
* @since 1.3
*/
@Target(METHOD)
@Retention(RUNTIME)
public @interface Stop {
// Indeed nothing
}
\ No newline at end of file
......@@ -43,6 +43,8 @@ import org.osoa.sca.annotations.Init;
import org.osoa.sca.annotations.Property;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Scope;
import org.ow2.frascati.tinfi.annotations.Start;
import org.ow2.frascati.tinfi.annotations.Stop;
import org.ow2.frascati.tinfi.reflect.AnnotatedElementFilter;
import org.ow2.frascati.tinfi.reflect.Filter;
import org.ow2.frascati.tinfi.reflect.Filters;
......@@ -128,6 +130,12 @@ public class ContentClassMetaData {
/** The method annotated with @{@link Destroy}, if any. */
public Method destroyMethod;
/** The method annotated with @{@link Start}, if any. */
public Method startMethod;
/** The method annotated with @{@link Stop}, if any. */
public Method stopMethod;
/** The field or setter method annotated with @{@link Context}, if any. */
public InjectionPoint<Context> contextAnnotatedElement;
......@@ -229,6 +237,24 @@ public class ContentClassMetaData {
destroyMethod =
checkFcUniqueAnnotatedVoidMethod(destroys,Destroy.class);
/*
* Retrieve the setter or field annotated with @Start, if any.
* Check that only one such method exists.
*/
filter = new AnnotatedElementFilter(Start.class);
Method[] starts = Filters.filter(methods,filter);
startMethod =
checkFcUniqueAnnotatedVoidMethod(starts,Start.class);
/*
* Retrieve the setter or field annotated with @Stop, if any.
* Check that only one such method exists.
*/
filter = new AnnotatedElementFilter(Stop.class);
Method[] stops = Filters.filter(methods,filter);
stopMethod =
checkFcUniqueAnnotatedVoidMethod(stops,Stop.class);
/*
* Retrieve the setter or field annotated with @Context, if any.
* Check that only one such element exists.
......
......@@ -117,6 +117,26 @@ public interface SCAContentController {
*/
public void eagerInit() throws ContentInstantiationException;
/**
* Invoke the @{@link org.ow2.frascati.tinfi.annotations.Start} annotated
* method on all current content instances associated with the component.
*
* @throws ContentInstantiationException
* in case of exception when invoking the method
* @since 1.3
*/
public void start() throws ContentInstantiationException;
/**
* Invoke the @{@link org.ow2.frascati.tinfi.annotations.Stop} annotated
* method on all current content instances associated with the component.
*
* @throws ContentInstantiationException
* in case of exception when invoking the method
* @since 1.3
*/
public void stop() throws ContentInstantiationException;
/**
* Return <code>true</code> if the specified property is declared by the
* content class managed by this controller.
......
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