Passed
Push — master ( d70339...8f8808 )
by Alessandro
05:45
created

findFlaws()   A

Complexity

Conditions 2

Size

Total Lines 45
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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