1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
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
;
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
;
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
;
27 * This class implements a state tree described in XML-defined pattern
29 * @author Jean-Christian Kouame
31 public class TmfXmlState
{
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
;
47 * Enum for the type of state
59 * Fail state type, the pattern has failed to match
63 * This is the normal state type, for states that are not the first,
64 * final or failing state
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
;
74 fTransitions
= transitions
;
76 fOnEntryActions
= onentryActions
;
77 fOnExitActions
= onexitActions
;
84 * The factory used to create XML model elements
86 * The XML root of this state
88 * The state system container this state definition belongs to
90 * The parent state of this state
91 * @return The new {@link TmfXmlState}
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
);
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
;
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
;
104 TmfXmlState state
= new TmfXmlState(container
, type
, id
, parent
, transitions
, new HashMap
<>(), onentryActions
, onexitActions
);
105 initState(state
, modelFactory
, container
, node
);
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
);
119 parentState
.fFinalStateId
= finalStateId
;
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();
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
);
139 if (i
== 0 && initial
.isEmpty()) {
140 initial
= child
.getId();
143 parentState
.fInitialStateId
= initial
.isEmpty() ?
null : initial
;
144 parentState
.fInitialTransition
= initialTransition
;
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
);
153 * Get the List of transitions for this state
155 * @param modelFactory
156 * The factory used to create XML model elements
158 * The XML root of this state definition
159 * @return The list of transitions
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();
169 TmfXmlStateTransition transition
= modelFactory
.createStateTransition(element
, container
);
170 transitions
.add(transition
);
176 * Get the state type from its XML definition
178 * The XML definition of the state
179 * @return The state type
181 private static Type
getStateType(Element node
) {
182 switch (node
.getNodeName()) {
183 case TmfXmlStrings
.FINAL
:
185 case TmfXmlStrings
.INITIAL
:
187 case TmfXmlStrings
.ABANDON
:
189 case TmfXmlStrings
.STATE
:
198 * @return The state id
200 public String
getId() {
207 * @return The container
209 public IXmlStateSystemContainer
getContainer() {
214 * The list of transitions of this state
216 * @return The list of transitions
218 public List
<TmfXmlStateTransition
> getTransitionList() {
223 * Get the actions to execute when entering this state, in an array
225 * @return The array of actions
227 public List
<String
> getOnEntryActions() {
228 return fOnEntryActions
;
232 * Get the actions to execute when leaving this state, in an array
234 * @return The array of actions
236 public List
<String
> getOnExitActions() {
237 return fOnExitActions
;
241 * Get children states of this state into a map
243 * @return The map of children state
245 public Map
<String
, TmfXmlState
> getChildren() {
250 * Get the initial transition of this state
252 * @return The initial transition
254 public @Nullable TmfXmlStateTransition
getInitialTransition() {
255 return fInitialTransition
;
259 * Get the initial state ID
261 * @return The initial state ID
263 public @Nullable String
getInitialStateId() {
264 return fInitialStateId
;
268 * Get the final state ID
270 * @return The final state ID
272 public @Nullable String
getFinalStateId() {
273 return fFinalStateId
;
277 * Get the parent state
279 * @return The parent state
281 public @Nullable TmfXmlState
getParent() {
286 * Get the type of this state
288 * @return The type of the state
290 public Type
getType() {