Passed
Push — master ( c71db0...37262d )
by Alessandro
05:46 queued 14s
created

doComputeFlawSolutions(Flaw)   C

Complexity

Conditions 10

Size

Total Lines 105
Code Lines 52

Duplication

Lines 79
Ratio 75.24 %

Importance

Changes 0
Metric Value
cc 10
eloc 52
dl 79
loc 105
rs 5.7709
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.timeline.scheduling.TimelineSchedulingResolver.doComputeFlawSolutions(Flaw) 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.microkernel.resolver.timeline.scheduling;
2
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.List;
6
7
import it.cnr.istc.pst.platinum.ai.framework.domain.component.Decision;
8
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.FlawSolutionApplicationException;
9
import it.cnr.istc.pst.platinum.ai.framework.domain.component.ex.RelationPropagationException;
10
import it.cnr.istc.pst.platinum.ai.framework.domain.component.sv.StateVariable;
11
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.ex.ConsistencyCheckException;
12
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.Flaw;
13
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.flaw.FlawSolution;
14
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.Relation;
15
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.RelationType;
16
import it.cnr.istc.pst.platinum.ai.framework.microkernel.lang.relations.temporal.BeforeRelation;
17
import it.cnr.istc.pst.platinum.ai.framework.microkernel.query.TemporalQueryType;
18
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.Resolver;
19
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ResolverType;
20
import it.cnr.istc.pst.platinum.ai.framework.microkernel.resolver.ex.UnsolvableFlawException;
21
import it.cnr.istc.pst.platinum.ai.framework.time.lang.query.IntervalOverlapQuery;
22
import it.cnr.istc.pst.platinum.ai.framework.utils.properties.FilePropertyReader;
23
24
/**
25
 * 
26
 * @author anacleto
27
 *
28
 */
