| 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 |