tmf.xml: Add mapping group to XML description
authorJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Wed, 13 Jul 2016 19:27:48 +0000 (15:27 -0400)
committerJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Wed, 24 Aug 2016 15:41:15 +0000 (11:41 -0400)
The mapping groups act as maps. They are used to avoid large if-else
condition in the XML. For example, if the relevant event for an FSM have
an integer field 'mode' and this value could be map to string. We could
save the 'mode' value in the state system and add a mapping group in the
XML to be able to directly use the string instead of the 'mode' value
when creating segments.

example of mode could be ;
* 1 - read only
* 2 - read - write
* 3 - write - only
* ....

Change-Id: I0237e62b304f984afcf78b09fd7b45c5687a80d5
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/76780
Reviewed-by: Hudson CI
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
17 files changed:
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/XmlSegmentTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/stubs/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stubs/PatternSegmentFactoryStub.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_traces/testTrace4.xml
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_consuming_fsm.xml
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlMapEntry.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlStateValue.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlCommon.xsd
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlPatternStateProvider.xsd
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlStateProvider.xsd
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java
tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java

index e9a53fae5df16616abc2e2c1cf2020febb8a0349..3c6cacb04a9806345364f8d85557cc6260c356c8 100644 (file)
@@ -143,4 +143,30 @@ public class TmfStateValueTest {
         ITmfStateValue[] expectedValues = { TmfStateValue.newValueLong(1l), TmfStateValue.newValueLong(5l), TmfStateValue.newValueLong(1l) };
         XmlUtilsTest.verifyStackStateIntervals("testStateValueModify", ss, quark, expectedStarts, expectedValues);
     }
+
+    /**
+     * Test the mapping groups. This test verifies that, when needed, the mapped
+     * value is used. In this test, the mapping group is used on the 'entry'
+     * event.
+     *
+     * @throws StateSystemDisposedException
+     *             Exceptions thrown during state system verification
+     * @throws AttributeNotFoundException
+     *             Exceptions thrown during state system verification
+     */
+    @Test
+    public void testStateValueMapping() throws AttributeNotFoundException, StateSystemDisposedException {
+        XmlStateSystemModule module = fModule;
+        assertNotNull(module);
+
+        ITmfStateSystem ss = module.getStateSystem();
+        assertNotNull(ss);
+
+        int quark = ss.getQuarkAbsolute("mapped");
+
+        final int[] expectedStarts = { 1, 3, 5, 7, 7 };
+        ITmfStateValue[] expectedValues = { TmfStateValue.newValueString("TRUE"), TmfStateValue.newValueString("FALSE"), TmfStateValue.newValueString("TRUE"), TmfStateValue.newValueString("FALSE") };
+        XmlUtilsTest.verifyStateIntervals("testMappingGroups", ss, quark, expectedStarts, expectedValues);
+
+    }
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/XmlSegmentTest.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/XmlSegmentTest.java
new file mode 100644 (file)
index 0000000..a7bfb04
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2016 É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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternAnalysis;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.common.TmfXmlTestFiles;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.module.XmlUtilsTest;
+import org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stubs.PatternSegmentFactoryStub;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test the XML pattern segment
+ *
+ * @author Jean-Christian Kouame
+ */
+public class XmlSegmentTest {
+
+    private static final @NonNull String TEST_TRACE = "test_traces/testTrace5.xml";
+
+    ITmfTrace fTrace;
+    XmlPatternAnalysis fModule;
+
+    /**
+     * Initializes the trace and the module for the tests
+     *
+     * @throws TmfAnalysisException
+     *             Any exception thrown during module initialization
+     */
+    @Before
+    public void setUp() throws TmfAnalysisException {
+        ITmfTrace trace = XmlUtilsTest.initializeTrace(TEST_TRACE);
+        @NonNull XmlPatternAnalysis module = XmlUtilsTest.initializePatternModule(TmfXmlTestFiles.CONSUMING_FSM_TEST);
+
+        module.setTrace(trace);
+
+        module.schedule();
+        module.waitForCompletion();
+
+        fTrace = trace;
+        fModule = module;
+    }
+
+    /**
+     * Dispose the module and the trace
+     */
+    @After
+    public void cleanUp() {
+        fTrace.dispose();
+        fModule.dispose();
+    }
+
+    /**
+     * Test segment generated using a mapping group
+     */
+    @Test
+    public void testMappingGroup() {
+        XmlPatternAnalysis module = fModule;
+        assertNotNull(module);
+
+        @Nullable ISegmentStore<@NonNull ISegment> ss = module.getSegmentStore();
+        assertNotNull(ss);
+        assertEquals("Segment store size", 1, ss.size());
+        Object segment = ss.toArray()[0];
+        assertTrue(segment instanceof TmfXmlPatternSegment);
+        XmlUtilsTest.testPatternSegmentData(PatternSegmentFactoryStub.TEST_3, (TmfXmlPatternSegment)segment);
+    }
+}
+
index d7cc8e39d66dbae2bae312a96ab60cf293cfe17f..741f3a098d3366106a648ad265f0bf06e1f6a30d 100644 (file)
@@ -8,6 +8,7 @@
  ******************************************************************************/
 package org.eclipse.tracecompass.tmf.analysis.xml.core.tests.stubs;
 
