Skip to content

Exercise 2

The main task of this exercise is to convert selective transition elements (of the flowchart model) into P tags (in HTML).

Input Model

Source model representing the flowchart instance (in XMI format) conforming to the flowchart domain is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<flowchart:Flowchart xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flowchart="flowchart" xmi:id="_9mLMwDY6EeOwt8pm-kjW_Q" name="Wakeup">
  <nodes xsi:type="flowchart:Action" xmi:id="_9mLMwTY6EeOwt8pm-kjW_Q" name="Wake up" outgoing="_9mLMxjY6EeOwt8pm-kjW_Q" incoming="_9mLMyDY6EeOwt8pm-kjW_Q _9mLz0TY6EeOwt8pm-kjW_Q"/>
  <nodes xsi:type="flowchart:Decision" xmi:id="_9mLMwjY6EeOwt8pm-kjW_Q" name="Is it really too early?" outgoing="_9mLMxzY6EeOwt8pm-kjW_Q _9mLz0DY6EeOwt8pm-kjW_Q" incoming="_9mLMxjY6EeOwt8pm-kjW_Q"/>
  <nodes xsi:type="flowchart:Action" xmi:id="_9mLMwzY6EeOwt8pm-kjW_Q" name="Sleep" outgoing="_9mLMyDY6EeOwt8pm-kjW_Q" incoming="_9mLMxzY6EeOwt8pm-kjW_Q"/>
  <nodes xsi:type="flowchart:Action" xmi:id="_9mLMxDY6EeOwt8pm-kjW_Q" name="Get up" incoming="_9mLz0DY6EeOwt8pm-kjW_Q"/>
  <nodes xsi:type="flowchart:Action" xmi:id="_9mLMxTY6EeOwt8pm-kjW_Q" name="begin" outgoing="_9mLz0TY6EeOwt8pm-kjW_Q"/>
  <transitions xmi:id="_9mLMxjY6EeOwt8pm-kjW_Q" name="" source="_9mLMwTY6EeOwt8pm-kjW_Q" target="_9mLMwjY6EeOwt8pm-kjW_Q"/>
  <transitions xmi:id="_9mLMxzY6EeOwt8pm-kjW_Q" name="Yes" source="_9mLMwjY6EeOwt8pm-kjW_Q" target="_9mLMwzY6EeOwt8pm-kjW_Q"/>
  <transitions xmi:id="_9mLMyDY6EeOwt8pm-kjW_Q" name="Some Time Passes" source="_9mLMwzY6EeOwt8pm-kjW_Q" target="_9mLMwTY6EeOwt8pm-kjW_Q"/>
  <transitions xmi:id="_9mLz0DY6EeOwt8pm-kjW_Q" name="No" source="_9mLMwjY6EeOwt8pm-kjW_Q" target="_9mLMxDY6EeOwt8pm-kjW_Q"/>
  <transitions xmi:id="_9mLz0TY6EeOwt8pm-kjW_Q" name="start" source="_9mLMxTY6EeOwt8pm-kjW_Q" target="_9mLMwTY6EeOwt8pm-kjW_Q"/>
</flowchart:Flowchart>

Expected Output Model

<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns="HTML">
  <P value="Node: Is it really too early? --> Transition: Yes"/>
  <P value="Node: Is it really too early? --> Transition: No"/>
</xmi:XMI>

Task

You must create a filter block that checks if the name of the source node of the transition object β€˜t’ is β€œIs it really too early?”. Only those transitions that pass this check are filtered through to be generated as output elements in the target model.

Base Transformation

Transformation class containing the MT definition. All rules are defined in the ruleStore().

package flowchartToHtmlExamples
import static yamtl.dsl.Rule.*
import org.eclipse.emf.ecore.EPackage
import yamtl.core.YAMTLModule
import yamtl.groovy.YAMTLGroovyExtensions
import yamtl.groovy.YAMTLGroovyExtensions_dynamicEMF

class Example2 extends YAMTLModule {
    public Example2(EPackage flowchartPk, EPackage htmlPk) {
        YAMTLGroovyExtensions_dynamicEMF.init(this)

        header().in("in", flowchartPk).out("out", htmlPk)

        ruleStore([
            //TODO: Update the rule with a .filter{} block
            rule('SelectedTransitions2Text')
                .in("t", flowchartPk.Transition)
                .out("p", htmlPk.P, {
                    p.value = "Node: ${t.source.name} --> Transition: ${t.name}".toString()
                })
        ])

    }
}

Test Script

This is a separate Groovy class that loads, executes and tests the model transformation. In particular, the source and target metamodels are loaded and passed to the transformation class. Then, the input model is loaded into this class and executed. Thus, creating an output model which is stored and tested for correctness.

package flowchartToHtmlExamples
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.Test
import yamtl.core.YAMTLModule
import yamtl.groovy.YAMTLGroovyExtensions
import yamtl.utils.EMFComparator

class Example2Test extends YAMTLModule {
    final BASE_PATH = 'model'

    @Test
    def void testExample2() {
        // model transformation execution
        def srcRes = YAMTLModule.preloadMetamodel(BASE_PATH + '/flowchart.ecore')
        def tgtRes = YAMTLModule.preloadMetamodel(BASE_PATH + '/html.ecore')

        def xform = new Example2(srcRes.contents[0], tgtRes.contents[0])
        YAMTLGroovyExtensions.init(this)
        xform.loadInputModels(['in': BASE_PATH + '/wakeup.xmi'])
        xform.execute()
        xform.saveOutputModels(['out': BASE_PATH + '/example2Output.xmi'])

        // test assertion
        def actualModel = xform.getOutputModel('out')
        EMFComparator comparator = new EMFComparator();

        // Load the expected model using the identical output metamodel from the transformation.
        // Essentially, use the same in-memory metamodel.
        xform.loadMetamodelResource(tgtRes)
        def expectedResource = xform.loadModel(BASE_PATH + '/example2ExpectedOutput.xmi', false)
        def assertionResult =  comparator.equals(expectedResource.getContents(), actualModel.getContents())
        assertTrue(assertionResult);
    }
}

Last update: October 13, 2023