/*******************************************************************************
- * Copyright (c) 2014, 2015 Ecole Polytechnique de Montreal
+ * Copyright (c) 2014, 2015 Ecole Polytechnique de Montreal and others
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* Florian Wininger - Initial API and implementation
* Naser Ezzati - Add the comparison operators
* Patrick Tasse - Add message to exceptions
+ * Jean-Christian Kouame - Add comparison between two state values
******************************************************************************/
package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
import java.util.List;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
* <stateValue type="null" />
* </condition>
* <condition>
+ * <stateValue type="long" value="2" />
+ * <stateValue type="long" value="5" />
* </condition>
* </and>
* </pre>
public class TmfXmlCondition {
private final List<TmfXmlCondition> fConditions = new ArrayList<>();
- private final @Nullable ITmfXmlStateValue fStateValue;
+ private final List<ITmfXmlStateValue> fStateValues;
private final LogicalOperator fOperator;
private final IXmlStateSystemContainer fContainer;
private final ConditionOperator fConditionOperator;
Element rootNode = node;
/* Process the conditions: in each case, only process Element nodes */
List<@Nullable Element> childElements = XmlUtils.getChildElements(rootNode);
+ final Element firstElement = NonNullUtils.checkNotNull(childElements.get(0));
/*
* If the node is an if, take the child as the root condition
*/
if (node.getNodeName().equals(TmfXmlStrings.IF)) {
if (childElements.isEmpty()) {
- throw new IllegalArgumentException("TmfXmlCondition constructor: IF node has no child element"); //$NON-NLS-1$
+ throw new IllegalArgumentException("TmfXmlCondition constructor: IF node with no child element"); //$NON-NLS-1$
}
- rootNode = childElements.get(0);
+ rootNode = firstElement;
childElements = XmlUtils.getChildElements(rootNode);
}
-
- if (rootNode == null) {
- throw new IllegalArgumentException();
+ int size = rootNode.getElementsByTagName(TmfXmlStrings.STATE_VALUE).getLength();
+ fStateValues = new ArrayList<>(size);
+ if (size > 2 || size == 0) {
+ throw new IllegalArgumentException("TmfXmlCondition: a condition should have 1 or 2 state values at most"); //$NON-NLS-1$
}
switch (rootNode.getNodeName()) {
case TmfXmlStrings.CONDITION:
fOperator = LogicalOperator.NONE;
- /* Read comparison type */
- String equationType = rootNode.getAttribute(TmfXmlStrings.OPERATOR);
-
- switch (equationType) {
- case TmfXmlStrings.EQ:
- fConditionOperator = ConditionOperator.EQ;
- break;
- case TmfXmlStrings.NE:
- fConditionOperator = ConditionOperator.NE;
- break;
- case TmfXmlStrings.GE:
- fConditionOperator = ConditionOperator.GE;
- break;
- case TmfXmlStrings.GT:
- fConditionOperator = ConditionOperator.GT;
- break;
- case TmfXmlStrings.LE:
- fConditionOperator = ConditionOperator.LE;
- break;
- case TmfXmlStrings.LT:
- fConditionOperator = ConditionOperator.LT;
- break;
- case TmfXmlStrings.NULL:
- fConditionOperator = ConditionOperator.EQ;
- break;
- default:
- throw new IllegalArgumentException("TmfXmlCondition: invalid comparison operator."); //$NON-NLS-1$
- }
- /* The last element is a state value node */
- Element stateValueElement = childElements.remove(childElements.size() - 1);
- if (stateValueElement == null) {
- throw new IllegalStateException();
- }
-
- /*
- * A state value is either preceded by an eventField or a number of
- * state attributes
- */
- @Nullable Element firstChild = childElements.get(0);
- if (firstChild == null) {
- throw new IllegalStateException();
- }
-
- if (childElements.size() == 1 && firstChild.getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) {
- String attribute = firstChild.getAttribute(TmfXmlStrings.NAME);
- fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attribute);
+ if (size == 1) {
+ fConditionOperator = getConditionOperator(rootNode);
+ getStateValuesForXmlCondition(modelFactory, NonNullUtils.checkNotNull(childElements));
} else {
- List<ITmfXmlStateAttribute> attributes = new ArrayList<>();
- for (Element element : childElements) {
- if (element == null || !element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
- throw new IllegalArgumentException("TmfXmlCondition: a condition either has a eventField element or a number of TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
- }
- ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
- attributes.add(attribute);
- }
- fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes);
+ fConditionOperator = ConditionOperator.EQ;
+ fStateValues.add(modelFactory.createStateValue(NonNullUtils.checkNotNull(childElements.get(0)), fContainer, new ArrayList<ITmfXmlStateAttribute>()));
+ fStateValues.add(modelFactory.createStateValue(NonNullUtils.checkNotNull(childElements.get(1)), fContainer, new ArrayList<ITmfXmlStateAttribute>()));
}
break;
case TmfXmlStrings.NOT:
fOperator = LogicalOperator.NOT;
- fStateValue = null;
fConditionOperator = ConditionOperator.NONE;
- Element element = childElements.get(0);
- if (element == null) {
- throw new IllegalArgumentException();
- }
+ Element element = firstElement;
fConditions.add(modelFactory.createCondition(element, fContainer));
break;
case TmfXmlStrings.AND:
fOperator = LogicalOperator.AND;
- fStateValue = null;
fConditionOperator = ConditionOperator.NONE;
for (Element condition : childElements) {
if (condition == null) {
break;
case TmfXmlStrings.OR:
fOperator = LogicalOperator.OR;
- fStateValue = null;
fConditionOperator = ConditionOperator.NONE;
for (Element condition : childElements) {
if (condition == null) {
}
}
+ private void getStateValuesForXmlCondition(ITmfXmlModelFactory modelFactory, List<@Nullable Element> childElements) {
+ Element stateValueElement = NonNullUtils.checkNotNull(childElements.remove(childElements.size() - 1));
+ /*
+ * A state value is either preceded by an eventField or a number of
+ * state attributes
+ */
+ final Element firstElement = NonNullUtils.checkNotNull(childElements.get(0));
+ if (childElements.size() == 1 && firstElement.getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) {
+ String attribute = firstElement.getAttribute(TmfXmlStrings.NAME);
+ fStateValues.add(modelFactory.createStateValue(stateValueElement, fContainer, attribute));
+ } else {
+ List<ITmfXmlStateAttribute> attributes = new ArrayList<>();
+ for (Element element : childElements) {
+ if (element == null) {
+ throw new NullPointerException("There should be at list one element"); //$NON-NLS-1$
+ }
+ if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
+ throw new IllegalArgumentException("TmfXmlCondition: a condition either has a eventField element or a number of TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
+ }
+ ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
+ attributes.add(attribute);
+ }
+ fStateValues.add(modelFactory.createStateValue(stateValueElement, fContainer, attributes));
+ }
+ }
+
+ private static ConditionOperator getConditionOperator(Element rootNode) {
+ String equationType = rootNode.getAttribute(TmfXmlStrings.OPERATOR);
+ switch (equationType) {
+ case TmfXmlStrings.EQ:
+ return ConditionOperator.EQ;
+ case TmfXmlStrings.NE:
+ return ConditionOperator.NE;
+ case TmfXmlStrings.GE:
+ return ConditionOperator.GE;
+ case TmfXmlStrings.GT:
+ return ConditionOperator.GT;
+ case TmfXmlStrings.LE:
+ return ConditionOperator.LE;
+ case TmfXmlStrings.LT:
+ return ConditionOperator.LT;
+ case TmfXmlStrings.NULL:
+ return ConditionOperator.EQ;
+ default:
+ throw new IllegalArgumentException("TmfXmlCondition: invalid comparison operator."); //$NON-NLS-1$
+ }
+ }
+
/**
* Test the result of the condition for an event
*
* @return Whether the condition is true or not
* @throws AttributeNotFoundException
* The state attribute was not found
+ * @since 1.0
*/
public boolean testForEvent(ITmfEvent event) throws AttributeNotFoundException {
ITmfStateSystem ss = fContainer.getStateSystem();
- /*
- * The condition is either the equality check of a state value or a
- * boolean operation on other conditions
- */
- if (fStateValue != null) {
- ITmfXmlStateValue filter = fStateValue;
- int quark = IXmlStateSystemContainer.ROOT_QUARK;
- for (ITmfXmlStateAttribute attribute : filter.getAttributes()) {
- quark = attribute.getAttributeQuark(event, quark);
- /*
- * When verifying a condition, the state attribute must exist,
- * if it does not, the query is not valid, we stop the condition
- * check
- */
- if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
- throw new AttributeNotFoundException(ss.getSSID() + " Attribute:" + attribute); //$NON-NLS-1$
- }
- }
-
- /* Get the value to compare to from the XML file */
- ITmfStateValue valueXML;
- valueXML = filter.getValue(event);
-
- /*
- * The actual value: it can be either queried in the state system or
- * found in the event
- */
- ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) :
- filter.getEventFieldValue(event);
- if (valueState == null) {
- throw new IllegalStateException();
- }
-
- return compare(valueState, valueXML, fConditionOperator);
-
+ if (!fStateValues.isEmpty()) {
+ return testForEvent(event, NonNullUtils.checkNotNull(ss));
} else if (!fConditions.isEmpty()) {
/* Verify a condition tree */
switch (fOperator) {
break;
}
- } else {
- throw new IllegalStateException("TmfXmlCondition: the condition should be either a state value or be the result of a condition tree"); //$NON-NLS-1$
}
return true;
}
+ private boolean testForEvent(ITmfEvent event, ITmfStateSystem ss) throws AttributeNotFoundException {
+ /*
+ * The condition is either the equality check of a state value or a
+ * boolean operation on other conditions
+ */
+ if (fStateValues.size() == 1) {
+ ITmfXmlStateValue filter = fStateValues.get(0);
+ int quark = IXmlStateSystemContainer.ROOT_QUARK;
+ for (ITmfXmlStateAttribute attribute : filter.getAttributes()) {
+ quark = attribute.getAttributeQuark(event, quark);
+ /*
+ * When verifying a condition, the state attribute must exist,
+ * if it does not, the query is not valid, we stop the condition
+ * check
+ */
+ if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
+ throw new AttributeNotFoundException(ss.getSSID() + " Attribute:" + attribute); //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * The actual value: it can be either queried in the state system or
+ * found in the event
+ */
+ ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) : filter.getEventFieldValue(event);
+ if (valueState == null) {
+ throw new IllegalStateException("TmfXmlCondition : The state value does not exist in the state system"); //$NON-NLS-1$
+ }
+
+ /* Get the value to compare to from the XML file */
+ ITmfStateValue valueXML;
+ valueXML = filter.getValue(event);
+ return compare(valueState, valueXML, fConditionOperator);
+ }
+ /* Get the two values needed for the comparison */
+ ITmfStateValue valuesXML1 = fStateValues.get(0).getValue(event);
+ ITmfStateValue valuesXML2 = fStateValues.get(1).getValue(event);
+ return valuesXML1.equals(valuesXML2);
+ }
+
@Override
public String toString() {
return "TmfXmlCondition: " + fOperator + " on " + fConditions; //$NON-NLS-1$ //$NON-NLS-2$
*/
public boolean compare(ITmfStateValue source, ITmfStateValue dest, ConditionOperator comparisonOperator) {
switch (comparisonOperator) {
+ //TODO The comparison operator should have a compareHelper that calls compare
case EQ:
return (source.compareTo(dest) == 0);
case NE:
default:
throw new IllegalArgumentException("TmfXmlCondition: invalid comparison operator."); //$NON-NLS-1$
}
-
}
-
}
\ No newline at end of file