29
public final class TimelineSchedulingResolver extends Resolver<StateVariable>
30
{
31
	private boolean load;
32
	private double schedulingCost;
33
	
34
	/**
35
	 * 
36
	 */
37
	protected TimelineSchedulingResolver() {
38
		super(ResolverType.TIMELINE_SCHEDULING_RESOLVER.getLabel(), 
39
				ResolverType.TIMELINE_SCHEDULING_RESOLVER.getFlawTypes());
40
		// set load flag
41
		this.load = false;
42
	}
43
	
44
	/**
45
	 * 
46
	 */
47
	private void load() {
48
		// get deliberative property file
49
		FilePropertyReader properties = new FilePropertyReader(
50
				FRAMEWORK_HOME + FilePropertyReader.DEFAULT_DELIBERATIVE_PROPERTY);
51
		// get weight
52
		this.schedulingCost = Double.parseDouble(properties.getProperty("scheduling-cost"));
53
		// set flag
54
		this.load = true;
55
	}
56
	
57
	/**
58
	 * 
59
	 */
60
	@Override
61
	protected void doApply(FlawSolution solution) 
62
			throws FlawSolutionApplicationException 
63
	{
64
		// get the flaw solution to consider
65
		DecisionPrecedenceConstraint pc = (DecisionPrecedenceConstraint) solution;
66
		// get reference and target decisions
67
		Decision reference = pc.getReference();
68
		Decision target = pc.getTarget();
69
			
70
		// create relation
71
		BeforeRelation before = this.component.create(RelationType.BEFORE, reference, target);
72
		// set bounds
73
		before.setBound(new long[] {
74
				0, 
75
				this.component.getHorizon()});
76
		// add created relation to solution
77
		solution.addCreatedRelation(before);
78
		
79
		try
80
		{
81
			// propagate relations
82
			this.component.activate(before);
83
			// add activated relations to solution
84
			solution.addActivatedRelation(before);
85
			debug("Precedence constraint successfully created and activated:\n"
86
					+ "- temporal constraint: " + before + "\n");
87
			
88
			// check feasibility
89
			this.tdb.verify();
90
		}
91
		catch (RelationPropagationException | ConsistencyCheckException ex) 
92
		{
93
			// write error message
94
			error("Error while applying flaw solution:\n"
95
					+ "- solution: " + solution + "\n"
96
					+ "- unfeasible precedence constraint: " + before + "\n");
97
98
			// deactivate relation
99
			this.component.deactivate(before);
100
			// delete relation
101
			this.component.delete(before);
102
			// not feasible solution
103
			throw new FlawSolutionApplicationException(ex.getMessage());
104
		}
105
	}
106
107
	
108
	/**
109
	 * 
110
	 */
111
	@Override
112
	protected List<Flaw> doFindFlaws() 
113
	{
114
		// check flag
115
		if (!this.load) {
116
			this.load();
117
		}
118
		
119
		// list of critical sets
120
		List<Flaw> flaws = new ArrayList<>();
121
		// list of active decisions
122
		List<Decision> decisions = this.component.getActiveDecisions();
123
		// sort decisions
124
		Collections.sort(decisions);
125
		// look for peaks
126
		for (int index = 0; index < decisions.size() - 1; index++)
127
		{
128
			// get active decision  
129
			Decision reference = decisions.get(index);
130
			// find possibly overlapping decisions
131
			for (int jndex = index + 1; jndex < decisions.size(); jndex++)
132
			{
133
				// get another active decision
134
				Decision target = decisions.get(jndex);
135
				// check if intervals can overlap
136
				IntervalOverlapQuery query = this.tdb.createTemporalQuery(
137
						TemporalQueryType.INTERVAL_OVERLAP);
138
				
139
				// set time points
140
				query.setReference(reference.getToken().getInterval());
141
				query.setTarget(target.getToken().getInterval());
142
				// process query
143
				this.tdb.process(query);
144
				// check overlapping 
145
				if (query.canOverlap())
146
				{
147
					// conflict found
148
					BinaryDecisionConflict c = new BinaryDecisionConflict(
149
							FLAW_COUNTER.getAndIncrement(), 
150
							this.component);
151
152
					// set overlapping decisions
153
					c.setDecisions(new Decision[] {
154
							reference,
155
							target
156
					});
157
					
158
					// check if decisions overlaps
159
					debug("Overlapping tokens:\n"
160
							+ "- component: " + this.component + "\n"
161
							+ "- reference token: " + reference + "\n"
162
							+ "- target token: " + target + "\n");
163
					
164
					// add conflict
165
					flaws.add(c);
166
				}
167
			}
168
		}
169
		
170
//		if (!flaws.isEmpty()) {
171
//			
172
//			// randomly select a scheduling flaw from the component
173
//			List<Flaw> conflicts = new ArrayList<>();
174
//			Random rand = new Random(System.currentTimeMillis());
175
//			conflicts.add(flaws.get(rand.nextInt(flaws.size())));
176
//			// get conflicts
177
//			return conflicts;
178
//		}
179
//		else {
180
		
181
		// return the list of flaws
182
		return flaws;
183
		
184
		
185
//		}
186
	}
187
	
188
189
	
190
	/**
191
	 * 
192
	 */
193
	protected void doComputeFlawSolutions(Flaw flaw) 
194
		throws UnsolvableFlawException 
195
	{
196
		// get detected conflict
197
		BinaryDecisionConflict conflict = (BinaryDecisionConflict) flaw;
198
199
		// check possible precedence constraints
200
		Decision reference = conflict.getDecisions()[0];
201
		Decision target = conflict.getDecisions()[1];
202
		// create possible solutions
203
		DecisionPrecedenceConstraint pc1 = new DecisionPrecedenceConstraint(conflict, reference, target, this.schedulingCost);
204
		DecisionPrecedenceConstraint pc2 = new DecisionPrecedenceConstraint(conflict, target, reference, this.schedulingCost);
205
		
206 View Code Duplication
		try
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
207
		{
208
			// create relation reference -> target
209
			BeforeRelation before = this.component.create(RelationType.BEFORE, reference, target);
210
			// set bounds
211
			before.setBound(new long[] {
212
					0, 
213
					this.component.getHorizon()});
214
			
215
			// add create relation
216
			pc1.addCreatedRelation(before);
217
			
218
			// activate relation
219
			if (this.component.activate(before)) {
220
				// add activated relations
221
				pc1.addActivatedRelation(before);
222
			}
223
			
224
			// check consistency
225
			this.tdb.verify();
226
			// add solution and deactivate relation
227
			conflict.addSolution(pc1);
228
		}
229
		catch (RelationPropagationException | ConsistencyCheckException ex) {
230
			// discard relation
231
			debug("Unfeasible precedence constraint:\n"
232
					+ "\t- reference: " + reference + "\n"
233
					+ "\t- target: " + target + "\n");
234
		}
235
		finally {
236
			
237
			// deactivate relation
238
			for (Relation rel : pc1.getActivatedRelations()) {
239
				// deactivate relation
240
				this.component.deactivate(rel);
241
			}
242
			
243
			for (Relation rel : pc1.getCreatedRelations()) {
244
				// delete relation
245
				this.component.delete(rel);
246
			}
247
		}
248
		
249
		
250 View Code Duplication
		try
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
		{
252
			// create relation reference -> target
253
			BeforeRelation before = this.component.create(RelationType.BEFORE, target, reference);
254
			// set bounds
255
			before.setBound(new long[] {
256
					0, 
257
					this.component.getHorizon()});
258
			
259
			// add created relation
260
			pc2.addCreatedRelation(before);
261
			// check if relation is feasible
262
			if (this.component.activate(before)) {
263
				// add activated relation
264
				pc2.addActivatedRelation(before);
265
			}
266
			
267
			// check consistency
268
			this.tdb.verify();
269
			// add solution and deactivate relation
270
			conflict.addSolution(pc2);
271
		}
272
		catch (RelationPropagationException | ConsistencyCheckException ex) {
273
			// discard relation
274
			debug("Unfeasible precedence constraint:\n"
275
					+ "\t- reference: " + target + "\n"
276
					+ "\t- target: " + reference + "\n");
277
		}
278
		finally {
279
			
280
			// deactivate relation
281
			for (Relation rel : pc2.getActivatedRelations()) {
282
				// deactivate relation
283
				this.component.deactivate(rel);
284
			}
285
			
286
			for (Relation rel : pc2.getCreatedRelations()) {
287
				// delete relation
288
				this.component.delete(rel);
289
			}
290
		}
291
		
292
		
293
		// check if any solution has been found
294
		if (conflict.getSolutions().isEmpty()) {
295
			throw new UnsolvableFlawException("Unsolvable decision conflict on timeline:\n"
296
					+ "\t- component: " + this.component.getName() + "\n"
297
					+ "\t- decisions: " + conflict.getDecisions()[0] + ", " + conflict.getDecisions()[1] + "\n");
298
		}
299
	}
300
}
301
302