diff options
9 files changed, 188 insertions, 0 deletions
diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/.gitignore b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/.gitignore new file mode 100644 index 000000000..e3db875ae --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/.gitignore @@ -0,0 +1 @@ +/Tree2List.atl.xmi diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Lib4MMTree.atl b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Lib4MMTree.atl new file mode 100644 index 000000000..03455deb1 --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Lib4MMTree.atl @@ -0,0 +1,38 @@ +-- @name Lib for MMTree +-- @version 1.0 +-- @domains +-- @authors Cyril Faure +-- @date 01/06/2007 +-- @description this lib contains helpers usefull for MMTree +-- @path MMTree=/org.eclipse.qvtd.atl.tests/models/tree2list/MMTree.ecore + +library Lib4MMTree; + +-- This helper returns true if the current tree element is the tree root +helper context MMTree!Node def : isTreeNodeRoot() : Boolean = + self.refImmediateComposite().oclIsUndefined(); + -- refImmediateComposite() is a reflective operation that returns the immediate composite (e.g. the immediate container) of self + -- So if there is no immediate composite then the current node is the root (we suppose in our example that there is only one root). + +-- We retrieve all the tree elements via a DFS starting from a given node +helper context MMTree!Node def : getAllChildren () : OrderedSet(MMTree!TreeElement) = + self.children->iterate( child ; elements : OrderedSet(MMTree!TreeElement) = + OrderedSet{} | + if child.oclIsTypeOf(MMTree!Node) then + elements.union(child.getAllChildren()) -- NODE : recursive call + else + elements.append(child) -- LEAF + endif + ) + ; + +-- This function sorts the leaves retrieved via the DFS +-- according to their size and to their position in the tree +helper context MMTree!Node def : getLeavesInOrder() : OrderedSet (MMTree!Leaf) = + let leavesList : OrderedSet (MMTree!Leaf) = + self.getAllChildren ()->select(currChild | currChild.oclIsTypeOf(MMTree!Leaf)) + in + leavesList->select(leaf | leaf.size = #big) + ->union(leavesList->select(leaf | leaf.size = #medium)) + ->union(leavesList->select(leaf | leaf.size = #small)) + ; diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMElementList.ecore b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMElementList.ecore new file mode 100644 index 000000000..957cfdf6d --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMElementList.ecore @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="MMElementList"
+ nsURI="platform:/resource/Tree2List/metamodels/MMElementList.ecore" nsPrefix="elmLst">
+ <eClassifiers xsi:type="ecore:EClass" name="AbstractElement" abstract="true">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="RootElement" eSuperTypes="#//AbstractElement">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="elements" upperBound="-1"
+ eType="#//CommonElement" containment="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="CommonElement" eSuperTypes="#//AbstractElement"/>
+</ecore:EPackage>
diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMTree.ecore b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMTree.ecore new file mode 100644 index 000000000..b3b1f53d5 --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/MMTree.ecore @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="MMTree"
+ nsURI="platform:/resource/Tree2List/metamodels/MMTree.ecore" nsPrefix="tree">
+ <eClassifiers xsi:type="ecore:EClass" name="TreeElement" abstract="true">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Node" eSuperTypes="#//TreeElement">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
+ eType="#//TreeElement" containment="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Leaf" eSuperTypes="#//TreeElement">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="size" eType="#//LeafSize"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EEnum" name="LeafSize">
+ <eLiterals name="small"/>
+ <eLiterals name="medium" value="1"/>
+ <eLiterals name="big" value="2"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List.atl b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List.atl new file mode 100644 index 000000000..d781595a1 --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List.atl @@ -0,0 +1,34 @@ +-- @name Tree structure to List structure +-- @version 1.0 +-- @domains +-- @authors Cyril Faure +-- @date 01/06/2007 +-- @description "toy example" of model transformation usually made with a DFS (Depth First Search) imperative algorithms +-- @see http://en.wikipedia.org/wiki/Depth-first_search +-- @path MMTree=/org.eclipse.qvtd.atl.tests/models/tree2list/MMTree.ecore +-- @path MMElementList=/org.eclipse.qvtd.atl.tests/models/tree2list/MMElementList.ecore + +module Tree2List; +create elmList : MMElementList from aTree : MMTree; + +uses Lib4MMTree; + +-- we want to process the tree via DFS and create an ordered list containing : +-- all big leafs, then all medium leafs, then all small leafs. We add the +-- constraint we want all three "sublists" to be ordered on the DFS traversal order +-- Note : the nodes (other than the tree root) are not kept in the destination model + +-- The transformation is done with only one matched rule. For each element of its elements reference, we create a MMElementList!CommonElement. +-- Each element of this list is computed via a distinct keyword which creates a CommonElement for each Leaf of a list we compute via an helper. +rule TreeNodeRoot2RootElement { + from -- should be unique + rt : MMTree!Node (rt.isTreeNodeRoot()) + to + lstRt : MMElementList!RootElement ( + name <- rt.name, + elements <- elmLst + ), + elmLst : distinct MMElementList!CommonElement foreach(leaf in rt.getLeavesInOrder())( + name <- leaf.name + ) +}
\ No newline at end of file diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List_usingATLResolveAlgorithm.atl b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List_usingATLResolveAlgorithm.atl new file mode 100644 index 000000000..3aa4650ba --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/Tree2List_usingATLResolveAlgorithm.atl @@ -0,0 +1,42 @@ +-- @name Tree structure to List structure (using ATL Resolve Algorithm) +-- @version 1.0 +-- @domains +-- @authors Cyril Faure, Freddy Allilaire +-- @date 01/07/2007 +-- @description "toy example" of model transformation usually made with a DFS (Depth First Search) imperative algorithms +-- @see http://en.wikipedia.org/wiki/Depth-first_search +-- @path MMTree=/Tree2List/metamodels/MMTree.ecore +-- @path MMElementList=/Tree2List/metamodels/MMElementList.ecore + +module Tree2List; +create elmList : MMElementList from aTree : MMTree; + +uses Lib4MMTree; + +-- we want to process the tree via DFS and create an ordered list containing : +-- all big leafs, then all medium leafs, then all small leafs. We add the +-- constraint we want all three "sublists" to be ordered on the DFS traversal order +-- Note : the nodes (other than the tree root) are not kept in the destination model + +-- Rule to transform "Tree Node Root" in "Element List Root" +rule TreeNodeRoot2RootElement { + from -- should be unique + rt : MMTree!Node (rt.isTreeNodeRoot()) + to + lstRt : MMElementList!RootElement ( + name <- rt.name, + elements <- rt.getLeavesInOrder() -- reference copy, + -- Correspondance "Leaf to CommonElement" will be made thanks to a traceability link. + -- Traceability links record correspondences between source and target elements established during transformation execution. + ) +} + +-- Rule to transform Leaf to CommonElement +rule Leaf2CommonElement { + from + s : MMTree!Leaf + to + t : MMElementList!CommonElement( + name <- s.name + ) +}
\ No newline at end of file diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/aTreeNode.xmi b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/aTreeNode.xmi new file mode 100644 index 000000000..637cd7269 --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/aTreeNode.xmi @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="ASCII"?> +<tree:Node xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tree="platform:/resource/Tree2List/metamodels/MMTree.ecore" name="T3h main node"> + <children xsi:type="tree:Node" name="another node"> + <children xsi:type="tree:Leaf" name="SUB MEDIUM azdzere" size="medium"/> + <children xsi:type="tree:Leaf" name="SUB SMALL fdfsdf"/> + <children xsi:type="tree:Leaf" name="SUB SMALL aaaaaaa"/> + </children> + <children xsi:type="tree:Leaf" name="MEDIUM a leaf in main node" size="medium"/> + <children xsi:type="tree:Leaf" name="BIG another leaf in main node" size="big"/> + <children xsi:type="tree:Leaf" name="SMALL leaf in main node"/> + <children xsi:type="tree:Node" name="last node"> + <children xsi:type="tree:Leaf" name="SUB2 SMALL2"/> + <children xsi:type="tree:Leaf" name="SUB2 MEDIUM" size="medium"/> + <children xsi:type="tree:Leaf" name="SUB2 SMALL"/> + </children> +</tree:Node> diff --git a/tests/org.eclipse.qvtd.atl.tests/models/tree2list/elmLst.xmi b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/elmLst.xmi new file mode 100644 index 000000000..ec6e9d74a --- /dev/null +++ b/tests/org.eclipse.qvtd.atl.tests/models/tree2list/elmLst.xmi @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="ISO-8859-1"?>
+<elmLst:RootElement xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:elmLst="platform:/resource/Tree2List/metamodels/MMElementList.ecore" name="T3h main node">
+ <elements name="BIG another leaf in main node"/>
+ <elements name="SUB MEDIUM azdzere"/>
+ <elements name="MEDIUM a leaf in main node"/>
+ <elements name="SUB2 MEDIUM"/>
+ <elements name="SUB SMALL fdfsdf"/>
+ <elements name="SUB SMALL aaaaaaa"/>
+ <elements name="SMALL leaf in main node"/>
+ <elements name="SUB2 SMALL2"/>
+ <elements name="SUB2 SMALL"/>
+</elmLst:RootElement>
diff --git a/tests/org.eclipse.qvtd.atl.tests/src/org/eclipse/qvtd/atl/tests/ATLExampleTests.java b/tests/org.eclipse.qvtd.atl.tests/src/org/eclipse/qvtd/atl/tests/ATLExampleTests.java index eed71f008..da7095a2f 100644 --- a/tests/org.eclipse.qvtd.atl.tests/src/org/eclipse/qvtd/atl/tests/ATLExampleTests.java +++ b/tests/org.eclipse.qvtd.atl.tests/src/org/eclipse/qvtd/atl/tests/ATLExampleTests.java @@ -153,6 +153,16 @@ public class ATLExampleTests extends LoadTestCase doATLExampleTest_CG("Families2Persons", getModelsURI("families2persons/Families2Persons.atl")); } + @Test + public void testATL2QVTr_Tree2List_CG() throws Exception { + // AbstractTransformer.EXCEPTIONS.setState(true); + // AbstractTransformer.INVOCATIONS.setState(true); + // PivotStandaloneSetup.init(); + QVTimperativeLibrary.install(); + QVTrelationToStringVisitor.FACTORY.getClass(); + doATLExampleTest_CG(URI.createPlatformResourceURI("org.eclipse.qvtd.atl.tests/models/tree2list", true), "Tree2List"); + } + /* @Test public void testATLExample_Families2PersonsMini_CG() throws Exception { AbstractTransformer.EXCEPTIONS.setState(true); |