From 1d7e62f95625b7f4c4f760acd1f3615b214ccefb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Genevi=C3=A8ve=20Bastien?= Date: Mon, 10 Mar 2014 15:10:17 -0400 Subject: [PATCH] TMF: Refactor XML model code, using factories to re-use element parsers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The same XML syntax (and thus parsing) can be used for many XML components' element, like state providers and views, but the behavior of each component may be different. We use a factory to define create the classes with the various behaviors. Change-Id: Iec5d54155b93a79b1ebc5ffeb8eaffef5e6569ca Signed-off-by: Geneviève Bastien Reviewed-on: https://git.eclipse.org/r/23157 Tested-by: Hudson CI Reviewed-by: Alexandre Montplaisir IP-Clean: Alexandre Montplaisir --- .../META-INF/MANIFEST.MF | 3 +- .../stateprovider/model/TmfXmlStateValue.java | 607 ------------------ .../xml/core/model/ITmfXmlModelFactory.java | 112 ++++ .../xml/core/model/ITmfXmlStateAttribute.java | 56 ++ .../xml/core/model/ITmfXmlStateValue.java | 78 +++ .../xml/core}/model/TmfXmlCondition.java | 50 +- .../xml/core}/model/TmfXmlEventHandler.java | 16 +- .../xml/core}/model/TmfXmlLocation.java | 52 +- .../xml/core}/model/TmfXmlStateAttribute.java | 175 +++-- .../xml/core}/model/TmfXmlStateChange.java | 44 +- .../xml/core/model/TmfXmlStateValue.java | 486 ++++++++++++++ .../TmfXmlModelFactoryReadWrite.java | 87 +++ .../TmfXmlStateAttributeReadWrite.java | 61 ++ .../readwrite/TmfXmlStateValueReadWrite.java | 375 +++++++++++ .../core/module/ITmfXmlTopLevelElement.java | 1 - .../core/module/IXmlStateSystemContainer.java | 5 +- .../xml/core/stateprovider/TmfXmlStrings.java | 1 + .../core/stateprovider/XmlStateProvider.java | 116 +--- 18 files changed, 1504 insertions(+), 821 deletions(-) delete mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateValue.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java rename org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/{internal/tmf/analysis/xml/core/stateprovider => tmf/analysis/xml/core}/model/TmfXmlCondition.java (77%) rename org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/{internal/tmf/analysis/xml/core/stateprovider => tmf/analysis/xml/core}/model/TmfXmlEventHandler.java (85%) rename org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/{internal/tmf/analysis/xml/core/stateprovider => tmf/analysis/xml/core}/model/TmfXmlLocation.java (56%) rename org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/{internal/tmf/analysis/xml/core/stateprovider => tmf/analysis/xml/core}/model/TmfXmlStateAttribute.java (50%) rename org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/{internal/tmf/analysis/xml/core/stateprovider => tmf/analysis/xml/core}/model/TmfXmlStateChange.java (77%) create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlModelFactoryReadWrite.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateAttributeReadWrite.java create mode 100644 org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateValueReadWrite.java diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.tmf.analysis.xml.core/META-INF/MANIFEST.MF index f276d53f53..6b572c9866 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/META-INF/MANIFEST.MF +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/META-INF/MANIFEST.MF @@ -11,7 +11,8 @@ Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.core.runtime, org.eclipse.linuxtools.tmf.core Export-Package: org.eclipse.linuxtools.internal.tmf.analysis.xml.core;x-friends:="org.eclipse.linuxtools.tmf.analysis.xml.core.tests", - org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;x-friends:="org.eclipse.linuxtools.tmf.analysis.xml.core.tests", + org.eclipse.linuxtools.tmf.analysis.xml.core.model, + org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite, org.eclipse.linuxtools.tmf.analysis.xml.core.module, org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateValue.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateValue.java deleted file mode 100644 index e4428df563..0000000000 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateValue.java +++ /dev/null @@ -1,607 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Ecole Polytechnique de Montreal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License v1.0 which - * accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Florian Wininger - Initial API and implementation - ******************************************************************************/ - -package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; -import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; -import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue; -import org.w3c.dom.Element; - -/** - * This Class implements a State Value in the XML state provider, along with the - * path to get to the value (either a list of state attributes or an event - * field) - * - *
- * Example:
- *   
- *   
- *   
- * 
- * - * @author Florian Wininger - */ -public class TmfXmlStateValue { - - private final TmfXmlStateValueType fStateValue; - - /* Path in the State System */ - private final List fPath; - /* Event field to match with this state value */ - private final String fEventField; - - /* Whether this state value is an increment of the previous value */ - private final boolean fIncrement; - /* Stack value */ - private final ValueTypeStack fStack; - /* Forced value type */ - private final ValueForcedType fForcedType; - - private final XmlStateProvider fProvider; - - private enum ValueTypeStack { - NULL, - PEEK, - POP, - PUSH, - } - - private enum ValueForcedType { - NULL, - STRING, - INT, - LONG - } - - /** - * Constructor where the path to the value is a list of state attributes - * - * @param node - * The state value XML element - * @param provider - * The state provider this state value belongs to - * @param attributes - * The attributes representing the path to this value - */ - public TmfXmlStateValue(Element node, XmlStateProvider provider, List attributes) { - this(node, provider, attributes, null); - if (attributes.isEmpty()) { - throw new IllegalArgumentException("TmfXmlStateValue constructor: the list of attributes should not be empty"); //$NON-NLS-1$ - } - } - - /** - * Constructor where the path to the value is an event field - * - * @param node - * The state value XML element - * @param provider - * The state provider this state value belongs to - * @param eventField - * The event field where to get the value - */ - public TmfXmlStateValue(Element node, XmlStateProvider provider, String eventField) { - this(node, provider, new ArrayList(), eventField); - } - - private TmfXmlStateValue(Element node, XmlStateProvider provider, List attributes, String eventField) { - fPath = attributes; - fProvider = provider; - fEventField = eventField; - if (!node.getNodeName().equals(TmfXmlStrings.STATE_VALUE)) { - throw new IllegalArgumentException("TmfXmlStateValue constructor: Element is not a stateValue"); //$NON-NLS-1$ - } - - /* Process the XML Element state value */ - String type = node.getAttribute(TmfXmlStrings.TYPE); - String value = fProvider.getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE)); - /* Check if there is an increment for the value */ - fIncrement = Boolean.valueOf(node.getAttribute(TmfXmlStrings.INCREMENT)); - - switch (type) { - case TmfXmlStrings.TYPE_INT: { - /* Integer value */ - ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value)); - fStateValue = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_LONG: { - /* Long value */ - ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value)); - fStateValue = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_STRING: { - /* String value */ - ITmfStateValue stateValue = TmfStateValue.newValueString(value); - fStateValue = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.TYPE_NULL: { - /* Null value */ - ITmfStateValue stateValue = TmfStateValue.nullValue(); - fStateValue = new TmfXmlStateValueTmf(stateValue); - break; - } - case TmfXmlStrings.EVENT_FIELD: - /* Event field */ - fStateValue = new TmfXmlStateValueEventField(value); - break; - case TmfXmlStrings.TYPE_EVENT_NAME: - /* The value is the event name */ - fStateValue = new TmfXmlStateValueEventName(); - break; - case TmfXmlStrings.TYPE_DELETE: - /* Deletes the value of an attribute */ - fStateValue = new TmfXmlStateValueDelete(); - break; - case TmfXmlStrings.TYPE_QUERY: - /* Value is the result of a query */ - List children = XmlUtils.getChildElements(node); - List childAttributes = new ArrayList<>(); - for (Element child : children) { - TmfXmlStateAttribute queryAttribute = new TmfXmlStateAttribute(child, fProvider); - childAttributes.add(queryAttribute); - } - fStateValue = new TmfXmlStateValueQuery(childAttributes); - break; - default: - throw new IllegalArgumentException(String.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type)); //$NON-NLS-1$ - } - - /* - * Forced type allows to convert the value to a certain type : For - * example, a process's TID in an event field may arrive with a LONG - * format but we want to store the data in an INT - */ - switch (node.getAttribute(TmfXmlStrings.FORCED_TYPE)) { - case TmfXmlStrings.TYPE_STRING: - fForcedType = ValueForcedType.STRING; - break; - case TmfXmlStrings.TYPE_INT: - fForcedType = ValueForcedType.INT; - break; - case TmfXmlStrings.TYPE_LONG: - fForcedType = ValueForcedType.LONG; - break; - default: - fForcedType = ValueForcedType.NULL; - } - - /* - * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods - */ - String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK); - switch (stack) { - case TmfXmlStrings.STACK_PUSH: - fStack = ValueTypeStack.PUSH; - break; - case TmfXmlStrings.STACK_POP: - fStack = ValueTypeStack.POP; - break; - case TmfXmlStrings.STACK_PEEK: - fStack = ValueTypeStack.PEEK; - break; - default: - fStack = ValueTypeStack.NULL; - } - } - - /** - * Get the current {@link ITmfStateValue} of this state value for an event. - * It does not increment the value and does not any other processing of the - * value. - * - * @param event - * The current event. - * @return the {@link ITmfStateValue} - * @throws AttributeNotFoundException - * May be thrown by the state system during the query - */ - public ITmfStateValue getValue(ITmfEvent event) - throws AttributeNotFoundException { - return fStateValue.getValue(event); - - } - - /** - * Get the value of the event field that is the path of this state value - * - * @param event - * The current event - * @return the value of the event field - */ - public ITmfStateValue getEventField(@NonNull ITmfEvent event) { - return getEventField(event, fEventField); - } - - /** - * Get the value of an event field - * - * @param event - * The current event - * @param fieldName - * The name of the field of which to get the value - * @return The value of the event field - */ - private ITmfStateValue getEventField(ITmfEvent event, String fieldName) { - - ITmfStateValue value = TmfStateValue.nullValue(); - - final ITmfEventField content = event.getContent(); - - /* Exception for "CPU", returns the source of this event */ - /* FIXME : Nameclash if a eventfield have "cpu" for name. */ - if (fieldName.equals(TmfXmlStrings.CPU)) { - value = TmfStateValue.newValueInt(Integer.valueOf(event.getSource())); - } else { - - if (content.getField(fieldName) == null) { - return value; - } - - Object field = content.getField(fieldName).getValue(); - - /* - * Try to find the right type. The type can be forced by - * "forcedType" argument. - */ - if (field instanceof String) { - String fieldString = (String) field; - - switch (fForcedType) { - case INT: - value = TmfStateValue.newValueInt(Integer.parseInt(fieldString)); - break; - case LONG: - value = TmfStateValue.newValueLong(Long.parseLong(fieldString)); - break; - case NULL: - case STRING: - default: - value = TmfStateValue.newValueString(fieldString); - break; - } - } else if (field instanceof Long) { - Long fieldLong = (Long) field; - - switch (fForcedType) { - case INT: - value = TmfStateValue.newValueInt(fieldLong.intValue()); - break; - case STRING: - value = TmfStateValue.newValueString(fieldLong.toString()); - break; - case LONG: - case NULL: - default: - value = TmfStateValue.newValueLong(fieldLong); - break; - } - } else if (field instanceof Integer) { - Integer fieldInterger = (Integer) field; - - switch (fForcedType) { - case LONG: - value = TmfStateValue.newValueLong(fieldInterger.longValue()); - break; - case STRING: - value = TmfStateValue.newValueString(fieldInterger.toString()); - break; - case INT: - case NULL: - default: - break; - - } - } - } - return value; - } - - /** - * Get the list of state attributes, the path to the state value - * - * @return the list of Attribute to have the path in the State System - */ - public List getAttributes() { - return fPath; - } - - /** - * Handles an event, by setting the value of the attribute described by the - * state attribute path in the state system. - * - * @param event - * The event to process - * @throws AttributeNotFoundException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws StateValueTypeException - * Pass through the exception it received - */ - public void handleEvent(ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { - int quark = XmlStateProvider.ROOT_QUARK; - - for (TmfXmlStateAttribute attribute : fPath) { - quark = attribute.getAttributeQuark(event, quark); - /* the query is not valid, we stop the state change */ - if (quark == XmlStateProvider.ERROR_QUARK) { - throw new AttributeNotFoundException(); - } - } - - long ts = event.getTimestamp().getValue(); - fStateValue.handleEvent(event, quark, ts); - } - - /* - * Base class for all state value. Contain default methods to handle event, - * process or increment the value - */ - private abstract class TmfXmlStateValueType { - - public abstract ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException; - - /** - * Execute the state change - * - * @param event - * The event being handled - * @param quark - * The quark for this value - * @param timestamp - * The timestamp of the event - * @throws StateValueTypeException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - public final void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - if (fIncrement) { - incrementValue(event, quark, timestamp); - } else { - ITmfStateValue value = getValue(event); - processValue(quark, timestamp, value); - } - } - - protected void processValue(int quark, long timestamp, ITmfStateValue value) throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { - ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem(); - switch (fStack) { - case POP: - ss.popAttribute(timestamp, quark); - break; - case PUSH: - ss.pushAttribute(timestamp, value, quark); - break; - case NULL: - case PEEK: - default: - ss.modifyAttribute(timestamp, value, quark); - break; - } - } - - /** - * Increments the value of the parameter - * - * @param event - * The event being handled - * @param quark - * The quark for this value - * @param timestamp - * The timestamp of the event - * @throws StateValueTypeException - * Pass through the exception it received - * @throws TimeRangeException - * Pass through the exception it received - * @throws AttributeNotFoundException - * Pass through the exception it received - */ - protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem(); - ss.incrementAttribute(timestamp, quark); - } - } - - /* This state value uses a constant value, defined in the XML */ - private class TmfXmlStateValueTmf extends TmfXmlStateValueType { - - private final ITmfStateValue fValue; - - public TmfXmlStateValueTmf(ITmfStateValue value) { - fValue = value; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - return fValue; - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem(); - switch (fValue.getType()) { - case LONG: { - long incrementLong = fValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - return; - } - case INTEGER: { - int increment = fValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$ - break; - } - } - } - - /* The state value uses the value of an event field */ - private class TmfXmlStateValueEventField extends TmfXmlStateValueType { - - private final String fFieldName; - - public TmfXmlStateValueEventField(String field) { - fFieldName = field; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - return getEventField(event, fFieldName); - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem(); - ITmfStateValue incrementValue = getValue(event); - switch (incrementValue.getType()) { - case INTEGER: { - int increment = incrementValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case LONG: { - long incrementLong = incrementValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning(String.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName, incrementValue.getType())); //$NON-NLS-1$ - break; - } - } - } - - /* The state value is the event name */ - private class TmfXmlStateValueEventName extends TmfXmlStateValueType { - - @Override - public ITmfStateValue getValue(ITmfEvent event) { - return TmfStateValue.newValueString(event.getType().getName()); - } - - } - - /* The state value deletes an attribute */ - private class TmfXmlStateValueDelete extends TmfXmlStateValueType { - - @Override - public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { - return TmfStateValue.nullValue(); - } - - @Override - protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, AttributeNotFoundException { - ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem(); - ss.removeAttribute(timestamp, quark); - } - - } - - /* The state value uses the result of a query */ - private class TmfXmlStateValueQuery extends TmfXmlStateValueType { - - private final List fQueryValue; - - public TmfXmlStateValueQuery(List attributes) { - fQueryValue = attributes; - } - - @Override - public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { - /* Query the state system for the value */ - ITmfStateValue value = TmfStateValue.nullValue(); - int quarkQuery = XmlStateProvider.ROOT_QUARK; - ITmfStateSystem ss = fProvider.getAssignedStateSystem(); - - for (TmfXmlStateAttribute attribute : fQueryValue) { - quarkQuery = attribute.getAttributeQuark(event, quarkQuery); - if (quarkQuery == XmlStateProvider.ERROR_QUARK) { - /* the query is not valid, we stop the state change */ - break; - } - } - /* - * the query can fail : for example, if a value is requested but has - * not been set yet - */ - if (quarkQuery != XmlStateProvider.ERROR_QUARK) { - value = ss.queryOngoingState(quarkQuery); - } - return value; - } - - @Override - public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { - ITmfStateSystem ss = fProvider.getAssignedStateSystem(); - ITmfStateValue incrementValue = getValue(event); - switch (incrementValue.getType()) { - case INTEGER: { - int increment = incrementValue.unboxInt(); - int currentValue = ss.queryOngoingState(quark).unboxInt(); - ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); - processValue(quark, timestamp, value); - break; - } - case LONG: { - long incrementLong = incrementValue.unboxLong(); - long currentValue = ss.queryOngoingState(quark).unboxLong(); - ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); - processValue(quark, timestamp, value); - break; - } - case DOUBLE: - case NULL: - case STRING: - default: - Activator.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$ - break; - } - } - } -} \ No newline at end of file diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java new file mode 100644 index 0000000000..bf7bdde065 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model; + +import java.util.List; + +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Interface to create XML model elements in different contexts. This allows to + * reuse the same XML syntax and parsers, but use the elements differently + * depending on the what is intended to be done with them. + * + * @author Geneviève Bastien + */ +public interface ITmfXmlModelFactory { + + /** + * Create a new XML state attribute + * + * @param attribute + * XML element of the attribute + * @param container + * The state system container this state attribute belongs to + * @return The new state attribute + */ + ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container); + + /** + * Create a new state value where the value corresponds to a path of + * {@link ITmfXmlStateAttribute} + * + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param attributes + * The attributes representing the path to this value + * @return The new state value + */ + ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes); + + /** + * Create a new state value where the value corresponds to a field in an + * event + * + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + * @return The new state value + */ + ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField); + + /** + * Create a new XML condition + * + * @param node + * The XML root of this condition + * @param container + * The state system container this condition belongs to + * @return The new XML condition + */ + TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML event handler + * + * @param node + * The XML event handler element + * @param container + * The state system container this state value belongs to + * @return The new XML event handler + */ + TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML state change + * + * @param node + * The XML state change element + * @param container + * The state system container this state change belongs to + * @return The new XML state change + */ + TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container); + + /** + * Create a new XML location + * + * @param node + * The XML location element + * @param container + * The state system container this location belongs to + * @return The new XML location + */ + TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container); + +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java new file mode 100644 index 0000000000..efb362b793 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateAttribute.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model; + +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; + +/** + * Interface that describe a state attribute defined in an XML element + * + * @author Geneviève Bastien + */ +public interface ITmfXmlStateAttribute { + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search + * the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found + */ + int getAttributeQuark(int startQuark); + + /** + * This method gets the quark for this state attribute in the State System. + * + * Unless this attribute is a location, in which case the quark must exist, + * the quark will be added to the state system if the state system is in + * builder mode. + * + * @param event + * The current event being handled + * @param startQuark + * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to search + * the full attribute tree + * @return the quark described by attribute or + * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be found + */ + int getAttributeQuark(ITmfEvent event, int startQuark); +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java new file mode 100644 index 0000000000..6163db058b --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/ITmfXmlStateValue.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; +import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; + +/** + * Interface that describe operations on a state value described in an XML + * element + * + * @author Geneviève Bastien + */ +public interface ITmfXmlStateValue { + + /** + * Get the current {@link ITmfStateValue} of this state value for an event. + * It does not increment the value and does not any other processing of the + * value. + * + * @param event + * The current event or null if no event is + * available. + * @return the {@link ITmfStateValue} + * @throws AttributeNotFoundException + * May be thrown by the state system during the query + */ + ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; + + /** + * Get the value of the event field that is the path of this state value + * + * @param event + * The current event + * @return the value of the event field + */ + ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event); + + /** + * Get the list of state attributes, the path to the state value + * + * @return the list of Attribute to have the path in the State System + */ + List getAttributes(); + + /** + * Handles an event, by setting the value of the attribute described by the + * state attribute path in the state system. + * + * @param event + * The event to process + * @throws AttributeNotFoundException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + */ + void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException; + +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlCondition.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java similarity index 77% rename from org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlCondition.java rename to org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java index ee0f3a2eb2..9e28f7c4ad 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlCondition.java +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlCondition.java @@ -10,23 +10,23 @@ * Florian Wininger - Initial API and implementation ******************************************************************************/ -package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model; +package org.eclipse.linuxtools.tmf.analysis.xml.core.model; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; -import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider; import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; import org.w3c.dom.Element; /** - * This Class implement a condition tree for a state change + * This Class implement a condition tree in the XML-defined state system. * *
  * example:
@@ -46,9 +46,9 @@ import org.w3c.dom.Element;
 public class TmfXmlCondition {
 
     private final List fConditions = new ArrayList<>();
-    private final TmfXmlStateValue fStateValue;
+    private final ITmfXmlStateValue fStateValue;
     private final ConditionOperator fOperator;
-    private final XmlStateProvider fProvider;
+    private final IXmlStateSystemContainer fContainer;
 
     private enum ConditionOperator {
         NONE,
@@ -60,13 +60,15 @@ public class TmfXmlCondition {
     /**
      * Constructor
      *
+     * @param modelFactory
+     *            The factory used to create XML model elements
      * @param node
      *            The XML root of this condition
-     * @param provider
-     *            The state provider this condition belongs to
+     * @param container
+     *            The state system container this condition belongs to
      */
-    public TmfXmlCondition(Element node, XmlStateProvider provider) {
-        fProvider = provider;
+    public TmfXmlCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
+        fContainer = container;
 
         Element rootNode = node;
         /* Process the conditions: in each case, only process Element nodes */
@@ -96,36 +98,36 @@ public class TmfXmlCondition {
              * state attributes
              */
             if (childElements.size() == 1 && childElements.get(0).getNodeName().equals(TmfXmlStrings.ELEMENT_FIELD)) {
-                fStateValue = new TmfXmlStateValue(stateValueElement, fProvider, childElements.get(0).getAttribute(TmfXmlStrings.NAME));
+                fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, childElements.get(0).getAttribute(TmfXmlStrings.NAME));
             } else {
-                List attributes = new ArrayList<>();
+                List attributes = new ArrayList<>();
                 for (Element element : childElements) {
                     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$
                     }
-                    TmfXmlStateAttribute attribute = new TmfXmlStateAttribute(element, fProvider);
+                    ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
                     attributes.add(attribute);
                 }
-                fStateValue = new TmfXmlStateValue(stateValueElement, fProvider, attributes);
+                fStateValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes);
             }
             break;
         case TmfXmlStrings.NOT:
             fOperator = ConditionOperator.NOT;
             fStateValue = null;
-            fConditions.add(new TmfXmlCondition(childElements.get(0), fProvider));
+            fConditions.add(modelFactory.createCondition(childElements.get(0), fContainer));
             break;
         case TmfXmlStrings.AND:
             fOperator = ConditionOperator.AND;
             fStateValue = null;
             for (Element condition : childElements) {
-                fConditions.add(new TmfXmlCondition(condition, fProvider));
+                fConditions.add(modelFactory.createCondition(condition, fContainer));
             }
             break;
         case TmfXmlStrings.OR:
             fOperator = ConditionOperator.OR;
             fStateValue = null;
             for (Element condition : childElements) {
-                fConditions.add(new TmfXmlCondition(condition, fProvider));
+                fConditions.add(modelFactory.createCondition(condition, fContainer));
             }
             break;
         default:
@@ -143,22 +145,22 @@ public class TmfXmlCondition {
      *             The state attribute was not found
      */
     public boolean testForEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException {
-        ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem();
+        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) {
-            TmfXmlStateValue filter = fStateValue;
-            int quark = XmlStateProvider.ROOT_QUARK;
-            for (TmfXmlStateAttribute attribute : filter.getAttributes()) {
+            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 == XmlStateProvider.ERROR_QUARK) {
+                if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
                     throw new AttributeNotFoundException();
                 }
             }
@@ -171,8 +173,8 @@ public class TmfXmlCondition {
              * The actual value: it can be either queried in the state system or
              * found in the event
              */
-            ITmfStateValue valueState = (quark != XmlStateProvider.ROOT_QUARK) ? ss.queryOngoingState(quark) :
-                    filter.getEventField(event);
+            ITmfStateValue valueState = (quark != IXmlStateSystemContainer.ROOT_QUARK) ? ss.queryOngoingState(quark) :
+                    filter.getEventFieldValue(event);
 
             return valueXML.equals(valueState);
 
diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlEventHandler.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java
similarity index 85%
rename from org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlEventHandler.java
rename to org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java
index fcc21e6373..f02a48c86e 100644
--- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlEventHandler.java
+++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlEventHandler.java
@@ -10,15 +10,15 @@
  *   Florian Wininger - Initial API and implementation
  ******************************************************************************/
 
-package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
+package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
@@ -27,7 +27,7 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
 /**
- * This Class implements an EventHandler in the XML state provider
+ * This Class implements an EventHandler in the XML-defined state system
  *
  * 
  * example:
@@ -48,24 +48,26 @@ public class TmfXmlEventHandler {
     /* list of states changes */
     private final List fStateChangeList = new ArrayList<>();
     private final String fName;
-    private final XmlStateProvider fParent;
+    private final IXmlStateSystemContainer fParent;
 
     /**
      * Constructor
      *
+     * @param modelFactory
+     *            The factory used to create XML model elements
      * @param node
      *            XML event handler element
      * @param parent
-     *            The state provider this event handler belongs to
+     *            The state system container this event handler belongs to
      */
-    public TmfXmlEventHandler(Element node, XmlStateProvider parent) {
+    public TmfXmlEventHandler(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer parent) {
         fParent = parent;
         fName = node.getAttribute(TmfXmlStrings.HANDLER_EVENT_NAME);
 
         NodeList nodesChanges = node.getElementsByTagName(TmfXmlStrings.STATE_CHANGE);
         /* load state changes */
         for (int i = 0; i < nodesChanges.getLength(); i++) {
-            TmfXmlStateChange stateChange = new TmfXmlStateChange((Element) nodesChanges.item(i), fParent);
+            TmfXmlStateChange stateChange = modelFactory.createStateChange((Element) nodesChanges.item(i), fParent);
             fStateChangeList.add(stateChange);
         }
     }
diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlLocation.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java
similarity index 56%
rename from org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlLocation.java
rename to org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java
index 7888d6580b..4491f7f0a3 100644
--- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlLocation.java
+++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlLocation.java
@@ -10,19 +10,19 @@
  *   Florian Wininger - Initial API and implementation
  ******************************************************************************/
 
-package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
+package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
+import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
 import org.w3c.dom.Element;
 
 /**
- * This Class implements a Location in the XML state provider, ie a named
+ * This Class implements a Location in the XML-defined state system, ie a named
  * shortcut to reach a given attribute, used in state attributes
  *
  * 
@@ -39,27 +39,29 @@ import org.w3c.dom.Element;
 public class TmfXmlLocation {
 
     /** Path in the State System */
-    private final List fPath = new ArrayList<>();
+    private final List fPath = new LinkedList<>();
 
     /** ID : name of the location */
     private final String fId;
-    private final XmlStateProvider fProvider;
+    private final IXmlStateSystemContainer fContainer;
 
     /**
      * Constructor
      *
+     * @param modelFactory
+     *            The factory used to create XML model elements
      * @param location
      *            XML node element
-     * @param provider
-     *            The state provider this location belongs to
+     * @param container
+     *            The state system container this location belongs to
      */
-    public TmfXmlLocation(Element location, XmlStateProvider provider) {
+    public TmfXmlLocation(ITmfXmlModelFactory modelFactory, Element location, IXmlStateSystemContainer container) {
         fId = location.getAttribute(TmfXmlStrings.ID);
-        fProvider = provider;
+        fContainer = container;
 
         List childElements = XmlUtils.getChildElements(location);
         for (Element attribute : childElements) {
-            TmfXmlStateAttribute xAttribute = new TmfXmlStateAttribute(attribute, fProvider);
+            ITmfXmlStateAttribute xAttribute = modelFactory.createStateAttribute(attribute, fContainer);
             fPath.add(xAttribute);
         }
     }
@@ -80,15 +82,35 @@ public class TmfXmlLocation {
      *            The event being handled
      * @param startQuark
      *            The starting quark for relative search, use
-     *            {@link XmlStateProvider#ROOT_QUARK} for the root of the
-     *            attribute tree
+     *            {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of
+     *            the attribute tree
      * @return The quark at the leaf of the path
      */
     public int getLocationQuark(ITmfEvent event, int startQuark) {
         int quark = startQuark;
-        for (TmfXmlStateAttribute attrib : fPath) {
+        for (ITmfXmlStateAttribute attrib : fPath) {
             quark = attrib.getAttributeQuark(event, quark);
-            if (quark == XmlStateProvider.ERROR_QUARK) {
+            if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
+                break;
+            }
+        }
+        return quark;
+    }
+
+    /**
+     * Get the quark for the path represented by this location
+     *
+     * @param startQuark
+     *            The starting quark for relative search, use
+     *            {@link IXmlStateSystemContainer#ROOT_QUARK} for the root of
+     *            the attribute tree
+     * @return The quark at the leaf of the path
+     */
+    public int getLocationQuark(int startQuark) {
+        int quark = startQuark;
+        for (ITmfXmlStateAttribute attrib : fPath) {
+            quark = attrib.getAttributeQuark(quark);
+            if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
                 break;
             }
         }
diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateAttribute.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java
similarity index 50%
rename from org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateAttribute.java
rename to org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java
index 512e715d8f..8fd988366f 100644
--- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateAttribute.java
+++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateAttribute.java
@@ -10,26 +10,29 @@
  *   Florian Wininger - Initial API and implementation
  ******************************************************************************/
 
-package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
+package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator;
+import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder;
 import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
 import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
 import org.w3c.dom.Element;
 
 /**
- * This Class implements a single attribute value
+ * This Class implements a single attribute value in the XML-defined state
+ * system.
  *
  * 
  * Examples:
@@ -43,14 +46,15 @@ import org.w3c.dom.Element;
  *
  * @author Florian Wininger
  */
-public class TmfXmlStateAttribute {
+public abstract class TmfXmlStateAttribute implements ITmfXmlStateAttribute {
 
     private enum StateAttributeType {
         NONE,
         CONSTANT,
         EVENTFIELD,
         QUERY,
-        LOCATION
+        LOCATION,
+        SELF
     }
 
     /** Type of attribute */
@@ -60,38 +64,40 @@ public class TmfXmlStateAttribute {
     private final String fName;
 
     /** List of attributes for a query */
-    private final List fQueryList = new ArrayList<>();
+    private final List fQueryList = new LinkedList<>();
 
-    private final XmlStateProvider fProvider;
+    private final IXmlStateSystemContainer fContainer;
 
     /**
      * Constructor
      *
+     * @param modelFactory
+     *            The factory used to create XML model elements
      * @param attribute
      *            XML element of the attribute
-     * @param provider
-     *            The state provider this state attribute belongs to
+     * @param container
+     *            The state system container this state attribute belongs to
      */
-    public TmfXmlStateAttribute(Element attribute, XmlStateProvider provider) {
-        fProvider = provider;
+    protected TmfXmlStateAttribute(ITmfXmlModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) {
+        fContainer = container;
 
         switch (attribute.getAttribute(TmfXmlStrings.TYPE)) {
         case TmfXmlStrings.TYPE_CONSTANT:
             fType = StateAttributeType.CONSTANT;
-            fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
+            fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
             break;
         case TmfXmlStrings.EVENT_FIELD:
             fType = StateAttributeType.EVENTFIELD;
-            fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
+            fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
             break;
         case TmfXmlStrings.TYPE_LOCATION:
             fType = StateAttributeType.LOCATION;
-            fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
+            fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
             break;
         case TmfXmlStrings.TYPE_QUERY:
             List childElements = XmlUtils.getChildElements(attribute);
             for (Element subAttributeNode : childElements) {
-                TmfXmlStateAttribute subAttribute = new TmfXmlStateAttribute(subAttributeNode, fProvider);
+                ITmfXmlStateAttribute subAttribute = modelFactory.createStateAttribute(subAttributeNode, fContainer);
                 fQueryList.add(subAttribute);
             }
             fType = StateAttributeType.QUERY;
@@ -101,6 +107,10 @@ public class TmfXmlStateAttribute {
             fType = StateAttributeType.NONE;
             fName = null;
             break;
+        case TmfXmlStrings.TYPE_SELF:
+            fType = StateAttributeType.SELF;
+            fName = null;
+            break;
         default:
             throw new IllegalArgumentException("TmfXmlStateAttribute constructor: The XML element is not of the right type"); //$NON-NLS-1$
         }
@@ -108,57 +118,124 @@ public class TmfXmlStateAttribute {
 
     /**
      * This method gets the quark for this state attribute in the State System.
-     * The method use the ss.getQuarkRelativeAndAdd method in the State System.
      *
      * Unless this attribute is a location, in which case the quark must exist,
-     * the quark will be added to the state system.
+     * the quark will be added to the state system if the state system is in
+     * builder mode.
      *
-     * @param event
-     *            The current event being handled
      * @param startQuark
-     *            root quark, use {@link XmlStateProvider#ROOT_QUARK} to search
-     *            the full attribute tree
+     *            root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to
+     *            search the full attribute tree
      * @return the quark described by attribute or
-     *         {@link XmlStateProvider#ERROR_QUARK} if quark cannot be found
+     *         {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be
+     *         found
+     */
+    @Override
+    public int getAttributeQuark(int startQuark) {
+        return getAttributeQuark(null, startQuark);
+    }
+
+    /**
+     * Basic quark-retrieving method. Pass an attribute in parameter as an array
+     * of strings, the matching quark will be returned. If the attribute does
+     * not exist, it will add the quark to the state system if the context
+     * allows it.
+     *
+     * See {@link ITmfStateSystemBuilder#getQuarkAbsoluteAndAdd(String...)}
+     *
+     * @param path
+     *            Full path to the attribute
+     * @return The quark for this attribute
+     * @throws AttributeNotFoundException
+     *             The attribute does not exist and cannot be added
+     */
+    protected abstract int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException;
+
+    /**
+     * Quark-retrieving method, but the attribute is queried starting from the
+     * startNodeQuark. If the attribute does not exist, it will add it to the
+     * state system if the context allows it.
+     *
+     * See {@link ITmfStateSystemBuilder#getQuarkRelativeAndAdd(int, String...)}
+     *
+     * @param startNodeQuark
+     *            The quark of the attribute from which 'path' originates.
+     * @param path
+     *            Relative path to the attribute
+     * @return The quark for this attribute
+     * @throws AttributeNotFoundException
+     *             The attribute does not exist and cannot be added
+     */
+    protected abstract int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException;
+
+    /**
+     * Get the state system associated with this attribute's container
+     *
+     * @return The state system associated with this state attribute
      */
-    public int getAttributeQuark(ITmfEvent event, int startQuark) {
-        final ITmfEventField content = event.getContent();
+    protected ITmfStateSystem getStateSystem() {
+        return fContainer.getStateSystem();
+    }
 
-        ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem();
+    /**
+     * This method gets the quark for this state attribute in the State System.
+     *
+     * Unless this attribute is a location, in which case the quark must exist,
+     * the quark will be added to the state system if the state system is in
+     * builder mode.
+     *
+     * @param event
+     *            The current event being handled, or null if no
+     *            event available in the context
+     * @param startQuark
+     *            root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to
+     *            search the full attribute tree
+     * @return the quark described by attribute or
+     *         {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be
+     *         found
+     */
+    @Override
+    public int getAttributeQuark(@Nullable ITmfEvent event, int startQuark) {
+        ITmfStateSystem ss = getStateSystem();
 
         try {
             switch (fType) {
             case CONSTANT: {
                 int quark;
-                if (startQuark == XmlStateProvider.ROOT_QUARK) {
-                    quark = ss.getQuarkAbsoluteAndAdd(fName);
+                if (startQuark == IXmlStateSystemContainer.ROOT_QUARK) {
+                    quark = getQuarkAbsoluteAndAdd(fName);
                 } else {
-                    quark = ss.getQuarkRelativeAndAdd(startQuark, fName);
+                    quark = getQuarkRelativeAndAdd(startQuark, fName);
                 }
                 return quark;
             }
             case EVENTFIELD: {
-                int quark = XmlStateProvider.ERROR_QUARK;
+                int quark = IXmlStateSystemContainer.ERROR_QUARK;
+                if (event == null) {
+                    Activator.logWarning("XML State attribute: looking for an event field, but event is null"); //$NON-NLS-1$
+                    return quark;
+                }
                 /* special case if field is CPU which is not in the field */
                 if (fName.equals(TmfXmlStrings.CPU)) {
-                    quark = ss.getQuarkRelativeAndAdd(startQuark, event.getSource());
+                    quark = getQuarkRelativeAndAdd(startQuark, event.getSource());
                 } else {
+                    final ITmfEventField content = event.getContent();
                     /* stop if the event field doesn't exist */
                     if (content.getField(fName) == null) {
-                        return XmlStateProvider.ERROR_QUARK;
+                        return IXmlStateSystemContainer.ERROR_QUARK;
                     }
 
                     Object field = content.getField(fName).getValue();
 
                     if (field instanceof String) {
                         String fieldString = (String) field;
-                        quark = ss.getQuarkRelativeAndAdd(startQuark, fieldString);
+                        quark = getQuarkRelativeAndAdd(startQuark, fieldString);
                     } else if (field instanceof Long) {
                         Long fieldLong = (Long) field;
-                        quark = ss.getQuarkRelativeAndAdd(startQuark, fieldLong.toString());
+                        quark = getQuarkRelativeAndAdd(startQuark, fieldLong.toString());
                     } else if (field instanceof Integer) {
                         Integer fieldInterger = (Integer) field;
-                        quark = ss.getQuarkRelativeAndAdd(startQuark, fieldInterger.toString());
+                        quark = getQuarkRelativeAndAdd(startQuark, fieldInterger.toString());
                     }
                 }
                 return quark;
@@ -166,41 +243,41 @@ public class TmfXmlStateAttribute {
             case QUERY: {
                 int quark;
                 ITmfStateValue value = TmfStateValue.nullValue();
-                int quarkQuery = XmlStateProvider.ROOT_QUARK;
+                int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK;
 
-                for (TmfXmlStateAttribute attrib : fQueryList) {
+                for (ITmfXmlStateAttribute attrib : fQueryList) {
                     quarkQuery = attrib.getAttributeQuark(event, quarkQuery);
-                    if (quarkQuery == XmlStateProvider.ERROR_QUARK) {
+                    if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) {
                         break;
                     }
                 }
 
                 // the query may fail: for example CurrentThread if there
                 // has not been a sched_switch event
-                if (quarkQuery != XmlStateProvider.ERROR_QUARK) {
+                if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) {
                     value = ss.queryOngoingState(quarkQuery);
                 }
 
                 switch (value.getType()) {
                 case INTEGER: {
                     int result = value.unboxInt();
-                    quark = ss.getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
+                    quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
                     break;
                 }
                 case LONG: {
                     long result = value.unboxLong();
-                    quark = ss.getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
+                    quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
                     break;
                 }
                 case STRING: {
                     String result = value.unboxStr();
-                    quark = ss.getQuarkRelativeAndAdd(startQuark, result);
+                    quark = getQuarkRelativeAndAdd(startQuark, result);
                     break;
                 }
                 case DOUBLE:
                 case NULL:
                 default:
-                    quark = XmlStateProvider.ERROR_QUARK; // error
+                    quark = IXmlStateSystemContainer.ERROR_QUARK; // error
                     break;
                 }
                 return quark;
@@ -209,17 +286,19 @@ public class TmfXmlStateAttribute {
                 int quark = startQuark;
                 String idLocation = fName;
 
-                /* TODO: Add a fProvider.getLocation(id) method */
-                for (TmfXmlLocation location : fProvider.getLocations()) {
+                /* TODO: Add a fContainer.getLocation(id) method */
+                for (TmfXmlLocation location : fContainer.getLocations()) {
                     if (location.getId().equals(idLocation)) {
                         quark = location.getLocationQuark(event, quark);
-                        if (quark == XmlStateProvider.ERROR_QUARK) {
+                        if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
                             break;
                         }
                     }
                 }
                 return quark;
             }
+            case SELF:
+                return startQuark;
             case NONE:
             default:
                 return startQuark;
@@ -229,14 +308,14 @@ public class TmfXmlStateAttribute {
              * This can be happen before the creation of the node for a query in
              * the state system. Example : current thread before a sched_switch
              */
-            return XmlStateProvider.ERROR_QUARK;
+            return IXmlStateSystemContainer.ERROR_QUARK;
         } catch (StateValueTypeException e) {
             /*
              * This would happen if we were trying to push/pop attributes not of
              * type integer. Which, once again, should never happen.
              */
             Activator.logError("StateValueTypeException", e); //$NON-NLS-1$
-            return XmlStateProvider.ERROR_QUARK;
+            return IXmlStateSystemContainer.ERROR_QUARK;
         }
     }
 
diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateChange.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java
similarity index 77%
rename from org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateChange.java
rename to org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java
index ae116323f2..85c268156d 100644
--- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/internal/tmf/analysis/xml/core/stateprovider/model/TmfXmlStateChange.java
+++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateChange.java
@@ -10,15 +10,15 @@
  *   Florian Wininger - Initial API and implementation
  ******************************************************************************/
 
-package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
+package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
 import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
-import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
@@ -27,7 +27,7 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
 /**
- * This Class implement a State Change in the XML state provider
+ * This Class implement a State Change in the XML-defined state system
  *
  * 
  *  example 1: Simple state change
@@ -64,18 +64,20 @@ import org.w3c.dom.Node;
 public class TmfXmlStateChange {
 
     private final IXmlStateChange fChange;
-    private final XmlStateProvider fProvider;
+    private final IXmlStateSystemContainer fContainer;
 
     /**
      * Constructor
      *
+     * @param modelFactory
+     *            The factory used to create XML model elements
      * @param statechange
      *            XML node root of this state change
-     * @param provider
-     *            The state provider this state change belongs to
+     * @param container
+     *            The state system container this state change belongs to
      */
-    public TmfXmlStateChange(Element statechange, XmlStateProvider provider) {
-        fProvider = provider;
+    public TmfXmlStateChange(ITmfXmlModelFactory modelFactory, Element statechange, IXmlStateSystemContainer container) {
+        fContainer = container;
 
         /*
          * child nodes is either a list of TmfXmlStateAttributes and
@@ -84,10 +86,10 @@ public class TmfXmlStateChange {
         Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
         if (ifNode != null) {
             /* the state change has a condition */
-            fChange = new XmlConditionalChange(statechange);
+            fChange = new XmlConditionalChange(modelFactory, statechange);
         } else {
             /* the state change does not have a condition */
-            fChange = new XmlStateValueChange(statechange);
+            fChange = new XmlStateValueChange(modelFactory, statechange);
         }
     }
 
@@ -121,29 +123,29 @@ public class TmfXmlStateChange {
         private final TmfXmlStateChange fThenChange;
         private final TmfXmlStateChange fElseChange;
 
-        public XmlConditionalChange(Element statechange) {
+        public XmlConditionalChange(ITmfXmlModelFactory modelFactory, Element statechange) {
             /*
              * The if node exists, it has been verified before calling this
              */
             Node ifNode = statechange.getElementsByTagName(TmfXmlStrings.IF).item(0);
-            fCondition = new TmfXmlCondition((Element) ifNode, fProvider);
+            fCondition = modelFactory.createCondition((Element) ifNode, fContainer);
 
             Node thenNode = statechange.getElementsByTagName(TmfXmlStrings.THEN).item(0);
             if (thenNode == null) {
                 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
             }
-            fThenChange = new TmfXmlStateChange((Element) thenNode, fProvider);
+            fThenChange = modelFactory.createStateChange((Element) thenNode, fContainer);
 
             Node elseNode = statechange.getElementsByTagName(TmfXmlStrings.ELSE).item(0);
             if (elseNode != null) {
-                fElseChange = new TmfXmlStateChange((Element) elseNode, fProvider);
+                fElseChange = modelFactory.createStateChange((Element) elseNode, fContainer);
             } else {
                 fElseChange = null;
             }
         }
 
         @Override
-        public void handleEvent(ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
+        public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
             TmfXmlStateChange toExecute = fThenChange;
             try {
                 if (!fCondition.testForEvent(event)) {
@@ -168,9 +170,9 @@ public class TmfXmlStateChange {
      * State change with no condition
      */
     private class XmlStateValueChange implements IXmlStateChange {
-        private final TmfXmlStateValue fValue;
+        private final ITmfXmlStateValue fValue;
 
-        public XmlStateValueChange(Element statechange) {
+        public XmlStateValueChange(ITmfXmlModelFactory modelFactory, Element statechange) {
             List childElements = XmlUtils.getChildElements(statechange);
 
             /*
@@ -178,22 +180,22 @@ public class TmfXmlStateChange {
              * to reach to value to set
              */
             Element stateValueElement = childElements.remove(childElements.size() - 1);
-            List attributes = new ArrayList<>();
+            List attributes = new ArrayList<>();
             for (Element element : childElements) {
                 if (!element.getNodeName().equals(TmfXmlStrings.STATE_ATTRIBUTE)) {
                     throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
                 }
-                TmfXmlStateAttribute attribute = new TmfXmlStateAttribute(element, fProvider);
+                ITmfXmlStateAttribute attribute = modelFactory.createStateAttribute(element, fContainer);
                 attributes.add(attribute);
             }
             if (attributes.isEmpty()) {
                 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
             }
-            fValue = new TmfXmlStateValue(stateValueElement, fProvider, attributes);
+            fValue = modelFactory.createStateValue(stateValueElement, fContainer, attributes);
         }
 
         @Override
-        public void handleEvent(ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
+        public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
             fValue.handleEvent(event);
         }
     }
diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java
new file mode 100644
index 0000000000..27f2a4b866
--- /dev/null
+++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/TmfXmlStateValue.java
@@ -0,0 +1,486 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ecole Polytechnique de Montreal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Florian Wininger - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
+
+import java.util.List;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
+import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
+import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
+import org.w3c.dom.Element;
+
+/**
+ * This Class implements a State Value in the XML-defined state system, along
+ * with the path to get to the value (either a list of state attributes or an
+ * event field)
+ *
+ * 
+ * Example:
+ *   
+ *   
+ *   
+ * 
+ * + * @author Florian Wininger + */ +public abstract class TmfXmlStateValue implements ITmfXmlStateValue { + + private final TmfXmlStateValueBase fStateValue; + + /* Path in the State System */ + private final List fPath; + /* Event field to match with this state value */ + private final String fEventField; + + /* Whether this state value is an increment of the previous value */ + private final boolean fIncrement; + /* Stack value */ + private final ValueTypeStack fStackType; + /* Forced value type */ + private final ITmfStateValue.Type fForcedType; + + private final IXmlStateSystemContainer fContainer; + + /** + * Different behaviors of an attribute that is to be stacked + */ + protected enum ValueTypeStack { + /** Not stacked */ + NULL, + /** Peek at the value at the top of the stack */ + PEEK, + /** Take the value at the top of the stack */ + POP, + /** Push the value on the stack */ + PUSH; + + /** + * Get the type stack value corresponding to a string + * + * @param input + * The string to match to a value + * @return The ValueTypeStack value + */ + public static ValueTypeStack getTypeFromString(String input) { + switch (input) { + case TmfXmlStrings.STACK_PUSH: + return PUSH; + case TmfXmlStrings.STACK_POP: + return POP; + case TmfXmlStrings.STACK_PEEK: + return PEEK; + default: + return NULL; + } + } + } + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + * @param attributes + * The attributes representing the path to this value + */ + protected TmfXmlStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { + fPath = attributes; + fContainer = container; + fEventField = eventField; + if (!node.getNodeName().equals(TmfXmlStrings.STATE_VALUE)) { + throw new IllegalArgumentException("TmfXmlStateValue constructor: Element is not a stateValue"); //$NON-NLS-1$ + } + + /* Check if there is an increment for the value */ + fIncrement = Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.INCREMENT)); + + /* Process the XML Element state value */ + fStateValue = initializeStateValue(modelFactory, node); + + /* + * Forced type allows to convert the value to a certain type : For + * example, a process's TID in an event field may arrive with a LONG + * format but we want to store the data in an INT + */ + switch (node.getAttribute(TmfXmlStrings.FORCED_TYPE)) { + case TmfXmlStrings.TYPE_STRING: + fForcedType = ITmfStateValue.Type.STRING; + break; + case TmfXmlStrings.TYPE_INT: + fForcedType = ITmfStateValue.Type.INTEGER; + break; + case TmfXmlStrings.TYPE_LONG: + fForcedType = ITmfStateValue.Type.LONG; + break; + default: + fForcedType = ITmfStateValue.Type.NULL; + } + + /* + * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods + */ + String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK); + fStackType = ValueTypeStack.getTypeFromString(stack); + } + + /** + * Initialize a {@link TmfXmlStateValueBase} object for the type and value + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @return The internal state value type corresponding to this state value + */ + protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { + return new TmfXmlStateValueNull(); + } + + /** + * Return the state system container this class is attached to + * + * @return The state system container + */ + protected IXmlStateSystemContainer getSsContainer() { + return fContainer; + } + + /** + * Get the state system associated with this value's container + * + * @return The state system associated with the state system container + */ + protected ITmfStateSystem getStateSystem() { + return fContainer.getStateSystem(); + } + + /** + * Return whether this value is an increment of the previous value + * + * @return true if the value is an increment + */ + protected boolean isIncrement() { + return fIncrement; + } + + /** + * Get the stack type of this attribute. If the attribute is to be pushed or + * popped to a stack. The behavior of the stack attribute will depend on the + * implementation of the model. + * + * @return The stack type of the attribute + */ + protected ValueTypeStack getStackType() { + return fStackType; + } + + /** + * Get the forced type of the value. For example, if the value obtained from + * the attributes is not in this forced type, it will be converted to this. + * + * @return The desired type of the value + */ + protected ITmfStateValue.Type getForcedType() { + return fForcedType; + } + + /** + * Get the current {@link ITmfStateValue} of this state value for an event. + * It does not increment the value and does not any other processing of the + * value. + * + * @param event + * The current event, or null if no event available. + * @return the {@link ITmfStateValue} + * @throws AttributeNotFoundException + * May be thrown by the state system during the query + */ + @Override + public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { + return fStateValue.getValue(event); + } + + /** + * Get the value of the event field that is the path of this state value + * + * @param event + * The current event + * @return the value of the event field + */ + @Override + public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) { + return getEventFieldValue(event, fEventField); + } + + /** + * Get the value of an event field + * + * @param event + * The current event + * @param fieldName + * The name of the field of which to get the value + * @return The value of the event field + */ + protected ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event, String fieldName) { + + ITmfStateValue value = TmfStateValue.nullValue(); + + final ITmfEventField content = event.getContent(); + + /* Exception for "CPU", returns the source of this event */ + /* FIXME : Nameclash if a eventfield have "cpu" for name. */ + if (fieldName.equals(TmfXmlStrings.CPU)) { + return TmfStateValue.newValueInt(Integer.valueOf(event.getSource())); + } + if (content.getField(fieldName) == null) { + return value; + } + + Object field = content.getField(fieldName).getValue(); + + /* + * Try to find the right type. The type can be forced by + * "forcedType" argument. + */ + + if (field instanceof String) { + String fieldString = (String) field; + + switch (fForcedType) { + case INTEGER: + value = TmfStateValue.newValueInt(Integer.parseInt(fieldString)); + break; + case LONG: + value = TmfStateValue.newValueLong(Long.parseLong(fieldString)); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString)); + break; + case NULL: + case STRING: + default: + value = TmfStateValue.newValueString(fieldString); + break; + } + } else if (field instanceof Long) { + Long fieldLong = (Long) field; + + switch (fForcedType) { + case INTEGER: + value = TmfStateValue.newValueInt(fieldLong.intValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldLong.toString()); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(fieldLong.doubleValue()); + break; + case LONG: + case NULL: + default: + value = TmfStateValue.newValueLong(fieldLong); + break; + } + } else if (field instanceof Integer) { + Integer fieldInteger = (Integer) field; + + switch (fForcedType) { + case LONG: + value = TmfStateValue.newValueLong(fieldInteger.longValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldInteger.toString()); + break; + case DOUBLE: + value = TmfStateValue.newValueDouble(fieldInteger.doubleValue()); + break; + case INTEGER: + case NULL: + default: + value = TmfStateValue.newValueInt(fieldInteger); + break; + } + } else if (field instanceof Double) { + Double fieldDouble = (Double) field; + + switch (fForcedType) { + case LONG: + value = TmfStateValue.newValueLong(fieldDouble.longValue()); + break; + case STRING: + value = TmfStateValue.newValueString(fieldDouble.toString()); + break; + case INTEGER: + value = TmfStateValue.newValueInt(fieldDouble.intValue()); + break; + case DOUBLE: + case NULL: + default: + value = TmfStateValue.newValueDouble(fieldDouble); + break; + } + } + return value; + } + + /** + * Get the list of state attributes, the path to the state value + * + * @return the list of Attribute to have the path in the State System + */ + @Override + public List getAttributes() { + return fPath; + } + + /** + * Handles an event, by setting the value of the attribute described by the + * state attribute path in the state system. + * + * @param event + * The event to process + * @throws AttributeNotFoundException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + */ + @Override + public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException { + int quark = IXmlStateSystemContainer.ROOT_QUARK; + + for (ITmfXmlStateAttribute attribute : fPath) { + quark = attribute.getAttributeQuark(event, quark); + /* the query is not valid, we stop the state change */ + if (quark == IXmlStateSystemContainer.ERROR_QUARK) { + throw new AttributeNotFoundException(); + } + } + + long ts = event.getTimestamp().getValue(); + fStateValue.handleEvent(event, quark, ts); + } + + /** + * Base class for all state values. Contain default methods to handle event, + * process or increment the value + */ + protected abstract class TmfXmlStateValueBase { + + /** + * Get the value associated with this state value. + * + * @param event + * The event which can be used to retrieve the value if + * necessary. The event can be null if no event + * is required. + * @return The state value corresponding to this XML state value + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + public abstract ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException; + + /** + * Do something with the state value, possibly using an event + * + * @param event + * The event being handled. If there is no event is + * available, use null. + * @param quark + * The quark for this value + * @param timestamp + * The timestamp of the event + * @throws StateValueTypeException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + public void handleEvent(@NonNull ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + if (fIncrement) { + incrementValue(event, quark, timestamp); + } else { + ITmfStateValue value = getValue(event); + processValue(quark, timestamp, value); + } + } + + /** + * Set the value of a quark at a given timestamp. + * + * @param quark + * The quark for this value + * @param timestamp + * The timestamp + * @param value + * The value of this state value + * @throws TimeRangeException + * Pass through the exception it received + * @throws StateValueTypeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + @SuppressWarnings("unused") + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException { + } + + /** + * Increments the value of the parameter + * + * @param event + * The event being handled + * @param quark + * The quark for this value + * @param timestamp + * The timestamp of the event + * @throws StateValueTypeException + * Pass through the exception it received + * @throws TimeRangeException + * Pass through the exception it received + * @throws AttributeNotFoundException + * Pass through the exception it received + */ + @SuppressWarnings("unused") + protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + } + } + + /* This state value uses a constant value, defined in the XML */ + private class TmfXmlStateValueNull extends TmfXmlStateValueBase { + + @Override + public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException { + return TmfStateValue.nullValue(); + } + + } + +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlModelFactoryReadWrite.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlModelFactoryReadWrite.java new file mode 100644 index 0000000000..fe815798d3 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlModelFactoryReadWrite.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateValue; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlCondition; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlEventHandler; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateChange; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.w3c.dom.Element; + +/** + * Concrete factory for XML model elements in read write mode + * + * @author Geneviève Bastien + */ +public class TmfXmlModelFactoryReadWrite implements ITmfXmlModelFactory { + + private static ITmfXmlModelFactory fInstance = null; + + /** + * Get the instance of this model creator + * + * @return The {@link TmfXmlModelFactoryReadWrite} instance + */ + @NonNull + public static synchronized ITmfXmlModelFactory getInstance() { + ITmfXmlModelFactory instance = fInstance; + if (instance == null) { + instance = new TmfXmlModelFactoryReadWrite(); + fInstance = instance; + } + return instance; + } + + @Override + public ITmfXmlStateAttribute createStateAttribute(Element attribute, IXmlStateSystemContainer container) { + return new TmfXmlStateAttributeReadWrite(this, attribute, container); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, List attributes) { + return new TmfXmlStateValueReadWrite(this, node, container, attributes); + } + + @Override + public ITmfXmlStateValue createStateValue(Element node, IXmlStateSystemContainer container, String eventField) { + return new TmfXmlStateValueReadWrite(this, node, container, eventField); + } + + @Override + public TmfXmlCondition createCondition(Element node, IXmlStateSystemContainer container) { + return new TmfXmlCondition(this, node, container); + } + + @Override + public TmfXmlEventHandler createEventHandler(Element node, IXmlStateSystemContainer container) { + return new TmfXmlEventHandler(this, node, container); + } + + @Override + public TmfXmlStateChange createStateChange(Element node, IXmlStateSystemContainer container) { + return new TmfXmlStateChange(this, node, container); + } + + @Override + public TmfXmlLocation createLocation(Element node, IXmlStateSystemContainer container) { + return new TmfXmlLocation(this, node, container); + } + +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateAttributeReadWrite.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateAttributeReadWrite.java new file mode 100644 index 0000000000..86db85c119 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateAttributeReadWrite.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; + +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateAttribute; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; +import org.w3c.dom.Element; + +/** + * Implements a state attribute in a read write mode. See + * {@link TmfXmlStateAttribute} for the syntax of this attribute. + * + * In read-write mode, attributes that are requested but do not exist are added + * to the state system. + * + * @author Geneviève Bastien + */ +public class TmfXmlStateAttributeReadWrite extends TmfXmlStateAttribute { + + /** + * Constructor + * + * @param modelFactory + * The factory used to create XML model elements + * @param attribute + * The XML element corresponding to this attribute + * @param container + * The state system container this state value belongs to + */ + public TmfXmlStateAttributeReadWrite(TmfXmlModelFactoryReadWrite modelFactory, Element attribute, IXmlStateSystemContainer container) { + super(modelFactory, attribute, container); + } + + @Override + protected ITmfStateSystemBuilder getStateSystem() { + return (ITmfStateSystemBuilder) super.getStateSystem(); + } + + @Override + protected int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkAbsoluteAndAdd(path); + } + + @Override + protected int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException { + return getStateSystem().getQuarkRelativeAndAdd(startNodeQuark, path); + } + +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateValueReadWrite.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateValueReadWrite.java new file mode 100644 index 0000000000..abe23b12da --- /dev/null +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/model/readwrite/TmfXmlStateValueReadWrite.java @@ -0,0 +1,375 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlStateAttribute; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlStateValue; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; +import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings; +import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; +import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; +import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue; +import org.w3c.dom.Element; + +/** + * Implements a state value in a read write mode. See {@link TmfXmlStateValue} + * for the syntax of the state value. + * + * In read/write mode, a state value can be considered as an assignation where + * the state value is assigned to the quark represented by the state attributes + * + * @author Geneviève Bastien + */ +public class TmfXmlStateValueReadWrite extends TmfXmlStateValue { + + /** + * Constructor where the path to the value is a list of state attributes + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param attributes + * The attributes representing the path to this value + */ + public TmfXmlStateValueReadWrite(TmfXmlModelFactoryReadWrite modelFactory, Element node, IXmlStateSystemContainer container, List attributes) { + this(modelFactory, node, container, attributes, null); + } + + /** + * Constructor where the path to the value is an event field + * + * @param modelFactory + * The factory used to create XML model elements + * @param node + * The state value XML element + * @param container + * The state system container this state value belongs to + * @param eventField + * The event field where to get the value + */ + public TmfXmlStateValueReadWrite(TmfXmlModelFactoryReadWrite modelFactory, Element node, IXmlStateSystemContainer container, String eventField) { + this(modelFactory, node, container, new ArrayList(), eventField); + } + + private TmfXmlStateValueReadWrite(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List attributes, String eventField) { + super(modelFactory, node, container, attributes, eventField); + } + + @Override + protected ITmfStateSystemBuilder getStateSystem() { + return (ITmfStateSystemBuilder) super.getStateSystem(); + } + + @Override + protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) { + TmfXmlStateValueBase stateValueType = null; + /* Process the XML Element state value */ + String type = node.getAttribute(TmfXmlStrings.TYPE); + String value = getSsContainer().getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE)); + + switch (type) { + case TmfXmlStrings.TYPE_INT: { + /* Integer value */ + ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value)); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_LONG: { + /* Long value */ + ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value)); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_STRING: { + /* String value */ + ITmfStateValue stateValue = TmfStateValue.newValueString(value); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.TYPE_NULL: { + /* Null value */ + ITmfStateValue stateValue = TmfStateValue.nullValue(); + stateValueType = new TmfXmlStateValueTmf(stateValue); + break; + } + case TmfXmlStrings.EVENT_FIELD: + /* Event field */ + stateValueType = new TmfXmlStateValueEventField(value); + break; + case TmfXmlStrings.TYPE_EVENT_NAME: + /* The value is the event name */ + stateValueType = new TmfXmlStateValueEventName(); + break; + case TmfXmlStrings.TYPE_DELETE: + /* Deletes the value of an attribute */ + stateValueType = new TmfXmlStateValueDelete(); + break; + case TmfXmlStrings.TYPE_QUERY: + /* Value is the result of a query */ + List children = XmlUtils.getChildElements(node); + List childAttributes = new ArrayList<>(); + for (Element child : children) { + ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer()); + childAttributes.add(queryAttribute); + } + stateValueType = new TmfXmlStateValueQuery(childAttributes); + break; + default: + throw new IllegalArgumentException(String.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type)); //$NON-NLS-1$ + } + return stateValueType; + } + + // ---------------------------------------------------------- + // Internal state value classes for the different types + // ---------------------------------------------------------- + + /** + * Base class for all state value. Contain default methods to handle event, + * process or increment the value + */ + protected abstract class TmfXmlStateValueTypeReadWrite extends TmfXmlStateValueBase { + + @Override + public final void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + if (isIncrement()) { + incrementValue(event, quark, timestamp); + } else { + ITmfStateValue value = getValue(event); + processValue(quark, timestamp, value); + } + } + + @Override + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws AttributeNotFoundException, TimeRangeException, StateValueTypeException { + switch (getStackType()) { + case POP: + getStateSystem().popAttribute(timestamp, quark); + break; + case PUSH: + getStateSystem().pushAttribute(timestamp, value, quark); + break; + case NULL: + case PEEK: + default: + getStateSystem().modifyAttribute(timestamp, value, quark); + break; + } + } + + @Override + protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + getStateSystem().incrementAttribute(timestamp, quark); + } + } + + /* This state value uses a constant value, defined in the XML */ + private class TmfXmlStateValueTmf extends TmfXmlStateValueTypeReadWrite { + + private final ITmfStateValue fValue; + + public TmfXmlStateValueTmf(ITmfStateValue value) { + fValue = value; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + return fValue; + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + switch (fValue.getType()) { + case LONG: { + long incrementLong = fValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + return; + } + case INTEGER: { + int increment = fValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$ + break; + } + } + } + + /* The state value uses the value of an event field */ + private class TmfXmlStateValueEventField extends TmfXmlStateValueTypeReadWrite { + + private final String fFieldName; + + public TmfXmlStateValueEventField(String field) { + fFieldName = field; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + if (event == null) { + Activator.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$ + return TmfStateValue.nullValue(); + } + return getEventFieldValue(event, fFieldName); + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getSsContainer().getStateSystem(); + ITmfStateValue incrementValue = getValue(event); + switch (incrementValue.getType()) { + case INTEGER: { + int increment = incrementValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case LONG: { + long incrementLong = incrementValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning(String.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName, incrementValue.getType())); //$NON-NLS-1$ + break; + } + } + } + + /* The state value is the event name */ + private class TmfXmlStateValueEventName extends TmfXmlStateValueTypeReadWrite { + + @Override + public ITmfStateValue getValue(ITmfEvent event) { + if (event == null) { + Activator.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$ + return TmfStateValue.nullValue(); + } + return TmfStateValue.newValueString(event.getType().getName()); + } + + } + + /* The state value deletes an attribute */ + private class TmfXmlStateValueDelete extends TmfXmlStateValueTypeReadWrite { + + @Override + public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { + return TmfStateValue.nullValue(); + } + + @Override + protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + if (!(ss instanceof ITmfStateSystemBuilder)) { + throw new IllegalStateException("incrementValue should never be called when not building the state system"); //$NON-NLS-1$ + } + ITmfStateSystemBuilder builder = (ITmfStateSystemBuilder) ss; + builder.removeAttribute(timestamp, quark); + } + + } + + /* The state value uses the result of a query */ + private class TmfXmlStateValueQuery extends TmfXmlStateValueTypeReadWrite { + + private final List fQueryValue; + + public TmfXmlStateValueQuery(List childAttributes) { + fQueryValue = childAttributes; + } + + @Override + public ITmfStateValue getValue(ITmfEvent event) throws AttributeNotFoundException { + /* Query the state system for the value */ + ITmfStateValue value = TmfStateValue.nullValue(); + int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK; + ITmfStateSystem ss = getStateSystem(); + + for (ITmfXmlStateAttribute attribute : fQueryValue) { + quarkQuery = attribute.getAttributeQuark(event, quarkQuery); + if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) { + /* the query is not valid, we stop the state change */ + break; + } + } + /* + * the query can fail : for example, if a value is requested but has + * not been set yet + */ + if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) { + value = ss.queryOngoingState(quarkQuery); + } + return value; + } + + @Override + public void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException { + ITmfStateSystem ss = getStateSystem(); + ITmfStateValue incrementValue = getValue(event); + switch (incrementValue.getType()) { + case INTEGER: { + int increment = incrementValue.unboxInt(); + int currentValue = ss.queryOngoingState(quark).unboxInt(); + ITmfStateValue value = TmfStateValue.newValueInt(increment + currentValue); + processValue(quark, timestamp, value); + break; + } + case LONG: { + long incrementLong = incrementValue.unboxLong(); + long currentValue = ss.queryOngoingState(quark).unboxLong(); + ITmfStateValue value = TmfStateValue.newValueLong(incrementLong + currentValue); + processValue(quark, timestamp, value); + break; + } + case DOUBLE: + case NULL: + case STRING: + default: + Activator.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$ + break; + } + } + } + +} diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java index b9566b0816..cfb59591c2 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/ITmfXmlTopLevelElement.java @@ -12,7 +12,6 @@ package org.eclipse.linuxtools.tmf.analysis.xml.core.module; - /** * Interface implemented by all classes representing XML top-level elements, for * example state providers and views diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java index 783aebb181..634807403c 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/module/IXmlStateSystemContainer.java @@ -12,14 +12,13 @@ package org.eclipse.linuxtools.tmf.analysis.xml.core.module; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model.TmfXmlLocation; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; /** * Interface that all XML defined objects who provide, use or contain state * system must implement in order to use the state provider model elements in - * {@link org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model} - * package + * {@link org.eclipse.linuxtools.tmf.analysis.xml.core.model} package * * @author Geneviève Bastien */ diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java index 1d217061dc..b606c0a303 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java @@ -65,6 +65,7 @@ public interface TmfXmlStrings { static final String EVENT_FIELD = "eventField"; static final String TYPE_LOCATION = "location"; static final String TYPE_QUERY = "query"; + static final String TYPE_SELF = "self"; static final String TYPE_INT = "int"; static final String TYPE_LONG = "long"; static final String TYPE_STRING = "string"; diff --git a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java index 4955d189fc..bb98befdc7 100644 --- a/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java +++ b/org.eclipse.linuxtools.tmf.analysis.xml.core/src/org/eclipse/linuxtools/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java @@ -12,33 +12,26 @@ package org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider; -import java.io.File; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - import org.eclipse.core.runtime.IPath; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model.TmfXmlEventHandler; -import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model.TmfXmlLocation; -import org.eclipse.linuxtools.tmf.analysis.xml.core.module.Messages; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.ITmfXmlModelFactory; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlEventHandler; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.TmfXmlLocation; +import org.eclipse.linuxtools.tmf.analysis.xml.core.model.readwrite.TmfXmlModelFactoryReadWrite; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer; +import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils; import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; -import org.eclipse.osgi.util.NLS; -import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; /** * This is the state change input plug-in for TMF's state system which handles @@ -46,21 +39,10 @@ import org.xml.sax.SAXException; * * @author Florian Wininger */ -public class XmlStateProvider extends AbstractTmfStateProvider { - - /** Root quark, to get values at the root of the state system */ - public static final int ROOT_QUARK = -1; - /** - * Error quark, value taken when a state system quark query is in error. - * - * FIXME: Originally in the code, the -1 was used for both root quark and - * return errors, so it has the same value as root quark, but maybe it can - * be changed to something else -2? A quark can never be negative - */ - public static final int ERROR_QUARK = -1; +public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlStateSystemContainer { private final IPath fFilePath; - private final String fStateId; + @NonNull private final String fStateId; /** List of all Event Handlers */ private final Set fEventHandlers = new HashSet<>(); @@ -86,16 +68,17 @@ public class XmlStateProvider extends AbstractTmfStateProvider { * @param file * Path to the XML file containing the state provider definition */ - public XmlStateProvider(ITmfTrace trace, String stateid, IPath file) { + public XmlStateProvider(ITmfTrace trace, @NonNull String stateid, IPath file) { super(trace, ITmfEvent.class, stateid); fStateId = stateid; fFilePath = file; - Element doc = loadXMLNode(); + Element doc = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); if (doc == null) { fLocations = new HashSet<>(); return; } + ITmfXmlModelFactory modelFactory = TmfXmlModelFactoryReadWrite.getInstance(); /* parser for defined Values */ NodeList definedStateNodes = doc.getElementsByTagName(TmfXmlStrings.DEFINED_VALUE); for (int i = 0; i < definedStateNodes.getLength(); i++) { @@ -108,7 +91,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { Set locations = new HashSet<>(); for (int i = 0; i < locationNodes.getLength(); i++) { Element element = (Element) locationNodes.item(i); - TmfXmlLocation location = new TmfXmlLocation(element, this); + TmfXmlLocation location = modelFactory.createLocation(element, this); locations.add(location); } fLocations = Collections.unmodifiableSet(locations); @@ -117,7 +100,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { NodeList nodes = doc.getElementsByTagName(TmfXmlStrings.EVENT_HANDLER); for (int i = 0; i < nodes.getLength(); i++) { Element element = (Element) nodes.item(i); - TmfXmlEventHandler handler = new TmfXmlEventHandler(element, this); + TmfXmlEventHandler handler = modelFactory.createEventHandler(element, this); fEventHandlers.add(handler); } } @@ -127,6 +110,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { * * @return The state id of the state provider */ + @NonNull public String getStateId() { return fStateId; } @@ -137,10 +121,9 @@ public class XmlStateProvider extends AbstractTmfStateProvider { @Override public int getVersion() { - Node ssNode = loadXMLNode(); - if (ssNode instanceof Element) { - Element element = (Element) ssNode; - return Integer.valueOf(element.getAttribute(TmfXmlStrings.VERSION)); + Element ssNode = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId); + if (ssNode != null) { + return Integer.parseInt(ssNode.getAttribute(TmfXmlStrings.VERSION)); } /* * The version attribute is mandatory and XML files that don't validate @@ -165,7 +148,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { } @Override - public ITmfStateSystemBuilder getAssignedStateSystem() { + public ITmfStateSystem getStateSystem() { return ss; } @@ -173,55 +156,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { // Operations // ------------------------------------------------------------------------ - /** - * Loads the XML file and returns the element at the root of the current - * state provider. - * - * @return The XML node at the root of the state provider - */ - private Element loadXMLNode() { - - try { - File XMLFile = fFilePath.toFile(); - if (XMLFile == null || !XMLFile.exists() || !XMLFile.isFile()) { - return null; - } - - /* Load the XML File */ - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder; - - dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(XMLFile); - doc.getDocumentElement().normalize(); - - /* get the state providers and find the corresponding one */ - NodeList stateproviderNodes = doc.getElementsByTagName(TmfXmlStrings.STATE_PROVIDER); - Element stateproviderNode = null; - - for (int i = 0; i < stateproviderNodes.getLength(); i++) { - Element node = (Element) stateproviderNodes.item(i); - String analysisid = node.getAttribute(TmfXmlStrings.ID); - if (analysisid.equals(fStateId)) { - stateproviderNode = node; - } - } - - return stateproviderNode; - } catch (ParserConfigurationException | IOException e) { - Activator.logError("Error loading XML file", e); //$NON-NLS-1$ - } catch (SAXException e) { - Activator.logError(NLS.bind(Messages.XmlUtils_XmlValidationError, e.getLocalizedMessage()), e); - } - - return null; - } - - /** - * Get the list of locations defined in this state provider - * - * @return The list of {@link TmfXmlLocation} - */ + @Override public Iterable getLocations() { return fLocations; } @@ -237,14 +172,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider { return fDefinedValues.get(constant); } - /** - * Get the requested value for an attribute. If the value is a pre-defined - * value, we return the string corresponding in the defined values map. - * - * @param name - * the string to get - * @return the actual string value - */ + @Override public String getAttributeValue(String name) { String attribute = name; if (attribute.startsWith(TmfXmlStrings.VARIABLE_PREFIX)) { -- 2.34.1