1 package cz.cuni.amis.pogamut.base.component.controller;
2
3 import java.util.HashSet;
4 import java.util.Set;
5 import java.util.concurrent.TimeUnit;
6 import java.util.logging.Level;
7 import java.util.logging.Logger;
8
9 import cz.cuni.amis.pogamut.base.component.IComponent;
10 import cz.cuni.amis.pogamut.base.component.exception.ComponentKilledException;
11 import cz.cuni.amis.utils.NullCheck;
12 import cz.cuni.amis.utils.flag.Flag;
13 import cz.cuni.amis.utils.flag.ImmutableFlag;
14 import cz.cuni.amis.utils.flag.WaitForFlagChange;
15 import cz.cuni.amis.utils.flag.WaitForFlagChange.IAccept;
16 import cz.cuni.amis.utils.token.IToken;
17 import cz.cuni.amis.utils.token.Tokens;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public abstract class AbstractComponentControllerBase<COMPONENT extends IComponent> implements IComponentControllerBase<COMPONENT> {
54
55
56
57
58
59
60
61
62 protected static class AwaitState implements IAccept<ComponentState> {
63
64 Set<ComponentState> awaiting = new HashSet<ComponentState>();
65
66 public AwaitState(ComponentState... states) {
67 for (ComponentState state : states) {
68 awaiting.add(state);
69 }
70 }
71
72 @Override
73 public boolean accept(ComponentState flagValue) {
74 return awaiting.contains(flagValue);
75 }
76
77 };
78
79
80
81
82
83
84
85
86 protected IToken controllerId;
87
88
89
90
91
92 protected IComponentControlHelper control;
93
94
95
96
97 protected COMPONENT component;
98
99
100
101
102 protected Logger log;
103
104
105
106
107
108
109
110
111 protected Flag<ComponentState> componentState = new Flag<ComponentState>(ComponentState.INSTANTIATED);
112
113
114
115
116
117
118
119
120
121
122
123 protected boolean broadcastingEvents = true;
124
125
126
127
128
129
130
131
132
133 public AbstractComponentControllerBase(COMPONENT component, IComponentControlHelper componentControlHelper, Logger log) {
134
135 this.log = log;
136 NullCheck.check(this.log, "log");
137 this.component = component;
138 NullCheck.check(this.component, "component");
139 this.control = componentControlHelper;
140 NullCheck.check(this.control, "componentControlHelper");
141
142
143 this.controllerId = Tokens.get(component.getComponentId().getToken() + "-controller");
144 }
145
146
147
148
149
150
151
152
153
154 public AbstractComponentControllerBase(IToken componentControllerId, COMPONENT component, IComponentControlHelper componentControlHelper, Logger log) {
155 this(component, componentControlHelper, log);
156 this.controllerId = componentControllerId;
157 NullCheck.check(controllerId, "componentControllerId");
158 }
159
160
161
162
163
164
165
166 @Override
167 public String toString() {
168 if (this == null) return "AbstractComponentControllerBase";
169 if (getComponentId() == null) return this.getClass().getSimpleName();
170 return this.getClass().getSimpleName()+ "[" + getComponentId().getToken() + "]";
171 }
172
173 @Override
174 public IToken getComponentId() {
175 return controllerId;
176 }
177
178 public Logger getLog() {
179 return log;
180 }
181
182 @Override
183 public COMPONENT getComponent() {
184 return component;
185 }
186
187
188
189
190
191
192
193 @Override
194 public boolean isBroadcastingEvents() {
195 return broadcastingEvents;
196 }
197
198 @Override
199 public void setBroadcastingEvents(boolean broadcastingEvents) {
200 this.broadcastingEvents = broadcastingEvents;
201 }
202
203 @Override
204 public IComponentControlHelper getComponentControl() {
205 return control;
206 }
207
208 @Override
209 public boolean isRunning() {
210 return inState(
211 ComponentState.PAUSING, ComponentState.PAUSED,
212 ComponentState.RESUMING, ComponentState.RUNNING
213 );
214 }
215
216 @Override
217 public boolean isPaused() {
218 return inState(
219 ComponentState.STARTING_PAUSED, ComponentState.PAUSED, ComponentState.PAUSING, ComponentState.RESUMING
220 );
221 }
222
223 @Override
224 public ImmutableFlag<ComponentState> getState() {
225 return componentState.getImmutable();
226 }
227
228 @Override
229 public boolean inState(ComponentState... states) {
230 return ComponentState.inside(componentState.getFlag(), states);
231 }
232
233 @Override
234 public boolean notInState(ComponentState... states) {
235 return ComponentState.notInside(componentState.getFlag(), states);
236 }
237
238 @Override
239 public ComponentState awaitState(ComponentState... states) throws ComponentKilledException {
240 ComponentState resultState;
241 resultState = new WaitForFlagChange<ComponentState>(componentState, new AwaitState(states)).await();
242 if (ComponentState.inside(resultState, ComponentState.KILLING, ComponentState.KILLED) &&
243 !ComponentState.partOf(states, ComponentState.KILLING, ComponentState.KILLED)) {
244 throw new ComponentKilledException(component, this);
245 }
246 return resultState;
247 }
248
249 @Override
250 public ComponentState awaitState(long timeoutMillis, ComponentState... states) throws ComponentKilledException {
251 ComponentState resultState;
252 resultState = new WaitForFlagChange<ComponentState>(componentState, new AwaitState(states)).await(timeoutMillis, TimeUnit.MILLISECONDS);
253 if (ComponentState.inside(resultState, ComponentState.KILLING, ComponentState.KILLED) &&
254 !ComponentState.partOf(states, ComponentState.KILLING, ComponentState.KILLED)) {
255 throw new ComponentKilledException(component, this);
256 }
257 return resultState;
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271 protected String id(IComponent component) {
272 if (component == null) return "null";
273 return component.getComponentId().getToken();
274 }
275
276
277
278
279
280 protected void setState(ComponentState state) {
281 if (state == this.componentState.getFlag()) return;
282 if (log.isLoggable(Level.FINEST)) log.finest("Switching to " + state + ".");
283 this.componentState.setFlag(state);
284 if (log.isLoggable(Level.INFO)) log.info("In state " + state + ".");
285 }
286
287 }