+import java.util.Collections;
 import java.util.Map;
 
 import org.eclipse.jdt.annotation.NonNull;
@@ -49,9 +50,15 @@ public class PatternSegmentFactoryStub {
      * end event for pattern segment TEST_2
      */
     public static final @NonNull ITmfEvent TEST_2_END_EVENT = new TmfEvent(null, ITmfContext.UNKNOWN_RANK, TmfTimestamp.fromNanos(10), null, null);
+    private static final String PATTERN_SEGMENT_PREFIX = "seg_";
 
     /**
      * The pattern segment TEST_2
      */
-    public static final @NonNull TmfXmlPatternSegment TEST_2 = new TmfXmlPatternSegment(TEST_2_START_EVENT.getTimestamp().getValue(), TEST_2_END_EVENT.getTimestamp().getValue(), ITmfTimestamp.NANOSECOND_SCALE, "seg_test2", TEST_2_CONTENT);
+    public static final @NonNull TmfXmlPatternSegment TEST_2 = new TmfXmlPatternSegment(TEST_2_START_EVENT.getTimestamp().getValue(), TEST_2_END_EVENT.getTimestamp().getValue(), ITmfTimestamp.NANOSECOND_SCALE, PATTERN_SEGMENT_PREFIX + "test2", TEST_2_CONTENT);
+
+    /**
+     * The pattern segment TEST_3
+     */
+    public static final @NonNull TmfXmlPatternSegment TEST_3 = new TmfXmlPatternSegment(TEST_2_START_EVENT.getTimestamp().getValue(), TEST_2_START_EVENT.getTimestamp().getValue(), ITmfTimestamp.NANOSECOND_SCALE, PATTERN_SEGMENT_PREFIX + "open", Collections.EMPTY_MAP);
 }
index e71e032e82b527f6c52804cb74516f6eab45eba6..978e6df81f16fb1eec8667be57d8ced815a2481b 100644 (file)
 <trace>
 <event timestamp="1" name="entry" source="0">
 <field name="cpu" type="int" value="0" />
+<field name="op" type="string" value="op1" />
 </event>
 <event timestamp="3" name="exit" source="0">
 <field name="cpu" type="int" value="0" />
 <field name="curState" type="string" value="GOOD" />
+<field name="op" type="string" value="op1" />
 </event>
 <event timestamp="5" name="entry" source="0">
 <field name="cpu" type="int" value="0" />
+<field name="op" type="string" value="op1" />
 </event>
 <event timestamp="7" name="exit" source="0">
 <field name="cpu" type="int" value="0" />
 <field name="curState" type="string" value="BAD" />
+<field name="op" type="string" value="op1" />
 </event>
 </trace>
\ No newline at end of file
index 498875ad6c15ba6f10f08cc59d614b6e1c422d97..364c3ade6c715e210f884260e00b7b4fe2fd16dd 100644 (file)
 * http://www.eclipse.org/legal/epl-v10.html
 *************************************************************************** -->
 <pattern version="0" id="syscall.analysis">
