View Javadoc

1   /*
2    * Created on 17-ago-2005
3    *
4    * TODO To change the template for this generated file go to
5    * Window - Preferences - Java - Code Style - Code Templates
6    */
7   package org.state4j.sm;
8   
9   import java.util.Iterator;
10  import java.util.List;
11  import java.util.Map;
12  
13  
14  /***
15   * @author andrea
16   * 
17   */
18  public class SmCompositeStateImpl extends SmStateImpl implements SmCompositeState {
19      private Map<String, SmState> states;
20  
21      public SmState getInitialState() {
22          SmState candidateResult = null;
23          Iterator itStates = this.getStates().values().iterator();
24          while (itStates.hasNext()) {
25              SmState currState = (SmState) itStates.next();
26              if (currState.isInitial()) {
27                  return currState;
28              }
29              candidateResult = currState;
30          }
31          if (candidateResult == null) {
32              throw new RuntimeException("Sorry!! cannot found initial state");
33          } else if (candidateResult instanceof SmCompositeState) {
34              return ((SmCompositeState) candidateResult).getInitialState();
35          } else {
36              return candidateResult;
37          }
38      }
39  
40      public SmState getState(String stateName) {
41          if (!this.hasState(stateName)) {
42              throw new RuntimeException("Sorry! cannot get state " + stateName + ". Does not exists");
43          }
44          return this.getStates().get(stateName);
45      }
46  
47      public Map<String, SmState> getStates() {
48          return states;
49      }
50  
51      public boolean hasState(String stateName) {
52          if (stateName == null || stateName.equals("")) {
53              throw new RuntimeException("Sorry!! cannot check state with name null/empty");
54          }
55          return this.getStates().containsKey(stateName) && this.getStates().get(stateName) != null;
56      }
57  
58      public boolean hasStates() {
59          return this.states != null && !this.states.isEmpty();
60      }
61  
62      public void setStates(Map<String, SmState> states) {
63          this.states = states;
64          if (!this.hasStates()) {
65              return;
66          }
67          Iterator itStates = this.getStates().values().iterator();
68          while (itStates.hasNext()) {
69              SmState currState = (SmState) itStates.next();
70              currState.setParent(this);
71          }
72      }
73  
74      public List<SmTransition> getFireableTransitions(SmContext cntx, boolean withTrigger) {
75          List<SmTransition> result = super.getFireableTransitions(cntx, withTrigger);
76          if (!this.hasStates()) {
77              return result;
78          }
79          Iterator itStates = this.getStates().values().iterator();
80          while (itStates.hasNext()) {
81              SmState currState = (SmState) itStates.next();
82              result.addAll(currState.getFireableTransitions(cntx, withTrigger));
83          }
84          return result;
85      }
86  
87      public SmState getActiveSubstate(SmContext cntx) {
88          SmState result = null;
89          Iterator itStates = this.getStates().values().iterator();
90          while (itStates.hasNext() && result == null) {
91              SmState currState = (SmState) itStates.next();
92              if (currState.isActive(cntx)) {
93                  result = currState;
94              }
95          }
96          if (result == null) {
97              throw new RuntimeException("Sorry!! cannot get active state from " + this.getName());
98          }
99          return result;
100     }
101 
102     public boolean hasActiveSubstate(SmContext cntx) {
103         boolean result = false;
104         if (!this.hasStates()) {
105             return result;
106         }
107         Iterator itStates = this.getStates().values().iterator();
108         while (itStates.hasNext() && !result) {
109             SmState currState = (SmState) itStates.next();
110             result = result || currState.isActive(cntx);
111         }
112         return result;
113     }
114 
115     public boolean isActive(SmContext cntx) {
116         return super.isActive(cntx) || this.hasActiveSubstate(cntx);
117     }
118 
119     public boolean deepContainsState(SmState state) {
120         boolean result = false;
121         if (!this.hasStates()) {
122             return result;
123         }
124         Iterator itStates = this.getStates().values().iterator();
125         while (itStates.hasNext() && !result) {
126             SmState currState = (SmState) itStates.next();
127             result = result || currState.equals(state) || currState.deepContainsState(state);
128         }
129         return result;
130     }
131 
132     public boolean containsState(SmState state) {
133         boolean result = false;
134         if (!this.hasStates()) {
135             return result;
136         }
137         Iterator itStates = this.getStates().values().iterator();
138         while (itStates.hasNext() && !result) {
139             SmState currState = (SmState) itStates.next();
140             result = result || currState.equals(state);
141         }
142         return result;
143     }
144 
145     public SmState closeDownState() {
146         return this.getInitialState().closeDownState();
147     }
148 
149     public SmCompositeState getLCA(SmState state1, SmState state2) {
150         SmCompositeState result = null;
151         if (this.containsState(state1) && this.containsState(state2)) {
152             result = this;
153         }
154         Iterator itStates = this.getStates().values().iterator();
155         while (itStates.hasNext()) {
156             SmState currState = (SmState) itStates.next();
157             if (currState.deepContainsState(state1) && currState.deepContainsState(state2)) {
158                 return ((SmCompositeState) currState).getLCA(state1, state2);
159             }
160         }
161         if (result == null) {
162             throw new RuntimeException("Sorry!! cannot get LCA from " + this.getName() + "; state1=" + state1.getName()
163                     + " - state2=" + state2.getName());
164         }
165         return result;
166     }
167 
168     public void registerLCA(SmTransition transition) {
169         if (this.deepContainsState(transition.getStateOut()) && this.deepContainsState(transition.getStateIn())) {
170             transition.setLCA(this);
171         } else {
172             if (this.hasParent()) {
173                 this.getParent().registerLCA(transition);
174             } else {
175                 throw new RuntimeException("Sorry!! cannot found LCA for transition " + transition.getName());
176             }
177         }
178     }
179 
180     public void init() {
181         super.init();
182         if (this.hasStates()) {
183             Iterator itStates = this.getStates().values().iterator();
184             while (itStates.hasNext()) {
185                 SmState currState = (SmState) itStates.next();
186                 currState.init();
187             }
188         }
189     }
190 }