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

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