Passed
Push — master ( ba4614...ebb470 )
by Alessandro
05:51
created

findFlaws()   B

Complexity

Conditions 6

Size

Total Lines 44
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
dl 0
loc 44
rs 8.5666
c 0
b 0
f 0
eloc 18

1 Method

Rating   Name   Duplication   Size   Complexity  
it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.Resolver.$Comparator$.compare(Flaw,Flaw) 0 6 ?
1
package it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver;
2
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.Collections;
6
import java.util.Comparator;
7
import java.util.HashSet;
8
import java.util.List;
9
import java.util.Set;
10
import java.util.concurrent.atomic.AtomicInteger;
11
12
import it.cnr.istc.pst.platinum.ai.framework.domain.component.Decision;
13
import it.cnr.istc.pst.platinum.ai.framework.domain.component.DomainComponent;
14
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.DecisionPropagationException;
15
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.FlawSolutionApplicationException;
16
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.RelationPropagationException;
17
import it.cnr.istc.pst.platinum.ai.framework.microkernel.FrameworkObject;
18
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.inject.framework.DomainComponentPlaceholder;
19
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.inject.framework.ParameterFacadePlaceholder;
20
import it.cnr.istc.pst.platinum.ai.framework.microkernel.annotation.inject.framework.TemporalFacadePlaceholder;
21
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ConsistencyCheckException;
22
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.Flaw;
23
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawSolution;
24
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawType;
25
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.Relation;
26
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ex.UnsolvableFlawException;
27
import it.cnr.istc.pst.platinum.ai.framework.parameter.ParameterFacade;
28
import it.cnr.istc.pst.platinum.ai.framework.time.TemporalFacade;
29
30
/**
31
 * 
32
 * @author alessandro
33
 *
34
 * @param <T>
35
 */
