Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » EMFTVM avoiding using elements from the output model
EMFTVM avoiding using elements from the output model [message #1114903] Mon, 23 September 2013 11:38 Go to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Hi everyone,
I'm trying to change my normal ATL transformation to use EMFTVM but I'm running into some problems.
Right now I'm getting this exception:
org.eclipse.m2m.atl.emftvm.util.VMException: java.lang.IllegalArgumentException: Cannot read properties of org.dews_online.ccui.core.view.viewparts.PhenomenonTreeView.viewerContribution:profile!Class, as it is contained in an output model


The code I'm using is:
helper def: xmlElements: Sequence(XML!Element) = XML!Element.allInstancesFrom('Plugin');

rule Model {
	from
		s: UML2!Model in IN (
			not s.oclIsUndefined() and not (s.name = 'root model') and not (s.name =
					'externals') and not (s.name = 'source references')
		)
	to
[...],
vac: UML2!Package (
			name <- 'viewActions',
			packagedElement <- thisModule.xmlElements -> select(e | e.name =
					'viewContribution') -> collect(e | [color=red]thisModule.ActionSetClass(e)[/color])
		)
}

lazy rule ActionSetClass {
	from
		s: XML!Element
	to
		r: UML2!Class (
			name <- s.children -> select(e | e.oclIsTypeOf(XML!Attribute) and not e.
					oclIsUndefined() and e.name = 'id').first().value 
		) 
		--- The stereotype can't be applied since the element is generated outside
		--- the model.
	
	do {
		thisModule.wbactions <-thisModule.wbactions.union([color=red]r.setGroup()[/color]);
	}
}

helper context UML2!Class def: setGroup(): Sequence(UML2!Class) =
	if (thisModule.classes -> select(e | e.value.toUpper().
			endsWith(self.name.toUpper() )).
			notEmpty()) then
		if (thisModule.classes -> select(e | e.value.toUpper().endsWith(self.name.
				toUpper())).first().parent.name = 'actionSet')
				then
			Sequence{self}
		else
			Sequence{}
		endif
	else
		Sequence{}
	endif;


That's all the problematic code right now. So I understand that I shouldn't be targeting the output model elements, but how do I do this then?what's the proper way of using elements that have been transformed?
I've tried several thins but I don't really understand how should I address these elements to avoid this kind of exception, I'm really lost with EMFTVM but I'm just starting, so any help is welcome.

Thanks in advance,
regards,
Javier
Re: EMFTVM avoiding using elements from the output model [message #1114965 is a reply to message #1114903] Mon, 23 September 2013 13:28 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

Note that your code is also illegal in standard ATL, but the standard VMs never check for it. Anyway, you should not navigate "self.name" in setGroup(), as it is an output element. You don't need to navigate to self.name either, because you already know the name: you've just generated its value! So, here's your fixed code:

lazy rule ActionSetClass {
	from
		s: XML!Element
	using {
		nameValue : String = s.children -> any(e | e.oclIsTypeOf(XML!Attribute) and
				e.name = 'id').value;
	}
	to
		r: UML2!Class (
			name <- nameValue 
		) 
		--- The stereotype can't be applied since the element is generated outside
		--- the model.
	
	do {
		thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue));
	}
}

helper context UML2!Class def: setGroup(name : String): Sequence(UML2!Class) =
	let nameUpper : String = name.toUpper() in
	if (thisModule.classes -> select(e | e.value.toUpper().
			endsWith(nameUpper)).notEmpty()) then
		if (thisModule.classes -> select(e | e.value.toUpper().endsWith(nameUpper))
				.first().parent.name = 'actionSet') then
			Sequence{self}
		else
			Sequence{}
		endif
	else
		Sequence{}
	endif;


N.B. If you can convert the ActionSetClass rule into a non-lazy rule (by putting the right condition in the from part), you can apply stereotypes in the "do" part. EMFTVM executes regular rules in three phases instead of two: match (from) - apply (to) - post-apply (do). This allows EMFTVM to work with UML stereotypes without using a special "driver" for UML support.


Cheers,
Dennis

[Updated on: Mon, 23 September 2013 13:28]

Report message to a moderator

