Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » M2M (model-to-model transformation) » ECore Meta-Model to XMI Transform Issue: Re-used Entities Only Take Last Map(Is there a way to force the creation of new mappings when a reused entity is encountered within a transform?)
icon5.gif  ECore Meta-Model to XMI Transform Issue: Re-used Entities Only Take Last Map [message #666795] Fri, 22 April 2011 11:57
DavidH Mising name is currently offline DavidH Mising name
Messages: 3
Registered: April 2011
Junior Member
I have an ecore meta-class called PropertySpecValueSet which has two associations.

PropertySpecValueSet --> 1..n allowedValue: PropertySpecValue
PropertySpecValueSet --> 0..1 defaultValue: PropertySpecValue

I create instances as follows:
There are four child allowed values (Monthly, Quarterly, Semi-Annual, Yearly)
There is one default value (Monthly)

When I run the transform (Instance of ECore model --> XMI), the instance 'Monthly' is encountered twice, but the second mapping overwrites the first mapping resulting in the following incorrect output:

<propertySpecValueSet>
     <allowedValue value="Yearly"/>
     <allowedValue value="Quarterly"/>
     <allowedValue value="Semiannual"/>
     <defaultValue value="Monthly"/>
</propertySpecValueSet>


This is my QVT code:
mapping PMSMG::PropertySpecValueSet::toPropertySpecValueSet() : SMG::PropertySpecValueSet {

	allowedValue += self.allowedValue -> toPropertySpecValue();
	defaultValue := self.defaultValue.map toPropertySpecValue();
}

mapping PMSMG::PropertySpecValue::toPropertySpecValue() : SMG::PropertySpecValue {

	value := self.value;
}


I thought resolve would solve this problem, so I coded the following which had no impact on the output:
mapping PMSMG::PropertySpecValueSet::toPropertySpecValueSet() : SMG::PropertySpecValueSet {

	allowedValue += self.allowedValue.resolve(SMG::PropertySpecValue);
	if (allowedValue -> size() = 0) then {
	     allowedValue += self.allowedValue -> toPropertySpecValue();
	}
	endif;
	
	defaultValue := self.defaultValue.resolveone(_t:SMG::PropertySpecValue|_t.value = self.defaultValue.value);
	if (defaultValue.oclIsUndefined()) then {
	     defaultValue := self.defaultValue.map toPropertySpecValue();
	}
	endif;
}

mapping PMSMG::PropertySpecValue::toPropertySpecValue() : SMG::PropertySpecValue {

	value := self.value;
}


Finally, the solution we came up with was to explicitly create the objects which resulted in the following correct output:
<propertySpecValueSet>
     <allowedValue value="Monthly"/>
     <allowedValue value="Yearly"/>
     <allowedValue value="Quarterly"/>
     <allowedValue value="Semiannual"/>
     <defaultValue value="Monthly"/>
</propertySpecValueSet>


The transform code that produced the above output is here:

mapping PMSMG::PropertySpecValueSet::toPropertySpecValueSet() : SMG::PropertySpecValueSet {

	self.allowedValue->forEach(av) {
		allowedValue += object SMG::PropertySpecValue {
			value := av.value;
			code += av.allSubobjectsOfType(PMSMG::Code).oclAsType(PMSMG::Code)->toCode();
		}
	};

	defaultValue := object SMG::PropertySpecValue {
		value := self.defaultValue.value;
		code += self.defaultValue.allSubobjectsOfType(PMSMG::Code).oclAsType(PMSMG::Code)->toCode();
	}
}



So - is this the right solution? Is there an easier way? Seems odd to have to write object creation code.
Previous Topic:[ATL] Format of output model
Next Topic:Annotations for shared super class attributes and associations?
Goto Forum:
  


Current Time: Thu Jul 24 11:38:18 EDT 2014

Powered by FUDForum. Page generated in 0.01771 seconds