Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » UM2L to UML2: don't want to transform certain Generalizations and Associations
icon4.gif  UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1043195] Wed, 17 April 2013 12:05 Go to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Hi everyone,
I'm doing an UML2 to UML2 transformation and I'm running into a bit of trouble.

I only transform certain stereotyped classes, so then when I transform the generalizatios, associations, and other kind of relationships there are many of them that are just empty when transformed, since the objects they were referencing were not transformed.

How could I filter this?

I tried it this way:
rule generalization {
	from
		gen: UML2!Generalization (
			not gen.oclIsUndefined() and gen.shouldBeCreated()
			and not gen.general.oclIsUndefined()
			
		)
	to
		trg: UML2!Generalization (
			general <- gen.general -> debug('Generalization')			
		)
}

but it doesn't work, I'm guessing since general is actually defined, just defined on the wrong model.
So I was thinking there maybe is some way to check whether the element is still referencing another element from the Input transformation, in which case it wouldn't get transformed.

Thanks in advance, hope someone knows how to solve this,
regards,
Javier
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1043245 is a reply to message #1043195] Wed, 17 April 2013 13:11 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 607
Registered: July 2009
Senior Member
Hello,

From your problem description, I would say you should modify your rule guard, for instance (cf. hasStereotype helper):
rule generalization {
	from
		gen: UML2!Generalization (
                        gen.refImmediateComposite().hasStereotype('MyProfile::MyStereotype') -- Instead of calling the refImmediateComposite() method, an equivalent available reference could be used if existing
		)
	to
		trg: UML2!Generalization (
			general <- gen.general -> debug('Generalization'),
                        ...			
		)
}

Also, I encourage you to take a look to the ATL Refining Mode. Using the corresponding Deletion feature could be relevant in your case in order to get only the required generalizations.
I hope this helps.

Best regards,

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1043869 is a reply to message #1043245] Thu, 18 April 2013 08:05 Go to previous messageGo to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Hi Hugo,
the hasStereotype helper doesn't seem to work for me, it said that no such operation existed, so I used this instead:
not gen.refImmediateComposite().getAppliedStereotypes().isEmpty()
and not gen.general.refImmediateComposite().getAppliedStereotypes().isEmpty()

And it doesn't work as intended, if I use only the first line I get to skip a few generalizations, which is nice, but still the ones that exist inside a stereotyped class sometimes point to a class that isn't transformed, so I added that second line and what happens is that no generalizations are created, so I guess I'm probably doing something wrong but I can't seem to thin of a way to fix it.

Now I have a very similar problem but on Associations and Dependencies, I have these rules:
rule Association {
	from
		ua: UML2!Association (
			ua.oclIsTypeOf(UML2!Association) and not ua.oclIsUndefined()			
		)
	to
		ma: UML2!Association (
			name <- ua.name,
			isAbstract <- ua.isAbstract,
			generalization <- ua.generalization,
			memberEnd <- ua.memberEnd,
			ownedEnd <- ua.ownedEnd
		)
}

rule Dependency {
	from
		ud: UML2!Dependency (
			not ud.oclIsUndefined()
			 and ud.oclIsTypeOf(UML2!Dependency)
		)
	to
		mi: UML2!Dependency (
			supplier <- ud.supplier,
			client <- ud.client,
			name <- ud.name
		)
}


So the thing is that when transformed, some of the memberEnd, ownedEnd, Supplier or client are not transformed, therefore the association/dependency shouldn't be transformed either, but I don' quite know how to do to filter it. Do you have any ideas? I tried some things but nothing seemed to work.

I'm checking the refining mode and it seems interesting, but it seems like though it might solve some of my problems it might cause some new ones, so I'm not completely sure that it would be a good choice to move my code to refining mode, but I'll do some further tests.

Thanks a lot for your help!

[Updated on: Thu, 18 April 2013 08:26]

Report message to a moderator

Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1043942 is a reply to message #1043869] Thu, 18 April 2013 09:50 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 607
Registered: July 2009
Senior Member
Hello Javier,

"hasStereotype" is not a method natively provided by ATL, it was just an example of a helper (that has to be declared in your transformation) that can be used in your context.
For your rules transformating Associations, Dependencies, etc. I guess you have to use quite similar filters than the ones I've shown you in my last post (i.e. checking that the Association/Dependency owner has the concerned stereotype...).

Concerning the Refining Mode, basically it depends of what you're doing: if you're actually filtering an already existing model then it is relevant, if your are producing a new model (i.e. doing a real semantic mapping) then the ATL standard mode is more appropriate.

Best regards,

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1043979 is a reply to message #1043942] Thu, 18 April 2013 10:42 Go to previous messageGo to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Ok, I thought it was native and that would have been a great help.
Now here you can see the method I have to check this:
helper context OclAny def: belongsToStereotypedClass(): Boolean =
	if self.oclIsUndefined() then
		false
	else
		if not self.refImmediateComposite().oclIsUndefined() then
			if self.refImmediateComposite().oclIsTypeOf(UML2!Class) then
				if not self.refImmediateComposite().getClass().getAppliedStereotype('RCP_Profile::View').oclIsUndefined() 
				or not self.refImmediateComposite().getClass().getAppliedStereotype('RCP_Profile::Perspective')
				.oclIsUndefined() then
					true
				else
					self.refImmediateComposite().belongsToStereotypedClass()
				endif
			else
				self.refImmediateComposite().belongsToStereotypedClass()
			endif
		else
			false
		endif
	endif;

It works with most elements, but the thing is that for instance on the Dependency rule I would need to apply it both to the client and supplier of the Dependency, and when I do this I get the following error:
Quote:
org.eclipse.m2m.atl.engine.emfvm.VMException: refImmediateComposite only valid on model elements

So I'm guessing that the immediateComposite of client/suppliers doesn't belong to the model, so how do I check if it belongs to a stereotyped class then?

Thanks once again for your help.
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1044084 is a reply to message #1043979] Thu, 18 April 2013 13:24 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 607
Registered: July 2009
Senior Member
Several remarks:

  • Only the root element of the model has no container, and your helper should never called on it. So I would say your two first tests with OclIdUndefined are useless;
  • I don't see why you are calling to getClass, as the getAppliedStereotype applies on a UML!Element (or one of its subtype) and that you already check before that you are handling a UML!Class (which is a subtype of UML!Element)
  • Generally, I don't see the need for using such a complex recursive helper here. But maybe I don't see the full point of your problem.

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1044690 is a reply to message #1044084] Fri, 19 April 2013 08:02 Go to previous messageGo to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Ok I didn't know that about the root element.
I also don't know why I called getClass, sometimes I overcomplicate things.

This helper is used for many things, for instance for a Parameter. Now the as I see it the Parameter is contained inside of an Operation, which is itself contained inside of a Class, therefore I thought it would be necessary to use recursivity here, to check if the parameter was inside a stereotyped class. Is there an easier way to check this? As otherwise I was getting some parameters transformed that didn't have an owner (the operation wasn't transformed) so I thought of this way to solve that problem, but any help is welcome.

So I still can't seem to be able to filter these elements (Association, Dependency..), since this helper still doesn't work, I tried some other ideas but nothing seems to work properly.

Thanks a lot for your input, I still need to learn a lot about ATL and I need all the help I can get!

Regards,
Javier
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1047468 is a reply to message #1043195] Tue, 23 April 2013 08:48 Go to previous messageGo to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
I finally got it done like this:

rule Association {
	from
		ua: UML2!Association (
			ua.oclIsTypeOf(UML2!Association) and not ua.oclIsUndefined()
		)
	to
		ma: UML2!Association (
			name <- ua.name -> debug('Association'),
			isAbstract <- ua.isAbstract,
			generalization <- ua.generalization,
			memberEnd <- ua.memberEnd,
			ownedEnd <- ua.ownedEnd,
			ownedComment <- ua.ownedComment
		)
		do{
			if (not ma.memberEnd.testSet(2))
			then ma.destroy()
			else
				false
			endif;
		}
}

I had to use the do block, which I don't really like, but it's the only possible solution I found.
Also in the if clause it forces me to write the else part, is there a way to avoid this? I just wrote "false" and it has no effect but it'd be nicer if I could delete that.

The testSet() method just tests the size of the memberEnd set, so when it's smaller than it should then it gets destroyed.

Let me know if you know of a better way to do this.
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1047772 is a reply to message #1047468] Tue, 23 April 2013 16:17 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 607
Registered: July 2009
Senior Member
Hello,

We generally recommend to don't use imperative constructs in ATL transformations, and you are normally not supposed to navigate the output model (because you don't know about the created elements) and you cannot "destroy" elements created before. This may work but we cannot guarantee it.
There is most of the time a solution by thinking the problem the other way round: if you don't need an element, don't create it instead of having to destroy it right after (cf. the corresponding matched rule).

Anyway, there are always different ways of implementing a same transformation.

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1048228 is a reply to message #1047772] Wed, 24 April 2013 07:37 Go to previous messageGo to next message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Hi Hugo, I must say that I completely agree with you, it just looks like I'm doing something wrong when I create an element and then destroy it, and it's no recommended to use the "do{}" block, so I will try to refine this, but so far I can't think of any other way of making it work, but I might come back for more guidance at some point.

Thanks for your help!
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1048265 is a reply to message #1048228] Wed, 24 April 2013 08:32 Go to previous messageGo to next message
Sylvain EVEILLARD is currently offline Sylvain EVEILLARD
Messages: 523
Registered: July 2009
Senior Member
The best solution imho is to externalize your rules conditions in helpers that all have the same name (e.g. filter).
You can then easily code your conditions.

For your example you'd do :
helper context UML2!Property def : filter : Boolean =
not self.testSet(2);


and then
helper context UML2!Association def : filter : Boolean =
self.oclIsTypeOf(UML2!Association) and not self.oclIsUndefined()
and self.memberEnd.filter;


and your rules will now look like :
rule Association {
	from
		ua: UML2!Association (
			ua.filter
		)
	to
Re: UM2L to UML2: don't want to transform certain Generalizations and Associations [message #1049722 is a reply to message #1048265] Fri, 26 April 2013 07:36 Go to previous message
Javier García is currently offline Javier García
Messages: 129
Registered: April 2013
Senior Member
Hi Sylvain, I tried that solution before but it doesn't work.
The thing is, the association in the input model is good, it has its "memberEnd" feature properly set, but since some of those elements belonging to the member end property don't get transformed, once the association is transformed the association gets transformed with one or none elements in the memberEnd property, so that's why I ended up doing it this way, since if I check on the input model it will tell me that it everything's fine. I don't know if it is supposed to work this way or if it should notice that the elements aren't transformed, but anyways the thing is that if I try it the way you said it doesn't seem to work.

Thanks a lot and any other advice would be appreciated!
Previous Topic:Cannot find class in reference model
Next Topic:Transform between Rose model and UML model
Goto Forum:
  


Current Time: Sat Oct 25 15:13:45 GMT 2014

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

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