Re: EMFTVM avoiding using elements from the output model [message #1115487 is a reply to message #1114965] Tue, 24 September 2013 07:04 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, thanks a lot!
I know I do things that I shouldn't do in ATL but it worked perrfectly as I intended. Still one of the reasons I wanted to check EMFTVM is to do everything accordingly to ATL rules so thanks a lot for explaining and fixing my code!
I noticed that the lazy rule is returning OclUndefined, why is this? I'm trying to find a reason I'll let you know if I find out why.

So then from what I understand I could use just normal rules instead of this lazy rule and then get the elements using resolveTemp or something like that?
Thanks again Dennis, I'm struggling to understand some features of EMFTVM but I can say that it looks promising!

EDIT:
I think that lazy rules return OclUndefined because of what I read here ( http://wiki.eclipse.org/ATL/EMFTVM#Lazy_rules ) where it says that Quote:
you have to specify the return value in a do block
so I changed my code to:
lazy rule ActionSetClass {
	from
		s: XML!Element (s.name =
					'viewContribution')
	using {
		nameValue : String = s.children -> any(e | e.oclIsTypeOf(XML!Attribute) and
				e.name = 'id').value;
	}
	to
		r: UML2!Class (
			name <- nameValue ->debug('name')
		) 
		--- The stereotype can't be applied since the element is generated outside
		--- the model.
	
	do {
		r->debug('class');
		thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue))->debug('wbactions');
	}
}

But still got the same error saying that I get a null value, and when debugging it I can see that it does return OclUndefined, but in the Do section here it shows that r is of the type UML2!Class so I'm confused.

[Updated on: Tue, 24 September 2013 09:10]

Report message to a moderator

Re: EMFTVM avoiding using elements from the output model [message #1115574 is a reply to message #1115487] Tue, 24 September 2013 09:29 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

The "do" block returns the value of the last statement, which is:

thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue))->debug('wbactions');


This is an assignment and does not return a value (so, OclUndefined). If you want to return the value of "r", you need to specify it last:

	do {
		thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue))->debug('wbactions');
		r->debug('class');
	}



Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1115612 is a reply to message #1115574] Tue, 24 September 2013 10:27 Go to previous messageGo to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Thanks a lot Dennis! that was it, plus a condition I had added before on the lazy rule (in normal ATL those conditions don't get evaluated so that confused me too...)
Ok so my transformation works almost perfectly now in EMFTVM, but now comes the tricky part, I need to set values to the stereotyped classes, I can do this if the values are strings and such, but certain values are other stereotyped classes which are stereotyped in this very same transformation (meaning they had no stereotypes in the input model), to do this in normal ATL I used an endpoint rule and used the Output model, but I can't do that here (and shouldn't do that in normal ATL), so what would you recommend to do then?
Because I can't write it in the normal do section as some classes might not have yet been stereotyped, so then the values wouldn't be set properly.

