tmf : Add parameters to XML core methods
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlStateChange.java
CommitLineData
0f7276b6
GB
1/*******************************************************************************
2 * Copyright (c) 2014 Ecole Polytechnique de Montreal
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 * Contributors:
10 * Florian Wininger - Initial API and implementation
11 ******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
0f7276b6
GB
14
15import java.util.ArrayList;
16import java.util.List;
17
18import org.eclipse.jdt.annotation.NonNull;
12685851 19import org.eclipse.jdt.annotation.Nullable;
e894a508
AM
20import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
21import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
22import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
2bdf0193
AM
23import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
24import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
25import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
26import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
0f7276b6
GB
27import org.w3c.dom.Element;
28import org.w3c.dom.Node;
29
30/**
1d7e62f9 31 * This Class implement a State Change in the XML-defined state system
0f7276b6
GB
32 *
33 * <pre>
34 * example 1: Simple state change
35 * <stateChange>
36 * <stateAttribute type="location" value="CurrentThread" />
37 * <stateAttribute type="constant" value="System_call" />
38 * <stateValue type="null" />
39 * </stateChange>
40 *
41 * example 2: Conditional state change
42 * <stateChange>
43 * <if>
44 * <condition>
45 * <stateAttribute type="location" value="CurrentThread" />
46 * <stateAttribute type="constant" value="System_call" />
47 * <stateValue type="null" />
48 * </condition>
49 * </if>
50 * <then>
51 * <stateAttribute type="location" value="CurrentThread" />
52 * <stateAttribute type="constant" value="Status" />
53 * <stateValue int="$PROCESS_STATUS_RUN_USERMODE"/>
54 * </then>
55 * <else>
56 * <stateAttribute type="location" value="CurrentThread" />
57 * <stateAttribute type="constant" value="Status" />
58 * <stateValue int="$PROCESS_STATUS_RUN_SYSCALL"/>
59 * </else>
60 * </stateChange>
61 * </pre>
62 *
63 * @author Florian Wininger
64 */
65public class TmfXmlStateChange {
66
67 private final IXmlStateChange fChange;
1d7e62f9 68 private final IXmlStateSystemContainer fContainer;
0f7276b6
GB
69
70 /**
71 * Constructor
72 *
1d7e62f9
GB
73 * @param modelFactory
74 * The factory used to create XML model elements
0f7276b6
GB
75 * @param statechange
76 * XML node root of this state change
1d7e62f9
GB
77 * @param container
78 * The state system container this state change belongs to
0f7276b6 79 */
1d7e62f9
GB
80 public TmfXmlStateChange(ITmfXmlModelFactory modelFactory, Element statechange, IXmlStateSystemContainer container) {
81 fContainer = container;
0f7276b6
GB
82
83 /*
84 * child nodes is either a list of TmfXmlStateAttributes and
85 * TmfXmlStateValues, or an if-then-else series of nodes.
86 */
87 Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
88 if (ifNode != null) {
89 /* the state change has a condition */
1d7e62f9 90 fChange = new XmlConditionalChange(modelFactory, statechange);
0f7276b6
GB
91 } else {
92 /* the state change does not have a condition */
1d7e62f9 93 fChange = new XmlStateValueChange(modelFactory, statechange);
0f7276b6
GB
94 }
95 }
96
97 /**
98 * Execute the state change for an event. If necessary, it validates the
99 * condition and executes the required change.
100 *
101 * @param event
102 * The event to process
0b563c20
JCK
103 * @param scenarioInfo
104 * The active scenario details. The value should be null if there
105 * no scenario.
0f7276b6
GB
106 * @throws AttributeNotFoundException
107 * Pass through the exception it received
108 * @throws TimeRangeException
109 * Pass through the exception it received
110 * @throws StateValueTypeException
111 * Pass through the exception it received
0b563c20 112 * @since 2.0
0f7276b6 113 */
0b563c20
JCK
114 public void handleEvent(ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
115 fChange.handleEvent(event, scenarioInfo);
0f7276b6
GB
116 }
117
446598f9
GB
118 @Override
119 public String toString() {
120 return "TmfXmlStateChange: " + fChange; //$NON-NLS-1$
121 }
122
0f7276b6
GB
123 /* Interface for both private classes to handle the event */
124 private interface IXmlStateChange {
0b563c20 125 void handleEvent(ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException;
0f7276b6
GB
126 }
127
128 /**
129 * Conditional state change with a condition to verify
130 */
131 private class XmlConditionalChange implements IXmlStateChange {
132 private final TmfXmlCondition fCondition;
133 private final TmfXmlStateChange fThenChange;
12685851 134 private final @Nullable TmfXmlStateChange fElseChange;
0f7276b6 135
1d7e62f9 136 public XmlConditionalChange(ITmfXmlModelFactory modelFactory, Element statechange) {
0f7276b6
GB
137 /*
138 * The if node exists, it has been verified before calling this
139 */
140 Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
12685851
GB
141 if (ifNode == null) {
142 throw new IllegalArgumentException();
143 }
1d7e62f9 144 fCondition = modelFactory.createCondition((Element) ifNode, fContainer);
0f7276b6
GB
145
146 Node thenNode = statechange.getElementsByTagName(TmfXmlStrings.THEN).item(0);
147 if (thenNode == null) {
148 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
149 }
1d7e62f9 150 fThenChange = modelFactory.createStateChange((Element) thenNode, fContainer);
0f7276b6
GB
151
152 Node elseNode = statechange.getElementsByTagName(TmfXmlStrings.ELSE).item(0);
153 if (elseNode != null) {
1d7e62f9 154 fElseChange = modelFactory.createStateChange((Element) elseNode, fContainer);
0f7276b6
GB
155 } else {
156 fElseChange = null;
157 }
158 }
159
160 @Override
0b563c20 161 public void handleEvent(@NonNull ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
0f7276b6
GB
162 TmfXmlStateChange toExecute = fThenChange;
163 try {
0b563c20 164 if (!fCondition.testForEvent(event, scenarioInfo)) {
0f7276b6
GB
165 toExecute = fElseChange;
166 }
167 } catch (AttributeNotFoundException e) {
168 /*
169 * An attribute in the condition did not exist (yet), return
170 * from the state change
171 */
172 return;
173 }
174
175 if (toExecute == null) {
176 return;
177 }
0b563c20 178 toExecute.handleEvent(event, scenarioInfo);
0f7276b6 179 }
446598f9
GB
180
181 @Override
182 public String toString() {
183 return "Condition: " + fCondition; //$NON-NLS-1$
184 }
0f7276b6
GB
185 }
186
187 /**
188 * State change with no condition
189 */
190 private class XmlStateValueChange implements IXmlStateChange {
1d7e62f9 191 private final ITmfXmlStateValue fValue;
0f7276b6 192
1d7e62f9 193 public XmlStateValueChange(ITmfXmlModelFactory modelFactory, Element statechange) {
4c4e2816 194 List<@Nullable Element> childElements = XmlUtils.getChildElements(statechange);
0f7276b6
GB
195
196 /*
197 * Last child element is the state value, the others are attributes
198 * to reach to value to set
199 */
200 Element stateValueElement = childElements.remove(childElements.size() - 1);
12685851
GB
201 if (stateValueElement == null) {
202 throw new IllegalStateException();
203 }
1d7e62f9 204 List<ITmfXmlStateAttribute> attributes = new ArrayList<>();
0f7276b6 205 for (Element element : childElements) {
4c4e2816 206 if (element == null || !element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
0f7276b6
GB
207 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
208 }
1d7e62f9 209 ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
0f7276b6
GB
210 attributes.add(attribute);
211 }
212 if (attributes.isEmpty()) {
213 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
214 }
1d7e62f9 215 fValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes);
0f7276b6
GB
216 }
217
218 @Override
0b563c20
JCK
219 public void handleEvent(@NonNull ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
220 fValue.handleEvent(event, scenarioInfo);
0f7276b6 221 }
446598f9
GB
222
223 @Override
224 public String toString() {
225 return "Value: " + fValue; //$NON-NLS-1$
226 }
0f7276b6
GB
227 }
228
229}
This page took 0.075554 seconds and 5 git commands to generate.