
org.objectweb.fractal.julia.control.lifecycle.BasicLifeCycleControllerMixin Maven / Gradle / Ivy
/***
* Julia: France Telecom's implementation of the Fractal API
* Copyright (C) 2001-2010 France Telecom R&D
*
* 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: Eric Bruneton
*/
package org.objectweb.fractal.julia.control.lifecycle;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;
import org.objectweb.fractal.api.factory.InstantiationException;
import org.objectweb.fractal.julia.Controller;
import org.objectweb.fractal.julia.InitializationContext;
import org.objectweb.fractal.julia.factory.ChainedInstantiationException;
/**
* Provides a basic implementation of the {@link
* org.objectweb.fractal.api.control.LifeCycleController} interface.
* This implementation is based on a counter managed by interceptors. This
* controller needs associated interceptor objects, such as those generated by
* the {@link org.objectweb.fractal.julia.asm.InterceptorClassGenerator} with a
* {@link org.objectweb.fractal.julia.asm.LifeCycleCodeGenerator}, in order to
* work properly (these interceptors are only needed on external server
* interfaces).
*
*
* Requirements
*
* - the component to which this controller object belongs must provide the
* {@link Component} interface and the {@link LifeCycleCoordinator}
* interface.
*
*/
public abstract class BasicLifeCycleControllerMixin
implements Controller, LifeCycleCoordinator
{
// -------------------------------------------------------------------------
// Private constructor
// -------------------------------------------------------------------------
private BasicLifeCycleControllerMixin () {
}
// -------------------------------------------------------------------------
// Fields and methods added and overriden by the mixin class
// -------------------------------------------------------------------------
/**
* The life cycle state of this component. Zero means stopped, one means
* stopping and two means started.
*/
public int fcState;
/**
* The number of currently executing method calls in this component.
*/
public int fcInvocationCounter;
/**
* The coordinator used to stop this component with other components
* simultaneously.
*/
public LifeCycleCoordinator fcCoordinator;
/**
* Initializes the fields of this mixin and then calls the overriden method.
*
* @param ic information about the component to which this controller object
* belongs.
* @throws InstantiationException if the initialization fails.
*/
public void initFcController (final InitializationContext ic)
throws InstantiationException
{
try {
if (!(ic.getInterface("lifecycle-controller") instanceof LifeCycleCoordinator)) {
throw new Exception();
}
} catch (Exception e) {
try {
ic.getInterface("/lifecycle-coordinator");
} catch (Exception f) {
throw new ChainedInstantiationException(
f, null, "The component must provide a LifeCycleCoordinator interface");
}
}
_super_initFcController(ic);
}
// -------------------------------------------------------------------------
// Implementation of the LifeCycleController interface
// -------------------------------------------------------------------------
public String getFcState () {
return fcState == 0 ? STOPPED : STARTED;
}
public void startFc () throws IllegalLifeCycleException {
if (fcState != 2) {
_this_setFcState(true);
}
}
public void stopFc () throws IllegalLifeCycleException {
if (fcState == 2) {
_this_stopFc(new LifeCycleCoordinator[] { getFcCoordinator() });
_this_setFcState(false);
}
}
// -------------------------------------------------------------------------
// Implementation of the LifeCycleCoordinator interface
// -------------------------------------------------------------------------
public boolean setFcStarted () throws IllegalLifeCycleException {
synchronized (this) {
if (fcState == 2) {
return false;
}
fcState = 2;
/**
* The following line unblock the threads that may be blocked in the
* component, in the incrementFcInvocationCounter method.
*/
notifyAll();
return true;
}
}
public void setFcStopping (final LifeCycleCoordinator coordinator)
throws IllegalLifeCycleException
{
synchronized (this) {
fcState = 1;
fcCoordinator = coordinator;
if (fcInvocationCounter == 0) {
fcCoordinator.fcInactivated(getFcCoordinator());
}
}
}
public boolean setFcStopped () throws IllegalLifeCycleException {
synchronized (this) {
if (fcState == 0) {
return false;
}
fcState = 0;
fcCoordinator = null;
return true;
}
}
// -------------------------------------------------------------------------
// Methods called by the associated interceptor
// -------------------------------------------------------------------------
/**
* Increments the number of currently executing method calls in this
* component. If the component is started this method just increments this
* counter. If the component is stopped, it waits until the component is
* restarted, and then increments the counter. Finally, if the component is
* stopping, there are two cases. If the counter is not null, it is just
* incremented. If it is null, this method asks the coordinator if the method
* call can be executed, or if it should be delayed until the component is
* restarted. The method then blocks or not, depending on the coordinator's
* response, before incrementing the counter.
*/
public void incrementFcInvocationCounter () {
/* this code is inlined in the interceptor objects
synchronized (this) {
if (fcState == 2) {
++fcInvocationCounter;
return;
} */
boolean ok;
do {
if (fcState == 0) {
ok = false;
} else if (fcState == 1) {
if (fcInvocationCounter == 0) {
ok = fcCoordinator.fcActivated(getFcCoordinator());
} else {
ok = true;
}
} else {
ok = true;
}
if (!ok) {
try {
wait();
} catch (final InterruptedException e) {
}
}
} while (!ok);
++fcInvocationCounter;
/* } */
}
/**
* Decrements the number of currently executing method calls in this
* component. If the component is stopping, and if the counter of currently
* executing method calls becomes null after being decremented, this method
* notifies the coordinator that the component has become inactive.
*/
public void decrementFcInvocationCounter () {
/* this code is inlined in the interceptor objects
synchronized (this) {
if (fcState == 2) {
--fcInvocationCounter;
return;
} */
--fcInvocationCounter;
if (fcInvocationCounter == 0) {
fcCoordinator.fcInactivated(getFcCoordinator());
}
/* } */
}
// -------------------------------------------------------------------------
// Utility methods
// -------------------------------------------------------------------------
/**
* Returns the {@link LifeCycleCoordinator} interface of this component.
*
* @return the {@link LifeCycleCoordinator} interface of the component to
* which this controller object belongs.
*/
public LifeCycleCoordinator getFcCoordinator () {
try {
return (LifeCycleCoordinator)_this_weaveableC.
getFcInterface("lifecycle-controller");
} catch (Exception e) {
try {
return (LifeCycleCoordinator)_this_weaveableC.
getFcInterface("/lifecycle-coordinator");
} catch (NoSuchInterfaceException f) {
throw new Error("Internal error"); // should not happen
}
}
}
// -------------------------------------------------------------------------
// Fields and methods required by the mixin class in the base class
// -------------------------------------------------------------------------
/**
* The weaveableC field required by this mixin. This field is
* supposed to reference the {@link Component} interface of the component to
* which this controller object belongs.
*/
public Component _this_weaveableC;
/**
* The setFcState method required by this mixin. This method is
* supposed to work as this {@link BasicLifeCycleCoordinatorMixin#setFcState
* setFcState} method.
*
* @param started true to set the lifecycle state of the components
* to {@link #STARTED STARTED}, or false to set this state to
* {@link #STOPPED STOPPED}.
* @throws IllegalLifeCycleException if a problem occurs.
*/
public abstract void _this_setFcState (boolean started)
throws IllegalLifeCycleException;
/**
* The stopFc method required by this mixin. This method is
* supposed to work as this {@link BasicLifeCycleCoordinatorMixin#stopFc
* stopFc} method.
*
* @param components the {@link LifeCycleCoordinator} interface of the
* components to be stopped.
* @throws IllegalLifeCycleException if a problem occurs.
*/
public abstract void _this_stopFc (LifeCycleCoordinator[] components)
throws IllegalLifeCycleException;
/**
* The {@link Controller#initFcController initFcController} method overriden
* by this mixin.
*
* @param ic information about the component to which this controller object
* belongs.
* @throws InstantiationException if the initialization fails.
*/
public abstract void _super_initFcController (InitializationContext ic)
throws InstantiationException;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy