Passed
Push — master ( 634a3f...1f3b93 )
by Alessandro
05:38
created

it.cnr.istc.pst.platinum.ai.framework.time.tn.TemporalNetwork   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 729
Duplicated Lines 12.62 %

Importance

Changes 0
Metric Value
eloc 224
dl 92
loc 729
rs 6.4799
c 0
b 0
f 0
wmc 54

32 Methods

Rating   Name   Duplication   Size   Complexity  
A getOriginTimePoint() 0 2 1
A subscribe(TemporalNetworkObserver) 0 4 1
getConstraints(TimePoint,TimePoint) 0 1 ?
doAddConstraint(TimePointDistanceConstraint) 0 2 ?
B addTimePoint(long) 48 48 5
A addDistanceConstraint(TimePointDistanceConstraint) 0 27 4
printDiagnosticData() 0 1 ?
A getOrigin() 0 2 1
A removeDistanceConstraint(List) 0 30 5
getTimePoint(int) 0 2 ?
A createDistanceConstraint(TimePoint,TimePoint,long[],boolean) 0 11 1
getConstraints(TimePoint) 0 1 ?
getConstraintBounds(TimePoint,TimePoint) 0 1 ?
B addTimePoint(long,long) 44 44 6
B addDistanceConstraint(TimePointDistanceConstraint[]) 0 58 7
doRemoveTimePoint(TimePoint) 0 1 ?
A removeConstraint(TimePointDistanceConstraint) 0 15 3
B addTimePoints(int) 0 52 6
getTimePoints() 0 1 ?
A TemporalNetwork(long,long) 0 19 1
A createTimePoint(long,long) 0 2 1
doRemoveDistanceConstraint(TimePointDistanceConstraint) 0 1 ?
getConstraintFromOrigin(TimePoint) 0 1 ?
getConstraintToHorizon(TimePoint) 0 1 ?
A getConstraints() 0 7 2
doAddTimePoint(TimePoint) 0 2 ?
A addTimePoint() 0 41 3
A removeTimePoints(List) 0 27 3
A getHorizon() 0 2 1
size() 0 1 ?
A removeTimePoint(TimePoint) 0 19 2
A getHorizonTimePoint() 0 2 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.framework.time.tn.TemporalNetwork 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.framework.time.tn;
2
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.HashSet;
6
import java.util.Iterator;
7
import java.util.LinkedList;
8
import java.util.List;
9
import java.util.Map;
10
import java.util.Set;
11
import java.util.concurrent.atomic.AtomicInteger;
12
13
import it.cnr.istc.pst.platinum.ai.framework.microkernel.FrameworkObject;
14
import it.cnr.istc.pst.platinum.ai.framework.time.tn.ex.InconsistentDistanceConstraintException;
15
import it.cnr.istc.pst.platinum.ai.framework.time.tn.ex.InconsistentTpValueException;
16
import it.cnr.istc.pst.platinum.ai.framework.time.tn.ex.TemporalNetworkTransactionFailureException;
17
import it.cnr.istc.pst.platinum.ai.framework.time.tn.ex.TimePointNotFoundException;
18
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.AddRelationTemporalNetworkNotification;
19
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.AddTimePointTemporalNetworkNotification;
20
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.DelRelationTemporalNetworkNotification;
21
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.DelTimePointTemporalNetworkNotification;
22
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.TemporalNetworkNotificationFactory;
23
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.TemporalNetworkNotificationTypes;
24
import it.cnr.istc.pst.platinum.ai.framework.time.tn.lang.event.TemporalNetworkObserver;
25
26
/**
27
 * 
28
 * @author alessandro
29
 *
30
 */
