1 package cz.cuni.amis.pogamut.base.component.lifecyclebus; 2 3 import java.lang.ref.WeakReference; 4 5 import cz.cuni.amis.pogamut.base.agent.IAgent; 6 import cz.cuni.amis.pogamut.base.component.IComponent; 7 import cz.cuni.amis.pogamut.base.component.ISharedComponent; 8 import cz.cuni.amis.pogamut.base.component.bus.ComponentBus; 9 import cz.cuni.amis.pogamut.base.component.bus.IComponentBus; 10 import cz.cuni.amis.pogamut.base.component.bus.exception.MoreComponentsForClassException; 11 import cz.cuni.amis.pogamut.base.component.controller.ComponentController; 12 import cz.cuni.amis.pogamut.base.component.controller.ComponentDependencies; 13 import cz.cuni.amis.pogamut.base.component.controller.ComponentState; 14 import cz.cuni.amis.pogamut.base.component.controller.IComponentControlHelper; 15 import cz.cuni.amis.pogamut.base.component.controller.IComponentController; 16 import cz.cuni.amis.pogamut.base.component.exception.ComponentLifecycleManagementAlreadyRegisteredException; 17 import cz.cuni.amis.utils.flag.FlagListener; 18 import cz.cuni.amis.utils.flag.ImmutableFlag; 19 import cz.cuni.amis.utils.token.IToken; 20 21 /** 22 * {@link ILifecycleBus} is extending {@link IComponentBus} by implementing the knowledge of lifecycle states of various {@link IComponent}s. It watches 23 * over the {@link ComponentState}s, providing information about them. 24 * <p><p> 25 * Additionally the class is providing the functionality of {@link ComponentController} offering components a helping hand to watch over 26 * events that are being broadcast over the bus and calls their lifecycle methods ({@link IComponentControlHelper} in correct times and 27 * according to their {@link ComponentDependencies}. 28 * <p><p> 29 * Additionally the {@link LifecycleBus} may accomodate {@link ISharedComponent}s as we're providing lifecycle management here as well. 30 * 31 * @author Jimmy 32 */ 33 public interface ILifecycleBus extends IComponentBus { 34 35 /** 36 * Returns current {@link ComponentState} of the component identified by 'componentId'. 37 * <p><p> 38 * Note that nothing guarantees that the state will change afterwards. 39 * <p><p> 40 * Note that we're not returning mere {@link ComponentState} but the immutable flag that you may use to attach {@link FlagListener}s to it 41 * allowing you to react on its changes as they happen. 42 * <p><p> 43 * WARNING: {@link ISharedComponent} state is always reported from the point of view of the bus, not the component! That 44 * means that the {@link ISharedComponent} may mask its behavior as if it would be a simple {@link IComponent} owned by single agent. 45 * For instance, after the bus broadcast {@link IFatalErrorEvent} as it is believed 46 * that all components will be killed thus the lifecycle bus will switch the component state into "KILLED" and after reset to "RESETED". 47 * Moreover, such behavior is quite a desired one because otherwise it would add unnecessary complexity from the point of view of the single agent 48 * and management of component auto-starting feature provided by {@link IComponentController}. 49 * 50 * @param componentId 51 * @return 52 */ 53 public ImmutableFlag<ComponentState> getComponentState(IToken componentId); 54 55 /** 56 * Returns current {@link ComponentState} of the component that implements / inherit the 'cls' class. 57 * <p><p> 58 * Note that nothing guarantees that the state will change afterwards. 59 * <p><p> 60 * If no components exist for 'cls', returns null. 61 * <p><p> 62 * Raises an exception {@link MoreComponentsForClassException} if more components for 'cls' exists. 63 * <p><p> 64 * Note that we're not returning mere {@link ComponentState} but the immutable flag that you may use to attach {@link FlagListener}s to it 65 * allowing you to react on its changes as they happen. 66 * <p><p> 67 * WARNING: {@link ISharedComponent} state is always reported from the point of view of the bus, not the component! That 68 * means that the {@link ISharedComponent} may mask its behavior as if it would be a simple {@link IComponent} owned by single agent. 69 * For instance, after the bus broadcast {@link IFatalErrorEvent} as it is believed 70 * that all components will be killed thus the lifecycle bus will switch the component state into "KILLED" and after reset to "RESETED". 71 * Moreover, such behavior is quite a desired one because otherwise it would add unnecessary complexity from the point of view of the single agent 72 * and management of component auto-starting feature provided by {@link IComponentController}. 73 * 74 * @param <T> 75 * @param cls 76 * @return flag with the state of the component 77 * @throws MoreComponentsForClassException 78 */ 79 public ImmutableFlag<ComponentState> getComponentState(Class<? extends IComponent> cls) throws MoreComponentsForClassException; 80 81 /** 82 * Registers 'lifecycleMethods' to be called in correct times according to 'componentDependencies' for the 'component'. 83 * <p><p> 84 * This method provides a powerful feature for {@link IComponent} to offload the troubles with sensing starting/stopping events of components 85 * it depends on in order to start/stop in correct times. It supplies the functionality of {@link ComponentController} which provides the same 86 * for simpler {@link ComponentBus}. 87 * <p><p> 88 * Every component may register only one lifecycle management. 89 * <p><p> 90 * The lifecycle management may be removed using {@link ILifecycleBus#removeEventListener(Class, cz.cuni.amis.pogamut.base.component.bus.IComponentEventListener)}. 91 * <p><p> 92 * WARNING: the 'lifecycleMethods' object is hold via {@link WeakReference}, you must store it for yourself! It also means you must have to 93 * store the instance of your component somewhere in the strongly referenced part of your code (i.e., in the {@link IAgent} instance). 94 * 95 * @param component 96 * @param lifecyleMethods 97 * @param componentDependencies 98 * @return controller that is used for the control of the component inside this bus 99 * @throws ComponentLifecycleManagementAlreadyRegisteredException 100 */ 101 public <T extends IComponent> IComponentController<T> addLifecycleManagement(T component, IComponentControlHelper lifecyleMethods, ComponentDependencies componentDependencies) throws ComponentLifecycleManagementAlreadyRegisteredException; 102 103 /** 104 * Removes lifecycle management for a concrete 'component'. 105 * <p><p> 106 * Does nothing if the component does not have life-cycle methods registered inside the bus. 107 * 108 * @param componentId 109 */ 110 public void removeLifecycleManagement(IComponent component); 111 112 }