Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » [EMFTVM] How to transform stereotypes values?(They point to elements from the input model)
[EMFTVM] How to transform stereotypes values? [message #1160845] Tue, 29 October 2013 11:44 Go to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Hi everyone,
I've had this problem before (also in regular ATL), but I found some workarounds in some particular transformations (because they had more input models that helped me) but now I'm stuck.

I have an UML2 to UML2 transformation, what I do mainly is that I just copy the stereotyped elements. My stereotypes are two: Observer and Subject, and in the profile there is an attribte in Subject which contains some elements of the type Observer.

Now in my input model there are at least two subjects (there could be even more eventually) and each one points to some different observers.

So if I do my transformation and apply the stereotypes and its values in the way recommended in the EMFTVM guide using this code:
lazy rule ApplyStereotypes {
	from s : UML2!"uml::Element" in IN
	using {
		t : UML2!"uml::Element" = s.resolve();
	}
	do {
		for (st in s.getAppliedStereotypes()) {
			t.applyStereotype(st);
			for (a in st.getAllAttributes()) {
				if (not a.name.startsWith('base_') and s.hasValue(st, a.name)) {
					t.setValue(st, a.name, s.getValue(st, a.name));
				}
			}
		}
	}
}

endpoint rule ApplyAllStereotypes() {
	do {
		for (element in thisModule.traces.defaultSourceElements
				->collect(e|e.object)
				->select(o|o.oclIsKindOf(UML2!"uml::Element"))) {
			thisModule.ApplyStereotypes(element);
		}
	}
}


Then what happens is that the stereotype's value in my output model points to elements existing in the input model.
So I'm guessing this happens either because this way of setting the values is not working properly, or because I'm not transforming the stereotype's values existing in the input model.

I've tried transforming the properties of the stereotypes, but they just showed up as regular properties but without a model, so I don't think that's the way of doing it and I really have no clue, as there seems to be no other way to do this.
So anyone has any ideas on how to make this work??

Thanks in advance,
regards,
Javier


EDIT: after further testing I see that each of these properties contains a Sequence with the stereotype applications of the elements, so as a workaround for each of these stereotype applications in the stereotype's value I find the corresponding class in the input model and then do "myClass.resolve().getStereotypeApplications().first()" to obtain the transformed version of the stereotyped application. I'm not sure it's the best way but at least it works, still I would like to know an easier way to do this.
Also let me know if you want to see the code.

[Updated on: Wed, 30 October 2013 11:39]

Report message to a moderator

Re: [EMFTVM] How to transform stereotypes values? [message #1165869 is a reply to message #1160845] Fri, 01 November 2013 15:59 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 171
Registered: September 2012
Senior Member

Hmmm, you want to assign a stereotype application (instance) to a property of another stereotype application. This is the first case I see of higher-order stereotyping Wink.

The example code above is just intended for primitive values, such as Strings and Integers. Adding ".resolve()" to the value also makes it work for regular model elements that are transformed elsewhere in the transformation:

t.setValue(st, a.name, s.getValue(st, a.name).resolve());


To make it work for elements generated by a "blackbox" API, such as stereotype applications, you have to first retrieve the model element it is applied to, trace that to its output element, and retrieve the equivalent stereotype application there. You'll need something like this (not verified):

let value : UML2!Stereotype = s.getValue(st, a.name) in
let source : UML2!Element = value.eClass().getEAllReferences()->any(base | base.name.startsWith('base_')) in
source.resolve().getAppliedStereotype(st.getQualifiedName())


I assume your not using sub-stereotypes? That would add yet another layer of complexity.


Cheers,
Dennis
Re: [EMFTVM] How to transform stereotypes values? [message #1169808 is a reply to message #1165869] Mon, 04 November 2013 07:51 Go to previous messageGo to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Hi Dennis,
I see this is a difficult one! Smile
I think your solution is more or less what I do, here is the code I'm currently using to apply the values:

helper def: observerType: UML2!Type = UML2!Type.allInstances()->select(e|e.name='Observer').first();
helper def: concreteObserverType: UML2!Type = UML2!Type.allInstances()->select(e|e.name='ConcreteObserver').first();
helper def: updateType: UML2!Type = UML2!Type.allInstances()->select(e|e.name='update').first();
--- A helpful sequence to set stereotypes' values
helper def: stereotypeValues: Sequence(UML2!Element) = Sequence{};
--- Contains all the UML2!Element from both input models
helper def: allInputElements: UML2!Element = thisModule.elementsFromFirst.union(thisModule.elementsFromSecond);
--- Returns the element from the input model corresponding to the stereotypeApplication provided
--- Thus allowing us to use resolve() in order to get the stereotypeApplication of the element
--- in the output model.
helper context OclAny def: getElementFromValue(): UML2!Element = 
	thisModule.allInputElements->select(e|e.getAppliedStereotypes().notEmpty())->select(e|e.getStereotypeApplications().first()=self).first();
--- Applies the values to the stereotyped classes, avoiding to point to the INPUT models
lazy rule applyStereotypeValues {
	from s : UML2!"uml::Element" (not s.oclIsTypeOf(UML2!Operation))
	using {
		t : UML2!"uml::Element" = s.resolve();
	}
	do {
		for (st in s.getAppliedStereotypes()) {
			for (a in st.getAllAttributes()) {
				if (not a.name.startsWith('base_') and s.hasValue(st, a.name)) {
					for (elem in s.getValue(st, a.name)){
						if (elem.getElementFromValue().resolve().getStereotypeApplications().notEmpty()){
							thisModule.stereotypeValues<-thisModule.stereotypeValues.append(elem.getElementFromValue().resolve().getStereotypeApplications().first());
						}
					}
					if (a.type=(thisModule.observerType) or a.type=(thisModule.concreteObserverType) or a.type=(thisModule.updateType)){ --We identify if the element is of the type of one of the stereotyped types
						t.setValue(st, a.name, thisModule.stereotypeValues);
					}
					else{
						t.setValue(st, a.name, s.getValue(st, a.name));
					}
					thisModule.stereotypeValues<-Sequence{};
				}
			}
		}
	}
}
endpoint rule ApplyAllStereotypesAndSetPackages() {
	do {
		--- Apply stereotypes:
		for (element in thisModule.traces.defaultSourceElements
				->collect(e|e.object)
				->select(o|o.oclIsKindOf(UML2!"uml::Element"))) {
			thisModule.applyStereotypeValues(element);
		}
	}
}


I think there are a couple things I can improve, but this works pretty good. Also note that some of the values are Sequences instead of just one value so I had to take this into account.

I haven't really used 'let' attributes in my transformations so I'm not really sure about how to apply the code you provided, is my code doing more or less what you mentioned? or can it be done just easily using the code you provided?

Thanks a lot for your help Dennis.
Re: [EMFTVM] How to transform stereotypes values? [message #1169943 is a reply to message #1169808] Mon, 04 November 2013 09:48 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 171
Registered: September 2012
Senior Member

Your code does use a different strategy: it updates a global helper attribute thisModule.stereotypeValues. In any case, I realised both our solutions have a remaining problem: you cannot refer to stereotype applications that have not yet been created! This means the code relies on rule execution order!

If it works for your current situation, that's fine, but it's important to realise that the solution is not general! You could try to improve the solution by:

1. applying all stereotypes in a first 'for' loop
2. setting all sterotype values in a second 'for' loop

That way, you have a guarantee that all stereotype applications exist.


Cheers,
Dennis
Re: [EMFTVM] How to transform stereotypes values? [message #1169998 is a reply to message #1169943] Mon, 04 November 2013 10:32 Go to previous message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Yes Dennis you're right! I actually used this in another transformation and did it the way you mentioned (splitting it into two different 'for' loops) because I think it was giving me some problems but I didn't modify it in this transformation, I will do it now.

I'm glad at least this can be done more or less easily, thanks once again for your help!
Previous Topic:run successive ATL transformations with java
Next Topic:Empty output model with ATL+ANT and metamodel from xsd file
Goto Forum:
  


Current Time: Sat Dec 20 20:22:54 GMT 2014

Powered by FUDForum. Page generated in 0.01748 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software