Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » QVT-OML » Can we map two abstract classes?
Can we map two abstract classes? [message #1847566] Mon, 01 November 2021 13:56 Go to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi all,

I have the following two metamodels:

This is the source metamodel: index.php/fa/41222/0/

And this is the target metamodel: index.php/fa/41223/0/

Up til now, I have written the following transformation in QVTo.

modeltype A uses metamodelA('http://www.example.org/metamodelA');
modeltype B uses metamodelB('http://www.example.org/metamodelB');


transformation test(in srcModel:A, out trgModel:B);

main() {
srcModel.rootObjects()[A::Map] -> map Map2Map();
}

abstract mapping Map:: abstractmapping() : B::Maps {
   name := self.name; 
}

abstract mapping Element:: Element2Element() : B::Element {
   name := self.name; 
}

mapping Map :: Map2Map() : B::Map 
inherits Map:: abstractmapping
{
element := self.element -> map Element2Element();
}


However, I am having issues with element := self.element... line.

It says :

The type 'test::Bag(Element)' does not conform to the type 'metamodelB::Element' of the property 'element'

Maybe even the Element2Element() abstract mapping is not correct, but I am not quite sure how to proceed with this line.
Any help is appreciated.

Thank you!
Re: Can we map two abstract classes? [message #1847570 is a reply to message #1847566] Mon, 01 November 2021 14:49 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7669
Registered: July 2009
Senior Member
Hi. John

No. It makes no sense. Consider Java, you cannot create a new instance of java.util.List; you must create an instance of concrete derived class such as ArrayList.

Just the same with models, you cannot create an incomplete instance, since it violates well-formedness principles. Not sure which WFR it might be; just common sense.

I suspect you want to use disjuncts so that you can specify alternative concrete derivations that may indeed inherit an abstract implementation.
You can find some examples of abstract/inherits/disjuncts in

https://git.eclipse.org/r/plugins/gitiles/ocl/org.eclipse.ocl/+/refs/heads/master/examples/org.eclipse.ocl.examples.build/src/org/eclipse/ocl/examples/build/qvto/UML2EcoreSynthesizer.qvto

Regards

Ed Willink
Re: Can we map two abstract classes? [message #1847572 is a reply to message #1847570] Mon, 01 November 2021 15:10 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi Ed,

Do you have any specific idea in this case on how to implement that?
Because I have tried using abstract/inherit/disjunct in other cases and this one too . For Maps it works, but for Element no. Source metamodel as before:

index.php/fa/41224/0/


And the target metamodel:

index.php/fa/41225/0/

In this case I do use what you mentioned in the following code snippet:

modeltype A uses metamodelA('http://www.example.org/metamodelA');
modeltype B uses metamodelB('http://www.example.org/metamodelB');


transformation test(in srcModel:A, out trgModel:B);

main() {
srcModel.rootObjects()[A::Map] -> map toMap();
}

abstract mapping Map:: abstractmapping() : B::Maps {
   name := self.name; 
}
mapping Map:: toMap() : B::Maps 
disjuncts Map :: Map2Map2, Map :: Map2Map {}


abstract mapping Element:: Element2Element() : B::Element {
   name := self.name; 
}

mapping Map :: Map2Map() : B::Map 
inherits Map:: abstractmapping
{
element := self.element -> map Elements();
}

mapping Map :: Map2Map2() : B::Map2 
inherits Map:: abstractmapping
{
}

mapping A::A :: A2A() : B::A
inherits Element:: Element2Element
{
}

mapping A::B :: B2B() : B::B
inherits Element:: Element2Element
{
}

mapping Element:: Elements() : B::Element
disjuncts A::A :: A2A, A::B :: B2B{}



However, in line : element := self.element -> map Elements();

I still get:

The type 'test::Bag(Element)' does not conform to the type 'metamodelB::Element' of the property 'element'


Many thanks in advance!

[Updated on: Mon, 01 November 2021 15:21]

Report message to a moderator

Re: Can we map two abstract classes? [message #1847573 is a reply to message #1847572] Mon, 01 November 2021 16:01 Go to previous messageGo to next message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 116
Registered: April 2011
Senior Member
Hi John

Quote:
The type 'test::Bag(Element)' does not conform to the type 'metamodelB::Element' of the property 'element'

The thing is that you are using the -> notation to invoke your mapping. This implies two things:

1. It implicitly converts the source element into a Set(Element)
2. It invokes the mapping on each element of that Set, resulting in a Bag(Element)

Of course that Bag cannot be assigned to the target element. Use -> only if you are invoking an operation on a collection. Does it work if you just replace the -> notation with the usual . notation?

element := self.element.map Element2Element();



Kind regards
Christopher
Re: Can we map two abstract classes? [message #1847574 is a reply to message #1847573] Mon, 01 November 2021 16:07 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi Christopher,

Thank you for your reply, but now I get the following error:

Can not call abstract mapping 'metamodelA::Element::Element2Element' with abstract out/result parameter type directly. Use with inherits, disjuncts, merges in other mappings
Re: Can we map two abstract classes? [message #1847576 is a reply to message #1847574] Mon, 01 November 2021 16:26 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
It works if I write

element := self.element.map Elements();

Many thanks :)

Just a question out of curiosity. Is this the simplest way how to make this transformation in QVTo?
Re: Can we map two abstract classes? [message #1847583 is a reply to message #1847576] Mon, 01 November 2021 19:46 Go to previous message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 116
Registered: April 2011
Senior Member
John Henbergs wrote on Mon, 01 November 2021 12:26
Is this the simplest way how to make this transformation in QVTo?

It depends on how you define 'simple'. There is no need to use inherits, you can also duplicate the respective code into each mapping. Thereby, you might improve the understandabaility of your transformation but you certainly affect its maintainability.

I see no way to get rid of the disjuncts in your case, but there is something I don't understand. You didn't specify any conditions in your disjunctive mappings, so the disjunction will always execute Map :: Map2Map2 (because it's first), never Map :: Map2Map. Hence you don't need the disjuncts at all.


Kind regards
Christopher

[Updated on: Mon, 01 November 2021 19:46]

Report message to a moderator

Previous Topic:Only recognise the first model type
Next Topic:Create new element in target model
Goto Forum:
  


Current Time: Sat Sep 14 20:48:24 GMT 2024

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

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

Back to the top