Total Complexity | 40 |
Total Lines | 245 |
Duplicated Lines | 12.65 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
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:
Complex classes like it.cnr.istc.pst.platinum.executive.dc.strategy.ListStrategy 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.executive.dc.strategy; |
||
15 | public class ListStrategy implements Strategy{ |
||
16 | private static int MAX_STRIKE = 99999999; |
||
17 | |||
18 | private long horizon; |
||
19 | private long time; |
||
20 | private int strikeTimer; |
||
21 | private Set<StateSet> states; |
||
22 | private Map<String,Long> timelineClocks; |
||
23 | private Map<String,String> expectedState; |
||
24 | private Set<String> uStates; |
||
25 | private Map<Transition,Map<String,String>> uPostConditions; |
||
26 | private Map<Long,Integer> out; |
||
27 | private int strikeMaxReached; |
||
28 | //private PrintWriter writer; |
||
29 | |||
30 | // ------------------------------ CONSTRUCTORS ------------------ |
||
31 | |||
32 | public ListStrategy(long horizon) { |
||
33 | this.horizon = horizon; |
||
34 | this.states = new HashSet<>(); |
||
35 | this.expectedState = new HashMap<>(); |
||
36 | this.uPostConditions = new HashMap<>(); |
||
37 | this.time = 0; |
||
38 | this.out = new HashMap<>(); |
||
39 | this.uStates = new HashSet<>(); |
||
40 | this.strikeTimer = 0; |
||
41 | this.strikeMaxReached = 0; |
||
42 | } |
||
43 | |||
44 | //---------------------------------- METHODS -------------------- |
||
45 | |||
46 | |||
47 | // the list strategy does not need building, kept for generalization |
||
48 | @Override |
||
49 | public void buildStrategyStructure() {return;} |
||
50 | |||
51 | //returns next strategy step (repeat until wait!!) using plan clock |
||
52 | @Override |
||
53 | public List<Action> askAllStrategySteps(long plan_clock, Map<String,String> actualState, boolean isPlanClock) { //throws Exception { |
||
54 | //System.out.println(expectedState + "plan clock " + plan_clock + "\n\n" + "clock " + this.timelineClocks); |
||
55 | long time = System.currentTimeMillis(); |
||
|
|||
56 | List<Action> actions = new ArrayList<>(); |
||
57 | this.updateExpectedState(actualState); |
||
58 | this.updateClocks(plan_clock-(this.timelineClocks.get("plan"))); |
||
59 | System.out.println(expectedState + "plan clock " + plan_clock + "clock " + this.timelineClocks); |
||
60 | Action action = askSingleStrategyStep(expectedState); |
||
61 | //System.out.println(action + "\n"); |
||
62 | actions.add(action); |
||
63 | while(action.getClass().equals(Transition.class)) { |
||
64 | action = askSingleStrategyStep(this.expectedState); |
||
65 | actions.add(action); |
||
66 | } |
||
67 | time = System.currentTimeMillis() - time; |
||
68 | this.time = this.time + time; |
||
69 | if(this.out.containsKey(time)) this.out.put(time, this.out.get(time)+1); |
||
70 | else this.out.put(time, 1); |
||
71 | System.out.println(">>>>>>> Answer all strategy steps: " + time + "ms, " + "current time: " + this.time + "\n" + this.out + "\n"); |
||
72 | return actions; |
||
73 | } |
||
74 | |||
75 | //returns next strategy step (repeat until wait!!) using tic |
||
76 | View Code Duplication | @Override |
|
77 | public List<Action> askAllStrategySteps(long tic, Map<String,String> actualState) { // throws Exception { |
||
78 | System.out.println(expectedState + "tic " + tic + "\n\n"); |
||
79 | long time = System.currentTimeMillis(); |
||
80 | List<Action> actions = new ArrayList<>(); |
||
81 | this.updateExpectedState(actualState); |
||
82 | this.updateClocks(tic); |
||
83 | Action action = askSingleStrategyStep(this.expectedState); |
||
84 | actions.add(action); |
||
85 | while(action.getClass().equals(Transition.class)) { |
||
86 | action = askSingleStrategyStep(this.expectedState); |
||
87 | actions.add(action); |
||
88 | } |
||
89 | time = System.currentTimeMillis() - time; |
||
90 | System.out.println("\n"+ "Answer all strategy steps: " + time + "ms, " + "\n"); |
||
91 | return actions; |
||
92 | } |
||
93 | |||
94 | //returns one action predicted for next step |
||
95 | private Action askSingleStrategyStep(Map<String, String> actualState) { // throws Exception { |
||
96 | //System.out.println(actualState + "\n\n"); |
||
97 | long time = System.currentTimeMillis(); |
||
98 | try |
||
99 | { |
||
100 | for(StateSet s : this.states) { |
||
101 | if(s.isStateSetStatus(actualState)) { //change in map |
||
102 | StateStrategy win = s.searchNextStepStrategy(timelineClocks); |
||
103 | this.timelineClocks = win.applyPostConditions(this.timelineClocks, this.horizon); |
||
104 | updateExpectedState(win.getAction()); |
||
105 | time = System.currentTimeMillis() - time; |
||
106 | //System.out.println("\n"+ "Answer single strategy steps: " + time + "ms\n"); |
||
107 | return win.getAction(); |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | catch (Exception ex) { |
||
112 | System.out.println("Warning: no state or clock found -> return default action WAIT\n"); |
||
113 | time = System.currentTimeMillis() - time; |
||
114 | this.strikeTimer = this.strikeTimer + 1; |
||
115 | if(this.strikeTimer > this.strikeMaxReached) { this.strikeMaxReached = this.strikeTimer; } |
||
116 | if(this.strikeTimer > ListStrategy.MAX_STRIKE) { |
||
117 | System.out.println("PostConditionsan out of bounds, strike max reached\n"); |
||
118 | } |
||
119 | //System.out.println("\n"+ "Answer single strategy steps: " + time + "ms\n"); |
||
120 | } |
||
121 | |||
122 | // default action |
||
123 | return new Wait(); |
||
124 | } |
||
125 | |||
126 | //update list of expected states with list of actual states given, resets local clocks if state changed |
||
127 | private void updateExpectedState(Map<String,String> actualStates) { |
||
128 | for(String timeline : actualStates.keySet()) { |
||
129 | if(!this.expectedState.get(timeline).equals(actualStates.get(timeline))) { |
||
130 | resetClocks(timeline,new Transition(timeline,this.expectedState.get(timeline),this.expectedState.get(timeline))); |
||
131 | this.expectedState.put(timeline, actualStates.get(timeline)); |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | // Resets the local clocks of uncontrollable events that took place in the tic |
||
137 | View Code Duplication | private void resetClocks(String timeline,Transition token) { |
|
138 | //this.timelineClocks.put(timeline+"."+timeline+"_clock",0); |
||
139 | //System.out.println(" RESET CLOCK : " + timeline + " " + token + "<<<<<<<<<<<<<<<<<<<\n"); |
||
140 | Map<String,String> condToken = this.uPostConditions.get(token); |
||
141 | //System.out.println("CONDTOKEN : " + condToken + "\n"); |
||
142 | if(condToken!=null) { |
||
143 | for(String cond : condToken.keySet()) { |
||
144 | if(condToken.get(cond).contains("0")) { |
||
145 | this.timelineClocks.put(cond, 0l); |
||
146 | } |
||
147 | if(condToken.get(cond).contains("H")) { |
||
148 | this.timelineClocks.put(cond, this.horizon*2); |
||
149 | } |
||
150 | } |
||
151 | this.timelineClocks.put(timeline, 0l); |
||
152 | }} |
||
153 | |||
154 | //updates, after a winning transition, the next expected state |
||
155 | private void updateExpectedState(Action action) { |
||
156 | if(action.getClass().equals(Transition.class)) { |
||
157 | Transition t = (Transition) action; |
||
158 | this.expectedState.put(t.getTransitionTo().getTimeline(),t.getTransitionTo().getToken()); |
||
159 | } |
||
160 | } |
||
161 | |||
162 | //updates clocks through plan clock |
||
163 | private void updateClocks(long n) { |
||
164 | for(String c : this.timelineClocks.keySet()) { |
||
165 | //System.out.println(">>> INCREMENT CLOCK BY " + n + ":::: CLOCK " + c + "\n"); |
||
166 | this.timelineClocks.put(c, this.timelineClocks.get(c)+n); |
||
167 | } |
||
168 | |||
169 | } |
||
170 | |||
171 | @Override |
||
172 | public void updateUncontrollable(Map<String, String> updatedState) { |
||
173 | // TODO Auto-generated method stub |
||
174 | System.out.println("WARNING: Unimplemented method 'updateUncontrollable'\n"); |
||
175 | |||
176 | } |
||
177 | |||
178 | @Override |
||
179 | public String toString() { |
||
180 | return "Strategy [STRATEGY = " + this.states + "]"; |
||
181 | } |
||
182 | |||
183 | //---------------------- GETTERS&SETTERS ------------------------ |
||
184 | |||
185 | public Set<StateSet> getStates() { |
||
186 | return this.states; |
||
187 | } |
||
188 | |||
189 | public void addState(StateSet states) { |
||
190 | this.states.add(states); |
||
191 | } |
||
192 | |||
193 | public Map<String,Long> getTimelineClocks() { |
||
194 | return this.timelineClocks; |
||
195 | } |
||
196 | |||
197 | @Override |
||
198 | public int getStrikeMaxReached() { |
||
199 | return this.strikeMaxReached; |
||
200 | } |
||
201 | |||
202 | @Override |
||
203 | public void setTimelineClocks(Map<String,Long> tc) { |
||
204 | this.timelineClocks = tc; |
||
205 | } |
||
206 | |||
207 | public Map<String, String> getExpectedState() { |
||
208 | return expectedState; |
||
209 | } |
||
210 | |||
211 | @Override |
||
212 | public void setInitialState(Map<String, String> expectedState) { |
||
213 | this.expectedState = expectedState; |
||
214 | } |
||
215 | |||
216 | public Map<Transition, Map<String, String>> getuPostConditions() { |
||
217 | return uPostConditions; |
||
218 | } |
||
219 | |||
220 | @Override |
||
221 | public void setuPostConditions(Map<Transition, Map<String, String>> uPostConditions) { |
||
222 | this.uPostConditions = uPostConditions; |
||
223 | } |
||
224 | |||
225 | // @Override //may be obsolete |
||
226 | // public void getStrategyAsList(Set<StateSet> accumulatedStates) { |
||
227 | // for (StateSet set : accumulatedStates) { |
||
228 | // this.addState(set); |
||
229 | // } |
||
230 | // } |
||
231 | |||
232 | @Override |
||
233 | public void getStrategyAsStrings(String ss, List<String> statesLine){ |
||
234 | StateSet stateSet = new StateSet(ss,statesLine); |
||
235 | this.states.add(stateSet); |
||
236 | } |
||
237 | |||
238 | @Override |
||
239 | public boolean isOutOfBounds() { |
||
240 | return (this.strikeTimer > ListStrategy.MAX_STRIKE); |
||
241 | } |
||
242 | |||
243 | // @Override //OBSOLETE AND NOT WORKING |
||
244 | // public boolean isStrategyFinished() { |
||
245 | // for( String tl : this.expectedState.keySet()) { |
||
246 | // if(!this.expectedState.get(tl).equals("finish")){ |
||
247 | // return false; |
||
248 | // } |
||
249 | // } |
||
250 | // return true; |
||
251 | // } |
||
252 | |||
253 | public Set<String> getuStates() { |
||
254 | return uStates; |
||
255 | } |
||
256 | |||
257 | @Override |
||
258 | public void setuStates(Set<String> uStates) { |
||
259 | this.uStates = uStates; |
||
260 | } |
||
267 |