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