tmf: Replace event matching API to use Collection
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.analysis.xml.core / src / org / eclipse / linuxtools / internal / tmf / analysis / xml / core / stateprovider / model / TmfXmlStateChange.java
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
13 package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
20 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
21 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
22 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
23 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
24 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
25 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
26 import org.w3c.dom.Element;
27 import org.w3c.dom.Node;
28
29 /**
30 * This Class implement a State Change in the XML state provider
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 */
64 public class TmfXmlStateChange {
65
66 private final IXmlStateChange fChange;
67 private final XmlStateProvider fProvider;
68
69 /**
70 * Constructor
71 *
72 * @param statechange
73 * XML node root of this state change
74 * @param provider
75 * The state provider this state change belongs to
76 */
77 public TmfXmlStateChange(Element statechange, XmlStateProvider provider) {
78 fProvider = provider;
79
80 /*
81 * child nodes is either a list of TmfXmlStateAttributes and
82 * TmfXmlStateValues, or an if-then-else series of nodes.
83 */
84 Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
85 if (ifNode != null) {
86 /* the state change has a condition */
87 fChange = new XmlConditionalChange(statechange);
88 } else {
89 /* the state change does not have a condition */
90 fChange = new XmlStateValueChange(statechange);
91 }
92 }
93
94 /**
95 * Execute the state change for an event. If necessary, it validates the
96 * condition and executes the required change.
97 *
98 * @param event
99 * The event to process
100 * @throws AttributeNotFoundException
101 * Pass through the exception it received
102 * @throws TimeRangeException
103 * Pass through the exception it received
104 * @throws StateValueTypeException
105 * Pass through the exception it received
106 */
107 public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
108 fChange.handleEvent(event);
109 }
110
111 /* Interface for both private classes to handle the event */
112 private interface IXmlStateChange {
113 void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException;
114 }
115
116 /**
117 * Conditional state change with a condition to verify
118 */
119 private class XmlConditionalChange implements IXmlStateChange {
120 private final TmfXmlCondition fCondition;
121 private final TmfXmlStateChange fThenChange;
122 private final TmfXmlStateChange fElseChange;
123
124 public XmlConditionalChange(Element statechange) {
125 /*
126 * The if node exists, it has been verified before calling this
127 */
128 Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
129 fCondition = new TmfXmlCondition((Element) ifNode, fProvider);
130
131 Node thenNode = statechange.getElementsByTagName(TmfXmlStrings.THEN).item(0);
132 if (thenNode == null) {
133 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
134 }
135 fThenChange = new TmfXmlStateChange((Element) thenNode, fProvider);
136
137 Node elseNode = statechange.getElementsByTagName(TmfXmlStrings.ELSE).item(0);
138 if (elseNode != null) {
139 fElseChange = new TmfXmlStateChange((Element) elseNode, fProvider);
140 } else {
141 fElseChange = null;
142 }
143 }
144
145 @Override
146 public void handleEvent(ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
147 TmfXmlStateChange toExecute = fThenChange;
148 try {
149 if (!fCondition.testForEvent(event)) {
150 toExecute = fElseChange;
151 }
152 } catch (AttributeNotFoundException e) {
153 /*
154 * An attribute in the condition did not exist (yet), return
155 * from the state change
156 */
157 return;
158 }
159
160 if (toExecute == null) {
161 return;
162 }
163 toExecute.handleEvent(event);
164 }
165 }
166
167 /**
168 * State change with no condition
169 */
170 private class XmlStateValueChange implements IXmlStateChange {
171 private final TmfXmlStateValue fValue;
172
173 public XmlStateValueChange(Element statechange) {
174 List<Element> childElements = XmlUtils.getChildElements(statechange);
175
176 /*
177 * Last child element is the state value, the others are attributes
178 * to reach to value to set
179 */
180 Element stateValueElement = childElements.remove(childElements.size() - 1);
181 List<TmfXmlStateAttribute> attributes = new ArrayList<>();
182 for (Element element : childElements) {
183 if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
184 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
185 }
186 TmfXmlStateAttribute attribute = new TmfXmlStateAttribute(element, fProvider);
187 attributes.add(attribute);
188 }
189 if (attributes.isEmpty()) {
190 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
191 }
192 fValue = new TmfXmlStateValue(stateValueElement, fProvider, attributes);
193 }
194
195 @Override
196 public void handleEvent(ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
197 fValue.handleEvent(event);
198 }
199 }
200
201 }
This page took 0.034142 seconds and 5 git commands to generate.