it.cnr.istc.pst.platinum.ai.executive.pdb.ExecutivePlanDataBase   F
last analyzed

Complexity

Total Complexity 110

Size/Duplication

Total Lines 1282
Duplicated Lines 31.83 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 497
c 4
b 1
f 0
dl 408
loc 1282
rs 2
wmc 110

34 Methods

Rating   Name   Duplication   Size   Complexity  
A addNode(ExecutionNode) 0 10 1
A addStopExecutionDependency(ExecutionNode,ExecutionNode,ExecutionNodeStatus[]) 0 3 1
A createNode(String,String,String,ParameterType[],String[],long[],long[],long[],ControllabilityType,ExecutionNodeStatus) 0 13 1
A getName() 0 2 1
A getHorizon() 0 2 1
A getNodeStartDependencies(ExecutionNode) 0 2 1
A getOrigin() 0 2 1
A addStartExecutionDependency(ExecutionNode,ExecutionNode,ExecutionNodeStatus[]) 0 3 1
A getNodeEndDependencies(ExecutionNode) 0 2 1
A updateNodeStatus(ExecutionNode,ExecutionNodeStatus) 0 14 1
D createConstraintsAndDependencies(ExecutionNode,ExecutionNode,Relation) 0 83 12
A export() 0 24 2
A getNodeStopDependencies(ExecutionNode) 0 2 1
A getNodesByStatus(ExecutionNodeStatus) 0 11 1
A addEndExecutionDependency(ExecutionNode,ExecutionNode,ExecutionNodeStatus[]) 0 3 1
A ExecutivePlanDataBase() 0 22 3
A checkSchedule(ExecutionNode) 0 7 1
C createConstraintsAndDependencies(ExecutionNode,ExecutionNode,RelationProtocolDescriptor) 0 87 11
A clearExecutedNodes() 0 30 5
F setup(PlanProtocolDescriptor) 202 280 31
A prepareStartsDuringTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 19 1
B checkStartExecutionDependencies(ExecutionNode) 26 38 6
A prepareDuringTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 44 44 1
A prepareEndsDuringTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 26 1
A scheduleStartTime(ExecutionNode,long) 21 21 2
B checkStopExecutionDependencies(ExecutionNode) 26 38 6
A prepareContainsTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 41 41 1
B checkEndExecutionDependencies(ExecutionNode) 26 37 6
A scheduleDuration(ExecutionNode,long) 0 19 2
A prepareBeforeTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 18 1
A prepareAfterTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 19 1
A scheduleEndTime(ExecutionNode,long) 22 22 2
A prepareEqualsTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 11 1
A prepareMeetsTemporalConstraint(ExecutionNode,ExecutionNode,long[[]]) 0 15 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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;
2
3
import java.io.BufferedWriter;
4
import java.io.File;
5
import java.io.FileWriter;
6
import java.io.IOException;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.Iterator;
10
import java.util.LinkedList;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Set;
14
15
import it.cnr.istc.pst.platinum.ai.framework.microkernel.ConstraintCategory;
16
import it.cnr.istc.pst.platinum.ai.framework.microkernel.FrameworkObject;
17
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.cfg.framework.TemporalFacadeConfiguration;
18
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.inject.framework.TemporalFacadePlaceholder;
19
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.Relation;
20
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.AfterRelation;
21
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.BeforeRelation;
22
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.ContainsRelation;
23
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.DuringRelation;
24
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.EndsDuringRelation;
25
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.EqualsRelation;
26
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.MeetsRelation;
27
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.MetByRelation;
28
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.StartsDuringRelation;
29
import it.cnr.istc.pst.platinum.ai.framework.microkernel.query.TemporalQueryType;
30
import it.cnr.istc.pst.platinum.ai.framework.parameter.lang.ParameterType;
31
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.ParameterDescriptor;
32
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.ParameterTypeDescriptor;
33
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.PlanProtocolDescriptor;
34
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.TimelineProtocolDescriptor;
35
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.TokenProtocolDescriptor;
36
import it.cnr.istc.pst.platinum.ai.framework.protocol.lang.relation.RelationProtocolDescriptor;
37
import it.cnr.istc.pst.platinum.ai.framework.time.TemporalFacade;
38
import it.cnr.istc.pst.platinum.ai.framework.time.TemporalInterval;
39
import it.cnr.istc.pst.platinum.ai.framework.time.ex.TemporalConsistencyException;
40
import it.cnr.istc.pst.platinum.ai.framework.time.ex.TemporalConstraintPropagationException;
41
import it.cnr.istc.pst.platinum.ai.framework.time.ex.TemporalIntervalCreationException;
42
import it.cnr.istc.pst.platinum.ai.framework.time.lang.FixIntervalDurationConstraint;
43
import it.cnr.istc.pst.platinum.ai.framework.time.lang.FixTimePointConstraint;
44
import it.cnr.istc.pst.platinum.ai.framework.time.lang.TemporalConstraintType;
45
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.AfterIntervalConstraint;
46
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.BeforeIntervalConstraint;
47
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.ContainsIntervalConstraint;
48
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.DuringIntervalConstraint;
49
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.EndsDuringIntervalConstraint;
50
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.EqualsIntervalConstraint;
51
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.MeetsIntervalConstraint;
52
import it.cnr.istc.pst.platinum.ai.framework.time.lang.allen.StartsDuringIntervalConstraint;
53
import it.cnr.istc.pst.platinum.ai.framework.time.lang.query.IntervalScheduleQuery;
54
import it.cnr.istc.pst.platinum.ai.framework.time.solver.TemporalSolverType;
55
import it.cnr.istc.pst.platinum.ai.framework.time.tn.TemporalNetworkType;
56
57
/**
58
 * 
59
 * @author alessandro
60
 *
61
 */
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<>();
0 ignored issues
show
Performance introduced by
When using a map whose keys are EnumValues, consider using an EnumMap instead, which is more performant in this case.

