Added condition converters
diff --git a/plugins/org.eclipse.app4mc.amalthea.converters.200/META-INF/MANIFEST.MF b/plugins/org.eclipse.app4mc.amalthea.converters.200/META-INF/MANIFEST.MF index 483834c..d5bce9d 100644 --- a/plugins/org.eclipse.app4mc.amalthea.converters.200/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.app4mc.amalthea.converters.200/META-INF/MANIFEST.MF
@@ -14,6 +14,7 @@ org.jdom2;version="2.0.6", org.osgi.service.component.annotations;version="[1.3.0,2.0.0)";resolution:=optional Bundle-ActivationPolicy: lazy -Service-Component: OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.SchedulerConverter.xml, +Service-Component: OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter.xml, + OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.SchedulerConverter.xml, OSGI-INF/org.eclipse.app4mc.amalthea.converters200.utils.SchedulerCache.xml
diff --git a/plugins/org.eclipse.app4mc.amalthea.converters.200/OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter.xml b/plugins/org.eclipse.app4mc.amalthea.converters.200/OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter.xml new file mode 100644 index 0000000..f42bf86 --- /dev/null +++ b/plugins/org.eclipse.app4mc.amalthea.converters.200/OSGI-INF/org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" activate="activate" name="org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter"> + <property name="input_model_version" value="1.2.0"/> + <property name="output_model_version" value="2.0.0"/> + <service> + <provide interface="org.eclipse.app4mc.amalthea.converters.common.base.IConverter"/> + </service> + <reference cardinality="1..1" field="logger" interface="org.eclipse.app4mc.util.sessionlog.SessionLogger" name="logger"/> + <implementation class="org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter"/> +</scr:component> \ No newline at end of file
diff --git a/plugins/org.eclipse.app4mc.amalthea.converters.200/src/org/eclipse/app4mc/amalthea/converters200/impl/ConditionConverter.java b/plugins/org.eclipse.app4mc.amalthea.converters.200/src/org/eclipse/app4mc/amalthea/converters200/impl/ConditionConverter.java new file mode 100644 index 0000000..b4d36cc --- /dev/null +++ b/plugins/org.eclipse.app4mc.amalthea.converters.200/src/org/eclipse/app4mc/amalthea/converters200/impl/ConditionConverter.java
@@ -0,0 +1,129 @@ +/********************************************************************************* + * Copyright (c) 2020, 2021 Robert Bosch GmbH and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial API and implementation + ******************************************************************************** + */ + +package org.eclipse.app4mc.amalthea.converters200.impl; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import org.eclipse.app4mc.amalthea.converters.common.ServiceConstants; +import org.eclipse.app4mc.amalthea.converters.common.base.ICache; +import org.eclipse.app4mc.amalthea.converters.common.base.IConverter; +import org.eclipse.app4mc.amalthea.converters.common.converter.AbstractConverter; +import org.eclipse.app4mc.amalthea.converters.common.utils.AmaltheaNamespaceRegistry; +import org.eclipse.app4mc.amalthea.converters.common.utils.HelperUtil; +import org.eclipse.app4mc.util.sessionlog.SessionLogger; +import org.jdom2.Attribute; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.Namespace; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +@Component( + property = { + ServiceConstants.INPUT_MODEL_VERSION_PROPERTY + "=1.2.0", + ServiceConstants.OUTPUT_MODEL_VERSION_PROPERTY + "=2.0.0" + }, + service = IConverter.class) + +public class ConditionConverter extends AbstractConverter { + + @Reference + SessionLogger logger; + + @Override + @Activate + protected void activate(Map<String, Object> properties) { + super.activate(properties); + } + + @Override + public void convert(File targetFile, Map<File, Document> fileDocumentMapping, List<ICache> caches) { + logger.info("Migration from {0} to {1} : Executing EventModel converter for model file : {2}", + getInputModelVersion(), getOutputModelVersion(), targetFile.getName()); + + basicConvert(targetFile, fileDocumentMapping); + } + + private void basicConvert(File file, Map<File, Document> map) { + // get the components with interfaces + final Document document = map.get(file); + if (document == null) { + return; + } + + final Element rootElement = document.getRootElement(); + updateConditions(rootElement); + updateWhileLoopConditions(rootElement); + } + + private void updateConditions(Element rootElement) { + final Namespace am = AmaltheaNamespaceRegistry.getNamespace(getInputModelVersion(), "am"); + final Namespace xsi = AmaltheaNamespaceRegistry.getGenericNamespace("xsi"); + + final StringBuilder xpathBuilder = new StringBuilder(); + xpathBuilder.append("./swModel/runnables/executionCondition/entries"); + xpathBuilder.append("|"); + xpathBuilder.append("./stimuliModel/stimuli/executionCondition/entries"); + + final List<Element> entries = HelperUtil.getXpathResult(rootElement, xpathBuilder.toString(), Element.class, am, xsi); + + if (entries == null) { + return; + } + + // Change type ModeConditionConjunction to ConditionConjunction + + for (Element entry : entries) { + Attribute typeAttr = entry.getAttribute("type", xsi); + if ("am:ModeConditionConjunction".equals(typeAttr.getValue())) { + typeAttr.setValue("am:ConditionConjunction"); + } + } + } + + private void updateWhileLoopConditions(Element rootElement) { + final Namespace am = AmaltheaNamespaceRegistry.getNamespace(getInputModelVersion(), "am"); + final Namespace xsi = AmaltheaNamespaceRegistry.getGenericNamespace("xsi"); + + final StringBuilder xpathBuilder = new StringBuilder(); + xpathBuilder.append("./swModel/tasks/activityGraph/items//condition/entries"); + xpathBuilder.append("|"); + xpathBuilder.append("./swModel/isrs/activityGraph/items//condition/entries"); + xpathBuilder.append("|"); + xpathBuilder.append("./swModel/runnables/activityGraph/items//condition/entries"); + final List<Element> entries = HelperUtil.getXpathResult(rootElement, xpathBuilder.toString(), Element.class, am, xsi); + + if (entries == null) { + return; + } + + // Change type ModeConditionConjunction to ConditionConjunction + + for (Element entry : entries) { + Attribute typeAttr = entry.getAttribute("type", xsi); + if ("am:ModeConditionConjunction".equals(typeAttr.getValue())) { + Element condition = entry.getParentElement(); + Element item = condition.getParentElement(); + if ("am:WhileLoop".equals(item.getAttributeValue("type", xsi))) { + typeAttr.setValue("am:ConditionConjunction"); + } + } + } + } + +}
diff --git a/tests/org.eclipse.app4mc.amalthea.converters.200.tests/TestModels/input/conditions/conditions.amxmi b/tests/org.eclipse.app4mc.amalthea.converters.200.tests/TestModels/input/conditions/conditions.amxmi new file mode 100644 index 0000000..c45d286 --- /dev/null +++ b/tests/org.eclipse.app4mc.amalthea.converters.200.tests/TestModels/input/conditions/conditions.amxmi
@@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<am:Amalthea xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:am="http://app4mc.eclipse.org/amalthea/1.2.0"> + <swModel> + <tasks xmi:id="no-name?type=Task" name="" multipleTaskActivationLimit="0"> + <activityGraph> + <items xsi:type="am:WhileLoop"> + <condition> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lot {}" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="42" relation="NOT_EQUAL"/> + </entries> + </condition> + </items> + <items xsi:type="am:Group" name="" ordered="true" interruptible="true"> + <items xsi:type="am:WhileLoop"> + <condition> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lot {}" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="42" relation="NOT_EQUAL"/> + </entries> + </condition> + </items> + <items xsi:type="am:ModeSwitch"> + <entries name=""> + <condition> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lot {}" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="42" relation="NOT_EQUAL"/> + </entries> + </condition> + </entries> + </items> + </items> + </activityGraph> + </tasks> + <runnables xmi:id="no-name?type=Runnable" name="" callback="false" service="false"> + <activityGraph> + <items xsi:type="am:WhileLoop"> + <condition> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lot {}" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="42" relation="NOT_EQUAL"/> + </entries> + </condition> + </items> + <items xsi:type="am:ModeSwitch"> + <entries name=""> + <condition> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lot {}" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="42" relation="NOT_EQUAL"/> + </entries> + </condition> + </entries> + </items> + </activityGraph> + <executionCondition> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="4711" relation="LESS_THAN"/> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="one_of?type=ModeLabel" value="lit []" relation="NOT_EQUAL"/> + <entries xsi:type="am:ModeLabelCondition" relation="NOT_EQUAL" label1="number?type=ModeLabel" label2="one_of?type=ModeLabel"/> + </entries> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeLabelCondition" relation="EQUAL" label1="number?type=ModeLabel" label2="number?type=ModeLabel"/> + </entries> + </executionCondition> + </runnables> + <modes xsi:type="am:NumericMode" xmi:id="Counter+%25_%C2%A7?type=NumericMode" name="Counter %_§"/> + <modes xsi:type="am:EnumMode" xmi:id="Selector+%2B+%3C%3E?type=EnumMode" name="Selector + <>"> + <literals xmi:id="Selector+%2B+%3C%3E/lit+%28%29?type=ModeLiteral" name="lit ()"/> + <literals xmi:id="Selector+%2B+%3C%3E/lit+%5B%5D?type=ModeLiteral" name="lit []"/> + <literals xmi:id="Selector+%2B+%3C%3E/lot+%7B%7D?type=ModeLiteral" name="lot {}"/> + </modes> + <modeLabels xmi:id="one_of?type=ModeLabel" name="one_of" mode="Selector+%2B+%3C%3E?type=EnumMode" initialValue="lit []"/> + <modeLabels xmi:id="number?type=ModeLabel" name="number" mode="Counter+%25_%C2%A7?type=NumericMode" initialValue="5"/> + </swModel> + <stimuliModel> + <stimuli xsi:type="am:PeriodicStimulus" xmi:id="Periodic+10ms?type=PeriodicStimulus" name="Periodic 10ms"> + <executionCondition> + <entries xsi:type="am:ModeConditionConjunction"> + <entries xsi:type="am:ModeValueCondition" label="number?type=ModeLabel" value="-45" relation="GREATER_THAN"/> + </entries> + </executionCondition> + </stimuli> + </stimuliModel> +</am:Amalthea>
diff --git a/tests/org.eclipse.app4mc.amalthea.converters.200.tests/src/org/eclipse/app4mc/amalthea/converters200/tests/ConditionConverterTest.java b/tests/org.eclipse.app4mc.amalthea.converters.200.tests/src/org/eclipse/app4mc/amalthea/converters200/tests/ConditionConverterTest.java new file mode 100644 index 0000000..9f8c063 --- /dev/null +++ b/tests/org.eclipse.app4mc.amalthea.converters.200.tests/src/org/eclipse/app4mc/amalthea/converters200/tests/ConditionConverterTest.java
@@ -0,0 +1,53 @@ +/********************************************************************************* + * Copyright (c) 2021 Robert Bosch GmbH and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial API and implementation + ******************************************************************************** + */ + +package org.eclipse.app4mc.amalthea.converters200.tests; + +import java.util.Arrays; +import java.util.Collection; + +import org.eclipse.app4mc.amalthea.converters.common.converter.NamespaceConverter; +import org.eclipse.app4mc.amalthea.converters200.impl.ConditionConverter; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.junit.runners.Parameterized; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@RunWith(Parameterized.class) +public class ConditionConverterTest extends Abstract200ConverterTest { + + @Parameterized.Parameters(name = "{index}: Test file: {0}") + public static Collection<Object[]> getTestData() { + + return Arrays.asList(new Object[][] { { "/conditions/conditions.amxmi", true } }); + } + + public ConditionConverterTest(final String xmlFileRelativeLocation, final boolean canExecuteTestCase) { + super(canExecuteTestCase, xmlFileRelativeLocation); + } + + @Test + public void testConversion() { + super.testConversion(NamespaceConverter.class, ConditionConverter.class); + } + + @Override + @Test + public void verification() { + super.verification(); + } + +}