+       <mappingGroup id="group">
+               <entry>
+                       <stateValue type="int" value="1" />
+                       <stateValue type="string" value="open" />
+               </entry>
+       </mappingGroup>
        <patternHandler>
                <action id="increment_counter_consuming">
                        <stateChange>
                        </state>
                        <final id="end"/>
                </fsm>
+
+               <action id="segment_create">
+                       <segment>
+                               <segType>
+                                       <segName>
+                                               <stateValue mappingGroup="group" type="int" value="1"/>
+                                       </segName>
+                               </segType>
+                       </segment>
+               </action>
+
+               <fsm id="mapping" multiple="false">
+                       <state id="start">
+                               <transition event="entry" target="end" action="segment_create" />
+                       </state>
+                       <final id="end"/>
+               </fsm>
        </patternHandler>
 </pattern>
 </tmfxml>
\ No newline at end of file
index 72b1b090c9b8de513e2bd2c6afebe551b43442a7..08a76c4682e17dadafe614b78a389d53597af59f 100644 (file)
 
        <stateProvider id="test.xml.attributes" version="1">
 
+               <mappingGroup id="operation">
+                       <entry>
+                               <stateValue type="string" value="read only" />
+                               <stateValue type="string" value="op1" />
+                       </entry>
+               </mappingGroup>
                <!-- Test to see that state values are updated or modified depending on the requested state change -->
                <eventHandler eventName="entry">
                        <stateChange>
                                <stateAttribute type="constant" value="stack"/>
                                <stateValue stack="push" type="eventField" value="timestamp" />
                        </stateChange>
+                       <stateChange>
+                               <if>
+                                       <condition>
+                                               <field name="op"/>
+                                               <stateValue mappingGroup="operation" type="string" value="read only"/>
+                                       </condition>
+                               </if>
+                               <then>
+                                       <stateAttribute type="constant" value="mapped" />
+                                       <stateValue type="string" value="TRUE" />
+                               </then>
+                               <else>
+                                       <stateAttribute type="constant" value="mapped" />
+                                       <stateValue type="string" value="FALSE" />
+                               </else>
+                       </stateChange>
                </eventHandler>
                <eventHandler eventName="exit">
                        <stateChange>
                                        <stateValue stack="pop" type="long"/>
                                </then>
                        </stateChange>
+                       <stateChange>
+                               <if>
+                                       <condition>
+                                               <field name="op"/>
+                                               <stateValue type="string" value="read only"/>
+                                       </condition>
+                               </if>
+                               <then>
+                                       <stateAttribute type="constant" value="mapped" />
+                                       <stateValue type="string" value="TRUE" />
+                               </then>
+                               <else>
+                                       <stateAttribute type="constant" value="mapped" />
+                                       <stateValue type="string" value="FALSE" />
+                               </else>
+                       </stateChange>
                </eventHandler>
        </stateProvider>
 </tmfxml>
