From 55df971700e93994a51abda884eff6ef21939afc Mon Sep 17 00:00:00 2001 From: Jean-Christian Kouame Date: Wed, 13 Jul 2016 15:27:48 -0400 Subject: [PATCH] tmf.xml: Add mapping group to XML description 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 Reviewed-on: https://git.eclipse.org/r/76780 Reviewed-by: Hudson CI Reviewed-by: Bernd Hufmann Tested-by: Bernd Hufmann --- .../core/tests/model/TmfStateValueTest.java | 26 ++++++ .../xml/core/tests/model/XmlSegmentTest.java | 88 +++++++++++++++++++ .../stubs/PatternSegmentFactoryStub.java | 9 +- .../test_traces/testTrace4.xml | 4 + .../test_valid/test_consuming_fsm.xml | 23 +++++ .../test_valid/test_state_values.xml | 38 ++++++++ .../xml/core/model/ITmfXmlModelFactory.java | 11 +++ .../xml/core/model/TmfXmlMapEntry.java | 67 ++++++++++++++ .../xml/core/model/TmfXmlStateValue.java | 33 ++++++- .../readonly/TmfXmlReadOnlyModelFactory.java | 6 ++ .../TmfXmlReadWriteModelFactory.java | 6 ++ .../analysis/xml/core/module/xmlCommon.xsd | 15 ++++ .../core/module/xmlPatternStateProvider.xsd | 3 + .../xml/core/module/xmlStateProvider.xsd | 6 ++ .../XmlPatternStateProvider.java | 40 +++++++++ .../xml/core/stateprovider/TmfXmlStrings.java | 2 + .../core/stateprovider/XmlStateProvider.java | 40 +++++++++ 17 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/XmlSegmentTest.java create mode 100644 tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlMapEntry.java diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java index e9a53fae5d..3c6cacb04a 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/TmfStateValueTest.java @@ -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 index 0000000000..a7bfb04ec6 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/src/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/model/XmlSegmentTest.java @@ -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); + } +} + diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/stubs/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stubs/PatternSegmentFactoryStub.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/stubs/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stubs/PatternSegmentFactoryStub.java index d7cc8e39d6..741f3a098d 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/stubs/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stubs/PatternSegmentFactoryStub.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/stubs/org/eclipse/tracecompass/tmf/analysis/xml/core/tests/stubs/PatternSegmentFactoryStub.java @@ -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); } diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_traces/testTrace4.xml b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_traces/testTrace4.xml index e71e032e82..978e6df81f 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_traces/testTrace4.xml +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_traces/testTrace4.xml @@ -12,16 +12,20 @@ + + + + \ No newline at end of file diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_consuming_fsm.xml b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_consuming_fsm.xml index 498875ad6c..364c3ade6c 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_consuming_fsm.xml +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_consuming_fsm.xml @@ -10,6 +10,12 @@ * http://www.eclipse.org/legal/epl-v10.html *************************************************************************** --> + + + + + + @@ -44,6 +50,23 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml index 72b1b090c9..08a76c4682 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core.tests/test_xml_files/test_valid/test_state_values.xml @@ -15,6 +15,12 @@ + + + + + + @@ -31,6 +37,22 @@ + + + + + + + + + + + + + + + + @@ -62,6 +84,22 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java index 09d1e1a1be..cac7ff93ae 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/ITmfXmlModelFactory.java @@ -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 index 0000000000..c2b162ae75 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlMapEntry.java @@ -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; + } +} diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlStateValue.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlStateValue.java index cd74f86d4b..2f0360a7bb 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlStateValue.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/TmfXmlStateValue.java @@ -13,12 +13,15 @@ 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 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(); + } } /** diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java index 085d30f912..3c1b96a582 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readonly/TmfXmlReadOnlyModelFactory.java @@ -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); + } } diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java index b1859e9ff7..6f92a3b02d 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/model/readwrite/TmfXmlReadWriteModelFactory.java @@ -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); + } } diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlCommon.xsd b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlCommon.xsd index 453a219155..57cf9ac303 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlCommon.xsd +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlCommon.xsd @@ -41,4 +41,19 @@ + + + + + + + + + + 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. + + + + + diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlPatternStateProvider.xsd b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlPatternStateProvider.xsd index 6b26b446c1..ee602299db 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlPatternStateProvider.xsd +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlPatternStateProvider.xsd @@ -25,6 +25,9 @@ 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. + + + Define a mapping group for state values. Describes the pattern behavior. It defines all the entities; i.e., all the transitions, actions and state machines that describe the pattern. diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlStateProvider.xsd b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlStateProvider.xsd index b8a31bdaa9..299ee8e74f 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlStateProvider.xsd +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/module/xmlStateProvider.xsd @@ -28,6 +28,9 @@ 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. + + + Define a mapping for a state value. A handler describe a state value V that will be use instead of a state value S. @@ -324,6 +327,9 @@ + + + Indicate which mapping group to use for this state value. 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. diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java index 3712dad1e2..b0c3c597b2 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/pattern/stateprovider/XmlPatternStateProvider.java @@ -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 diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java index d8bdecb8cd..3912de93bd 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/TmfXmlStrings.java @@ -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 diff --git a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java index 13a0a3304f..854217dd4f 100644 --- a/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java +++ b/tmf/org.eclipse.tracecompass.tmf.analysis.xml.core/src/org/eclipse/tracecompass/internal/tmf/analysis/xml/core/stateprovider/XmlStateProvider.java @@ -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 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 -- 2.34.1