Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » Xpand: avoid duplicates?
icon5.gif  Xpand: avoid duplicates? [message #683066] Sun, 12 June 2011 20:15 Go to next message
Uli  is currently offline Uli
Messages: 5
Registered: April 2011
Junior Member
Hi all,

I'm trying to convert a model with Xpand. So far this works quite well. But there is a split and join situation, like shown below. Foreach 'followingElement' Class1 is expanded. This results in the correct generation of 'Action1' and 'Action2'. But when expanding the followingElement'-reference of 'Class1' I get two 'Join'-elements instead of one.
Any ideas how to avoid that? Is it possible to store every expanded element in a variable to be able to check, wheather it has already been generated?
     split
       /\
      /  \
    a1   a2
     \   /
      \ /
     join



example of a model:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0">
  <Split name="s1" followingElement="/1 /2"/>
  <Class1 name="Action1" followingElement="/3"/>
  <Class1 name="Action2" followingElement="/3"/>
  <Join name="j1">
</xmi:XMI>


Thank you,
Uli
Re: Xpand: avoid duplicates? [message #683190 is a reply to message #683066] Mon, 13 June 2011 03:31 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6143
Registered: July 2009
Senior Member
Hi,

since you didn't post your metamodel and sample template code it's hard to give you best advice

(1) you can of course use a already processed list with a global var http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.xpand.doc/help/ch04s02.html or a parameter «DEFINE definition(Set alreadyProcessed) FOR Type» and add the Things you have processed - there and stop the processing if an elment was already processed.
(2) or you try to change your generation strategy e.g. by differentiating beween the Things And the Connection between the things - but as said before this is hard to tell without knowing the metamodel not the target code.

~Christian
Re: Xpand: avoid duplicates? [message #683404 is a reply to message #683190] Mon, 13 June 2011 13:13 Go to previous messageGo to next message
Uli  is currently offline Uli
Messages: 5
Registered: April 2011
Junior Member
Hi ~Christian,

thank you very much for your answer!

Probably your second suggestion would be the better way to go. But as the rest of the transformation is already fine, I'd prefer not to change the whole strategy, but if it helps, I of course would.

Could you explain your first suggestion a bit more detailed? I did not work with GeneratorExtensions so far. The example in the Eclipse documentation only shows how to store a single string. How can I store a List? I assume I then have to define some setter and getter method, right? I don't know how to include that in my template.

Sorry for those noob questions...

metamodel:
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0"
    xmlns:xmi="...omg.org/XMI" xmlns:xsi="...w3.org/2001/XMLSchema-instance"
    xmlns:ecore="...eclipse.org/emf/2002/Ecore" name="Model"
    nsURI="....example.com/model">
  <eClassifiers xsi:type="ecore:EClass" name="Class1" eSuperTypes="#//Class3"/>
  <eClassifiers xsi:type="ecore:EClass" name="Class2" eSuperTypes="#//Class3"/>
  <eClassifiers xsi:type="ecore:EClass" name="Class3">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType ...eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="followingElement_A" upperBound="-1"
        eType="#//Class1"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="followingElement_B" upperBound="-1"
        eType="#//Class2"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Split" eSuperTypes="#//Class2"/>
  <eClassifiers xsi:type="ecore:EClass" name="Join" eSuperTypes="#//Class2"/>
</ecore:EPackage>


index.php/fa/3019/0/

sample code:
«IMPORT Model»

«DEFINE main FOR Split»
«FILE "testoutput.txt"-»

«this.name-» (following: «FOREACH followingElement_A AS e» «e.name» «ENDFOREACH») 
-------------------------------
«EXPAND def1 FOREACH  this.followingElement_A»
«ENDFILE»
«ENDDEFINE»

«DEFINE def1 FOR Model::Class1»
«this.name» (following: «FOREACH followingElement_B AS e» «e.name» «ENDFOREACH»)
-------------------------------
«EXPAND def2 FOREACH  this.followingElement_B»
«ENDDEFINE»


«DEFINE def2 FOR Model::Class2»
«this.name»
«ENDDEFINE»



model:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xmi:XMI xmi:version="2.0">
  <Split name="split1" followingElement_A="/1 /2"/>
  <Class1 name="Action1" followingElement_B="/3"/>
  <Class1 name="Action2" followingElement_B="/3"/>
  <Join name="join1"/>
</xmi:XMI>



output:
split1 (following:  Action1  Action2 ) 
-------------------------------

Action1 (following:  join1 )
-------------------------------

join1


Action2 (following:  join1 )
-------------------------------

join1


Now I would just like to get rid of that second 'join1'

Uli
  • Attachment: metamodel.png
    (Size: 14.23KB, Downloaded 276 times)
Re: Xpand: avoid duplicates? [message #683430 is a reply to message #683404] Mon, 13 June 2011 13:58 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6143
Registered: July 2009
Senior Member
Hi i am thinking of something like

template/extensions.ext (you need to and xtend stdlib to path)
extension org::eclipse::xtend::util::stdlib::globalvar;

String addProcessedElement(Object o) :
	getGlobalVar("processed") == null ? (storeGlobalVar("processed", {o}) -> "") : (((List)getGlobalVar("processed")).add(o) -> "");
	
Boolean isProcessedElement(Object o) :
	getGlobalVar("processed") == null ? false : ((List)getGlobalVar("processed")).contains(o);


«IMPORT metamodel»

«EXTENSION template::extensions»

«DEFINE main FOR Split»
«addProcessedElement(this)»
«FILE "testoutput.txt"-»

«this.name-» (following: «FOREACH followingElement_A AS e» «e.name» «ENDFOREACH») 
-------------------------------
«EXPAND def1 FOREACH  this.followingElement_A»
«ENDFILE»
«ENDDEFINE»

«DEFINE def1 FOR Class1»
«addProcessedElement(this)»
«this.name» (following: «FOREACH followingElement_B AS e» «e.name» «ENDFOREACH»)
-------------------------------
«EXPAND def2 FOREACH  this.followingElement_B»
«ENDDEFINE»


«DEFINE def2 FOR Class2»
«IF !isProcessedElement(this)»
«addProcessedElement(this)»
«this.name»
«ENDIF»

«ENDDEFINE»


~Christian
Re: Xpand: avoid duplicates? [message #683739 is a reply to message #683430] Tue, 14 June 2011 06:23 Go to previous messageGo to next message
Uli  is currently offline Uli
Messages: 5
Registered: April 2011
Junior Member
Hi Christian,

wow, thanks a lot!! That solution works perfectly fine! Great!

Uli
Re: Xpand: avoid duplicates? [message #768965 is a reply to message #683066] Wed, 21 December 2011 01:48 Go to previous messageGo to next message
andi0879 Missing name is currently offline andi0879 Missing name
Messages: 3
Registered: December 2011
Junior Member
Hi all,

I recognized this interesting topic. Currently I have similar problems!

I am writing a code generator for an Autosar XML file. (See file attached)!
In this XML file all necessary information for variable declarations, functionality, etc. are stored. I am reading out all needed information (e.g. for variable declarations) with following commands:


*************************
FOREACH runnable.dataSendPoints.dataSendPoint.dataElementIref AS dataElementIref-»
«LET dataElementIref.dataElementPrototypeRef.value.split("/PortInterface/").last().split("/").first() AS dataElementPrototypeRef_IF-»
«FOREACH this.eAllContents.typeSelect(autosar::SenderReceiverInterface) AS SenderReceiverInterface-»
«IF SenderReceiverInterface.shortName==dataElementPrototypeRef_IF-»
«LET SenderReceiverInterface.dataElements.dataElementPrototype.typeTref.value.split("/DataType/").last() AS dataElementPrototypeType-»
«dataElementPrototypeType-» genType_«dataElementPrototypeType-»;
«ENDLET-»
«ENDIF-»
«ENDFOREACH-»
«ENDLET-»
«ENDFOREACH-»
*************************

In my example following code is generated:

*************************
TMode genType_TMode;
TMode genType_TMode;
TPercent genType_TPercent;
TBool genType_TBool;
c02_AKS_Rq genType_c02_AKS_Rq;
c02_Comp_Rq genType_c02_Comp_Rq;
c08_perc_0_100_0k5 genType_c08_perc_0_100_0k5;
c02_Reset_Rq genType_c02_Reset_Rq;
*************************

As you can see I have a duplicated variable declarations!

How can I avoid this? Are there any commands to avoid duplications?

Thanks in advance.

Andreas
Re: Xpand: avoid duplicates? [message #769105 is a reply to message #768965] Wed, 21 December 2011 07:23 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6143
Registered: July 2009
Senior Member
Hi,

yes. first i would move a lot of your stuff to a xtend file to get rid of this let stuff.
then i would return a set within this extension.
thus duplicates will be avoided.

~Christian
Re: Xpand: avoid duplicates? [message #774601 is a reply to message #769105] Wed, 04 January 2012 04:15 Go to previous messageGo to next message
andi0879 Missing name is currently offline andi0879 Missing name
Messages: 3
Registered: December 2011
Junior Member
Hello Christian,

thanks for your reply. But unfortunately I dont't understand your suggestion completely?

What do you mean with moving my stuff to xtend file? Can you give me an example? That would be really helpful.

Thanks in advance.

Regards,
Andreas
Re: Xpand: avoid duplicates? [message #774663 is a reply to message #774601] Wed, 04 January 2012 06:09 Go to previous message
Christian Dietrich is currently offline Christian Dietrich
Messages: 6143
Registered: July 2009
Senior Member
Hi, have a look at the docs it is explained there.
Previous Topic:[workflow] run workflow error
Next Topic:[Xpand] Generating multiple times to the same file
Goto Forum:
  


Current Time: Thu Jul 31 01:40:40 EDT 2014

Powered by FUDForum. Page generated in 0.01902 seconds