36
public abstract class Resolver<T extends DomainComponent> extends FrameworkObject implements FlawManager 
37
{
38
	@TemporalFacadePlaceholder
39
	protected TemporalFacade tdb;
40
	
41
	@ParameterFacadePlaceholder
42
	protected ParameterFacade pdb;
43
	
44
	@DomainComponentPlaceholder
45
	protected T component;
46
	
47
	protected String label;
48
	protected FlawType[] flawTypes;
49
50
	// static information
51
	protected static final AtomicInteger FLAW_COUNTER = new AtomicInteger(0);
52
	
53
	
54
	/**
55
	 * 
56
	 * @param label
57
	 * @param flawTypes
58
	 */
59
	protected Resolver(String label, FlawType[] flawTypes) {
60
		super();
61
		this.label = label;
62
		this.flawTypes = flawTypes;
63
		
64
		// reset counter if necessary
65
		FLAW_COUNTER.set(0);
66
	}
67
	
68
	/**
69
	 * 
70
	 * @return
71
	 */
72
	public String getLabel() {
73
		return label;
74
	}
75
	
76
	/**
77
	 * 
78
	 * @return
79
	 */
80
	public FlawType[] getFlawTypes() {
81
		return this.flawTypes;
82
	}
83
	
84
	/**
85
	 * 
86
	 */
87
	@Override
88
	public synchronized List<Flaw> checkFlaws() {
89
		// get detected flaws
90
		return new ArrayList<>(this.doFindFlaws());
91
	}
92
	
93
	/**
94
	 * 
95
	 */
96
	@Override
97
	public synchronized List<Flaw> findFlaws() 
98
			throws UnsolvableFlawException {
99
		
100
		// list of flaws on the related component
101
		List<Flaw> flaws = new ArrayList<>();
102
		// find flaws on component
103
		for (Flaw flaw :  this.doFindFlaws()) {
104
			
105
			// compute possible solutions
106
			this.doComputeFlawSolutions(flaw);
107
			// add flaw
108
			flaws.add(flaw);
109
		}
110
		
111
		// randomly select a flaw if any 
112
		List<Flaw> list = new ArrayList<>();
113
		if (flaws.size() > 1) {
114
			
115
			// get the flaw with the lowest number of solutions - fail first principle
116
			Collections.sort(flaws, new Comparator<Flaw>() {
117
				
118
				/**
119
				 * 
120
				 */
121
				@Override
122
				public int compare(Flaw o1, Flaw o2) {
123
					
124
					// compare available solutions
125
					return o1.getSolutions().size() < o2.getSolutions().size() ? -1 : 
126
						o1.getSolutions().size() > o2.getSolutions().size() ? 1 : 0;
127
				}
128
			});
129
			
130
			// get the hardest flaw to solve
131
			list.add(flaws.get(0));
132
133
		} else {
134
			
135
			list = flaws;
136
		}
137
		
138
		// get detected flaws
139
		return list;
140
	}
141
	
142
	/**
143
	 * 
144
	 */
145
	@Override
146
	public final synchronized void apply(FlawSolution solution) 
147
			throws FlawSolutionApplicationException 
148
	{
149
		// check flaw type
150
		if (!Arrays.asList(this.flawTypes).contains(solution.getFlaw().getType())) {
151
			throw new FlawSolutionApplicationException("Impossible to apply solution for flaws of type type " + solution.getFlaw().getType());
152
		}
153
		
154
		// apply flaw solution
155
		this.doApply(solution);
156
	}
157
	
158
	/**
159
	 * 
160
	 */
161
	@Override
162
	public final synchronized void restore(FlawSolution solution) 
163
			throws Exception 
164
	{
165
		// check flaw type
166
		if (!Arrays.asList(this.flawTypes).contains(solution.getFlaw().getType())) {
167
			throw new FlawSolutionApplicationException("Impossible to restore solution for flaws of type type " + solution.getFlaw().getType());
168
		}
169
		
170
		// apply flaw solution
171
		this.doRestore(solution);
172
	}
173
	
174
	/**
175
	 * 
176
	 */
177
	@Override
178
	public final synchronized void retract(FlawSolution solution) 
179
	{
180
		// check flaw type
181
		if (!Arrays.asList(this.flawTypes).contains(solution.getFlaw().getType())) {
182
			throw new RuntimeException("Impossible to retract solution for flaws of type " + solution.getFlaw().getType());
0 ignored issues
show
Best Practice introduced by
Dedicated exceptions should be preferred over throwing the generic Exception.
Loading history...
183
		}
184
		
185
		// retract solution
186
		this.doRetract(solution);
187
	}
188
	
189
	/**
190
	 * 
191
	 * @param solution
192
	 */
193
	protected void doRetract(FlawSolution solution)  {
194
		
195
		// get the list of activated relations
196
		for (Relation relation : solution.getActivatedRelations()) {
197
			// get reference component
198
			DomainComponent refComp = relation.getReference().getComponent();
199
			// deactivate relation
200
			refComp.deactivate(relation);
201
		}
202
		
203
		// get the list of created relations
204
		for (Relation relation : solution.getCreatedRelations()) {
205
			// get reference component
206
			DomainComponent refComp = relation.getReference().getComponent();
207
			// remove relation from the data structure
208
			refComp.delete(relation);
209
		}
210
		
211
		// get the list of activated decisions
212
		for (Decision decision : solution.getActivatedDecisions()) {
213
			// get decision component
214
			DomainComponent dComp = decision.getComponent();
215
			// deactivate decision
216
			dComp.deactivate(decision);
217
		}
218
		
219
		// get the list of created decisions
220
		for (Decision decision : solution.getCreatedDecisions()) {
221
			// get decision component
222
			DomainComponent dComp = decision.getComponent();
223
			// delete decision from pending "list" 
224
			dComp.free(decision);
225
		}
226
	}
227
	
228
//	/**
229
//	 * 
230
//	 * @param constraint
231
//	 * @throws ConstraintPropagationException
232
//	 */
233
//	protected void doPropagetConstraint(Constraint constraint) 
234
//			throws ConstraintPropagationException 
235
//	{
236
//		// check constraint category
237
//		switch (constraint.getCategory()) 
238
//		{
239
//			// temporal constraint
240
//			case  TEMPORAL_CONSTRAINT : {
241
//				// cast constraint
242
//				TemporalConstraint cons = (TemporalConstraint) constraint;
243
//				// propagate temporal constraint
244
//				this.tdb.propagate(cons);
245
//			}
246
//			break;
247
//			
248
//			// parameter constraint
249
//			case PARAMETER_CONSTRAINT : {
250
//				// cast constraint
251
//				ParameterConstraint  cons = (ParameterConstraint) constraint;
252
//				// propagate parameter constraint
253
//				this.pdb.propagate(cons);
254
//			}
255
//			break;
256
//		}
257
//	}
258
	
259
//	/**
260
//	 * 
261
//	 * @param constraint
262
//	 */
263
//	protected void doRetractConstraint(Constraint constraint) {
264
//		// check constraint category
265
//		switch (constraint.getCategory()) {
266
//		
267
//			// temporal constraint
268
//			case  TEMPORAL_CONSTRAINT : {
269
//				
270
//				// cast constraint
271
//				TemporalConstraint cons = (TemporalConstraint) constraint;
272
//				// retract temporal constraint
273
//				this.tdb.retract(cons);
274
//			}
275
//			break;
276
//			
277
//			// parameter constraint
278
//			case PARAMETER_CONSTRAINT : {
279
//				
280
//				// cast constraint
281
//				ParameterConstraint cons = (ParameterConstraint) constraint;
282
//				// retract parameter constraint
283
//				this.pdb.retract(cons);
284
//			}
285
//			break;
286
//		}
287
//	}
288
	
289
	/**
290
	 * 
291
	 * @param solution
292
	 * @throws Exception
293
	 */
294
	protected abstract void doApply(FlawSolution solution) 
295
			throws FlawSolutionApplicationException;
296
	
297
	/**
298
	 * 
299
	 * @param solution
300
	 * @throws RelationPropagationException
301
	 * @throws DecisionPropagationException
302
	 */
303
	protected void doRestore(FlawSolution solution) 
304
			throws RelationPropagationException, DecisionPropagationException 
305
	{
306
		// list of restored decisions
307
		Set<Decision> dRestored = new HashSet<>();
308
		// list of activated decisions
309
		Set<Decision> dActivated = new HashSet<>();
310
		// list of restored relations
311
		Set<Relation> rRestored = new HashSet<>();
312
		// list of activated relations
313
		Set<Relation> rActivated = new HashSet<>();
314
		
315
		try
316
		{
317
			// get the list of created decisions
318
			for (Decision decision : solution.getCreatedDecisions()) {
319
				// get decision component
320
				DomainComponent dComp = decision.getComponent();
321
				// restore decision SILENT -> PENDING
322
				dComp.restore(decision);
323
				// add 
324
				dRestored.add(decision);
325
			}
326
			
327
			
328
			// check activated decisions
329
			for (Decision decision : solution.getActivatedDecisions()) {
330
				// get decision component
331
				DomainComponent dComp = decision.getComponent();
332
				// activate decision PENDING -> ACTIVE
333
				dComp.activate(decision);
334
				// add
335
				dActivated.add(decision);
336
			}
337
			
338
			// get the list of created relations
339
			for (Relation relation : solution.getCreatedRelations()) {
340
				// get reference component
341
				DomainComponent refComp = relation.getReference().getComponent();
342
				// restore relation
343
				refComp.restore(relation);
344
				// add
345
				rRestored.add(relation);
346
			}
347
348
			// check activated relations
349
			for (Relation relation : solution.getActivatedRelations()) {
350
				// get reference component
351
				DomainComponent refComp = relation.getReference().getComponent();
352
				// activate relation
353
				refComp.activate(relation);
354
				// add relation to committed list
355
				rActivated.add(relation);
356
			}
357
			
358
			// check consistency
359
			this.tdb.verify();
360
			this.pdb.verify();
361
		}
362
		catch (DecisionPropagationException | ConsistencyCheckException ex) 
363
		{
364
			// deactivate activated relations
365
			for (Relation rel : rActivated) {
366
				// get reference component
367
				DomainComponent refComp = rel.getReference().getComponent();
368
				// deactivate relation
369
				refComp.deactivate(rel);
370
			}
371
			
372
			// remove restored relations
373
			for (Relation rel : rRestored) {
374
				// get reference component
375
				DomainComponent refComp = rel.getReference().getComponent();
376
				// deactivate relation
377
				refComp.delete(rel);
378
			}
379
			
380
			// deactivate decisions
381
			for (Decision dec : dActivated) {
382
				// get decision component
383
				DomainComponent decComp = dec.getComponent();
384
				// deactivate decision
385
				decComp.deactivate(dec);
386
			}
387
			
388
			// remove restored decisions
389
			for (Decision dec: dRestored) {
390
				// get decision component
391
				DomainComponent decComp = dec.getComponent();
392
				// free decision
393
				decComp.free(dec);
394
			}
395
			
396
			// throw exception
397
			throw new DecisionPropagationException(ex.getMessage());
398
		}
399
	}
400
	
401
	/**
402
	 * 
403
	 * @return
404
	 */
405
	protected abstract List<Flaw> doFindFlaws();
406
	
407
	/**
408
	 * 
409
	 * @param flaw
410
	 * @throws UnsolvableFlawException
411
	 */
412
	protected abstract void doComputeFlawSolutions(Flaw flaw) 
413
			throws UnsolvableFlawException;
414
}
415