31
public abstract class TemporalNetwork extends FrameworkObject 
32
{
33
	private final AtomicInteger COUNTER = new AtomicInteger(0);				// time point ID counter
34
	protected long origin;
35
	protected long horizon;
36
	
37
	// origin time point
38
	protected TimePoint tpOrigin;
39
	// horizon time point
40
	protected TimePoint tpHorizion;
41
	
42
	// data structures
43
	protected Set<TimePoint> recyclePoints;
44
	
45
	// temporal network observers
46
	private final List<TemporalNetworkObserver> observers;
47
	
48
	/**
49
	 * Creates and initialize a Temporal Network instance.
50
	 * 
51
	 * The constructor takes as input a temporal origin and a 
52
	 * temporal horizon. These values determine the lower and the 
53
	 * upper bounds of time points variables respectively.
54
	 * 
55
	 * @param origin
56
	 * @param horizon
57
	 */
58
	protected TemporalNetwork(long origin, long horizon) {
59
		super();
60
		// initialize data
61
		this.origin = origin;
62
		this.horizon = horizon;
63
		
64
		// create the origin time point
65
		this.tpOrigin = new TimePoint(COUNTER.getAndIncrement(), origin, origin);
66
		this.tpOrigin.setLowerBound(origin);
67
		this.tpOrigin.setUpperBound(origin);
68
		
69
		// create the horizon time point
70
		this.tpHorizion = new TimePoint(COUNTER.getAndIncrement(), horizon, horizon);
71
		this.tpHorizion.setLowerBound(horizon);
72
		this.tpHorizion.setUpperBound(horizon);
73
		
74
		// setup recycle points and observers
75
		this.recyclePoints = new HashSet<TimePoint>();
76
		this.observers = new LinkedList<TemporalNetworkObserver>();
77
	}
78
79
	/**
80
	 * Subscribes a new observer to the Temporal Network
81
	 * 
82
	 * @param obs
83
	 */
84
	public final void subscribe(TemporalNetworkObserver obs) {
85
		synchronized (this.observers) {
86
			// add observer
87
			this.observers.add(obs);
88
		}
89
	}
90
	
91
	/**
92
	 * Returns the value of the origin
93
	 * 
94
	 * @return
95
	 */
96
	public final long getOrigin() {
97
		return origin;
98
	}
99
	
100
	/**
101
	 * Returns the value of the horizon
102
	 * 
103
	 * @return
104
	 */
105
	public final long getHorizon() {
106
		return this.horizon;
107
	}
108
	
109
	/**
110
	 * 
111
	 * @return
112
	 */
113
	public abstract int size();
114
	
115
	/**
116
	 * Returns the temporal origin reference time point
117
	 * 
118
	 * @return
119
	 */
120
	public final TimePoint getOriginTimePoint() {
121
		return this.tpOrigin;
122
	}
123
	
124
	/**
125
	 * 
126
	 * @return
127
	 */
128
	public final TimePoint getHorizonTimePoint() {
129
		return this.tpHorizion;
130
	}
131
	
132
	/**
133
	 * Returns the time point with selected id
134
	 * 
135
	 * @param id
136
	 * @return
137
	 * @throws TimePointNotFoundException
138
	 */
139
	public abstract TimePoint getTimePoint(int id) 
140
			throws TimePointNotFoundException;
141
	
142
	/**
143
	 * Returns all the time points of the temporal network
144
	 * 
145
	 * @return
146
	 */
147
	public abstract List<TimePoint> getTimePoints();
148
	
149
	/**
150
	 * Returns all distance constraints where the specified 
151
	 * time point is the source of the constraint
152
	 * 
153
	 * @param tp
154
	 * @return
155
	 */
156
	public abstract List<TimePointDistanceConstraint> getConstraints(TimePoint tp);
157
	
158
	/**
159
	 * Returns the list of all distance constraints of the network
160
	 * 
161
	 * @return
162
	 */
163
	public List<TimePointDistanceConstraint> getConstraints() {
164
		Set<TimePointDistanceConstraint> set = new HashSet<>();
165
		for (TimePoint tp : this.getTimePoints()) {
166
			// add constraints
167
			set.addAll(this.getConstraints(tp));
168
		}
169
		return new ArrayList<>(set);
170
	}
171
	
172
	/**
173
	 * Returns all distance constraints involving time points tp1 and tp2. The 
174
	 * method returns both constraints (tp1,tp2) and constraints (tp2,tp1) if
175
	 * they exist
176
	 * 
177
	 * @param tp1
178
	 * @param tp2
179
	 * @return
180
	 */
181
	public abstract List<TimePointDistanceConstraint> getConstraints(TimePoint tp1, TimePoint tp2);
182
	
183
	/**
184
	 * Returns the distance constraint between the origin of the network and the time point.
185
	 * 
186
	 * The method returns null if no constraint is found
187
	 * 
188
	 * @param point
189
	 * @return
190
	 */
191
	public abstract List<TimePointDistanceConstraint> getConstraintFromOrigin(TimePoint point);
192
	
193
	/**
194
	 * 
195
	 * @param tp
196
	 * @return
197
	 */
198
	public abstract List<TimePointDistanceConstraint> getConstraintToHorizon(TimePoint tp);
199
	
200
	/**
201
	 * Creates a new flexible TimePoint
202
	 * 
203
	 * The method can also use a previously created (and 
204
	 * deleted) time point rather than create a new instance
205
	 * 
206
	 * @return
207
	 * @throws InconsistentDistanceConstraintException
208
	 */
209
	public final TimePoint addTimePoint() 
210
			throws InconsistentDistanceConstraintException {
211
		
212
		// create a time point or use a previous created one
213
		TimePoint tp = null;
214
		// extract the first element
215
		Iterator<TimePoint> it = this.recyclePoints.iterator();
216
		// check among recycled time points first
217
		if (it.hasNext()) {
218
			
219
			// extract next time point
220
			tp = it.next();
221
			// remove time point from the set
222
			it.remove();
223
		}
224
		else {
225
			
226
			// actually create flexible time point
227
			tp = new TimePoint(COUNTER.getAndIncrement(), this.origin, this.horizon);
228
		}
229
		
230
		// add time point to the network
231
		this.doAddTimePoint(tp);
232
		// create notification
233
		AddTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory.
234
				createNotification(TemporalNetworkNotificationTypes.ADD_TP);
235
		// add time point
236
		info.addTimePoint(tp);
237
		
238
		// check observers
239
		synchronized (this.observers) {
240
			
241
			// notify observers
242
			for (TemporalNetworkObserver obs : this.observers) {
243
				// do notify 
244
				obs.notify(info);
245
			}
246
		}
247
248
		// return new time point
249
		return tp;
250
	}
251
	
252
	/**
253
	 * Creates N flexible time points 
254
	 * 
255
	 * The method can also use previously created (and 
256
	 * deleted) time points rather than create new instances
257
	 * 
258
	 * @param n
259
	 * @return
260
	 * @throws TemporalNetworkTransactionFailureException
261
	 * 
262
	 */
263
	public final List<TimePoint> addTimePoints(int n) 
264
			throws TemporalNetworkTransactionFailureException 
265
	{
266
		// notify flag
267
		boolean notify = true;
268
		// create notification
269
		AddTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory.
270
				createNotification(TemporalNetworkNotificationTypes.ADD_TP);
271
		
272
		try {
273
			
274
			// create time points
275
			for (int i= 0; i < n; i++) {
276
			
277
				// create a flexible time point
278
				TimePoint tp = this.addTimePoint();
279
				// add time point to the notification
280
				info.addTimePoint(tp);
281
			}
282
		}
283
		catch (InconsistentDistanceConstraintException ex) {
284
			
285
			// remove created time points
286
			for (TimePoint tp : info.getPoints()) {
287
				
288
				// remove created time point
289
				this.doRemoveTimePoint(tp);
290
			}
291
			
292
			// do not notify
293
			notify = false;
294
			// throw exception
295
			throw new TemporalNetworkTransactionFailureException(ex.getMessage());
296
		}
297
		finally {
298
			
299
			// check if notification is necessary
300
			if (notify) {
301
			
302
				// check observers
303
				synchronized (this.observers) {
304
					// notify observers
305
					for (TemporalNetworkObserver obs : this.observers) {
306
						// do notify
307
						obs.notify(info);
308
					}
309
				}
310
			}
311
		}
312
		
313
		// get time points
314
		return info.getPoints();
315
	}
316
	
317
	/**
318
	 * Creates a new TimePoint and fix it into the network at
319
	 * the desired time (at)
320
	 * 
321
	 * The method throws an exception if the specified value (at)
322
	 * is out of the temporal network domain
323
	 * 
324
	 * The method can also use a previously created (and deleted) time
325
	 * point rather than create a new instance
326
	 * 
327
	 * @param at
328
	 * @return
329
	 * @throws InconsistentTpValueException
330
	 */
331 View Code Duplication
	public final TimePoint addTimePoint(long at) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
332
			throws InconsistentTpValueException, InconsistentDistanceConstraintException {
333
		
334
		// check desired value
335
		if (at < this.origin || at > this.horizon) {
336
			// inconsistent value
337
			throw new InconsistentTpValueException("TimePoint value (= " + at +") out of the domain [origin= " + this.origin + ", horizon= " + this.horizon);
338
		}
339
		
340
		// create a time point or use a previous created one
341
		TimePoint tp = null;
342
		// extract the first element
343
		Iterator<TimePoint> it = this.recyclePoints.iterator();
344
		// check recycled time points first
345
		if (it.hasNext()) {
346
			// extract next time point
347
			tp = it.next();
348
			// set bounds
349
			tp.setDomLb(at);
350
			tp.setDomUb(at);
351
			// remove time point from the underlying set
352
			it.remove();
353
		}
354
		else {
355
			
356
			// create time point
357
			tp = new TimePoint(COUNTER.getAndIncrement(), at, at);
358
		}
359
		
360
		// add time point to the network
361
		this.doAddTimePoint(tp);
362
363
		// create notification
364
		AddTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory.createNotification(TemporalNetworkNotificationTypes.ADD_TP);
365
		info.addTimePoint(tp);
366
		
367
		
368
		// check observers
369
		synchronized (this.observers) {
370
			// notify observers
371
			for (TemporalNetworkObserver obs : this.observers) {
372
				// do notify
373
				obs.notify(info);
374
			}
375
		}
376
377
		// return new time point
378
		return tp;
379
	}
380
	
381
	/**
382
	 * 
383
	 * @param lb
384
	 * @param ub
385
	 * @return
386
	 * @throws InconsistentTpValueException
387
	 * @throws InconsistentDistanceConstraintException
388
	 */
389 View Code Duplication
	public final TimePoint addTimePoint(long lb, long ub) 
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
390
			throws InconsistentTpValueException, InconsistentDistanceConstraintException
391
	{
392
		// check domain
393
		if (lb > ub || lb < this.origin || ub > this.horizon) {
394
			// inconsistent value
395
			throw new InconsistentTpValueException("TimePoint (lb= " + lb +", ub= " + ub + ") is inconsistent or it is out of the domain [origin= " + this.origin + ", horizon= " + this.horizon);
396
		}
397
		
398
		// create a time point or use a previous created one
399
		TimePoint tp = null;
400
		// extract the first element
401
		Iterator<TimePoint> it = this.recyclePoints.iterator();
402
		// check recycled time points first
403
		if (it.hasNext()) {
404
			// extract next time point
405
			tp = it.next();
406
			// set desired bounds
407
			tp.setDomLb(lb);
408
			tp.setDomUb(ub);
409
			// remove time point from the set
410
			it.remove();
411
		}
412
		else {
413
			// create time point
414
			tp = new TimePoint(COUNTER.getAndIncrement(), lb, ub);
415
		}
416
		
417
		// add time point to the network
418
		this.doAddTimePoint(tp);
419
		// create notification
420
		AddTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory.createNotification(TemporalNetworkNotificationTypes.ADD_TP);
421
		info.addTimePoint(tp);
422
		
423
		// check observers
424
		synchronized (this.observers) {
425
			// notify observers
426
			for (TemporalNetworkObserver obs : this.observers) {
427
				obs.notify(info);
428
			}
429
		}
430
431
		// return new time point
432
		return tp;
433
	}
434
	
435
	/**
436
	 * 
437
	 * @param tp
438
	 * @throws InconsistentDistanceConstraintException
439
	 */
440
	protected abstract void doAddTimePoint(TimePoint tp) 
441
			throws InconsistentDistanceConstraintException;
442
443
	/**
444
	 * Removes a Time Point from the network
445
	 * 
446
	 * @param tp
447
	 */
448
	public final void removeTimePoint(TimePoint tp) 
449
	{
450
		// delete time point
451
		this.doRemoveTimePoint(tp);
452
		// add time point to recycle list
453
		this.recyclePoints.add(tp);
454
		
455
		// create notification
456
		DelTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory
457
				.createNotification(TemporalNetworkNotificationTypes.DEL_TP);
458
		info.addTimePoint(tp);
459
		
460
		// check observers
461
		synchronized (this.observers) {
462
			
463
			// notify observers
464
			for (TemporalNetworkObserver obs : this.observers) {
465
				// do notify
466
				obs.notify(info);
467
			}
468
		}
469
	}
470
	
471
	/**
472
	 * 
473
	 * Remove a list of time points from the temporal network 
474
	 * 
475
	 * @param tps
476
	 */
477
	public final synchronized void removeTimePoints(List<TimePoint> tps) {
478
		
479
		// create notification
480
		DelTimePointTemporalNetworkNotification info = TemporalNetworkNotificationFactory
481
				.createNotification(TemporalNetworkNotificationTypes.DEL_TP);
482
		
483
		// map of time points the associated distance constraints that have been removed 
484
		Map<TimePoint, List<TimePointDistanceConstraint>> committed = new HashMap<>();
485
		// check time points to remove
486
		for (TimePoint tp : tps) {
487
			
488
			// delete time point
489
			List<TimePointDistanceConstraint> cRemoved = this.doRemoveTimePoint(tp);
490
			// add time point to recycle list
491
			this.recyclePoints.add(tp);
492
			// add deleted time point to the notification
493
			info.addTimePoint(tp);
494
			// add entry to the map
495
			committed.put(tp, cRemoved);
496
		}
497
			
498
		// check observers 
499
		synchronized (this.observers) {
500
			// notify observers
501
			for (TemporalNetworkObserver obs : this.observers) {
502
				// do notify
503
				obs.notify(info);
504
			}
505
		}
506
	}
507
	
508
	/**
509
	 * Actually delete the selected time point from the network 
510
	 * and all related constraints
511
	 * 
512
	 * @param tp
513
	 * @return
514
	 */
515
	protected abstract List<TimePointDistanceConstraint> doRemoveTimePoint(TimePoint tp); 
516
	
517
	/**
518
	 * 
519
	 * @param originTimePoint
520
	 * @param tp1
521
	 * @return
522
	 */
523
	public abstract long[] getConstraintBounds(TimePoint originTimePoint, TimePoint tp1);
524
	
525
	/**
526
	 * Creates a distance constraint between two time points with the 
527
	 * specified lower and upper bounds
528
	 * 
529
	 * Throws an exception when trying to create a distance constraint with
530
	 * lower bound greater than upper bound (lb > ub)
531
	 * 
532
	 * @param constraint
533
	 * @return
534
	 * @throws InconsistentTpDistanceRelation
535
	 */
536
	public final void addDistanceConstraint(TimePointDistanceConstraint constraint) 
537
			throws InconsistentDistanceConstraintException {
538
		
539
		// check consistency of distance bound
540
		if (constraint.getDistanceLowerBound() > constraint.getDistanceUpperBound())  {
541
			// inconsistent value
542
			throw new InconsistentDistanceConstraintException("DistanceConstraint "
543
					+ "(dmin= " + constraint.getDistanceLowerBound() +", "
544
					+ "dmax= " + constraint.getDistanceUpperBound() + ") "
545
					+ "is inconsistent or it is not compatible wih the domain [origin= " + this.origin + ", horizon= " + this.horizon + "]");
546
		}
547
		
548
		// add constraint to the network and check changes
549
		if (this.doAddConstraint(constraint)) {
550
			
551
			// create notification
552
			AddRelationTemporalNetworkNotification info = TemporalNetworkNotificationFactory
553
					.createNotification(TemporalNetworkNotificationTypes.ADD_REL);
554
			// set constraint
555
			info.addRelation(constraint);
556
		
557
			// check observers
558
			synchronized (this.observers) {
559
				// notify observers
560
				for (TemporalNetworkObserver obs : this.observers) {
561
					// do notify
562
					obs.notify(info);
563
				}
564
			}
565
		}
566
	}
567
568
	/**
569
	 * Create N distance constraints all at once.
570
	 * 
571
	 * The method is atomic, i.e. if a constraint creation operation fails than all the 
572
	 * constraints previously created by the method are aborted. So if something goes wrong
573
	 * during the creation of constraints then the network is restored to the status before
574
	 * method invocation.   
575
	 * 
576
	 * @param constraints
577
	 * @return
578
	 * @throws TemporalNetworkTransactionFailureException
579
	 */
580
	public final synchronized void addDistanceConstraint(TimePointDistanceConstraint[] constraints) 
581
			throws TemporalNetworkTransactionFailureException 
582
	{
583
		// flag of successful operation and notification notification
584
		boolean notify = false;
585
		// create notification
586
		AddRelationTemporalNetworkNotification info = TemporalNetworkNotificationFactory.
587
				createNotification(TemporalNetworkNotificationTypes.ADD_REL);
588
		
589
		// list of committed distance constraints
590
		List<TimePointDistanceConstraint> committed = new ArrayList<>();
591
		try {
592
			
593
			// propagate constraints
594
			for (int i = 0; i < constraints.length; i++) {
595
				
596
				// get constraint
597
				TimePointDistanceConstraint constraint = constraints[i];
598
				// add constraint to network
599
				boolean changed = this.doAddConstraint(constraint);
600
				// add committed constraint
601
				committed.add(constraint);
602
				// check if something changes 
603
				if (changed) {
604
					
605
					// add constraint to notification
606
					info.addRelation(constraint);
607
					// set notify flag
608
					notify = true;
609
				}
610
			}
611
		}
612
		catch (InconsistentDistanceConstraintException ex ) {
613
			
614
			// remove all committed constraints
615
			for (TimePointDistanceConstraint tpd : committed) {
616
				// remove added constraint
617
				this.doRemoveDistanceConstraint(tpd);
618
			}
619
			
620
			// do not send notification
621
			notify = false;
622
			
623
			// throw exception
624
			throw new TemporalNetworkTransactionFailureException("Error while creating temporal constraints - Rollback Transaction");
625
		}
626
		finally {
627
		
628
			// check if transaction has been successfully done and a notification should be sent
629
			if (notify) {
630
				
631
				// check observers
632
				synchronized (this.observers) {
633
					
634
					// notify observers
635
					for (TemporalNetworkObserver obs : this.observers) {
636
						// do notify
637
						obs.notify(info);
638
					}
639
				}
640
			}
641
		}
642
	}
643
	
644
	/**
645
	 * 
646
	 * @param rel
647
	 * @throws InconsistentDistanceConstraintException
648
	 */
649
	protected abstract boolean doAddConstraint(TimePointDistanceConstraint rel) 
650
			throws InconsistentDistanceConstraintException;
651
	
652
	/**
653
	 * Removes the distance constraint from the network
654
	 * 
655
	 * @param rel
656
	 */
657
	public final void removeConstraint(TimePointDistanceConstraint rel)  
658
	{
659
		// remove temporal relation and check if a notification should be sent
660
		if (this.doRemoveDistanceConstraint(rel)) {
661
		
662
			// create notification
663
			DelRelationTemporalNetworkNotification info = TemporalNetworkNotificationFactory.createNotification(TemporalNetworkNotificationTypes.DEL_REL);
664
			info.addRelation(rel);
665
			
666
			// check observers
667
			synchronized (this.observers) {
668
				// notify observers
669
				for (TemporalNetworkObserver obs : this.observers) {
670
					// do notify
671
					obs.notify(info);
672
				}
673
			}
674
		}
675
	}
676
	
677
	/**
678
	 * Removes N distance constraints all at once
679
	 *
680
	 * @param rels
681
	 */
682
	public final void removeDistanceConstraint(List<TimePointDistanceConstraint> rels) 
683
	{
684
		// notification flag
685
		boolean notify = false;
686
		// create notification
687
		DelRelationTemporalNetworkNotification info = TemporalNetworkNotificationFactory
688
				.createNotification(TemporalNetworkNotificationTypes.DEL_REL);
689
		
690
		// get constraints to delete
691
		for (TimePointDistanceConstraint rel : rels) {
692
			// remove temporal relation
693
			if (this.doRemoveDistanceConstraint(rel)) {
694
				// set notification flag
695
				notify = true;
696
			}
697
			
698
			// add constraint to notify
699
			info.addRelation(rel);
700
		}
701
		
702
		// check if a notification is necessary
703
		if (notify) {
704
			
705
			// check observers
706
			synchronized (this.observers) {
707
				
708
				// notify observers
709
				for (TemporalNetworkObserver obs : this.observers) {
710
					// do notify
711
					obs.notify(info);
712
				}
713
			}
714
		}
715
	}
716
	
717
	/**
718
	 * Actually remove constraint from network
719
	 * 
720
	 * @param rel
721
	 * @return
722
	 */
723
	protected abstract boolean doRemoveDistanceConstraint(TimePointDistanceConstraint rel);
724
	
725
	/**
726
	 * 
727
	 * @param lb
728
	 * @param ub
729
	 * @return
730
	 */
731
	protected TimePoint createTimePoint(long lb, long ub) {
732
		return new TimePoint(COUNTER.getAndIncrement(), lb, ub);
733
	}
734
	
735
	/**
736
	 * 
737
	 * @param from
738
	 * @param to
739
	 * @param distance
740
	 * @param controllable
741
	 * @return
742
	 */
743
	protected final TimePointDistanceConstraint createDistanceConstraint(TimePoint from, TimePoint to, long[] distance, boolean controllable) 
744
	{
745
		// create constraint
746
		TimePointDistanceConstraint c = new TimePointDistanceConstraint();
747
		c.setReference(from);
748
		c.setTarget(to);
749
		c.setDistanceLowerBound(distance[0]);
750
		c.setDistanceUpperBound(distance[1]);
751
		c.setControllable(controllable);
752
		// get constraint
753
		return c;
754
	}
755
756
	/**
757
	 * 
758
	 */
759
	public abstract void printDiagnosticData();
760
	
761
}