12807b4665da06d092cc2b9d99980f0ef22f1e11
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / internal / tmf / analysis / xml / core / model / TmfXmlState.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 ******************************************************************************/
9 package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collections;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.common.core.NonNullUtils;
21 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
22 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
23 import org.w3c.dom.Element;
24 import org.w3c.dom.NodeList;
25
26 /**
27 * This class implements a state tree described in XML-defined pattern
28 *
29 * @author Jean-Christian Kouame
30 */
31 public class TmfXmlState {
32
33 private final String fId;
34 private final IXmlStateSystemContainer fContainer;
35 private final List<TmfXmlStateTransition> fTransitions;
36 private @Nullable TmfXmlState fparent;
37 private List<String> fOnEntryActions;
38 private List<String> fOnExitActions;
39 //TODO Sub-state are not yet supported.
40 private Map<String, TmfXmlState> fChildren;
41 private @Nullable TmfXmlStateTransition fInitialTransition;
42 private @Nullable String fInitialStateId;
43 private @Nullable String fFinalStateId;
44 private Type fType;
45
46 /**
47 * Enum for the type of state
48 */
49 public enum Type {
50 /**
51 * Final state type
52 */
53 FINAL,
54 /**
55 * Initial state type
56 */
57 INITIAL,
58 /**
59 * Fail state type, the pattern has failed to match
60 */
61 FAIL,
62 /**
63 * This is the normal state type, for states that are not the first,
64 * final or failing state
65 */
66 DEFAULT
67 }
68
69 private TmfXmlState(IXmlStateSystemContainer container, Type type, String id, @Nullable TmfXmlState parent, List<@NonNull TmfXmlStateTransition> transitions, Map<@NonNull String, @NonNull TmfXmlState> children, List<String> onentryActions, List<String> onexitActions) {
70 fContainer = container;
71 fType = type;
72 fId = id;
73 fparent = parent;
74 fTransitions = transitions;
75 fChildren = children;
76 fOnEntryActions = onentryActions;
77 fOnExitActions = onexitActions;
78 }
79
80 /**
81 * Constructor
82 *
83 * @param modelFactory
84 * The factory used to create XML model elements
85 * @param node
86 * The XML root of this state
87 * @param container
88 * The state system container this state definition belongs to
89 * @param parent
90 * The parent state of this state
91 * @return The new {@link TmfXmlState}
92 */
93 public static TmfXmlState create(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, @Nullable TmfXmlState parent) {
94 Type type = getStateType(node);
95 String id = node.getAttribute(TmfXmlStrings.ID);
96 List<TmfXmlStateTransition> transitions = getTransitions(modelFactory, container, node);
97
98 NodeList nodesOnentry = node.getElementsByTagName(TmfXmlStrings.ONENTRY);
99 List<String> onentryActions = nodesOnentry.getLength() > 0 ? Arrays.asList(((Element) nodesOnentry.item(0)).getAttribute(TmfXmlStrings.ACTION).split(TmfXmlStrings.AND_SEPARATOR)) : Collections.EMPTY_LIST;
100
101 NodeList nodesOnexit = node.getElementsByTagName(TmfXmlStrings.ONEXIT);
102 List<String> onexitActions = nodesOnexit.getLength() > 0 ? Arrays.asList(((Element) nodesOnexit.item(0)).getAttribute(TmfXmlStrings.ACTION).split(TmfXmlStrings.AND_SEPARATOR)) : Collections.EMPTY_LIST;
103
104 TmfXmlState state = new TmfXmlState(container, type, id, parent, transitions, new HashMap<>(), onentryActions, onexitActions);
105 initState(state, modelFactory, container, node);
106
107 return state;
108 }
109
110 private static void getFinalState(TmfXmlState parentState, ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, Element node) {
111 NodeList nodesFinal = node.getElementsByTagName(TmfXmlStrings.FINAL);
112 String finalStateId = null;
113 if (nodesFinal.getLength() > 0) {
114 final Element finalElement = NonNullUtils.checkNotNull((Element) nodesFinal.item(0));
115 finalStateId = nodesFinal.getLength() > 0 ? finalElement.getAttribute(TmfXmlStrings.ID) : null;
116 TmfXmlState finalState = modelFactory.createState(finalElement, container, parentState);
117 parentState.getChildren().put(finalState.getId(), finalState);
118 }
119 parentState.fFinalStateId = finalStateId;
120 }
121
122 private static void getSubStates(TmfXmlState parentState, ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, Element node) {
123 String initial = node.getAttribute(TmfXmlStrings.INITIAL);
124 TmfXmlStateTransition initialTransition = null;
125 if (initial.isEmpty()) {
126 NodeList nodesInitial = node.getElementsByTagName(TmfXmlStrings.INITIAL);
127 if (nodesInitial.getLength() == 1) {
128 final @NonNull Element transitionElement = NonNullUtils.checkNotNull((Element) ((Element) nodesInitial.item(0)).getElementsByTagName(TmfXmlStrings.TRANSITION).item(0));
129 initialTransition = modelFactory.createStateTransition(transitionElement, container);
130 initial = initialTransition.getTarget();
131 }
132 }
133
134 NodeList nodesState = node.getElementsByTagName(TmfXmlStrings.STATE);
135 for (int i = 0; i < nodesState.getLength(); i++) {
136 TmfXmlState child = modelFactory.createState(NonNullUtils.checkNotNull((Element) nodesState.item(i)), container, parentState);
137 parentState.getChildren().put(child.getId(), child);
138
139 if (i == 0 && initial.isEmpty()) {
140 initial = child.getId();
141 }
142 }
143 parentState.fInitialStateId = initial.isEmpty() ? null : initial;
144 parentState.fInitialTransition = initialTransition;
145 }
146
147 private static void initState(TmfXmlState state, ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, Element node) {
148 getSubStates(state, modelFactory, container, node);
149 getFinalState(state, modelFactory, container, node);
150 }
151
152 /**
153 * Get the List of transitions for this state
154 *
155 * @param modelFactory
156 * The factory used to create XML model elements
157 * @param node
158 * The XML root of this state definition
159 * @return The list of transitions
160 */
161 private static List<@NonNull TmfXmlStateTransition> getTransitions(ITmfXmlModelFactory modelFactory, IXmlStateSystemContainer container, Element node) {
162 List<@NonNull TmfXmlStateTransition> transitions = new ArrayList<>();
163 NodeList nodesTransition = node.getElementsByTagName(TmfXmlStrings.TRANSITION);
164 for (int i = 0; i < nodesTransition.getLength(); i++) {
165 final Element element = (Element) nodesTransition.item(i);
166 if (element == null) {
167 throw new IllegalArgumentException();
168 }
169 TmfXmlStateTransition transition = modelFactory.createStateTransition(element, container);
170 transitions.add(transition);
171 }
172 return transitions;
173 }
174
175 /**
176 * Get the state type from its XML definition
177 * @param node
178 * The XML definition of the state
179 * @return The state type
180 */
181 private static Type getStateType(Element node) {
182 switch (node.getNodeName()) {
183 case TmfXmlStrings.FINAL:
184 return Type.FINAL;
185 case TmfXmlStrings.INITIAL:
186 return Type.INITIAL;
187 case TmfXmlStrings.ABANDON:
188 return Type.FAIL;
189 case TmfXmlStrings.STATE:
190 default:
191 return Type.DEFAULT;
192 }
193 }
194
195 /**
196 * Get the state id
197 *
198 * @return The state id
199 */
200 public String getId() {
201 return fId;
202 }
203
204 /**
205 * Get the container
206 *
207 * @return The container
208 */
209 public IXmlStateSystemContainer getContainer() {
210 return fContainer;
211 }
212
213 /**
214 * The list of transitions of this state
215 *
216 * @return The list of transitions
217 */
218 public List<TmfXmlStateTransition> getTransitionList() {
219 return fTransitions;
220 }
221
222 /**
223 * Get the actions to execute when entering this state, in an array
224 *
225 * @return The array of actions
226 */
227 public List<String> getOnEntryActions() {
228 return fOnEntryActions;
229 }
230
231 /**
232 * Get the actions to execute when leaving this state, in an array
233 *
234 * @return The array of actions
235 */
236 public List<String> getOnExitActions() {
237 return fOnExitActions;
238 }
239
240 /**
241 * Get children states of this state into a map
242 *
243 * @return The map of children state
244 */
245 public Map<String, TmfXmlState> getChildren() {
246 return fChildren;
247 }
248
249 /**
250 * Get the initial transition of this state
251 *
252 * @return The initial transition
253 */
254 public @Nullable TmfXmlStateTransition getInitialTransition() {
255 return fInitialTransition;
256 }
257
258 /**
259 * Get the initial state ID
260 *
261 * @return The initial state ID
262 */
263 public @Nullable String getInitialStateId() {
264 return fInitialStateId;
265 }
266
267 /**
268 * Get the final state ID
269 *
270 * @return The final state ID
271 */
272 public @Nullable String getFinalStateId() {
273 return fFinalStateId;
274 }
275
276 /**
277 * Get the parent state
278 *
279 * @return The parent state
280 */
281 public @Nullable TmfXmlState getParent() {
282 return fparent;
283 }
284
285 /**
286 * Get the type of this state
287 *
288 * @return The type of the state
289 */
290 public Type getType() {
291 return fType;
292 }
293 }
This page took 0.03926 seconds and 4 git commands to generate.