\ No newline at end of file
index 09d1e1a1be87619ea6e344594cdcb2fc4270fc69..cac7ff93aea37f5dc35ca0cca12a0f0994901e95 100644 (file)
@@ -199,4 +199,15 @@ public interface ITmfXmlModelFactory {
      * @return The new {@link TmfXmlPatternSegmentBuilder}
      */
     TmfXmlPatternSegmentBuilder createPatternSegmentBuilder(Element node, IXmlStateSystemContainer container);
+
+    /**
+     * Create a new pattern map entry
+     *
+     * @param node
+     *            The XML map entry element
+     * @param container
+     *            The state system container this state value handler belongs to
+     * @return The new {@link TmfXmlMapEntry}
+     */
+    TmfXmlMapEntry createMapEntry(Element node, IXmlStateSystemContainer container);
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlMapEntry.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlMapEntry.java
new file mode 100644 (file)
index 0000000..c2b162a
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * 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
+ ******************************************************************************/
+package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model;
+
+import java.util.Collections;
+
+import org.eclipse.tracecompass.common.core.NonNullUtils;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * This Class implements a map entry tree for mapping group in the XML-defined state system. A
+ * map entry is composed of two state values. The first value is a key to get the
+ * second state value.
+ *
+ * @author Jean-Christian Kouame
+ */
+public class TmfXmlMapEntry {
+    ITmfXmlStateValue fKey;
+    ITmfXmlStateValue fValue;
+
+    /**
+     * Constructor
+     *
+     * @param modelFactory
+     *            The model factory
+     * @param node
+     *            The XML element representing this {@link TmfXmlMapEntry}
+     * @param container
+     *            The state system container this {@link TmfXmlMapEntry}
+     *            belongs to
+     */
+    public TmfXmlMapEntry(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
+        NodeList nodesSV = node.getElementsByTagName(TmfXmlStrings.STATE_VALUE);
+        if (nodesSV.getLength() != 2) {
+            throw new IllegalStateException("A map entry is composed of exactly 2 statevalues. Actual value is : " + nodesSV.getLength()); //$NON-NLS-1$
+        }
+        fKey = modelFactory.createStateValue((Element) NonNullUtils.checkNotNull(nodesSV.item(0)), container, Collections.EMPTY_LIST);
+        fValue = modelFactory.createStateValue((Element) NonNullUtils.checkNotNull(nodesSV.item(1)), container, Collections.EMPTY_LIST);
+    }
+
+    /**
+     * Get the value for this entry.
+     *
+     * @return The value
+     */
+    public ITmfXmlStateValue getValue() {
+        return fValue;
+    }
+
+    /**
+     * Get the key for this value
+     *
+     * @return The key
+     */
+    public ITmfXmlStateValue getKey() {
+        return fKey;
+    }
+}
index cd74f86d4b3a2db81b3ed7a6dfd78ccc4a4ad2eb..2f0360a7bb740d9b1b11852e78b4785b60fb770d 100644 (file)
 package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model;
 
 import java.util.List;
+import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternStateProvider;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
@@ -65,6 +68,8 @@ public abstract class TmfXmlStateValue implements ITmfXmlStateValue {
 
     private final IXmlStateSystemContainer fContainer;
 
+    private final String fMappingGroup;
+
     /**
      * Different behaviors of an attribute that is to be stacked
      */
@@ -157,6 +162,8 @@ public abstract class TmfXmlStateValue implements ITmfXmlStateValue {
          */
         String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK);
         fStackType = ValueTypeStack.getTypeFromString(stack);
+
+        fMappingGroup = node.getAttribute(TmfXmlStrings.MAPPING_GROUP);
     }
 
     /**
@@ -232,7 +239,31 @@ public abstract class TmfXmlStateValue implements ITmfXmlStateValue {
 
     @Override
     public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
-        return fStateValue.getValue(event, scenarioInfo);
+        return getMappedValue(event, scenarioInfo, fStateValue.getValue(event, scenarioInfo));
+    }
+
+    private ITmfStateValue getMappedValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo, ITmfStateValue value) {
+        try {
+            Set<TmfXmlMapEntry> group = null;
+            if (fContainer instanceof XmlPatternStateProvider) {
+                group = ((XmlPatternStateProvider) fContainer).getMappingGroup(fMappingGroup);
+            } else if (fContainer instanceof XmlStateProvider) {
+                group = ((XmlStateProvider) fContainer).getMappingGroup(fMappingGroup);
+            }
+            if (group != null) {
+                for (TmfXmlMapEntry entry : group) {
+                    if (entry.getKey().getValue(event, scenarioInfo).equals(value)) {
+                        return entry.getValue().getValue(event, scenarioInfo);
+                    }
+                }
+            }
+            return value;
+        } catch (AttributeNotFoundException e) {
+            Activator.logError("Unable to map the state value"); //$NON-NLS-1$
+            // FIXME maybe we should return the raw state value instead of a
+            // null state value
+            return TmfStateValue.nullValue();
+        }
     }
 
     /**
index 085d30f912ad9d4127f2f31128be99209aa84e87..3c1b96a582dbb61f2e3de8614d962655eef44af6 100644 (file)
@@ -23,6 +23,7 @@ import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlActio
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlCondition;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlFsm;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlMapEntry;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlLocation;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlPatternEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlPatternSegmentBuilder;
@@ -131,4 +132,9 @@ public class TmfXmlReadOnlyModelFactory implements ITmfXmlModelFactory {
     public TmfXmlPatternSegmentBuilder createPatternSegmentBuilder(Element node, IXmlStateSystemContainer container) {
         return new TmfXmlPatternSegmentBuilder(this, node, container);
     }
+
+    @Override
+    public @NonNull TmfXmlMapEntry createMapEntry(@NonNull Element node, @NonNull IXmlStateSystemContainer container) {
+        return new TmfXmlMapEntry(this, node, container);
+    }
 }
index b1859e9ff765833add98ee4f90f76732f721c976..6f92a3b02dbd32dc174126470cfa07a450a873c6 100644 (file)
@@ -23,6 +23,7 @@ import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlActio
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlCondition;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlFsm;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlMapEntry;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlLocation;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlPatternEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlPatternSegmentBuilder;
@@ -131,4 +132,9 @@ public class TmfXmlReadWriteModelFactory implements ITmfXmlModelFactory {
     public TmfXmlPatternSegmentBuilder createPatternSegmentBuilder(Element node, IXmlStateSystemContainer container) {
         return new TmfXmlPatternSegmentBuilder(this, node, container);
     }
+
+    @Override
+    public @NonNull TmfXmlMapEntry createMapEntry(@NonNull Element node, @NonNull IXmlStateSystemContainer container) {
+        return new TmfXmlMapEntry(this, node, container);
+    }
 }
index 453a219155e9602952d06e569bdb8a25fb7217d0..57cf9ac3039473c313752fd63d9dec065a3dc626 100644 (file)
                <xs:anyAttribute />
        </xs:complexType>
 
+       <xs:complexType name="mappingGroup">
+               <xs:sequence>
+                       <xs:element maxOccurs="unbounded" name="entry" type="mapEntry" />
+               </xs:sequence>
+               <xs:attribute name="id" type="xs:string" use="required" />
+       </xs:complexType>
+
+       <xs:complexType name="mapEntry">
+               <xs:annotation>
+                       <xs:documentation>Define a handler for a state value. The second state value defined in the handler will be used instead of the first state one whenever it will be met.</xs:documentation></xs:annotation>
+               <xs:sequence maxOccurs="1" minOccurs="1">
+                       <xs:element maxOccurs="2" minOccurs="2" name="stateValue" type="stateValue" />
+               </xs:sequence>
+       </xs:complexType>
+
 </xs:schema>
index 6b26b446c1de986bf293dbee4bac5f9e4654403f..ee602299db3f8c61e692e61c6bd12666a0a974a8 100644 (file)
@@ -25,6 +25,9 @@
                        <xs:element maxOccurs="unbounded" minOccurs="0" name="location" type="location" >
                                <xs:annotation>
                                        <xs:documentation>Declares shortcuts to frequently used attribute/data locations. For instance, if a path to an often-used attribute is CPUs/{event.some_field}/Threads/Status, it may be a good idea to put this path in a location and then use the location name in the event handlers.</xs:documentation></xs:annotation></xs:element>
+                       <xs:element maxOccurs="unbounded" minOccurs="0" name="mappingGroup" type="mappingGroup" >
+                                               <xs:annotation>
+                                                       <xs:documentation>Define a mapping group for state values.</xs:documentation></xs:annotation></xs:element>
                        <xs:element maxOccurs="1" minOccurs="1" name="patternHandler" type="patternHandler" >
                                <xs:annotation>
                                        <xs:documentation>Describes the pattern behavior. It defines all the entities; i.e., all the transitions, actions and state machines that describe the pattern.</xs:documentation></xs:annotation></xs:element>
index b8a31bdaa9fc1f93b20e851ef79470359ddf7022..299ee8e74f481613efde2bbe128f3e989580c445 100644 (file)
@@ -28,6 +28,9 @@
                                        <xs:element maxOccurs="unbounded" minOccurs="0" name="location" type="location" >
                                                <xs:annotation>
                                                        <xs:documentation>Declare shortcuts to frequently used attribute/data locations. For instance, if a path to an often-used attribute is CPUs/{event.some_field}/Threads/Status, it may be a good idea to put this path in a location and then use the location name in the event handlers.</xs:documentation></xs:annotation></xs:element>
+                                       <xs:element maxOccurs="unbounded" minOccurs="0" name="mappingGroup" type="mappingGroup" >
+                                               <xs:annotation>
+                                                       <xs:documentation>Define a mapping for a state value. A handler describe a state value V that will be use instead of a state value S.</xs:documentation></xs:annotation></xs:element>
                                </xs:choice>
                                <xs:element maxOccurs="unbounded" minOccurs="1" name="eventHandler" type="eventHandler" >
                                        <xs:annotation>
                                </xs:restriction>
                        </xs:simpleType>
                </xs:attribute>
+               <xs:attribute name="mappingGroup" type="xs:string">
+                       <xs:annotation>
+                               <xs:documentation>Indicate which mapping group to use for this state value.</xs:documentation></xs:annotation></xs:attribute>
                <xs:attribute name="value" type="xs:string" >
                        <xs:annotation>
                                <xs:documentation>Indicate what the value is. A value should be specified only if the type is int, long, string or event_field. See the documentation on types for information on what to put for value.</xs:documentation></xs:annotation></xs:attribute>
index 3712dad1e27e762b75bbffe5fc242e68fe1a990e..b0c3c597b2e4ae66f4051c0fd52d3a69653f835c 100644 (file)
@@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.common.core.NonNullUtils;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.ITmfXmlModelFactory;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlMapEntry;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlLocation;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlPatternEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlScenarioHistoryBuilder;
@@ -52,6 +53,8 @@ public class XmlPatternStateProvider extends AbstractTmfStateProvider implements
     /** List of all Locations */
     private final @NonNull Set<@NonNull TmfXmlLocation> fLocations;
 
+    private final @NonNull Map<@NonNull String, @NonNull Set<@NonNull TmfXmlMapEntry>> fMappingGroups;
+
     /** Map for stored values */
     private final @NonNull Map<@NonNull String, @NonNull String> fStoredFields = new HashMap<>();
 
@@ -82,6 +85,7 @@ public class XmlPatternStateProvider extends AbstractTmfStateProvider implements
         Element doc = XmlUtils.getElementInFile(pathString, TmfXmlStrings.PATTERN, fStateId);
         if (doc == null) {
             fLocations = new HashSet<>();
+            fMappingGroups = new HashMap<>();
             Activator.logError("Failed to find a pattern in " + pathString); //$NON-NLS-1$
             return;
         }
@@ -115,6 +119,31 @@ public class XmlPatternStateProvider extends AbstractTmfStateProvider implements
         }
         fLocations = Collections.unmodifiableSet(locations);
 
