View Javadoc

1   /*
2    * Copyright (c) 2007 committers of Talante (http://talante.sf.net) and others. 
3    * All rights reserved.
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package net.sf.talante.cartridge.ext;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.StringTokenizer;
24  
25  import org.eclipse.uml2.uml.Constraint;
26  import org.eclipse.uml2.uml.Event;
27  import org.eclipse.uml2.uml.FinalState;
28  import org.eclipse.uml2.uml.OpaqueExpression;
29  import org.eclipse.uml2.uml.Operation;
30  import org.eclipse.uml2.uml.Parameter;
31  import org.eclipse.uml2.uml.ParameterDirectionKind;
32  import org.eclipse.uml2.uml.Pseudostate;
33  import org.eclipse.uml2.uml.PseudostateKind;
34  import org.eclipse.uml2.uml.Region;
35  import org.eclipse.uml2.uml.SignalEvent;
36  import org.eclipse.uml2.uml.State;
37  import org.eclipse.uml2.uml.TimeEvent;
38  import org.eclipse.uml2.uml.Transition;
39  import org.eclipse.uml2.uml.Vertex;
40  import org.eclipse.uml2.uml.internal.impl.UMLFactoryImpl;
41  
42  /**
43   * Talante OAW/UML2 state machine extension.
44   * 
45   * @author Bernd Mau
46   * 
47   * @since 0.1
48   */
49  public class StateMachine {
50  
51      private static HashSet<String> actionMethods;
52  
53      public static void initialize() {
54          actionMethods = new HashSet<String>();
55      }
56  
57      public static boolean isInitialState(Vertex state) {
58  
59          return (state instanceof Pseudostate) ? ((Pseudostate) state).getKind()
60                  .equals(PseudostateKind.get(PseudostateKind.INITIAL)) : false;
61      }
62  
63      public static boolean isTerminateState(Vertex state) {
64          return (state instanceof Pseudostate) ? ((Pseudostate) state).getKind()
65                  .equals(PseudostateKind.get(PseudostateKind.TERMINATE)) : false;
66      }
67  
68      public static boolean isChoiceState(Vertex state) {
69          return (state instanceof Pseudostate) ? ((Pseudostate) state).getKind()
70                  .equals(PseudostateKind.get(PseudostateKind.CHOICE)) : false;
71      }
72  
73      public static boolean isFinalState(State state) {
74          return state instanceof FinalState;
75      }
76  
77      public static boolean isSignalEvent(Event event) {
78          return event instanceof SignalEvent;
79      }
80  
81      public static boolean isTimeEvent(Event event) {
82          return event instanceof TimeEvent;
83      }
84  
85      public static Pseudostate getInitialState(Region region) {
86  
87          for (Iterator iter = region.getSubvertices().iterator(); iter.hasNext();) {
88              Vertex v = (Vertex) iter.next();
89              if (v instanceof Pseudostate) {
90                  Pseudostate ps = (Pseudostate) v;
91                  if (isInitialState(ps)) {
92                      return ps;
93                  }
94              }
95          }
96          return null;
97      }
98  
99      public static Collection getGuardMethods(Collection guardExpressions) {
100         HashSet<String> guardMethods = new HashSet<String>();
101 
102         for (Object object : guardExpressions) {
103             String expression = (String) object;
104 
105             StringTokenizer tokenizer = new StringTokenizer(expression, " ",
106                     false);
107 
108             while (tokenizer.hasMoreTokens()) {
109                 String token = tokenizer.nextToken();
110                 if (token.startsWith("!")) {
111                     token = token.substring(1);
112                 }
113                 if (token.length() != 0) {
114                     if (token.startsWith("(") || token.startsWith(")")
115                             || token.startsWith("&") || token.startsWith("|")
116                             || token.startsWith("In")) {
117                         // do nothing
118                     } else {
119                         guardMethods.add(token);
120                     }
121 
122                 }
123             }
124         }
125 
126         return guardMethods;
127     }
128 
129     public static String guardExpression(Collection guardExpressions,
130             String context) {
131         String expression = "";
132 
133         for (Object object : guardExpressions) {
134             String tempExpression = (String) object;
135 
136             StringTokenizer tokenizer = new StringTokenizer(tempExpression,
137                     " ", false);
138 
139             while (tokenizer.hasMoreTokens()) {
140                 String token = tokenizer.nextToken();
141 
142                 if (token.startsWith("!")) {
143                     expression += "!";
144                     token = token.substring(1);
145                 }
146                 if (token.startsWith("(") || token.startsWith(")")) {
147                     expression += token + " ";
148                 } else if (token.startsWith("&") || token.startsWith("|")) {
149                     expression += token + token + " ";
150                 } else if (token.startsWith("In(")) {
151                     token = token.substring("In(".length(),
152                             (token.length() - 1));
153                     expression += "((" + context + ") aContext).isInState"
154                             + token + "() ";
155                 } else {
156                     expression += "((" + context + ") aContext)."
157                             + firstToLowerCase(token) + "() ";
158                 }
159             }
160         }
161 
162         return expression;
163     }
164 
165     private static final String firstToLowerCase(String input) {
166         String first = input.substring(0, 1);
167         first = first.toLowerCase();
168         return first + input.substring(1);
169     }
170 
171     public static Collection methodParameter(Operation operation) {
172         ArrayList<Parameter> operationParameter = new ArrayList<Parameter>();
173 
174         for (Object ownedParameter : operation.getOwnedParameters()) {
175             Parameter parameter = (Parameter) ownedParameter;
176 
177             if (!parameter.getDirection().equals(ParameterDirectionKind.RETURN)) {
178                 operationParameter.add(parameter);
179             }
180         }
181 
182         return operationParameter;
183     }
184 
185     public static Parameter returnValue(Operation operation) {
186 
187         for (Object ownedParameter : operation.getOwnedParameters()) {
188             Parameter parameter = (Parameter) ownedParameter;
189 
190             if (parameter.getDirection().equals(ParameterDirectionKind.RETURN)) {
191                 return parameter;
192             }
193         }
194 
195         return null;
196     }
197 
198     public static boolean isActionMethodExisting(String methodName) {
199         if (methodName.indexOf("[]") != -1) {
200             methodName = methodName.substring(0, methodName.indexOf("[]"))
201                     + methodName.substring(methodName.indexOf("[]") + 2,
202                             methodName.length());
203         }
204         return !actionMethods.add(methodName);
205     }
206 
207     @SuppressWarnings("unchecked")
208     public static Transition getConstraint(Transition transition) {
209         OpaqueExpression opaqueExpression = null;
210         if (transition.getGuard() != null) {
211             opaqueExpression = (OpaqueExpression) transition.getGuard()
212                     .getSpecification();
213             opaqueExpression.getBodies().add(" & ");
214         } else {
215             Constraint constraint = new UMLFactoryImpl().createConstraint();
216             constraint.setContext(transition.getNamespace());
217             transition.setGuard(constraint);
218             opaqueExpression = new UMLFactoryImpl().createOpaqueExpression();
219         }
220         opaqueExpression.getBodies().add(
221                 "In(" + transition.getSource().getName() + ")");
222         transition.getGuard().setSpecification(opaqueExpression);
223         return transition;
224     }
225 
226     public static String getEnumName(final Vertex state) {
227         String enumName = state.getName().toUpperCase();
228         Region region = state.getContainer();
229         while (region != null && region.getName().length() > 0
230                 && region.getStateMachine() == null) {
231             enumName = state.getContainer().getName().toUpperCase() + "_"
232                     + enumName;
233             region = region.getState() != null ? region.getState()
234                     .getContainer() : null;
235         }
236         if (Logger.isDebugEnabled()) {
237             Logger.debug("return enumName: " + enumName);
238         }
239         return enumName;
240     }
241 
242 }