1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.gridsystems.nextgrid.api.pom;
19
20 import java.net.URI;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.PriorityQueue;
27
28 import nextgrid.api.env.Prioritiser;
29 import nextgrid.api.env.ProcessEnvironment;
30 import nextgrid.api.pom.AbstractProcess;
31 import nextgrid.api.pom.ControlProcess;
32 import nextgrid.api.pom.Process;
33 import nextgrid.api.pom.ProcessException;
34 import nextgrid.api.pom.Reference;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public abstract class ControlProcessImpl extends ProcessImpl
51 implements ControlProcess {
52
53
54
55
56
57
58 private List<Process> children;
59
60
61
62
63 private Map<String, Reference<?>> localVars;
64
65
66
67
68 private final int maxChildren;
69
70
71
72
73 private boolean memoize;
74
75
76
77
78
79
80 protected ControlProcessImpl(int maxChildren) {
81 super();
82 this.maxChildren = maxChildren;
83 this.children = new ArrayList<Process>();
84 this.localVars = new HashMap<String, Reference<?>>();
85 }
86
87
88
89
90 public final Process findProcessById(URI id) {
91 if (id == null) {
92 return null;
93 } else if (this.getId().equals(id)) {
94 return this;
95 } else {
96 for (Process child : this.getChildren()) {
97 Process found = child.findProcessById(id);
98 if (found != null) {
99 return found;
100 }
101 }
102 return null;
103 }
104 }
105
106
107
108
109 public final void prioritise(ProcessEnvironment env, PriorityQueue<Process> queue)
110 throws ProcessException {
111
112
113 Prioritiser prioritiser = env.getPrioritiserFor(this.getId());
114 if (prioritiser != null) {
115 prioritiser.prioritise(this);
116 }
117
118 for (Process p : getChildren()) {
119 p.prioritise(env, queue);
120 }
121 }
122
123
124
125
126 public void discover(ProcessEnvironment env) throws ProcessException {
127 for (Process p : getChildren()) {
128 p.discover(env);
129 }
130 }
131
132
133
134
135 @Override
136 public final void doEvaluate(ProcessEnvironment env) throws ProcessException {
137 discover(env);
138 PriorityQueue<Process> queue = prioritise(env);
139
140 Process p = queue.poll();
141 while (p != null) {
142 p.evaluate(env);
143 if (p instanceof AbstractProcess) {
144 ENACTOR_LOG.debug("Prioritising...");
145 Process selected = ((AbstractProcess)p).getSelected();
146 if (selected != null) {
147 selected.prioritise(env, queue);
148 }
149 ENACTOR_LOG.debug("Prioritised");
150 }
151 p = queue.poll();
152 }
153 }
154
155
156
157
158 public final boolean isMemoizeActive() {
159 return this.memoize;
160 }
161
162
163
164
165 public final void setMemoizeActive(boolean memoizeActive) {
166 this.memoize = memoizeActive;
167 }
168
169
170
171
172
173
174
175
176
177
178 public final Process[] getChildren() {
179 synchronized (children) {
180 return children.toArray(new Process[children.size()]);
181 }
182 }
183
184
185
186
187
188
189
190 public final Process getChildren(int index) {
191 synchronized (children) {
192 if (index >= children.size()) {
193 return null;
194 } else {
195 return children.get(index);
196 }
197 }
198 }
199
200
201
202
203
204
205 public final int getChildCount() {
206 synchronized (children) {
207 return children.size();
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220 public final void trim(int count) {
221 synchronized (this.children) {
222 int last = this.children.size() - 1;
223 while (last >= count) {
224 this.children.remove(last--);
225 }
226 }
227 }
228
229
230
231
232
233
234 public final void setChildren(Process... children) {
235 synchronized (this.children) {
236 int pos = 0;
237 for (Process item : children) {
238 if (pos == this.children.size()) {
239 addChildren(pos++, item);
240 } else {
241 setChildren(pos++, item);
242 }
243 }
244 trim(pos);
245 }
246 }
247
248
249
250
251
252
253
254
255
256 public final void setChildren(int index, Process child) {
257 if (maxChildren == 0) {
258 throw new UnsupportedOperationException("Children not supported");
259 }
260
261 synchronized (children) {
262 if (maxChildren < 0 || index >= maxChildren) {
263 throw new IndexOutOfBoundsException("Bad index: " + index);
264 }
265
266 Process previous;
267 if (index >= children.size()) {
268 children.add(child);
269 previous = null;
270 } else {
271 previous = children.set(index, child);
272 }
273
274 if (child != null) {
275 child.setParent(this);
276 }
277 if (previous != null) {
278 if (previous.getParent() instanceof ControlProcess) {
279 ((ControlProcess)previous.getParent()).removeChild(previous);
280 }
281 previous.setParent(this);
282 }
283 }
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311 public final void addChildren(int index, Process child) {
312 if (maxChildren == 0) {
313 throw new UnsupportedOperationException("Children not supported");
314 } else if (maxChildren > 0 && index != getChildCount()) {
315
316 throw new IndexOutOfBoundsException("Bad index: " + index);
317 }
318
319 synchronized (children) {
320 children.add(index, child);
321
322 if (child != null) {
323 if (child.getParent() instanceof ControlProcess) {
324 ((ControlProcess)child.getParent()).removeChild(child);
325 }
326 child.setParent(this);
327 }
328 }
329 }
330
331
332
333
334
335
336 public final void addChildren(Process... processes) {
337 int pos = this.getChildCount();
338 for (Process item : processes) {
339 addChildren(pos++, item);
340 }
341 }
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 public final Process removeChild(int index) {
361 if (maxChildren == 0) {
362 throw new UnsupportedOperationException("Children not supported");
363 } else if (maxChildren > 0 && index != getChildCount() - 1) {
364
365 throw new IndexOutOfBoundsException("Bad index: " + index);
366 }
367
368 Process removed;
369 synchronized (children) {
370 removed = children.remove(index);
371 removed.setParent(null);
372 }
373
374 return removed;
375 }
376
377
378
379
380
381
382
383 public final boolean removeChild(Process child) {
384 synchronized (children) {
385 int pos = children.indexOf(child);
386 if (pos == -1) {
387 return false;
388 } else {
389 removeChild(pos);
390 return true;
391 }
392 }
393 }
394
395
396
397
398 public final Reference<?> getLocalVar(String name) {
399 return this.localVars.get(name);
400 }
401
402
403
404
405 public final void setLocalVar(String name, Reference<?> value) {
406 this.localVars.put(name, value);
407 }
408
409
410
411
412 public final Map<String, Reference<?>> getLocalVars() {
413 return Collections.unmodifiableMap(localVars);
414 }
415
416
417
418
419 @Override public Process copy() {
420 ControlProcessImpl copy = (ControlProcessImpl)super.copy();
421
422 copy.children = new ArrayList<Process>();
423 for (Process p : children) {
424 copy.children.add(p.copy());
425 }
426
427 return copy;
428 }
429
430
431
432
433
434
435 @Override protected final void resetChildren() {
436 for (Process p : this.getChildren()) {
437 p.reset();
438 }
439 }
440 }