+        /* parser for the mapping groups */
+        final @NonNull Map<@NonNull String, @NonNull Set<@NonNull TmfXmlMapEntry>> mapGroups = new HashMap<>();
+        NodeList mapNodes = doc.getElementsByTagName(TmfXmlStrings.MAPPING_GROUP);
+        for (int i = 0; i < mapNodes.getLength(); i++) {
+            Element map = (Element) mapNodes.item(i);
+            String id = map.getAttribute(TmfXmlStrings.ID);
+
+            Set<@NonNull TmfXmlMapEntry> entrySet = mapGroups.get(id);
+            if (entrySet == null) {
+                entrySet = new HashSet<>();
+                mapGroups.put(id, entrySet);
+            }
+
+            NodeList entryNodes = map.getElementsByTagName(TmfXmlStrings.ENTRY);
+            for (int j = 0; j < entryNodes.getLength(); j++) {
+                Element entryElement = (Element) entryNodes.item(j);
+                if (entryElement == null) {
+                    continue;
+                }
+                TmfXmlMapEntry entry = modelFactory.createMapEntry(entryElement, this);
+                entrySet.add(entry);
+            }
+        }
+        fMappingGroups = Collections.unmodifiableMap(mapGroups);
+
         /* parser for the event handlers */
         NodeList nodes = doc.getElementsByTagName(TmfXmlStrings.PATTERN_HANDLER);
         fHandler = modelFactory.createPatternEventHandler(NonNullUtils.checkNotNull((Element) nodes.item(0)), this);
