1 package cz.cuni.amis.pogamut.base.component.controller; 2 3 import cz.cuni.amis.pogamut.base.component.IComponent; 4 import cz.cuni.amis.pogamut.base.component.bus.event.IFatalErrorEvent; 5 import cz.cuni.amis.pogamut.base.component.bus.event.IPausedEvent; 6 import cz.cuni.amis.pogamut.base.component.bus.event.IPausingEvent; 7 import cz.cuni.amis.pogamut.base.component.bus.event.IStoppedEvent; 8 import cz.cuni.amis.pogamut.base.component.bus.event.IStoppingEvent; 9 import cz.cuni.amis.pogamut.base.component.exception.ComponentKilledException; 10 import cz.cuni.amis.utils.exception.PogamutInterruptedException; 11 import cz.cuni.amis.utils.flag.ImmutableFlag; 12 import cz.cuni.amis.utils.flag.WaitForFlagChange; 13 14 /** 15 * Base interface for component controllers, be it {@link IComponentController} or {@link ISharedComponentController}. 16 * <p><p> 17 * The component controller base interface is meant to provide a gateway for starting/stopping/pausing/resuming the component and 18 * querying the component current {@link ComponentState}. 19 * <p><p> 20 * Use {@link AbstractComponentControllerBase} abstraction for the implementation of custom controllers. 21 * 22 * @author Jimmy 23 */ 24 public interface IComponentControllerBase<COMPONENT extends IComponent> extends IComponent { 25 26 /** 27 * Returns last fatal error event that has triggered the system failure. 28 */ 29 public IFatalErrorEvent getFatalError(); 30 31 /** 32 * Whether the component has been started, is not stopped or killed, may be paused. 33 * @return component is running 34 */ 35 public boolean isRunning(); 36 37 /** 38 * Whether the component is paused (or is pausing/resuming). 39 * @return 40 */ 41 public boolean isPaused(); 42 43 /** 44 * Returns state of the controlled component (state of the component life-cycle). 45 * <p><p> 46 * It returns flag - therefore you may use {@link WaitForFlagChange} to synchronize on the flag changes in other threads or use 47 * awaitState() method. 48 * @return immutable flag 49 */ 50 public ImmutableFlag<ComponentState> getState(); 51 52 /** 53 * Whether the component is in one of 'states'. 54 * @param states 55 * @return 56 */ 57 public boolean inState(ComponentState... states); 58 59 /** 60 * Whether the component is not in any of 'states'. 61 * @param states 62 * @return 63 */ 64 public boolean notInState(ComponentState... states); 65 66 /** 67 * Waits until the component reaches one of 'states' or KILLING / KILLED state is reached. 68 * <p><p> 69 * If KILLING / KILLED state is not among 'states' then reaching of this state will throw {@link ComponentKilledException} exception. 70 * <p><p> 71 * If interrupted, {@link PogamutInterruptedException} is thrown. 72 * 73 * @param state 74 * @return reached component state 75 * @throws ComponentKilledException 76 */ 77 public ComponentState awaitState(ComponentState... states); 78 79 /** 80 * Waits until the component reaches one of 'states' or KILLING / KILLED state is reached. 81 * <p><p> 82 * If KILLING / KILLED state is not among 'states' then reaching of this state will throw {@link ComponentKilledException} exception. 83 * <p><p> 84 * If interrupted, {@link PogamutInterruptedException} is thrown. 85 * <p><p> 86 * If times out, null is returned. 87 * 88 * @param millis 89 * @param state 90 * @return reached component state 91 * @throws ComponentKilledException 92 */ 93 public ComponentState awaitState(long timeoutMillis, ComponentState... states); 94 95 /** 96 * Provides the way to manually start the component. 97 */ 98 public void manualStart(String reason); 99 100 /** 101 * Provides the way to manually start the component into paused state. 102 */ 103 public void manualStartPaused(String reason); 104 105 /** 106 * Provides the way to stop the component (constructor of this controller). 107 * <p><p> 108 * Note that you should not use {@link IComponentControlHelper}.stop() alone to stop your component 109 * as it won't produce {@link IStoppingEvent} and {@link IStoppedEvent}. 110 * <p><p> 111 * If you require your component to stop prematurely - call this method. 112 * 113 * @param reason why the component is stopping 114 */ 115 public void manualStop(String reason); 116 117 /** 118 * Provides the way to kill the component (constructor of this controller). 119 * <p><p> 120 * Note that you should not use {@link IComponentControlHelper}.kill() alone to stop your component 121 * as it won't produce {@link IFatalErrorEvent}. 122 * <p><p> 123 * If you require your component to stop prematurely - call this method. 124 * 125 * @param reason why the component is stopping 126 */ 127 public void manualKill(String reason); 128 129 /** 130 * Provides the way to pause the component (constructor of this controller). 131 * <p><p> 132 * Note that you should not use {@link IComponentControlHelper}.pause() alone to stop your component 133 * as it won't produce {@link IPausingEvent} and {@link IPausedEvent}. 134 * 135 * @param reason why the component is pausing 136 */ 137 public void manualPause(String reason); 138 139 /** 140 * Provides the way to pause the component (constructor of this controller). 141 * <p><p> 142 * Note that you should not use {@link IComponentControlHelper}.pause() alone to stop your component 143 * as it won't produce {@link IPausingEvent} and {@link IPausedEvent}. 144 * 145 * @param reason why the component is pausing 146 */ 147 public void manualResume(String reason); 148 149 /** 150 * Broadcasts fatal error with controlled component as source. 151 * <p><p> 152 * Sets state to KILLING, broadcasts {@link IFatalErrorEvent} and then sets the state to KILLED. 153 * <p><p> 154 * <b>WARNING:</b> Note that the ComponentController assumes that you will kill your component 155 * yourself before or after you call this method. Therefore the components kill() method won't be called. That's because 156 * whenever fatal error occurs, the component is in undefined state and you have to decide what to do based 157 * on that fatal error. 158 * 159 * @param message 160 */ 161 public void fatalError(String message); 162 163 /** 164 * Broadcasts fatal error with controlled component as source. 165 * <p><p> 166 * Sets state to KILLING, broadcasts {@link IFatalErrorEvent} and then sets the state to KILLED. 167 * <p><p> 168 * <b>WARNING:</b> Note that the ComponentController assumes that you will kill your component 169 * yourself before or after you call this method. Therefore the components kill() method won't be called. That's because 170 * whenever fatal error occurs, the component is in undefined state and you have to decide what to do based 171 * on that fatal error. 172 * 173 * @param message 174 * @param e 175 */ 176 public void fatalError(String message, Throwable e); 177 178 /** 179 * Returns controlled component instance. 180 * @return controlled component 181 */ 182 public COMPONENT getComponent(); 183 184 /** 185 * Returns component control with lifecycle methods of the component controlled by this instance. I.e., methods that are 186 * directly controlling the component {@link IComponentController#getComponent()}. 187 * <p><p> 188 * IT IS DISCOURAGED TO USE METHODS OF THE {@link IComponentControlHelper} DIRECTLY! IT DEFIES THE PURPOSE OF THE CONTROLLER TOTALLY 189 * AND THE CONTROLLER WILL PROBABLY WON'T COPE WITH SUCH BEHAVIOR. 190 * <p><p> 191 * But what the hell, if it solves your problem, go ahead ;-) 192 * 193 * @return 194 */ 195 public IComponentControlHelper getComponentControl(); 196 197 /** 198 * Tells whether the controller sends events about the state of the component, i.e., whether it should automatically send 199 * starting/stopping events or not. 200 * <p><p> 201 * DEFAULT: TRUE (the controller is broadcasting events as default) 202 * <p><p> 203 * Exception: {@link IComponentControllerBase#fatalError(String)} and {@link IComponentControllerBase#fatalError(String, Throwable)} 204 * must always send fatal error! 205 * 206 * @return 207 */ 208 public boolean isBroadcastingEvents(); 209 210 /** 211 * Enables (== true) / Disables (== false) sending events about the state of the component, i.e., whether it should automatically send 212 * starting/stopping events or not. 213 * <p><p> 214 * Exception: {@link IComponentControllerBase#fatalError(String)} and {@link IComponentControllerBase#fatalError(String, Throwable)} 215 * must always send fatal error! 216 * 217 * @param broadcastEvents Enables (== true) / Disables (== false) 218 */ 219 public void setBroadcastingEvents(boolean broadcastEvents); 220 221 }