Fix references to linuxtools in comments, examples and unused code
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlCondition.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
5ddeee68 11 * Naser Ezzati - Add the comparison operators
0f7276b6
GB
12 ******************************************************************************/
13
2bdf0193 14package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
0f7276b6
GB
15
16import java.util.ArrayList;
17import java.util.List;
18
12685851 19import org.eclipse.jdt.annotation.Nullable;
e894a508
AM
20import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
21import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
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;
28
29/**
1d7e62f9 30 * This Class implement a condition tree in the XML-defined state system.
0f7276b6
GB
31 *
32 * <pre>
33 * example:
34 * <and>
35 * <condition>
36 * <stateAttribute type="location" value="CurrentThread" />
37 * <stateAttribute type="constant" value="System_call" />
38 * <stateValue type="null" />
39 * </condition>
40 * <condition>
41 * </condition>
42 * </and>
43 * </pre>
44 *
45 * @author Florian Wininger
46 */
47public class TmfXmlCondition {
48
49 private final List<TmfXmlCondition> fConditions = new ArrayList<>();
12685851 50 private final @Nullable ITmfXmlStateValue fStateValue;
5ddeee68 51 private final LogicalOperator fOperator;
1d7e62f9 52 private final IXmlStateSystemContainer fContainer;
5ddeee68 53 private final ConditionOperator fConditionOperator;
0f7276b6 54
5ddeee68 55 private enum LogicalOperator {
0f7276b6
GB
56 NONE,
57 NOT,
58 AND,
59 OR,
60 }
61
5ddeee68
NE
62 private enum ConditionOperator {
63 NONE,
64 EQ,
65 NE,
66 GE,
67 GT,
68 LE,
69 LT
70 }
71
0f7276b6
GB
72 /**
73 * Constructor
74 *
1d7e62f9
GB
75 * @param modelFactory
76 * The factory used to create XML model elements
0f7276b6
GB
77 * @param node
78 * The XML root of this condition
1d7e62f9
GB
79 * @param container
80 * The state system container this condition belongs to
0f7276b6 81 */
1d7e62f9
GB
82 public TmfXmlCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
83 fContainer = container;
0f7276b6
GB
84
85 Element rootNode = node;
86 /* Process the conditions: in each case, only process Element nodes */
87 List<Element> childElements = XmlUtils.getChildElements(rootNode);
88
89 /*
90 * If the node is an if, take the child as the root condition
91 *
92 * FIXME: Maybe the caller should do this instead.
93 */
94 if (node.getNodeName().equals(TmfXmlStrings.IF)) {
95 if (childElements.isEmpty()) {
96 throw new IllegalArgumentException("TmfXmlCondition constructor: IF node has no child element"); //$NON-NLS-1$
97 }
98 rootNode = childElements.get(0);
99 childElements = XmlUtils.getChildElements(rootNode);
100 }
101
102 switch (rootNode.getNodeName()) {
103 case TmfXmlStrings.CONDITION:
5ddeee68
NE
104 fOperator = LogicalOperator.NONE;
105 /* Read comparison type */
106 String equationType = rootNode.getAttribute(TmfXmlStrings.OPERATOR);
107
108 switch (equationType) {
109 case TmfXmlStrings.EQ:
110 fConditionOperator = ConditionOperator.EQ;
111 break;
112 case TmfXmlStrings.NE:
113 fConditionOperator = ConditionOperator.NE;
114 break;
115 case TmfXmlStrings.GE:
116 fConditionOperator = ConditionOperator.GE;
117 break;
118 case TmfXmlStrings.GT:
119 fConditionOperator = ConditionOperator.GT;
120 break;
121 case TmfXmlStrings.LE:
122 fConditionOperator = ConditionOperator.LE;
123 break;
124 case TmfXmlStrings.LT:
125 fConditionOperator = ConditionOperator.LT;
126 break;
127 case TmfXmlStrings.NULL:
128 fConditionOperator = ConditionOperator.EQ;
129 break;
130 default:
131 throw new IllegalArgumentException("TmfXmlCondition: invalid comparison operator."); //$NON-NLS-1$
132 }
0f7276b6
GB
133 /* The last element is a state value node */
134 Element stateValueElement = childElements.remove(childElements.size() - 1);
12685851
GB
135 if (stateValueElement == null) {
136 throw new IllegalStateException();
137 }
0f7276b6
GB
138
139 /*
140 * A state value is either preceded by an eventField or a number of
141 * state attributes
142 */
143 if (childElements.size() == 1 && childElements.get(0).getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) {
12685851
GB
144 String attribute = childElements.get(0).getAttribute(TmfXmlStrings.NAME);
145 if (attribute == null) {
146 throw new IllegalArgumentException();
147 }
148 fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attribute);
0f7276b6 149 } else {
1d7e62f9 150 List<ITmfXmlStateAttribute> attributes = new ArrayList<>();
0f7276b6
GB
151 for (Element element : childElements) {
152 if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
153 throw new IllegalArgumentException("TmfXmlCondition: a condition either has a eventField element or a number of TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
154 }
1d7e62f9 155 ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
0f7276b6
GB
156 attributes.add(attribute);
157 }
1d7e62f9 158 fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes);
0f7276b6
GB
159 }
160 break;
161 case TmfXmlStrings.NOT:
5ddeee68 162 fOperator = LogicalOperator.NOT;
0f7276b6 163 fStateValue = null;
5ddeee68 164 fConditionOperator = ConditionOperator.NONE;
12685851
GB
165 Element element = childElements.get(0);
166 if (element == null) {
167 throw new IllegalArgumentException();
168 }
169 fConditions.add(modelFactory.createCondition(element, fContainer));
0f7276b6
GB
170 break;
171 case TmfXmlStrings.AND:
5ddeee68 172 fOperator = LogicalOperator.AND;
0f7276b6 173 fStateValue = null;
5ddeee68 174 fConditionOperator = ConditionOperator.NONE;
0f7276b6 175 for (Element condition : childElements) {
12685851
GB
176 if (condition == null) {
177 continue;
178 }
1d7e62f9 179 fConditions.add(modelFactory.createCondition(condition, fContainer));
0f7276b6
GB
180 }
181 break;
182 case TmfXmlStrings.OR:
5ddeee68 183 fOperator = LogicalOperator.OR;
0f7276b6 184 fStateValue = null;
5ddeee68 185 fConditionOperator = ConditionOperator.NONE;
0f7276b6 186 for (Element condition : childElements) {
12685851
GB
187 if (condition == null) {
188 continue;
189 }
1d7e62f9 190 fConditions.add(modelFactory.createCondition(condition, fContainer));
0f7276b6
GB
191 }
192 break;
193 default:
194 throw new IllegalArgumentException("TmfXmlCondition constructor: XML node is of the wrong type"); //$NON-NLS-1$
195 }
196 }
197
198 /**
199 * Test the result of the condition for an event
200 *
201 * @param event
202 * The event on which to test the condition
203 * @return Whether the condition is true or not
204 * @throws AttributeNotFoundException
205 * The state attribute was not found
206 */
12685851 207 public boolean testForEvent(ITmfEvent event) throws AttributeNotFoundException {
1d7e62f9 208 ITmfStateSystem ss = fContainer.getStateSystem();
0f7276b6
GB
209 /*
210 * The condition is either the equality check of a state value or a
211 * boolean operation on other conditions
212 */
213 if (fStateValue != null) {
1d7e62f9
GB
214 ITmfXmlStateValue filter = fStateValue;
215 int quark = IXmlStateSystemContainer.ROOT_QUARK;
216 for (ITmfXmlStateAttribute attribute : filter.getAttributes()) {
0f7276b6
GB
217 quark = attribute.getAttributeQuark(event, quark);
218 /*
219 * When verifying a condition, the state attribute must exist,
220 * if it does not, the query is not valid, we stop the condition
221 * check
222 */
1d7e62f9 223 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
0f7276b6
GB
224 throw new AttributeNotFoundException();
225 }
226 }
227
228 /* Get the value to compare to from the XML file */
229 ITmfStateValue valueXML;
230 valueXML = filter.getValue(event);
231
232 /*
233 * The actual value: it can be either queried in the state system or
234 * found in the event
235 */
1d7e62f9
GB
236 ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) :
237 filter.getEventFieldValue(event);
12685851
GB
238 if (valueState == null) {
239 throw new IllegalStateException();
240 }
0f7276b6 241
5ddeee68 242 return compare(valueState, valueXML, fConditionOperator);
0f7276b6
GB
243
244 } else if (!fConditions.isEmpty()) {
245 /* Verify a condition tree */
246 switch (fOperator) {
247 case AND:
248 for (TmfXmlCondition childCondition : fConditions) {
249 if (!childCondition.testForEvent(event)) {
250 return false;
251 }
252 }
253 return true;
254 case NONE:
255 break;
256 case NOT:
257 return !fConditions.get(0).testForEvent(event);
258 case OR:
259 for (TmfXmlCondition childCondition : fConditions) {
260 if (childCondition.testForEvent(event)) {
261 return true;
262 }
263 }
264 return false;
265 default:
266 break;
267
268 }
269 } else {
270 throw new IllegalStateException("TmfXmlCondition: the condition should be either a state value or be the result of a condition tree"); //$NON-NLS-1$
271 }
272 return true;
273 }
274
446598f9
GB
275 @Override
276 public String toString() {
277 return "TmfXmlCondition: " + fOperator + " on " + fConditions; //$NON-NLS-1$ //$NON-NLS-2$
278 }
279
5ddeee68
NE
280 /**
281 * Compare two ITmfStateValues based on the given comparison operator
282 *
283 * @param source
284 * the state value to compare to
285 * @param dest
286 * the state value to be compared with
287 * @param comparisonOperator
288 * the operator to compare the inputs
289 * @return the boolean result of the comparison
290 */
291 public boolean compare(ITmfStateValue source, ITmfStateValue dest, ConditionOperator comparisonOperator) {
5ddeee68
NE
292 switch (comparisonOperator) {
293 case EQ:
294 return (source.compareTo(dest) == 0);
295 case NE:
296 return (source.compareTo(dest) != 0);
297 case GE:
298 return (source.compareTo(dest) >= 0);
299 case GT:
300 return (source.compareTo(dest) > 0);
301 case LE:
302 return (source.compareTo(dest) <= 0);
303 case LT:
304 return (source.compareTo(dest) < 0);
305 case NONE:
306 default:
307 throw new IllegalArgumentException("TmfXmlCondition: invalid comparison operator."); //$NON-NLS-1$
308 }
309
310 }
311
0f7276b6 312}
This page took 0.06712 seconds and 5 git commands to generate.