@@ -209,4 +238,15 @@ public class XmlPatternStateProvider extends AbstractTmfStateProvider implements
     public @NonNull TmfXmlScenarioHistoryBuilder getHistoryBuilder() {
         return fHistoryBuilder;
     }
+
+    /**
+     * Get the list of state value handlers defined in this top level element
+     *
+     * @param id
+     *            The mapping group id
+     * @return The set of {@link TmfXmlMapEntry}
+     */
+    public @Nullable Set<@NonNull TmfXmlMapEntry> getMappingGroup(@NonNull String id) {
+        return fMappingGroups.get(id);
+    }
 }
\ No newline at end of file
index d8bdecb8cdb87e1ea47f14f11c9d2bb7639f96af..3912de93bd4d47c3551cba2222bcc5dae6c34116 100644 (file)
@@ -166,4 +166,6 @@ public interface TmfXmlStrings {
     String ALIAS = "alias";
     String ABANDON = "abandon";
     String CONSUMING = "consuming";
+    String MAPPING_GROUP = "mappingGroup";
+    String ENTRY = "entry";
 }
\ No newline at end of file
index 13a0a3304f833df9b39614dc3d5a5e7b2ef8950c..854217dd4f982ba4837aa8806ab9b53c2933e35b 100644 (file)
@@ -22,9 +22,11 @@ import java.util.Set;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.ITmfXmlModelFactory;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlEventHandler;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlLocation;
+import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.TmfXmlMapEntry;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model.readwrite.TmfXmlReadWriteModelFactory;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.XmlUtils;
@@ -55,6 +57,8 @@ public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlSt
     /** Map for defined values */
     private final Map<String, String> fDefinedValues = new HashMap<>();
 
