Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 315153

Summary: Dict only partially saved in .qvtotrace
Product: [Modeling] QVTo Reporter: Nicolas Rouquette <nicolas.f.rouquette>
Component: EngineAssignee: Project Inbox <mmt-qvt.operational-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: christopher.gerking, serg.boyko2011
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
qvto.ecore2uml transformation modified to pass a dictionary argument.
none
result of the transformation for the family.ecore example
none
trace showing that QVT Dict values are only partially saved in .qvtotrace files.
none
Patch for QVTo's ModuleInstanceFactory none

Description Nicolas Rouquette CLA 2010-05-31 20:27:44 EDT
I have been using QVTo quite extensively to automate some of the most error-prone steps involved in producing the normative artifacts for OMG's UML 2.4.
In that context, I've been using QVT's dictionary types to track various correspondences. 
However, I have had to work around a limitation due to OCL / QVT in that OCL doesn't have support for QVT's dictionary type. 
For example, the following is syntactically correct but cannot be launched:

transformation Ecore2UML(in eModel : ECORE, out umlModel : UML);

// syntax is OK; at launch this produces an error: "OCL collection kind (Collection) is not implemented in the java collection factory."
property table : Dictionary(ecore::EClassifier, UML::Classifier) = Dict{}; 

main() {
	...
}

To work around this limitation, I've passed dictionary values as parameters to queries, helpers & mapping rules.
Here's an example of this in a modified version of the qvto.ecore2uml example:

mapping EClass::toClass(inout table : Dict(ecore::EClassifier, UML::Classifier)) : Class inherits ENamedElement::toNamedElement when { not self.interface } {
	superClass := self.eSuperTypes->map toClass(table);
	interfaceRealization := self.eSuperTypes[interface]->xcollect( i |
		object InterfaceRealization {
			contract := i.map toInterface(table);
		}
	);

	isAbstract := self._abstract;
	ownedAttribute += self.eStructuralFeatures->map toProperty(table);
	
	table->put(self, result);
}

After the transformation finishes, the family.uml.qvtotrace contains only the values of the dictionary, not the key/value pairs; e.g:

  <traceRecords>
    <mappingOperation name="toClass" package="Ecore2UML" module="Ecore2UML">
      <runtimeMappingOperation href="platform:/resource/qvto.ecore2uml/transforms/Ecore2UML.qvtox#//toClass"/>
    </mappingOperation>
    <context>
      <context name="self" type="EClass">
        <value>
          <modelElement href="platform:/resource/qvto.ecore2uml/in/family.ecore#//Family"/>
        </value>
      </context>
    </context>
    <parameters>
      <parameters kind="INOUT" name="table" type="Dictionary(EClassifier, Classifier)">
        <value collectionType="OclCollection">
          <collection>
            <modelElement href="platform:/resource/qvto.ecore2uml/out/family.uml#_QV12T20REd-a2rPGu1hnsg"/>
          </collection>
          <collection>
            <modelElement href="platform:/resource/qvto.ecore2uml/out/family.uml#_QV12aG0REd-a2rPGu1hnsg"/>
          </collection>
          <collection>
            <modelElement href="platform:/resource/qvto.ecore2uml/out/family.uml#_QV12VG0REd-a2rPGu1hnsg"/>
          </collection>
          <collection>
            <modelElement href="platform:/resource/qvto.ecore2uml/out/family.uml#_QV12QW0REd-a2rPGu1hnsg"/>
          </collection>
        </value>
      </parameters>
    </parameters>
    <result>
      <result kind="OUT" name="result" type="Class">
        <value>
          <modelElement href="platform:/resource/qvto.ecore2uml/out/family.uml#_QV12WW0REd-a2rPGu1hnsg"/>
        </value>
      </result>
    </result>
  </traceRecords>
Comment 1 Nicolas Rouquette CLA 2010-05-31 20:28:50 EDT
Created attachment 170597 [details]
qvto.ecore2uml transformation modified to pass a dictionary argument.
Comment 2 Nicolas Rouquette CLA 2010-05-31 20:29:41 EDT
Created attachment 170598 [details]
result of the transformation for the family.ecore example
Comment 3 Nicolas Rouquette CLA 2010-05-31 20:30:28 EDT
Created attachment 170599 [details]
trace showing that QVT Dict values are only partially saved in .qvtotrace files.
Comment 4 Nicolas Rouquette CLA 2010-05-31 20:43:06 EDT
Actually, passing dictionaries as arguments is only a limited solution; the trace files grow very large because they contain copies of the dictionary for every invocation of every mapping rule. 

We really need to be able to type a transformation property by a dictionary.
Comment 5 Nicolas Rouquette CLA 2010-07-18 16:45:16 EDT
Created attachment 174585 [details]
Patch for QVTo's ModuleInstanceFactory

The attached patch applies the same strategy for initializing variables in QvtOperationalEvaluationVisitorImpl.visitVariableInitExp() to the initialization of module properties in ModuleInstanceFactory.

With this simple patch, module properties typed by a QVTo dictionary are initialized the in the same way as if they were variables defined in a helper or a mapping operation instead of a module.

This considerably reduces the need to pass dictionaries as arguments to helpers or mapping operations because they can be easily accessed directly or indirectly from module parameters.
Comment 6 Christopher Gerking CLA 2014-04-24 01:54:35 EDT
This should have been fixed as part of bug 414472.
Comment 7 Sergey Boyko CLA 2014-05-06 02:56:11 EDT
(In reply to Christopher Gerking from comment #6)
> This should have been fixed as part of bug 414472.

This bug provides solution for Comment #5.

Additional patch is provided which fixes the problem listed in bug's title (Dict only partially saved in .qvtotrace).

Pushed to master for M7.
commit f870d42db7fecdda3519f988b9787ad90c71c120