Thanks a lot for your help Dennis!
regards,
Javier
Re: EMFTVM avoiding using elements from the output model [message #1117402 is a reply to message #1115612] Thu, 26 September 2013 11:59 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

Hmm, you should normally set the stereotype values at the same place where you apply the stereotypes. Can you explain why you need to set these in different rules?

Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1118182 is a reply to message #1117402] Fri, 27 September 2013 06:28 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 will just explain showing you a small part of my transformation:
I have two stereotypes: View and Perspective. They both have a few attributes (Name, icon, etc...) which are of the type String, so I can set the value without a problem. Then Perspective has one more attribute caled Views which is a list of classes with the stereotype View.
So then if I try to set this value in the normal do section where I transform classes with the Perspective stereotype it won't work as intended because some classes o the type View won't yet be stereotyped and therefore won't show in the 'Views' property, since all these profile applications are done in the 'Do' section of the rules I think there's no way to know for sure which one gets run first, therefore I think that the only way to know for sure that all stereotypes have been applied is at the endpoint rule (so that's why I do most of the code there).

I hope I explained it properly, but it is a bit tricky and difficult to explain maybe so if you need to know something else just let me know, also note that here I just talk about two stereotypes but I do actually have about 10 and might have more at some point.
thanks,
regards,
Javier
Re: EMFTVM avoiding using elements from the output model [message #1118797 is a reply to message #1118182] Fri, 27 September 2013 19:59 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

I see: if I understand correctly, you cannot set the stereotype value before the value has its own stereotype assigned. In that case, you can still use your endpoint rule. However, instead of iterating over the output model, you should iterate over either:

1. the input elements that map to the stereotyped value you need, or
2. the traces that contain the source-target relationships (http://wiki.eclipse.org/ATL/EMFTVM#Advanced_tracing)

If you create the stereotyped elements you want to assign in a normal matched rule, you can simply iterate over the corresponding source elements and use the resolve() method. If you use lazy rules, you can iterate over the traces generated by the corresponding lazy rule, and select the target values you want in that way.

Hint: if you want to know how you should navigate the traces model, first run your current transformation with the required settings to save your trace model to a file (http://wiki.eclipse.org/ATL/EMFTVM#Advanced_tracing). Then you can look into the file to see what the traces look like.


Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1121133 is a reply to message #1118797] Mon, 30 September 2013 09:53 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,
that's exactly what I have been doing and it seems to work great.

I'm facing two more problem though:
1 - I'm generating some elements using a lazy rule, but I create them in my endpoint rule (depending on certain values I set on the stereotypes I need to create an Association) so I wanted to assign these elements to a certain package. The package is created in a matched rule, so I thought I could use resolveTemp() to get to it, but it is not working, here's my code:
rule Model {
	from
		s: UML2!Model in IN (
			not s.oclIsUndefined() and not (s.name = 'root model') and not (s.name =
					'externals') and not (s.name = 'source references')
		)
	to
		t: UML2!Model (
			[...]
		),
		[...]
		),
		[...]	

		),
		wac: UML2!Package (
			name <- 'workbenchActions'
			,
--			packagedElement <- thisModule.xmlElements -> select(e | e.name = 'actionSet')->debug('ActionSets!')
--					-> collect(e | thisModule.WorkbenchActions(e))
			packagedElement<- Sequence{thisModule.resolveTemp(XML!Element.allInstances()->select(e|e.name='actionSet').first(), 'wAction')}
		),
		[...]
		)

The package I need is 'wac', so to call it I was trying to use
thisModule.resolveTemp(thisModule.mainModel,'wac')
but apparently that doesn't work so I don't know if there is any other way I could get the package.

2 - My second problem seems more tricky. Again I create an element in my endpoint rule by means of a lazy rule and this time it's of the type UML2!Property. So I want to set the type of this property to a type that exists in the output model, but not in the input model, how can I do this? The problem is that the element exists in an input XML model and it gets transformed to an UML2 element, so I'm not sure if I can target the traces or how could I do it.


Also, I'm not sure I should be creating elements through a lazy rule in the endpoint rule, is this somehow "illegal" in ATL or is it just not recommended or should there be no problem?

Thanks again for all your help Dennis, hopefully you know how to solve these issues too!

Re: EMFTVM avoiding using elements from the output model [message #1121540 is a reply to message #1121133] Mon, 30 September 2013 18:40 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

Op 30-09-13 11:53, Javier García schreef:
> 1 - I'm generating some elements using a lazy rule, but I create them in my
> endpoint rule (depending on certain values I set on the stereotypes I need to
> create an Association) so I wanted to assign these elements to a certain
> package. The package is created in a matched rule, so I thought I could use
> resolveTemp() to get to it, but it is not working, here's my code:

The matched rule is processed before the endpoint rule, so no traces generated
by the endpoint rule can be accessed. Here's the execution order:

1. Match all matched rules (including any lazy rule invocations)
2. Apply all matched rules (including any lazy rule invocations)
3. Post-apply all matched rules ("do" block) (including any lazy rule invocations)
4. Run the endpoint rule, if any (including any lazy rule invocations)

Note that I added " (including any lazy rule invocations)" at each stage. This
is because you can basically insert a lazy rule invocation anywhere. Even in
the "from" condition part, although that does not seem useful.

> 2 - My second problem seems more tricky. Again I create an element in my
> endpoint rule by means of a lazy rule and this time it's of the type
> UML2!Property. So I want to set the type of this property to a type that
> exists in the output model, but not in the input model, how can I do this? The
> problem is that the element exists in an input XML model and it gets
> transformed to an UML2 element, so I'm not sure if I can target the traces or
> how could I do it.

Your output model is empty at the start of your transformation, so your
transformation must have generated the UML Type that you want to assign
somewhere. Depending on how your transformation generated the Type element,
you can find it back through either:

1. Implicit tracing (matched rules, default output element)
2. thisModule.resolveTemp() (matched rules, non-default output element)
3. Calling a unique lazy rule again (same output is returned)
4. Using reflection on thisModule.traces (lazy rules)

Note that you can elaborate option (4) by first trying to find the trace, and
if there is none, call the lazy rule. This strategy can also be useful for
unique lazy rules that are called recursively, and where you need the output
elements of the rule before the rule returns.

> Also, I'm not sure I should be creating elements through a lazy rule in the
> endpoint rule, is this somehow "illegal" in ATL or is it just not recommended
> or should there be no problem?

It's perfectly legal in ATL, but you should remember the execution order
stated above. Any traces generated as late as in the endpoint rule cannot be
accessed from matched rules.


Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1122222 is a reply to message #1121540] Tue, 01 October 2013 10:44 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, thanks a lot, this is really useful and I'll be testing it these days and let you know how it goes.

I do have a couple more problems:
First one is that after reading you in this thread I think shouldn't be happening, so I'll explain:
As you told me in one of the earlier threads I should be able to give an stereotype to classes generated in lazy rules, but that was not the case in my transformation as I was getting errors so I have to apply the stereotype in the endpoint rule.
Here is the code:

rule Model {
	from
		s: UML2!Model in IN (
			not s.oclIsUndefined() and not (s.name = 'root model') and not (s.name =
					'externals') and not (s.name = 'source references')
		)
	to
		t: UML2!Model (
			name <- s.name ,
			visibility <- s.visibility,
			viewpoint <- s.viewpoint,
			eAnnotations <- s.eAnnotations,
			ownedComment <- s.ownedComment,
			clientDependency <- s.clientDependency,
			nameExpression <- s.nameExpression,
			elementImport <- s.elementImport,
			packageImport <- s.packageImport,
			ownedRule <- s.ownedRule,
			templateParameter <- s.templateParameter,
			templateBinding <- s.templateBinding,
			ownedTemplateSignature <- s.ownedTemplateSignature,
			packageMerge <- s.packageMerge,
			packagedElement <- s.packagedElement.union(Sequence {pck})
		),
		[...]
		),
		tool: UML2!Package (
			name <- 'Toolbars'
			,
			packagedElement <- thisModule.toolbarsHelper->select(e|e.isClass() and not e.isInterface()) ->collect(e|thisModule.lazyToolbarClass(e)).union(
				thisModule.toolbarsHelper->select(e|not e.isClass() and not e.isInterface()) ->collect(e|thisModule.lazyToolbarClass(e))).union(
			thisModule.toolbarsHelper->select(e|e.isInterface()) ->collect(e|thisModule.lazyToolbarInterface(e)))
		)

	do {
		thisModule.mainModel<-s;
		--- We apply the profile and the Workbench stereotype.
		t.applyProfile(profile!Profile.allInstances().asSequence().first())->debug('profile'); 
		t.applyStereotype(profile!Stereotype.allInstances().asSequence() -> select(i | i.
				qualifiedName = 'RCP::Workbench').last()); 
		[...]
		}

This is the model that calls the lazy rules, and here are the lazy rules:
lazy rule lazyToolbarClass {
	from
		s: XML!Element in Plugin
		using {
		nameValue : String = s.getElementName();
	}
	to
		r: UML2!Class (
			name <- nameValue
		) 
	do {
		
		thisModule.transformedToolbars <-thisModule.transformedToolbars.union(Sequence{r});
		thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue));
		r;
	}
}
lazy rule lazyToolbarInterface {
	from
		s: XML!Element in Plugin
	to
		r: UML2!Interface (
			name <- s.getElementName()
		) 
		--- The stereotype can't be applied since the element is generated outside
		--- the model.
	
	do {
		
		thisModule.transformedToolbars <-thisModule.transformedToolbars.union(Sequence{r});
		r;
	}
}

So if I try to add to any of these lazy rules in the do section something like:
r.applyStereotype(profile!Stereotype.allInstances().asSequence() -> select(i | i.
				qualifiedName = 'RCP::Toolbar').last()); 

then I get a java.lang.IllegalArgumentException.
My guess is that maybe the DO section from the lazyToolbar rule is done before the DO section of the Model matched rule, and therefore even though the Toolbar gets generated in the right place, the profile hasn't been yet applied to the model and no stereotypes can be applied, is this right?


Second problem:
This time it's similar to what I mentioned in this other thread here ( http://www.eclipse.org/forums/index.php/t/521205/ )and the thing is that the values of the stereotyped classes don't get transformed, but copies, therefore my output transformation is referencing the input transformation.
what would be the proper way to do this? as suggested in the other thread I checked this other thread ( http://www.eclipse.org/forums/index.php/mv/msg/452702/1010024/#msg_1010024 ) but I can't see a way to fix this right now.

Thanks a lot for all your help Dennis, and sorry for giving so much trouble but I think I'm getting to understand EMFTVM better and so far it seems faster than the regular ATL VM.

Regards,
Javier
Re: EMFTVM avoiding using elements from the output model [message #1122370 is a reply to message #1122222] Tue, 01 October 2013 13:47 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

Ok, in that particular case you can avoid lazy rules altogether:

helper def toolbarStereotype : profile!Stereotype =
	profile!Stereotype.allInstances().asSequence() -> select(i | i.
				qualifiedName = 'RCP::Toolbar').last();

rule Model {
	from
		s: UML2!Model in IN (
			not s.oclIsUndefined() and not (s.name = 'root model') and not (s.name =
					'externals') and not (s.name = 'source references')
		)
	to
		t: UML2!Model (
		[...]
		),
		tool: UML2!Package (
			name <- 'Toolbars'
			,
			packagedElement <- thisModule.toolbarsHelper->select(e|e.isClass() and not e.isInterface()) ->union(
				thisModule.toolbarsHelper->select(e|not e.isClass() and not e.isInterface()) ->union(
			thisModule.toolbarsHelper->select(e|e.isInterface()))
		)

	do {
		thisModule.mainModel<-s;
		--- We apply the profile and the Workbench stereotype.
		t.applyProfile(profile!Profile.allInstances().asSequence().first())->debug('profile'); 
		t.applyStereotype(profile!Stereotype.allInstances().asSequence() -> select(i | i.
				qualifiedName = 'RCP::Workbench').last()); 
		[...]
		}

rule ToolbarClass {
	from
		s: XML!Element in Plugin (thisModule.toolbarsHelper->includes(s) and not s.isInterface())
		using {
		nameValue : String = s.getElementName();
	}
	to
		r: UML2!Class (
			name <- nameValue
		) 
	do {
		thisModule.transformedToolbars <-thisModule.transformedToolbars.union(Sequence{r});
		thisModule.wbactions <-thisModule.wbactions.union(r.setGroup(nameValue));
		r.applyStereotype(thisModule.toolbarStereotype);
	}
}

rule ToolbarInterface {
	from
		s: XML!Element in Plugin (thisModule.toolbarsHelper->includes(s) and s.isInterface())
	to
		r: UML2!Interface (
			name <- s.getElementName()
		) 
		--- The stereotype can't be applied since the element is generated outside
		--- the model.
	
	do {
		thisModule.transformedToolbars <-thisModule.transformedToolbars.union(Sequence{r});
		r.applyStereotype(thisModule.toolbarStereotype);
	}
}


Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1124114 is a reply to message #1122370] Thu, 03 October 2013 07:43 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,
thanks for your help but sadly I can't do that because here you can see the toolbarsHelper:
helper def: toolbarsHelper: Sequence (XML!Element) = thisModule.xmlElements 
	-> select(e | e.name ='viewContribution' or e.name='actionSet' or e.name='objectContribution');

and the problem is I have a matched rule for elements that are 'viewContribution', another for 'actionSet' and another for 'objectContribution', so it won't be as easy. I'll work on it as I think my problems would be fixed if I can change that.


Now I got a different error when using resolveTemp. Here is my transformation:

create OUT: UML2 from IN: UML2, Initial: UML2, Plugin: XML, Profile: profile;

helper def: initialClasses: Sequence(UML2!Class) =
	UML2!Class.allInstancesFrom('Initial'); 

helper context UML2!Class def: getOwnedAttributes(): Sequence(UML2!Property) =
	if thisModule.initialClasses -> select(e | e.name = self.name).isEmpty() then
		Sequence{}
	else
		if not (thisModule.initialClasses -> select(e | e.name = self.name).first().
				getAllAttributes().isEmpty()) then
			thisModule.initialClasses -> select(e | e.name = self.name).first().
					getAllAttributes()
		else
			Sequence{}
		endif
	endif;
[...]


rule ClassFromIN {
	from
		s: UML2!Class in IN (
			s.oclIsTypeOf(UML2!"uml::Class")
			and not s.oclIsUndefined()
		)
	to
		t: UML2!"uml::Class" (
			name <- s.name,
			visibility <- s.visibility,
			isLeaf <- s.isLeaf,
			isAbstract <- s.isAbstract,
			isActive <- s.isActive,
			eAnnotations <- s.eAnnotations,
			ownedComment <- s.ownedComment,
			clientDependency <- s.clientDependency,
			nameExpression <- s.nameExpression,
			elementImport <- s.elementImport,
			packageImport <- s.packageImport,
			ownedRule <- s.ownedRule,
			templateParameter <- s.templateParameter,
			templateBinding <- s.templateBinding,
			ownedTemplateSignature <- s.ownedTemplateSignature,
			generalization <- s.generalization,
			powertypeExtent <- s.powertypeExtent,
			redefinedClassifier <- s.redefinedClassifier,
			substitution <- s.substitution,
			representation <- s.representation,
			collaborationUse <- s.collaborationUse,
			ownedUseCase <- s.ownedUseCase,
			useCase <- s.useCase,
			ownedAttribute <- s.ownedAttribute,
			ownedConnector <- s.ownedConnector,
			ownedBehavior <- s.ownedBehavior,
			classifierBehavior <- s.classifierBehavior,
			interfaceRealization <- s.interfaceRealization,
			nestedClassifier <- s.nestedClassifier
			ownedReception <- s.ownedReception
		)
		---Keeps the applied stereotypes and values(CURRENTLY NOT WORKING)
	do {		
		t.ownedOperation <- s.getOwnedOperations()->debug('OwnedOperations') -> collect(e | thisModule.
					resolveTemp(e, 't'));
		t.ownedAttribute <- s.getOwnedAttributes()->debug('OwnedAttributtes') 
			-> collect(e | thisModule.
					resolveTemp(e->debug('e'), 'tgt'));
	}

rule PropertyFromInitial {
	from
		src: UML2!Property in Initial (
			---We need to make sure that the property is not empty,and also
			---that it doesn't belong to a type that is not transformed.
		if src.refImmediateComposite().oclIsTypeOf(UML2!Class) then
			src.refImmediateComposite().existsInIN() and not thisModule.inClasses ->
					select(e | e.name = src.refImmediateComposite().name).first().
					belongsToPackage('google') and if src.type.oclIsUndefined() then
				false
			else
				if src.type.getModel().oclIsUndefined() then
					true
				else
					not (src.type.getModel().name = UML2!Model.
							allInstancesFrom('IN').first().name)
				endif
			endif
		else
			false
		endif
		)
	to
		tgt: UML2!Property (
			name <- src.name,
			visibility <- src.visibility,
			lower <- src.lower,
			upper <- src.upper,
			type <- src.setType(),
			aggregation <- src.aggregation,
			association <- src.association,
			isStatic <- src.isStatic,
			ownedComment <- src.ownedComment
		)
}



So, as you can see I transform the properties and I transform the classes.
Then on the do section I use resolveTemp to assign these transformed properties to the correspondent classes, and that's when I get this exception:
Quote:

org.eclipse.m2m.atl.emftvm.util.VMException: Cannot resolve default trace target 'tgt' for org.dews_online.ccui.core.view.viewparts.PhenomenonTreeView.viewerContribution:UML2!Property
at static EMFTVM!ExecEnv::resolveTemp(var: Object, target_pattern_name: String) : Object(OCL)
Local variables: [org.dews_online.ccui.core.view.viewparts.PhenomenonTreeView.viewerContribution:UML2!Property, 'tgt']
at rule ClassFromIN@postApply@1#5(platform:/resource//ATLTesting/EMFTVMTest/Transformations/Third/EMFTVMThird.atl#[235:19-236:39])
Local variables: [e = org.dews_online.ccui.core.view.viewparts.PhenomenonTreeView.viewerContribution:UML2!Property]
at public org.eclipse.m2m.atl.emftvm.util.LazyList org.eclipse.m2m.atl.emftvm.util.LazyList.collect(org.eclipse.m2m.atl.emftvm.CodeBlock)
Local variables: []
at rule ClassFromIN@postApply#17(platform:/resource//ATLTesting/EMFTVMTest/Transformations/Third/EMFTVMThird.atl#[234:4-236:41])
Local variables: [__trace__: TRACE!TraceLink = 933c0c:TRACE!TraceLink, s: UML2!Class = MapElementsView:UML2!Class, t: UML2!uml::Class = MapElementsView:UML2!Class]
at static EMFTVM!ExecEnv::main() : Object(platform:/resource//ATLTesting/EMFTVMTest/Transformations/Third/EMFTVMThird.atl)
Local variables: []


That transformation did work on normal ATL, so I don't know what is the issue here, I don't really understand it because I am transforming the properties the same way in both normal ATL and EMFTVM, as always any help is welcome.

thanks again,
regards,
Javier
Re: EMFTVM avoiding using elements from the output model [message #1124210 is a reply to message #1124114] Thu, 03 October 2013 09:43 Go to previous messageGo to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Ok that problem from the last post is FIXED.
I changed the way I checked for the elements, as I think somehow it tried to do resolveTemp for some attributes that weren't transformed, AND also, there is an already existing method called getOwnedAttributes() which was overriding my method. This method doesn't show anywhere I can see so I just needed to change the name of my helper, I'm not sure if this is an error or something, but after debugging the code apparently getOwnedAttributes() returned the attributes already on the class, not sure if this is supposed to work this way but it was quite confusing because the helper didn't show as an option when pressing ctrl+space.
Re: EMFTVM avoiding using elements from the output model [message #1124478 is a reply to message #1124210] Thu, 03 October 2013 15:24 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

Javier García wrote on Thu, 03 October 2013 11:43
...there is an already existing method called getOwnedAttributes() which was overriding my method. This method doesn't show anywhere I can see so I just needed to change the name of my helper, I'm not sure if this is an error or something, but after debugging the code apparently getOwnedAttributes() returned the attributes already on the class, not sure if this is supposed to work this way but it was quite confusing because the helper didn't show as an option when pressing ctrl+space.


That behaviour is explained here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=408391

If you define your own getOwnedAttributes() on a superclass, the native implementation will override your implementation.


Cheers,
Dennis
Re: EMFTVM avoiding using elements from the output model [message #1128114 is a reply to message #1124478] Mon, 07 October 2013 10:58 Go to previous messageGo to next message
Javier García is currently offline Javier GarcíaFriend
Messages: 129
Registered: April 2013
Senior Member
Ok thanks a lot for all your help Dennis, I managed to get over all my issues and my transformation works perfectly now.

Just one little thing I want to ask, though I'm not sure if I should open a new post for this but anyways, what's the way to transform associations in EMFTVM?
I ask because I always used to do something like:

lazy rule createAssociation {
	from
		s: String,  s2: String
	to
		tgt: UML2!Association (
			ownedEnd <- Sequence{thisModule.createProperty(tgt,s,true)},
			memberEnd<-Sequence{thisModule.createProperty(tgt,s2,false)}
		)
	do{
		tgt;	
	}
}

BUT apparently ownedEnd and memberEnd are the same list, so what this was doing was overwrite the list with the last element I used (in this case memberEnd), so I had to do this instead:
lazy rule createAssociation {
	from
		s: String,  s2: String
	to
		tgt: UML2!Association (
			ownedEnd <- Sequence{thisModule.createProperty(tgt,s,true),thisModule.createProperty(tgt,s2,false)}
		)
	do{
		tgt;	
	}
}


It took me quite a while until I understood why this was happening, so I think it just happens due to the difference in regular ATL and EMFTVM on handling these things, as in normal ATL assigning a new value to a list in a transformation seemed to just make an union of both lists but in EMFTVM it seems to replace it.

So not sure if this is intended to work this way or if it is a bug or just a result of the way EMFTVM works, but anyways all my problems seem fixed so far, so thanks for all your help!
Re: EMFTVM avoiding using elements from the output model [message #1129064 is a reply to message #1128114] Tue, 08 October 2013 08:48 Go to previous message
Dennis Wagelaar is currently offline Dennis WagelaarFriend
Messages: 589
Registered: September 2012
Location: Belgium
Senior Member

ATL/EMFTVM always uses "set" semantics for assigning to properties, while regular ATL uses "set" for single-valued properties and "add" for multi-valued properties (collections). ATL/EMFTVM chooses "set" - even for collections - because that offers better control when overriding property assignments in sub-rules.

Cheers,
Dennis
Previous Topic:resolveTemp crashes the ATL module
Next Topic:[EMFTVM] Path to import modules
Goto Forum:
  


Current Time: Thu Mar 28 09:26:14 GMT 2024

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

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

Back to the top