+    private final @NonNull Map<@NonNull String, @NonNull Set<@NonNull TmfXmlMapEntry>> fMappingGroups;
+
     // ------------------------------------------------------------------------
     // Constructor
     // ------------------------------------------------------------------------
@@ -77,6 +81,7 @@ public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlSt
         Element doc = XmlUtils.getElementInFile(fFilePath.makeAbsolute().toOSString(), TmfXmlStrings.STATE_PROVIDER, fStateId);
         if (doc == null) {
             fLocations = new HashSet<>();
+            fMappingGroups = new HashMap<>();
             return;
         }
 
@@ -100,6 +105,31 @@ public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlSt
         }
         fLocations = Collections.unmodifiableSet(locations);
 
+        /* parser for the mapping groups */
+        final @NonNull Map<@NonNull String, @NonNull Set<@NonNull TmfXmlMapEntry>> mapGroups = new HashMap<>();
+        NodeList mapNodes = doc.getElementsByTagName(TmfXmlStrings.MAPPING_GROUP);
+        for (int i = 0; i < mapNodes.getLength(); i++) {
+            Element map = (Element) mapNodes.item(i);
+            String id = map.getAttribute(TmfXmlStrings.ID);
+
+            Set<@NonNull TmfXmlMapEntry> entrySet = mapGroups.get(id);
+            if (entrySet == null) {
+                entrySet = new HashSet<>();
+                mapGroups.put(id, entrySet);
+            }
+
+            NodeList entryNodes = map.getElementsByTagName(TmfXmlStrings.ENTRY);
+            for (int j = 0; j < entryNodes.getLength(); j++) {
+                Element entryElement = (Element) entryNodes.item(j);
+                if (entryElement == null) {
+                    continue;
+                }
+                TmfXmlMapEntry entry = modelFactory.createMapEntry(entryElement, this);
+                entrySet.add(entry);
+            }
+        }
+        fMappingGroups = Collections.unmodifiableMap(mapGroups);
+
         /* parser for the event handlers */
         childElements = XmlUtils.getChildElements(doc, TmfXmlStrings.EVENT_HANDLER);
         for (Element element : childElements) {
@@ -185,4 +215,14 @@ public class XmlStateProvider extends AbstractTmfStateProvider implements IXmlSt
         return attribute;
     }
 
+    /**
+     * Get the list of state value handlers defined in this top level element
+     *
+     * @param id
+     *            The mapping group id
+     * @return The set of {@link TmfXmlMapEntry}
+     */
+    public @Nullable Set<@NonNull TmfXmlMapEntry> getMappingGroup(@NonNull String id) {
+        return fMappingGroups.get(id);
+    }
 }
\ No newline at end of file
This page took 0.036169 seconds and 5 git commands to generate.