Total Complexity | 110 |
Total Lines | 1282 |
Duplicated Lines | 31.83 % |
Changes | 4 | ||
Bugs | 1 | Features | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like it.cnr.istc.pst.platinum.ai.executive.pdb.ExecutivePlanDataBase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | package it.cnr.istc.pst.platinum.ai.executive.pdb; |
||
62 | @TemporalFacadeConfiguration( |
||
63 | |||
64 | // temporal network |
||
65 | network = TemporalNetworkType.STNU, |
||
66 | |||
67 | // temporal solver |
||
68 | solver = TemporalSolverType.APSP |
||
69 | ) |
||
70 | public class ExecutivePlanDataBase extends FrameworkObject |
||
71 | { |
||
72 | private PlanProtocolDescriptor plan; // the plan to execute |
||
73 | |||
74 | @TemporalFacadePlaceholder |
||
75 | protected TemporalFacade facade; // temporal data base |
||
76 | |||
77 | // plan locks |
||
78 | private final Object[] locks; |
||
79 | |||
80 | // plan's nodes |
||
81 | protected Map<ExecutionNodeStatus, List<ExecutionNode>> nodes; |
||
82 | |||
83 | // execution dependency graphs |
||
84 | protected Map<ExecutionNode, Map<ExecutionNode, ExecutionNodeStatus[]>> sdg; // start dependency graph - array of disjunctive start conditions |
||
85 | protected Map<ExecutionNode, Map<ExecutionNode, ExecutionNodeStatus[]>> edg; // end dependency graph - array of disjunctive end conditions |
||
86 | protected Map<ExecutionNode, Map<ExecutionNode, ExecutionNodeStatus[]>> stop; // stop dependency graph - array of disjunctive end conditions |
||
87 | |||
88 | /** |
||
89 | * |
||
90 | * @param origin |
||
91 | * @param horizon |
||
92 | */ |
||
93 | protected ExecutivePlanDataBase() { |
||
94 | super(); |
||
95 | |||
96 | // set array of locks |
||
97 | this.locks = new Object[ExecutionNodeStatus.values().length]; |
||
98 | // add locks |
||
99 | for (ExecutionNodeStatus s : ExecutionNodeStatus.values()) { |
||
100 | // set lock |
||
101 | this.locks[s.getIndex()] = new Object(); |
||
102 | } |
||
103 | |||
104 | // set data structures |
||
105 | this.nodes = new HashMap<>(); |
||
|
|||
106 | for (ExecutionNodeStatus s : ExecutionNodeStatus.values()) { |
||
107 | // set the index of execution nodes |
||
108 | this.nodes.put(s, new LinkedList<ExecutionNode>()); |
||
109 | } |
||
110 | |||
111 | // set the dependency graph |
||
112 | this.sdg = new HashMap<>(); |
||
113 | this.edg = new HashMap<>(); |
||
114 | this.stop = new HashMap<>(); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * |
||
119 | * @return |
||
120 | */ |
||
121 | public long getOrigin() { |
||
122 | return this.facade.getOrigin(); |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * |
||
127 | * @return |
||
128 | */ |
||
129 | public long getHorizon() { |
||
130 | return this.facade.getHorizon(); |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * |
||
135 | * @return |
||
136 | */ |
||
137 | public String export() throws IOException { |
||
138 | |||
139 | // prepare file |
||
140 | //System.out.println("Prepare file plans/exported/plan.txt... "); |
||
141 | File output = new File("plans/exported/plan.txt"); |
||
142 | // export current plan (if any) to a known file |
||
143 | if (this.plan != null) |
||
144 | { |
||
145 | // get plan encoding |
||
146 | String encoding = this.plan.export(); |
||
147 | // write to a file |
||
148 | System.out.println("Writing file:\n"); |
||
149 | try (BufferedWriter writer = new BufferedWriter(new FileWriter(output))) { |
||
150 | // get data |
||
151 | //System.out.println(encoding +"\n"); |
||
152 | writer.write(encoding); |
||
153 | //System.out.println("Done!"); |
||
154 | writer.close(); |
||
155 | } |
||
156 | } |
||
157 | |||
158 | // get absolute file |
||
159 | //System.out.println(output.getAbsolutePath()); |
||
160 | return output.getAbsolutePath(); |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * |
||
165 | * @return |
||
166 | */ |
||
167 | public String getName() { |
||
168 | return this.plan.getName(); |
||
169 | } |
||
170 | |||
171 | |||
172 | /** |
||
173 | * |
||
174 | * @param plan |
||
175 | */ |
||
176 | public void setup(PlanProtocolDescriptor plan) { |
||
177 | |||
178 | try { |
||
179 | |||
180 | // get plan descriptor |
||
181 | this.plan = plan; |
||
182 | // map token descriptor to nodes |
||
183 | Map<TokenProtocolDescriptor, ExecutionNode> dictionary = new HashMap<>(); |
||
184 | // check time-lines |
||
185 | View Code Duplication | for (TimelineProtocolDescriptor tl : plan.getTimelines()) { |
|
186 | |||
187 | // setup node arrays |
||
188 | ExecutionNode[] list = new ExecutionNode[tl.getTokens().size()]; |
||
189 | // list index |
||
190 | int counter = 0; |
||
191 | // create an execution node for each token |
||
192 | for (TokenProtocolDescriptor token : tl.getTokens()) { |
||
193 | // check predicate |
||
194 | if (!token.getPredicate().toLowerCase().equals("unallocated")) { |
||
195 | |||
196 | // get token's bound |
||
197 | long[] start = token.getStartTimeBounds(); |
||
198 | long[] end = token.getEndTimeBounds(); |
||
199 | long[] duration = token.getDurationBounds(); |
||
200 | |||
201 | // set default controllability type |
||
202 | ControllabilityType controllability = null; |
||
203 | // check specific type |
||
204 | if (tl.isExternal()) { |
||
205 | // uncontrollable |
||
206 | controllability = ControllabilityType.UNCONTROLLABLE; |
||
207 | |||
208 | } else if (token.getPredicate().startsWith("_")) { |
||
209 | // partially controllable token |
||
210 | controllability = ControllabilityType.PARTIALLY_CONTROLLABLE; |
||
211 | |||
212 | } else { |
||
213 | // controllable |
||
214 | controllability = ControllabilityType.CONTROLLABLE; |
||
215 | } |
||
216 | |||
217 | // set parameter information |
||
218 | String signature = token.getPredicate(); |
||
219 | String[] paramValues = new String[token.getParameters().size()]; |
||
220 | ParameterType[] paramTypes = new ParameterType[token.getParameters().size()]; |
||
221 | for (int index = 0; index < token.getParameters().size(); index++) { |
||
222 | |||
223 | // get parameter |
||
224 | ParameterDescriptor param= token.getParameter(index); |
||
225 | // check type |
||
226 | if (param.getType().equals(ParameterTypeDescriptor.NUMERIC)) |
||
227 | { |
||
228 | // set type |
||
229 | paramTypes[index] = ParameterType.NUMERIC_PARAMETER_TYPE; |
||
230 | // set value |
||
231 | paramValues[index] = Long.toString(param.getBounds()[0]); |
||
232 | } |
||
233 | else |
||
234 | { |
||
235 | // enumeration |
||
236 | paramTypes[index] = ParameterType.ENUMERATION_PARAMETER_TYPE; |
||
237 | // set value |
||
238 | paramValues[index] = param.getValues()[0]; |
||
239 | } |
||
240 | } |
||
241 | |||
242 | // create a node |
||
243 | ExecutionNode node = this.createNode(tl.getComponent(), tl.getName(), |
||
244 | signature, paramTypes, paramValues, |
||
245 | start, end, duration, controllability, token.getStartExecutionState()); |
||
246 | |||
247 | // add node |
||
248 | this.addNode(node); |
||
249 | // add entry to the dictionary |
||
250 | dictionary.put(token, node); |
||
251 | |||
252 | // add node to list |
||
253 | list[counter] = node; |
||
254 | counter++; |
||
255 | } |
||
256 | } |
||
257 | |||
258 | // link subsequent nodes |
||
259 | if (list.length > 1) { |
||
260 | for (int pos = 0; pos < list.length; pos++) { |
||
261 | |||
262 | // check first node |
||
263 | if (pos == 0) { |
||
264 | |||
265 | // first node of the timeline |
||
266 | ExecutionNode first = list[pos]; |
||
267 | // set next node |
||
268 | first.setNext(list[pos+1]); |
||
269 | |||
270 | } else if (pos == list.length - 1) { |
||
271 | |||
272 | // last node of the timeline |
||
273 | ExecutionNode last = list[pos]; |
||
274 | // set previous node |
||
275 | last.setPrev(list[pos-1]); |
||
276 | |||
277 | } else { |
||
278 | |||
279 | // intermediate node |
||
280 | ExecutionNode i = list[pos]; |
||
281 | // set previous |
||
282 | i.setPrev(list[pos-1]); |
||
283 | // set next |
||
284 | i.setNext(list[pos+1]); |
||
285 | } |
||
286 | } |
||
287 | } |
||
288 | } |
||
289 | |||
290 | // check observations |
||
291 | View Code Duplication | for (TimelineProtocolDescriptor tl : plan.getObservations()) { |
|
292 | |||
293 | // setup node arrays |
||
294 | ExecutionNode[] list = new ExecutionNode[tl.getTokens().size()]; |
||
295 | // list index |
||
296 | int counter = 0; |
||
297 | // create an execution node for each token |
||
298 | for (TokenProtocolDescriptor token : tl.getTokens()) { |
||
299 | // check predicate |
||
300 | if (!token.getPredicate().toLowerCase().equals("unallocated")) { |
||
301 | |||
302 | // get token's bound |
||
303 | long[] start = token.getStartTimeBounds(); |
||
304 | long[] end = token.getEndTimeBounds(); |
||
305 | long[] duration = token.getDurationBounds(); |
||
306 | |||
307 | // check controllability type |
||
308 | // set default controllability type |
||
309 | ControllabilityType controllability = null; |
||
310 | // check specific type |
||
311 | if (tl.isExternal()) { |
||
312 | |||
313 | // uncontrollable |
||
314 | controllability = ControllabilityType.UNCONTROLLABLE; |
||
315 | |||
316 | } else if (token.getPredicate().startsWith("_")) { |
||
317 | |||
318 | // partially controllable token |
||
319 | controllability = ControllabilityType.PARTIALLY_CONTROLLABLE; |
||
320 | |||
321 | } else { |
||
322 | |||
323 | // controllable token |
||
324 | controllability = ControllabilityType.CONTROLLABLE; |
||
325 | } |
||
326 | |||
327 | // set parameter information |
||
328 | String signature = token.getPredicate(); |
||
329 | String[] paramValues = new String[token.getParameters().size()]; |
||
330 | ParameterType[] paramTypes = new ParameterType[token.getParameters().size()]; |
||
331 | for (int index = 0; index < token.getParameters().size(); index++) { |
||
332 | |||
333 | // get parameter |
||
334 | ParameterDescriptor param= token.getParameter(index); |
||
335 | // check type |
||
336 | if (param.getType().equals(ParameterTypeDescriptor.NUMERIC)) { |
||
337 | // set type |
||
338 | paramTypes[index] = ParameterType.NUMERIC_PARAMETER_TYPE; |
||
339 | // set value |
||
340 | paramValues[index] = Long.toString(param.getBounds()[0]); |
||
341 | |||
342 | } else { |
||
343 | |||
344 | // enumeration |
||
345 | paramTypes[index] = ParameterType.ENUMERATION_PARAMETER_TYPE; |
||
346 | // set value |
||
347 | paramValues[index] = param.getValues()[0]; |
||
348 | } |
||
349 | } |
||
350 | |||
351 | // create a node |
||
352 | ExecutionNode node = this.createNode(tl.getComponent(), tl.getName(), |
||
353 | signature, paramTypes, paramValues, |
||
354 | start, end, duration, controllability, token.getStartExecutionState()); |
||
355 | |||
356 | // add node |
||
357 | this.addNode(node); |
||
358 | // add entry to the dictionary |
||
359 | dictionary.put(token, node); |
||
360 | |||
361 | // add node to list |
||
362 | list[counter] = node; |
||
363 | counter++; |
||
364 | } |
||
365 | |||
366 | } |
||
367 | |||
368 | // link subsequent nodes |
||
369 | for (int pos = 0; pos < list.length; pos++) { |
||
370 | |||
371 | // check first node |
||
372 | if (pos == 0) { |
||
373 | |||
374 | // first node of the timeline |
||
375 | ExecutionNode first = list[pos]; |
||
376 | // set next node |
||
377 | first.setNext(list[pos+1]); |
||
378 | |||
379 | } else if (pos == list.length - 1) { |
||
380 | // last node of the timeline |
||
381 | ExecutionNode last = list[pos]; |
||
382 | // set previous ndoe |
||
383 | last.setPrev(list[pos-1]); |
||
384 | |||
385 | } else { |
||
386 | |||
387 | // intermediate node |
||
388 | ExecutionNode i = list[pos]; |
||
389 | // set prev |
||
390 | i.setPrev(list[pos-1]); |
||
391 | // set next |
||
392 | i.setNext(list[pos+1]); |
||
393 | } |
||
394 | } |
||
395 | } |
||
396 | |||
397 | // check relations |
||
398 | for (RelationProtocolDescriptor rel : plan.getRelations()) { |
||
399 | try { |
||
400 | |||
401 | // get related nodes |
||
402 | ExecutionNode reference = dictionary.get(rel.getFrom()); |
||
403 | ExecutionNode target = dictionary.get(rel.getTo()); |
||
404 | // add temporal constraints and related execution dependencies |
||
405 | this.createConstraintsAndDependencies(reference, target, rel); |
||
406 | |||
407 | } catch (Exception ex) { |
||
408 | |||
409 | // exception |
||
410 | throw new TemporalConsistencyException("Error while propagating plan's relation " + rel + "\n" + ex.getMessage()); |
||
411 | } |
||
412 | } |
||
413 | |||
414 | // check consistency |
||
415 | this.facade.verifyTemporalConsistency(); |
||
416 | // check the schedule for all temporal intervals |
||
417 | for (ExecutionNode node : dictionary.values()) { |
||
418 | // check node schedule |
||
419 | IntervalScheduleQuery query = this.facade.createTemporalQuery(TemporalQueryType.INTERVAL_SCHEDULE); |
||
420 | query.setInterval(node.getInterval()); |
||
421 | this.facade.process(query); |
||
422 | } |
||
423 | |||
424 | // prepare log message |
||
425 | String msg = ""; |
||
426 | // print execution dependency graph (for debug only) |
||
427 | for (ExecutionNodeStatus status : this.nodes.keySet()) { |
||
428 | // get nodes by status |
||
429 | for (ExecutionNode node : this.nodes.get(status)) { |
||
430 | |||
431 | // print node and the related execution conditions |
||
432 | msg += "Execution node " + node + "\n"; |
||
433 | msg += "\tNode execution starting conditions:\n"; |
||
434 | Map<ExecutionNode, ExecutionNodeStatus[]> dependencies = this.getNodeStartDependencies(node); |
||
435 | for (ExecutionNode dep : dependencies.keySet()) { |
||
436 | msg += "\t\tCan start if -> " + dep.getId() + ":"+ dep.getGroundSignature() + " is in " + dependencies.get(dep) + "\n"; |
||
437 | } |
||
438 | |||
439 | // get end conditions |
||
440 | dependencies = this.getNodeEndDependencies(node); |
||
441 | msg += "\tNode execution ending conditions:\n"; |
||
442 | for (ExecutionNode dep : dependencies.keySet()) { |
||
443 | msg += "\t\tCan end if -> " + dep.getId() + ":" + dep.getGroundSignature() + " is in " + dependencies.get(dep) + "\n"; |
||
444 | } |
||
445 | } |
||
446 | } |
||
447 | |||
448 | // print log message |
||
449 | debug(msg); |
||
450 | |||
451 | } catch (TemporalIntervalCreationException ex) { |
||
452 | throw new RuntimeException(ex.getMessage()); |
||
453 | |||
454 | } catch (TemporalConsistencyException ex) { |
||
455 | throw new RuntimeException(ex.getMessage()); |
||
456 | } |
||
457 | } |
||
458 | |||
459 | |||
460 | |||
461 | /** |
||
462 | * |
||
463 | * @param reference |
||
464 | * @param target |
||
465 | * @param rel |
||
466 | * @throws Exception |
||
467 | */ |
||
468 | protected void createConstraintsAndDependencies(ExecutionNode reference, ExecutionNode target, Relation rel) |
||
469 | throws Exception { |
||
470 | |||
471 | // check temporal category |
||
472 | if (rel.getCategory().equals(ConstraintCategory.TEMPORAL_CONSTRAINT)) { |
||
473 | // check relation |
||
474 | switch (rel.getType()) { |
||
475 | |||
476 | // meets temporal relation |
||
477 | case MEETS : { |
||
478 | // get meets relation |
||
479 | MeetsRelation meets = (MeetsRelation) rel; |
||
480 | // prepare meets constraint |
||
481 | this.prepareMeetsTemporalConstraint(reference, target, meets.getBounds()); |
||
482 | } |
||
483 | break; |
||
484 | |||
485 | // before temporal relation |
||
486 | case BEFORE : { |
||
487 | // get before relation |
||
488 | BeforeRelation before = (BeforeRelation) rel; |
||
489 | // prepare before constraint |
||
490 | this.prepareBeforeTemporalConstraint(reference, target, before.getBounds()); |
||
491 | } |
||
492 | break; |
||
493 | |||
494 | case MET_BY : { |
||
495 | // get met-by relation |
||
496 | MetByRelation metby = (MetByRelation) rel; |
||
497 | this.prepareAfterTemporalConstraint(reference, target, metby.getBounds()); |
||
498 | } |
||
499 | break; |
||
500 | |||
501 | case AFTER : { |
||
502 | // get after relation |
||
503 | AfterRelation after = (AfterRelation) rel; |
||
504 | // prepare after constraint |
||
505 | this.prepareAfterTemporalConstraint(reference, target, after.getBounds()); |
||
506 | } |
||
507 | break; |
||
508 | |||
509 | case CONTAINS : { |
||
510 | // get contains relation |
||
511 | ContainsRelation contains = (ContainsRelation) rel; |
||
512 | // prepare contains constraint |
||
513 | this.prepareContainsTemporalConstraint(reference, target, contains.getBounds()); |
||
514 | } |
||
515 | break; |
||
516 | |||
517 | case DURING : { |
||
518 | // get during relation |
||
519 | DuringRelation during = (DuringRelation) rel; |
||
520 | // prepare during constraint |
||
521 | this.prepareDuringTemporalConstraint(reference, target, during.getBounds()); |
||
522 | } |
||
523 | break; |
||
524 | |||
525 | case EQUALS : { |
||
526 | // get equals relation |
||
527 | EqualsRelation equals = (EqualsRelation) rel; |
||
528 | // prepare equals constraint |
||
529 | this.prepareEqualsTemporalConstraint(reference, target, equals.getBounds()); |
||
530 | } |
||
531 | break; |
||
532 | |||
533 | case STARTS_DURING : { |
||
534 | // get starts-during relation |
||
535 | StartsDuringRelation sduring = (StartsDuringRelation) rel; |
||
536 | // prepare starts-during constraint |
||
537 | this.prepareStartsDuringTemporalConstraint(reference, target, sduring.getBounds()); |
||
538 | } |
||
539 | break; |
||
540 | |||
541 | case ENDS_DURING : { |
||
542 | // get ends-during relation |
||
543 | EndsDuringRelation eduring = (EndsDuringRelation) rel; |
||
544 | // prepare ends-during constraint |
||
545 | this.prepareEndsDuringTemporalConstraint(reference, target, eduring.getBounds()); |
||
546 | } |
||
547 | break; |
||
548 | |||
549 | default : { |
||
550 | throw new RuntimeException("Unknown relation " + rel.getType()); |
||
551 | } |
||
552 | |||
553 | } |
||
554 | } |
||
555 | } |
||
556 | |||
557 | /** |
||
558 | * |
||
559 | * @param reference |
||
560 | * @param target |
||
561 | * @param rel |
||
562 | */ |
||
563 | protected void createConstraintsAndDependencies(ExecutionNode reference, ExecutionNode target, RelationProtocolDescriptor rel) |
||
564 | throws Exception { |
||
565 | |||
566 | // check relation type |
||
567 | switch (rel.getType()) { |
||
568 | |||
569 | // meets temporal relation |
||
570 | case "meets" : { |
||
571 | // prepare meets constraint |
||
572 | this.prepareMeetsTemporalConstraint(reference, target, new long[][] { |
||
573 | {0, 0} |
||
574 | }); |
||
575 | } |
||
576 | break; |
||
577 | |||
578 | case "before" : { |
||
579 | // prepare before constraint |
||
580 | this.prepareBeforeTemporalConstraint(reference, target, new long[][] { |
||
581 | rel.getFirstBound() |
||
582 | }); |
||
583 | } |
||
584 | break; |
||
585 | |||
586 | case "met-by" : { |
||
587 | // prepare after constraint |
||
588 | this.prepareMeetsTemporalConstraint(target, reference, new long[][] { |
||
589 | {0, 0} |
||
590 | }); |
||
591 | } |
||
592 | break; |
||
593 | |||
594 | case "after" : { |
||
595 | // prepare after constraint |
||
596 | this.prepareAfterTemporalConstraint(reference, target, new long[][] { |
||
597 | rel.getFirstBound() |
||
598 | }); |
||
599 | } |
||
600 | break; |
||
601 | |||
602 | case "during" : { |
||
603 | // prepare during constraint |
||
604 | this.prepareDuringTemporalConstraint(reference, target, new long[][] { |
||
605 | rel.getFirstBound(), |
||
606 | rel.getSecondBound() |
||
607 | }); |
||
608 | } |
||
609 | break; |
||
610 | |||
611 | case "contains" : { |
||
612 | // prepare contains constraint |
||
613 | this.prepareContainsTemporalConstraint(reference, target, new long[][] { |
||
614 | rel.getFirstBound(), |
||
615 | rel.getSecondBound() |
||
616 | }); |
||
617 | } |
||
618 | break; |
||
619 | |||
620 | case "equals" : { |
||
621 | // prepare equals constraint |
||
622 | this.prepareEqualsTemporalConstraint(reference, target, new long[][] { |
||
623 | {0, 0}, |
||
624 | {0, 0} |
||
625 | }); |
||
626 | } |
||
627 | break; |
||
628 | |||
629 | case "starts_during" : { |
||
630 | // prepare starts-during constraint |
||
631 | this.prepareStartsDuringTemporalConstraint(reference, target, new long[][] { |
||
632 | rel.getFirstBound(), |
||
633 | rel.getSecondBound() |
||
634 | }); |
||
635 | } |
||
636 | break; |
||
637 | |||
638 | case "ends_during" : { |
||
639 | // prepare ends-during constraint |
||
640 | this.prepareEndsDuringTemporalConstraint(reference, target, new long[][] { |
||
641 | rel.getFirstBound(), |
||
642 | rel.getSecondBound() |
||
643 | }); |
||
644 | } |
||
645 | break; |
||
646 | |||
647 | default : { |
||
648 | // unknown temporal relation |
||
649 | throw new RuntimeException("Unknown relation " + rel.getType()); |
||
650 | } |
||
651 | } |
||
652 | } |
||
653 | |||
654 | |||
655 | /** |
||
656 | * |
||
657 | * @return |
||
658 | */ |
||
659 | public List<ExecutionNode> getNodesByStatus(ExecutionNodeStatus status) { |
||
660 | |||
661 | // list of nodes |
||
662 | List<ExecutionNode> list = new LinkedList<>(); |
||
663 | synchronized (this.locks[status.getIndex()]) { |
||
664 | // get all nodes with the desired status |
||
665 | list.addAll(this.nodes.get(status)); |
||
666 | } |
||
667 | |||
668 | // get the list of node with the desired status |
||
669 | return list; |
||
670 | } |
||
671 | |||
672 | /** |
||
673 | * |
||
674 | * @param node |
||
675 | * @param status |
||
676 | */ |
||
677 | public synchronized void updateNodeStatus(ExecutionNode node, ExecutionNodeStatus status) { |
||
678 | |||
679 | // remove node from the current status |
||
680 | synchronized (this.locks[node.getStatus().getIndex()]) { |
||
681 | // remove node from list |
||
682 | this.nodes.get(node.getStatus()).remove(node); |
||
683 | } |
||
684 | |||
685 | // add node to the new status |
||
686 | synchronized (this.locks[status.getIndex()]) { |
||
687 | // add node |
||
688 | this.nodes.get(status).add(node); |
||
689 | // update status |
||
690 | node.setStatus(status); |
||
691 | } |
||
692 | } |
||
693 | |||
694 | /** |
||
695 | * |
||
696 | * @param node |
||
697 | * @return |
||
698 | */ |
||
699 | public Map<ExecutionNode, ExecutionNodeStatus[]> getNodeStartDependencies(ExecutionNode node) { |
||
700 | return new HashMap<>(this.sdg.get(node)); |
||
701 | } |
||
702 | |||
703 | /** |
||
704 | * |
||
705 | * @param node |
||
706 | * @return |
||
707 | */ |
||
708 | public Map<ExecutionNode, ExecutionNodeStatus[]> getNodeEndDependencies(ExecutionNode node) { |
||
709 | return new HashMap<>(this.edg.get(node)); |
||
710 | } |
||
711 | |||
712 | /** |
||
713 | * |
||
714 | * @param node |
||
715 | * @return |
||
716 | */ |
||
717 | public Map<ExecutionNode, ExecutionNodeStatus[]> getNodeStopDependencies(ExecutionNode node) { |
||
718 | return new HashMap<>(this.stop.get(node)); |
||
719 | } |
||
720 | |||
721 | |||
722 | /** |
||
723 | * |
||
724 | * @param node |
||
725 | */ |
||
726 | public void checkSchedule(ExecutionNode node) { |
||
727 | |||
728 | // check resulting schedule of the interval |
||
729 | IntervalScheduleQuery query = this.facade. |
||
730 | createTemporalQuery(TemporalQueryType.INTERVAL_SCHEDULE); |
||
731 | query.setInterval(node.getInterval()); |
||
732 | this.facade.process(query); |
||
733 | } |
||
734 | |||
735 | /** |
||
736 | * |
||
737 | * @param node |
||
738 | */ |
||
739 | public void addNode(ExecutionNode node) { |
||
740 | |||
741 | // check expected initial execution state |
||
742 | ExecutionNodeStatus initial = node.getStartExecutionState(); |
||
743 | node.setStatus(initial); |
||
744 | this.nodes.get(initial).add(node); |
||
745 | // setup dependency graph data structures |
||
746 | this.sdg.put(node, new HashMap<ExecutionNode, ExecutionNodeStatus[]>()); |
||
747 | this.edg.put(node, new HashMap<ExecutionNode, ExecutionNodeStatus[]>()); |
||
748 | this.stop.put(node, new HashMap<ExecutionNode, ExecutionNodeStatus[]>()); |
||
749 | } |
||
750 | |||
751 | /** |
||
752 | * |
||
753 | */ |
||
754 | public void clearExecutedNodes() { |
||
755 | |||
756 | // check executed nodes |
||
757 | Set<ExecutionNode> nodes = new HashSet<>(this.nodes.get(ExecutionNodeStatus.EXECUTED)); |
||
758 | // clear nodes |
||
759 | this.nodes.get(ExecutionNodeStatus.EXECUTED).clear(); |
||
760 | // clear execution graph |
||
761 | for (ExecutionNode node : nodes) { |
||
762 | // clear map entries |
||
763 | this.sdg.remove(node); |
||
764 | this.edg.remove(node); |
||
765 | this.stop.remove(node); |
||
766 | |||
767 | // clear edges |
||
768 | for (ExecutionNode n : this.sdg.keySet()) { |
||
769 | // remove edge |
||
770 | this.sdg.get(n).remove(node); |
||
771 | |||
772 | } |
||
773 | |||
774 | // clear edges |
||
775 | for (ExecutionNode n : this.edg.keySet()) { |
||
776 | // remove edge |
||
777 | this.edg.get(n).remove(node); |
||
778 | } |
||
779 | |||
780 | // clear edges |
||
781 | for (ExecutionNode n : this.stop.keySet()) { |
||
782 | // remove edge |
||
783 | this.stop.get(n).remove(node); |
||
784 | } |
||
785 | } |
||
786 | } |
||
787 | |||
788 | /** |
||
789 | * |
||
790 | * @param component |
||
791 | * @param timeline |
||
792 | * @param signature |
||
793 | * @param pTypes |
||
794 | * @param pValues |
||
795 | * @param start |
||
796 | * @param end |
||
797 | * @param duration |
||
798 | * @param controllability |
||
799 | * @param state |
||
800 | * @return |
||
801 | * @throws TemporalIntervalCreationException |
||
802 | */ |
||
803 | protected ExecutionNode createNode(String component, String timeline, |
||
804 | String signature, ParameterType[] pTypes, String[] pValues, |
||
805 | long[] start, long[] end, long[] duration, |
||
806 | ControllabilityType controllability, |
||
807 | ExecutionNodeStatus state) |
||
808 | throws TemporalIntervalCreationException { |
||
809 | |||
810 | // create temporal interval - consider all intervals as controllable during execution |
||
811 | TemporalInterval interval = this.facade.createTemporalInterval(start, end, duration, true); |
||
812 | // create predicate |
||
813 | NodePredicate predicate = new NodePredicate(component, timeline, signature, pTypes, pValues); |
||
814 | // create execution node |
||
815 | return new ExecutionNode(predicate, interval, controllability, state); |
||
816 | } |
||
817 | |||
818 | /** |
||
819 | * |
||
820 | * @param node |
||
821 | * @param dependency |
||
822 | * @param condition |
||
823 | */ |
||
824 | protected void addStartExecutionDependency(ExecutionNode node, ExecutionNode dependency, ExecutionNodeStatus[] conditions) { |
||
825 | // add node's start dependency and related condition |
||
826 | this.sdg.get(node).put(dependency, conditions); |
||
827 | } |
||
828 | |||
829 | /** |
||
830 | * |
||
831 | * @param node |
||
832 | * @param dependency |
||
833 | * @param condition |
||
834 | */ |
||
835 | protected void addEndExecutionDependency(ExecutionNode node, ExecutionNode dependency, ExecutionNodeStatus[] conditions) { |
||
836 | // add node's end dependency and related condition |
||
837 | this.edg.get(node).put(dependency, conditions); |
||
838 | } |
||
839 | |||
840 | /** |
||
841 | * |
||
842 | * @param node |
||
843 | * @param dependency |
||
844 | * @param conditions |
||
845 | */ |
||
846 | protected void addStopExecutionDependency(ExecutionNode node, ExecutionNode dependency, ExecutionNodeStatus[] conditions) { |
||
847 | // add node's end dependency and related condition |
||
848 | this.stop.get(node).put(dependency, conditions); |
||
849 | } |
||
850 | |||
851 | /** |
||
852 | * |
||
853 | * @param node |
||
854 | * @return |
||
855 | */ |
||
856 | public boolean checkEndExecutionDependencies(ExecutionNode node) { |
||
857 | |||
858 | // set end execution flag |
||
859 | boolean canEnd = true; |
||
860 | // check dependencies if any |
||
861 | Map<ExecutionNode, ExecutionNodeStatus[]> dependencies = this.getNodeEndDependencies(node); |
||
862 | View Code Duplication | if (!dependencies.isEmpty()) { |
|
863 | |||
864 | // check if conditions are satisfied |
||
865 | Iterator<ExecutionNode> it = dependencies.keySet().iterator(); |
||
866 | // at least one condition for each dependency should be satisfied |
||
867 | while (it.hasNext() && canEnd) { |
||
868 | |||
869 | // get next dependency |
||
870 | ExecutionNode d = it.next(); |
||
871 | // get end conditions for the current node |
||
872 | ExecutionNodeStatus[] conditions = dependencies.get(d); |
||
873 | |||
874 | // check if at least one is satisfied |
||
875 | boolean satisfied = false; |
||
876 | // check if one of the disjunctive conditions is satisfied |
||
877 | for (ExecutionNodeStatus condition : conditions) { |
||
878 | // check condition |
||
879 | if (d.getStatus().equals(condition)) { |
||
880 | satisfied = true; |
||
881 | break; |
||
882 | } |
||
883 | |||
884 | } |
||
885 | |||
886 | // update can end flag |
||
887 | canEnd = satisfied; |
||
888 | } |
||
889 | } |
||
890 | |||
891 | // true if the node can end execution |
||
892 | return canEnd; |
||
893 | } |
||
894 | |||
895 | /** |
||
896 | * |
||
897 | * @param node |
||
898 | * @return |
||
899 | */ |
||
900 | public boolean checkStopExecutionDependencies(ExecutionNode node) { |
||
901 | |||
902 | // set stop condition |
||
903 | boolean canStop = true; |
||
904 | // check dependencies if any |
||
905 | Map<ExecutionNode, ExecutionNodeStatus[]> dependencies = this.getNodeStopDependencies(node); |
||
906 | // check execution flag |
||
907 | View Code Duplication | if (!dependencies.isEmpty()) { |
|
908 | |||
909 | // check if conditions are satisfied |
||
910 | Iterator<ExecutionNode> it = dependencies.keySet().iterator(); |
||
911 | // check all conditions |
||
912 | while (it.hasNext() && canStop) { |
||
913 | |||
914 | // get next dependency |
||
915 | ExecutionNode d = it.next(); |
||
916 | // get end conditions |
||
917 | ExecutionNodeStatus[] conditions = dependencies.get(d); |
||
918 | // check if at least one is satisfied |
||
919 | boolean satisfied = false; |
||
920 | |||
921 | // check if one of the disjunctive conditions is satisfied |
||
922 | for (ExecutionNodeStatus condition : conditions) { |
||
923 | // check condition |
||
924 | if (d.getStatus().equals(condition)) { |
||
925 | satisfied = true; |
||
926 | break; |
||
927 | } |
||
928 | |||
929 | } |
||
930 | |||
931 | // update can end flag |
||
932 | canStop = satisfied; |
||
933 | } |
||
934 | } |
||
935 | |||
936 | // true if the node can stop execution |
||
937 | return canStop; |
||
938 | } |
||
939 | |||
940 | /** |
||
941 | * |
||
942 | * @param node |
||
943 | * @return |
||
944 | */ |
||
945 | public boolean checkStartExecutionDependencies(ExecutionNode node) { |
||
946 | |||
947 | // set start condition |
||
948 | boolean canStart = true; |
||
949 | // get node's start dependencies |
||
950 | Map<ExecutionNode, ExecutionNodeStatus[]> dependencies = this.getNodeStartDependencies(node); |
||
951 | // check execution flag |
||
952 | View Code Duplication | if (!dependencies.isEmpty()) { |
|
953 | |||
954 | // check if conditions are satisfied |
||
955 | Iterator<ExecutionNode> it = dependencies.keySet().iterator(); |
||
956 | // check all conditions |
||
957 | while (it.hasNext() && canStart) { |
||
958 | |||
959 | // get a dependency parent |
||
960 | ExecutionNode d = it.next(); |
||
961 | // get start conditions |
||
962 | ExecutionNodeStatus[] conditions = dependencies.get(d); |
||
963 | // check if at least one is satisfied |
||
964 | boolean satisfied = false; |
||
965 | |||
966 | // check if one of the disjunctive conditions is satisfied |
||
967 | for (ExecutionNodeStatus condition : conditions) { |
||
968 | // check condition |
||
969 | if (d.getStatus().equals(condition)) { |
||
970 | // node can start |
||
971 | satisfied = true; |
||
972 | break; |
||
973 | } |
||
974 | } |
||
975 | |||
976 | // update can start flag |
||
977 | canStart = satisfied; |
||
978 | } |
||
979 | } |
||
980 | |||
981 | // true if ready |
||
982 | return canStart; |
||
983 | } |
||
984 | |||
985 | /** |
||
986 | * |
||
987 | * @param node |
||
988 | * @param duration |
||
989 | * @throws TemporalConstraintPropagationException |
||
990 | */ |
||
991 | public final void scheduleDuration(ExecutionNode node, long duration) |
||
992 | throws TemporalConstraintPropagationException { |
||
993 | |||
994 | // fix start time first |
||
995 | FixIntervalDurationConstraint fix = this.facade. |
||
996 | createTemporalConstraint(TemporalConstraintType.FIX_INTERVAL_DURATION); |
||
997 | fix.setReference(node.getInterval()); |
||
998 | fix.setDuration(duration); |
||
999 | // propagate constraint |
||
1000 | this.facade.propagate(fix); |
||
1001 | try { |
||
1002 | |||
1003 | // check the consistency of the resulting network |
||
1004 | this.facade.verifyTemporalConsistency(); |
||
1005 | |||
1006 | } catch (TemporalConsistencyException ex) { |
||
1007 | // retract propagated constraint and throw exception |
||
1008 | this.facade.retract(fix); |
||
1009 | throw new TemporalConstraintPropagationException("Error while propagating duration constraint for node\n- duration= " + duration +"\n- node= " + node + "\n"); |
||
1010 | } |
||
1011 | } |
||
1012 | |||
1013 | /** |
||
1014 | * |
||
1015 | * @param node |
||
1016 | * @param time |
||
1017 | * @throws TemporalConstraintPropagationException |
||
1018 | */ |
||
1019 | View Code Duplication | public final void scheduleStartTime(ExecutionNode node, long time) |
|
1020 | throws TemporalConstraintPropagationException { |
||
1021 | |||
1022 | // create constraint |
||
1023 | FixTimePointConstraint fix = this.facade. |
||
1024 | createTemporalConstraint(TemporalConstraintType.FIX_TIME_POINT); |
||
1025 | // set time point |
||
1026 | fix.setReference(node.getInterval().getStartTime()); |
||
1027 | fix.setTime(time); |
||
1028 | // propagate constraint |
||
1029 | this.facade.propagate(fix); |
||
1030 | try { |
||
1031 | |||
1032 | // check consistency of the resulting network |
||
1033 | this.facade.verifyTemporalConsistency(); |
||
1034 | |||
1035 | } catch (TemporalConsistencyException ex) { |
||
1036 | // retract propagated constraint and throw exception |
||
1037 | this.facade.retract(fix); |
||
1038 | throw new TemporalConstraintPropagationException("Error while propagating start constraint for node\n- " |
||
1039 | + "time= " + time+ "\n- node= " + node + "\n"); |
||
1040 | } |
||
1041 | } |
||
1042 | |||
1043 | /** |
||
1044 | * |
||
1045 | * @param node |
||
1046 | * @param end |
||
1047 | * @throws TemporalConstraintPropagationException |
||
1048 | */ |
||
1049 | View Code Duplication | public void scheduleEndTime(ExecutionNode node, long time) |
|
1050 | throws TemporalConstraintPropagationException { |
||
1051 | |||
1052 | // create constraint |
||
1053 | FixTimePointConstraint fix = this.facade. |
||
1054 | createTemporalConstraint(TemporalConstraintType.FIX_TIME_POINT); |
||
1055 | // set time point |
||
1056 | fix.setReference(node.getInterval().getEndTime()); |
||
1057 | // set time |
||
1058 | fix.setTime(time); |
||
1059 | // propagate constraint |
||
1060 | this.facade.propagate(fix); |
||
1061 | try { |
||
1062 | |||
1063 | // check consistency of the resulting network |
||
1064 | this.facade.verifyTemporalConsistency(); |
||
1065 | |||
1066 | } catch (TemporalConsistencyException ex) { |
||
1067 | // retract propagated constraint and throw exception |
||
1068 | this.facade.retract(fix); |
||
1069 | throw new TemporalConstraintPropagationException("Error while propagating end constraint for node\n" |
||
1070 | + "- time= " + time+ "\n- node= " + node + "\n"); |
||
1071 | } |
||
1072 | } |
||
1073 | |||
1074 | /** |
||
1075 | * |
||
1076 | * @param reference |
||
1077 | * @param target |
||
1078 | * @param bounds |
||
1079 | * @throws Exception |
||
1080 | */ |
||
1081 | protected void prepareBeforeTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1082 | throws Exception { |
||
1083 | |||
1084 | // create and propagate temporal constraint |
||
1085 | BeforeIntervalConstraint constraint = this.facade. |
||
1086 | createTemporalConstraint(TemporalConstraintType.BEFORE); |
||
1087 | |||
1088 | // set data |
||
1089 | constraint.setReference(reference.getInterval()); |
||
1090 | constraint.setTarget(target.getInterval()); |
||
1091 | constraint.setLowerBound(bounds[0][0]); |
||
1092 | constraint.setUpperBound(bounds[0][1]); |
||
1093 | // propagate constraint |
||
1094 | this.facade.propagate(constraint); |
||
1095 | |||
1096 | // set execution constraints |
||
1097 | this.addStartExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1098 | ExecutionNodeStatus.EXECUTED |
||
1099 | }); |
||
1100 | } |
||
1101 | |||
1102 | /** |
||
1103 | * |
||
1104 | * @param reference |
||
1105 | * @param target |
||
1106 | * @param bounds |
||
1107 | * @throws Exception |
||
1108 | */ |
||
1109 | protected void prepareMeetsTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1110 | throws Exception { |
||
1111 | |||
1112 | // create and propagate temporal constraint |
||
1113 | MeetsIntervalConstraint constraint = this.facade. |
||
1114 | createTemporalConstraint(TemporalConstraintType.MEETS); |
||
1115 | // set data |
||
1116 | constraint.setReference(reference.getInterval()); |
||
1117 | constraint.setTarget(target.getInterval()); |
||
1118 | // propagate constraint |
||
1119 | this.facade.propagate(constraint); |
||
1120 | |||
1121 | // set execution constraints |
||
1122 | this.addStartExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1123 | ExecutionNodeStatus.EXECUTED |
||
1124 | }); |
||
1125 | } |
||
1126 | |||
1127 | /** |
||
1128 | * |
||
1129 | * @param reference |
||
1130 | * @param target |
||
1131 | * @param bounds |
||
1132 | * @throws Exception |
||
1133 | */ |
||
1134 | protected void prepareAfterTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1135 | throws Exception { |
||
1136 | |||
1137 | // create constraint |
||
1138 | AfterIntervalConstraint constraint = this.facade. |
||
1139 | createTemporalConstraint(TemporalConstraintType.AFTER); |
||
1140 | // set references |
||
1141 | constraint.setReference(reference.getInterval()); |
||
1142 | constraint.setTarget(target.getInterval()); |
||
1143 | |||
1144 | // set bounds |
||
1145 | constraint.setLowerBound(bounds[0][0]); |
||
1146 | constraint.setUpperBound(bounds[0][1]); |
||
1147 | // propagate temporal constraint |
||
1148 | this.facade.propagate(constraint); |
||
1149 | |||
1150 | // add execution dependencies |
||
1151 | this.addStartExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1152 | ExecutionNodeStatus.EXECUTED |
||
1153 | }); |
||
1154 | } |
||
1155 | |||
1156 | /** |
||
1157 | * |
||
1158 | * @param reference |
||
1159 | * @param target |
||
1160 | * @param bounds |
||
1161 | * @throws Exception |
||
1162 | */ |
||
1163 | View Code Duplication | protected void prepareDuringTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
|
1164 | throws Exception { |
||
1165 | |||
1166 | // create constraint |
||
1167 | DuringIntervalConstraint constraint = this.facade. |
||
1168 | createTemporalConstraint(TemporalConstraintType.DURING); |
||
1169 | // set references |
||
1170 | constraint.setReference(reference.getInterval()); |
||
1171 | constraint.setTarget(target.getInterval()); |
||
1172 | |||
1173 | // set bounds |
||
1174 | constraint.setStartTimeBound(bounds[0]); |
||
1175 | constraint.setEndTimeBound(bounds[1]); |
||
1176 | // propagate temporal constraint |
||
1177 | this.facade.propagate(constraint); |
||
1178 | |||
1179 | |||
1180 | // add execution dependencies |
||
1181 | this.addStartExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1182 | ExecutionNodeStatus.IN_EXECUTION |
||
1183 | }); |
||
1184 | |||
1185 | this.addEndExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1186 | ExecutionNodeStatus.IN_EXECUTION, |
||
1187 | }); |
||
1188 | |||
1189 | this.addEndExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1190 | ExecutionNodeStatus.EXECUTED, |
||
1191 | }); |
||
1192 | |||
1193 | |||
1194 | |||
1195 | |||
1196 | // add stop execution condition |
||
1197 | this.addStopExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1198 | ExecutionNodeStatus.IN_EXECUTION, |
||
1199 | ExecutionNodeStatus.FAILURE, |
||
1200 | }); |
||
1201 | |||
1202 | // add stop execution condition |
||
1203 | this.addStopExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1204 | ExecutionNodeStatus.EXECUTED, |
||
1205 | ExecutionNodeStatus.FAILURE, |
||
1206 | ExecutionNodeStatus.WAITING |
||
1207 | }); |
||
1208 | } |
||
1209 | |||
1210 | /** |
||
1211 | * |
||
1212 | * @param reference |
||
1213 | * @param target |
||
1214 | * @param bounds |
||
1215 | * @throws Exception |
||
1216 | */ |
||
1217 | View Code Duplication | protected void prepareContainsTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
|
1218 | throws Exception { |
||
1219 | |||
1220 | // create constraint |
||
1221 | ContainsIntervalConstraint constraint = this.facade. |
||
1222 | createTemporalConstraint(TemporalConstraintType.CONTAINS); |
||
1223 | // set references |
||
1224 | constraint.setReference(reference.getInterval()); |
||
1225 | constraint.setTarget(target.getInterval()); |
||
1226 | |||
1227 | // set bounds |
||
1228 | constraint.setStartTimeBound(bounds[0]); |
||
1229 | constraint.setEndTimeBound(bounds[1]); |
||
1230 | // propagate temporal constraint |
||
1231 | this.facade.propagate(constraint); |
||
1232 | |||
1233 | // add execution dependencies |
||
1234 | this.addEndExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1235 | ExecutionNodeStatus.EXECUTED, |
||
1236 | }); |
||
1237 | |||
1238 | this.addStartExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1239 | ExecutionNodeStatus.IN_EXECUTION |
||
1240 | }); |
||
1241 | |||
1242 | this.addEndExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1243 | ExecutionNodeStatus.IN_EXECUTION, |
||
1244 | }); |
||
1245 | |||
1246 | |||
1247 | // add stop execution condition |
||
1248 | this.addStopExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1249 | ExecutionNodeStatus.EXECUTED, |
||
1250 | ExecutionNodeStatus.FAILURE, |
||
1251 | ExecutionNodeStatus.WAITING |
||
1252 | }); |
||
1253 | |||
1254 | // add stop execution condition |
||
1255 | this.addStopExecutionDependency(target, reference, new ExecutionNodeStatus[] { |
||
1256 | ExecutionNodeStatus.IN_EXECUTION, |
||
1257 | ExecutionNodeStatus.FAILURE, |
||
1258 | |||
1259 | }); |
||
1260 | } |
||
1261 | |||
1262 | /** |
||
1263 | * |
||
1264 | * @param reference |
||
1265 | * @param target |
||
1266 | * @param bounds |
||
1267 | * @throws Exception |
||
1268 | */ |
||
1269 | protected void prepareEqualsTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1270 | throws Exception { |
||
1271 | |||
1272 | // create constraint |
||
1273 | EqualsIntervalConstraint constraint = this.facade. |
||
1274 | createTemporalConstraint(TemporalConstraintType.EQUALS); |
||
1275 | // set references |
||
1276 | constraint.setReference(reference.getInterval()); |
||
1277 | constraint.setTarget(target.getInterval()); |
||
1278 | // propagate temporal constraint |
||
1279 | this.facade.propagate(constraint); |
||
1280 | } |
||
1281 | |||
1282 | /** |
||
1283 | * |
||
1284 | * @param reference |
||
1285 | * @param target |
||
1286 | * @param bounds |
||
1287 | * @throws Exception |
||
1288 | */ |
||
1289 | protected void prepareStartsDuringTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1290 | throws Exception { |
||
1291 | |||
1292 | // create constraint |
||
1293 | StartsDuringIntervalConstraint constraint = this.facade. |
||
1294 | createTemporalConstraint(TemporalConstraintType.STARTS_DURING); |
||
1295 | // set references |
||
1296 | constraint.setReference(reference.getInterval()); |
||
1297 | constraint.setTarget(target.getInterval()); |
||
1298 | |||
1299 | // set bounds |
||
1300 | constraint.setFirstBound(bounds[0]); |
||
1301 | constraint.setSecondBound(bounds[1]); |
||
1302 | // propagate temporal constraint |
||
1303 | this.facade.propagate(constraint); |
||
1304 | |||
1305 | // add start dependency |
||
1306 | this.addStartExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1307 | ExecutionNodeStatus.IN_EXECUTION |
||
1308 | }); |
||
1309 | } |
||
1310 | |||
1311 | /** |
||
1312 | * |
||
1313 | * @param reference |
||
1314 | * @param target |
||
1315 | * @param bounds |
||
1316 | * @throws Exception |
||
1317 | */ |
||
1318 | protected void prepareEndsDuringTemporalConstraint(ExecutionNode reference, ExecutionNode target, long[][] bounds) |
||
1319 | throws Exception { |
||
1320 | |||
1321 | // create constraint |
||
1322 | EndsDuringIntervalConstraint constraint = this.facade. |
||
1323 | createTemporalConstraint(TemporalConstraintType.ENDS_DURING); |
||
1324 | |||
1325 | // set references |
||
1326 | constraint.setReference(reference.getInterval()); |
||
1327 | constraint.setTarget(target.getInterval()); |
||
1328 | // set bounds |
||
1329 | constraint.setFirstBound(bounds[0]); |
||
1330 | constraint.setSecondBound(bounds[1]); |
||
1331 | // propagate temporal constraint |
||
1332 | this.facade.propagate(constraint); |
||
1333 | |||
1334 | // add end dependency |
||
1335 | this.addEndExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1336 | ExecutionNodeStatus.IN_EXECUTION, |
||
1337 | }); |
||
1338 | |||
1339 | |||
1340 | // add stop execution condition |
||
1341 | this.addStopExecutionDependency(reference, target, new ExecutionNodeStatus[] { |
||
1342 | ExecutionNodeStatus.IN_EXECUTION, |
||
1343 | ExecutionNodeStatus.FAILURE |
||
1344 | }); |
||
1347 | } |
The Java documentation explain EnumMap.