The Java documentation explain EnumMap.

Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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")) {
0 ignored issues
show
Best Practice introduced by
Consider replacing calls these toUpperCase()/toLowerCase() and equals() calls with a single equalsIgnoreCase() call, as equalsIgnoreCase() is slightly faster.
Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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")) {
0 ignored issues
show
Best Practice introduced by
Consider replacing calls these toUpperCase()/toLowerCase() and equals() calls with a single equalsIgnoreCase() call, as equalsIgnoreCase() is slightly faster.
Loading history...
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()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
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";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
433
					msg += "\tNode execution starting conditions:\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
434
					Map<ExecutionNode, ExecutionNodeStatus[]> dependencies = this.getNodeStartDependencies(node);
435
					for (ExecutionNode dep : dependencies.keySet()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
436
						msg += "\t\tCan start if -> " + dep.getId() + ":"+ dep.getGroundSignature() + " is in " + dependencies.get(dep) + "\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
437
					}
438
					
439
					// get end conditions
440
					dependencies = this.getNodeEndDependencies(node);
441
					msg += "\tNode execution ending conditions:\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
442
					for (ExecutionNode dep : dependencies.keySet()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
443
						msg += "\t\tCan end if -> " + dep.getId() + ":" + dep.getGroundSignature() + " is in " + dependencies.get(dep) + "\n";
0 ignored issues
show
Performance introduced by
String concatenation with + is inefficient. Doing so in a loop may incur a significant performance penalty. Consider using a StringBuilder instead
Loading history...
444
					}
445
				}
446
			}
447
			
448
			// print log message
449
			debug(msg);
450
			
451
		} catch (TemporalIntervalCreationException ex) {
452
			throw new RuntimeException(ex.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
453
			
454
		} catch (TemporalConsistencyException ex) {
455
			throw new RuntimeException(ex.getMessage());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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));
0 ignored issues
show
Comprehensibility introduced by
The variable nodesshadows a field with the same name declared in line 81. Consider renaming it.
Loading history...
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()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
769
				// remove edge
770
				this.sdg.get(n).remove(node);
771
				
772
			}
773
			
774
			// clear edges
775
			for (ExecutionNode n : this.edg.keySet()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
776
				// remove edge
777
				this.edg.get(n).remove(node);
778
			}
779
			
780
			// clear edges
781
			for (ExecutionNode n : this.stop.keySet()) {
0 ignored issues
show
Performance introduced by
When you need both the keys and the value of a Map, iterating over entrySet() instead of keySet() is more readable.
Loading history...
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, 
0 ignored issues
show
Comprehensibility introduced by
Method has 10 parameters, which is greater than 7 authorized.
Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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 {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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) 
0 ignored issues
show
Unused Code introduced by
Remove this unused method parameter "bounds".
Loading history...
1110
			throws Exception {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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 {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1164
			throws Exception {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1218
			throws Exception {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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) 
0 ignored issues
show
Unused Code introduced by
Remove this unused method parameter "bounds".
Loading history...
1270
			throws Exception {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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 {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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 {
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
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
		});
1345
		
1346
	}
1347
}