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