Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » QVT-OML » Support of metamodels referencing other metamodels
Support of metamodels referencing other metamodels [message #1836846] Fri, 15 January 2021 14:08 Go to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 285
Registered: August 2013
Senior Member
Hi

Here is a sample project: https://github.com/AresEkb/test_qvto_nsuri

It contains a simple Ecore-metamodel and a simple QVTo-transformation.

The metamodel refers to another metamodel ( http://www.eclipse.org/ocl/2015/Pivot ). It doesn't matter what model is referred. I have the same problem for any referenced metamodel.

One can run a nested Eclipse instance, open the transformation in QVTo editor. The transformation doesn't have any validation errors.

However if you will open it in the initial Eclipse instance (not the nested one), then you will get the following error:
"Type mismatch: can not convert from 'null' to 'pivot::State' type"
index.php/fa/39739/0/

The problem is that GenModel wizard replaces the following line in the ecore file:
    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="ecore:EClass http://www.eclipse.org/ocl/2015/Pivot#//State"/>
by this one
    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="ecore:EClass ../../org.eclipse.ocl.pivot/model/Pivot.ecore#//State"/>

So QVTo is unable to resolve the reference to State class anymore. If one reverts this line, then QVTo works fine again.

I understand why GenModel replaces the URI:
1) The GenModel-file references ../../org.eclipse.ocl.pivot/model/Pivot.genmodel#//pivot
2) Pivot.genmodel references ../../org.eclipse.ocl.pivot/model/Pivot.ecore
3) So my.ecore file should containt the same relative reference to Pivot.ecore

If I'll replace the relative URI by http://www.eclipse.org/ocl/2015/Pivot then my.genmodel will stop working, because it will reference a static EPackage ( http://www.eclipse.org/ocl/2015/Pivot ) and a dynamic EPackage ( ../../org.eclipse.ocl.pivot/model/Pivot.ecore ) at the same time:
"The package 'http://www.eclipse.org/ocl/2015/Pivot#/' has the same namespace URI 'http://www.eclipse.org/ocl/2015/Pivot' as package 'platform:/resource/org.eclipse.ocl.pivot/model/Pivot.ecore#P-pivot'"

So if my ecore-file contains relative URI, then GenModel works fine. And if it contains a http URI, then QVTo works fine. I spend two days to understand it :)

Could you please help to fix it?
Re: Support of metamodels referencing other metamodels [message #1836861 is a reply to message #1836846] Fri, 15 January 2021 19:05 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7169
Registered: July 2009
Senior Member
Hi

Welcome to the wonderful world of metamodel schizophrenia. IMHO EMF's biggest design error.

You must decide which alternative to use and only use that and do so consistently everywhere. Much easier said than done since each tool has its own inconsistent approaches to ease (complicate) the situation.

I have often found it impossible, so OCL provides its StandaloneProjectMap/ProjectMap that can impose the principle that attempts to load a diversity of same-nsURI EPackages result in a single load. This can solve the problem but can be troublesome to get the classpath and priorities right. StandaloneProjectMap is based on original ideas from MWE's StandaloneSetup that are partially available using the EcorePlugin.ExtensionProcessor. Skilled use of the ExtensionProcessor can sometimes solve the problem.

/org.eclipse.ocl.examples.build/src/org/eclipse/ocl/examples/build/GeneratePivotModel.mwe2 demonstrates using a QVTo tx chain as part of the conversion from Pivot.uml to Java to demonstrate that the Pivot OCL metamodel is 'UML aligned'. It's rather a long chain to study so you might find /org.eclipse.ocl.examples.xtext2lpg/src/org/eclipse/ocl/examples/xtext2lpg/GenerateLPG.mwe2 easier; it converts an LL Xtext grammar to an LALR LPG enabling shift/reduce-reduce checks to detect grammar ambiguities.

Regards

Ed Willink
Re: Support of metamodels referencing other metamodels [message #1836863 is a reply to message #1836861] Fri, 15 January 2021 21:00 Go to previous messageGo to next message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 69
Registered: April 2011
Member
Ed Willink wrote on Fri, 15 January 2021 14:05

You must decide which alternative to use and only use that and do so consistently everywhere.

I basically agree, but this time it actually seems to be a QVTo bug. Even if I change the metamodel URI to platform:/plugin/org.eclipse.ocl.pivot/model/Pivot.ecore#T-pivot-State, the error remains. More previsely, it changes to "Type mismatch: can not convert from 'pivot::State' to 'pivot::State' type", which clearly indicates the metamodel schizophrenia. However QVTo should be able to handle this case, I will have a look into it soon.

Denis, if you just want to make your transformation compile, try the following:
var q1 = self.ref1;

This should compile because it omits the State type, but I'm not sure whether it runs successfully.
Re: Support of metamodels referencing other metamodels [message #1836867 is a reply to message #1836863] Sat, 16 January 2021 04:54 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 285
Registered: August 2013
Senior Member
Thanks a lot for your answers!

I can workaround this problem by an explicit type cast:
var q1 : OCL::State := self.ref1.oclAsType(OCL::State).deepclone();
At least it doesn't show validation errors.

However it is not applicable to a more complicated scenarios. For example, if my class (MY::MyClass) has a super class from an external metamodel (OCL::State):
mapping MY::MyClass::baseMapping() : OCL::State
{
}

mapping MY::MyClass::derivedMapping() : MY::MyClass
inherits MY::MyClass::baseMapping
{
}
The code is wrong, because I guess that a classes should not be derived from Pivot classes. However, it just demonstrates the problem.

Because of the bug the super type of MY:MyClass is null. And there is no a workaround for such a QVTo mappings.
index.php/fa/39741/0/

I get the error:
"Mapping operation 'my::MyClass::baseMapping' has non-conformant signature for 'inherits' in 'my::MyClass::derivedMapping'"
Re: Support of metamodels referencing other metamodels [message #1836868 is a reply to message #1836867] Sat, 16 January 2021 07:44 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7169
Registered: July 2009
Senior Member
Hi

Quote:
I basically agree, but this time it actually seems to be a QVTo bug.


Discussion moved to https://bugs.eclipse.org/bugs/show_bug.cgi?id=570407

Regards

Ed Willink
Re: Support of metamodels referencing other metamodels [message #1836903 is a reply to message #1836867] Mon, 18 January 2021 11:50 Go to previous messageGo to next message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 69
Registered: April 2011
Member
Denis, try to manually set up your metamodel as follows:

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="my" nsURI="http://www.example.org/my" nsPrefix="my">
  <eClassifiers xsi:type="ecore:EClass" name="MyClass">
    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="ecore:EClass http://www.eclipse.org/ocl/2015/Pivot#//State"/>
  </eClassifiers>
</ecore:EPackage>


This way, the namespace URI of Pivot is used, so that QVTo won't load the same package twice. That works for me.

The problem I see is that there is no UI support for referencing packages like above. "Load Resource..." allows to select a namespace URI, but then replaces that one with the platform:/plugin URI (otherwise it wouldn't load a resource, so the clue is in the name).
Re: Support of metamodels referencing other metamodels [message #1837016 is a reply to message #1836903] Thu, 21 January 2021 05:06 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 285
Registered: August 2013
Senior Member
I can change URI manually, and it will fix QVTo. However it will break GenModel:
index.php/fa/39764/0/

I get the error:

"The package 'http://www.eclipse.org/ocl/2015/Pivot#/' has the same namespace URI 'http://www.eclipse.org/ocl/2015/Pivot' as package 'platform:/resource/org.eclipse.ocl.pivot/model/Pivot.ecore#P-pivot'"

The problem is that
1) my.genmodel refers to ../../org.eclipse.ocl.pivot/model/Pivot.genmodel
2) Pivot.genmodel refers to Pivot.ecore
3) Pivot.ecore is resolved to platform:/resource/org.eclipse.ocl.pivot/model/Pivot.ecore
4) However my.ecore refers to http://www.eclipse.org/ocl/2015/Pivot
5) As a result 3 and 4 confilcts

So it seems that the only right way to refer ecore-files is to use a relative URIs like ../../org.eclipse.ocl.pivot/model/Pivot.ecore

I guess that QVTo should be able to resolve such a relative URIs.
Re: Support of metamodels referencing other metamodels [message #1837018 is a reply to message #1837016] Thu, 21 January 2021 05:31 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 285
Registered: August 2013
Senior Member
Here is even a simpler example:

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="my" nsURI="http://www.example.org/my" nsPrefix="my">
  <eClassifiers xsi:type="ecore:EClass" name="MyClass">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="attr1" eType="ecore:EDataType ../../org.eclipse.emf.ecore/model/Ecore.ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>


modeltype MY uses 'http://www.example.org/my';

transformation NewTransformation(in my : MY);

main() {
}

mapping MY::MyClass::toMyClass()
{
    var q2 : String := self.attr1;
}


The type of attr1 is null.

For sure I can replace "../../org.eclipse.emf.ecore/model/Ecore.ecore#//EString" by "http://www.eclipse.org/emf/2002/Ecore#//EString". It will fix QVTo and even will not break GenModel. However GenModel will raise the following error during code generation:

org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap - Conflicting access to 'platform:/resource/org.eclipse.emf.ecore/model/Ecore.ecore' or 'platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore' already accessed as 'http://www.eclipse.org/emf/2002/Ecore'

It seems to be a non critical error. I guess that Ecore metamodel is handled differently. However for other metamodels the usage of http URIs breaks GenModel completly.

So I decided that only relative URIs (../../) should be used. I guess that http URIs should be used in model instances only, not in ecore-files. Maybe I'm wrong.
Re: Support of metamodels referencing other metamodels [message #1837019 is a reply to message #1837018] Thu, 21 January 2021 06:29 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7169
Registered: July 2009
Senior Member
Hi

"org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap - Conflicting access to" is indeed non-critical. It tells you that a metamodel schizophrenia has been avoided by replacing references to one possibility by another.

You can make the warning go away by e.g.

		//
		// http://www.eclipse.org/emf/2002/Ecore is referenced by just about any model load
		// Ecore.core is referenced from Ecore.genmodel that is used by the CG to coordinate Ecore objects with their Java classes
		// therefore suppress diagnostics about confusing usage.
		//
		projectManager.configureLoadFirst(resourceSet, EcorePackage.eNS_URI);


The StandaloneProjectMap, IProjectDescriptor and IPackageDescriptor configure methods give considerable flexibility as to the strategy used to select the metamodel resolution, and the strategy used to diagnose the resolution.

Regards

Ed Willink
Re: Support of metamodels referencing other metamodels [message #1837023 is a reply to message #1837016] Thu, 21 January 2021 08:04 Go to previous messageGo to next message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 69
Registered: April 2011
Member
Denis Nikiforov wrote on Thu, 21 January 2021 00:06
I can change URI manually, and it will fix QVTo. However it will break GenModel:

What if you just reinitialize your genmodel from scratch after the metamodel modification? I just did that (see attachment) and it doesn't show any errors. The generated code is the same.
  • Attachment: my.genmodel
    (Size: 0.97KB, Downloaded 21 times)
Re: Support of metamodels referencing other metamodels [message #1837024 is a reply to message #1837023] Thu, 21 January 2021 08:10 Go to previous messageGo to next message
Denis Nikiforov is currently offline Denis NikiforovFriend
Messages: 285
Registered: August 2013
Senior Member
Actually it's a one more crazy stuff on GenModel :) Yes, reinitializtion fixes GenModel. But when you reopen the genmodel editor, the error appears again. I could ignore this error message and keep using GenModel. However, this error partially breakes code generation procedure, and GenModel generates a little bit different (wrong) code.
Re: Support of metamodels referencing other metamodels [message #1837037 is a reply to message #1837024] Thu, 21 January 2021 09:43 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7169
Registered: July 2009
Senior Member
Hi

Consider the definition of Ecore's ENamedElement::name as an EString while loading ..../Ecore.ecore.

If the reference is to http://www.eclipse.org/emf/2002/Ecore#//EString then the currently being loaded Ecore uses a previously Java compiled EString which might be different to the EString in ..../Ecore.ecore.

If the reference is ..../Ecore.ecore#//EString then the currently being loaded Ecore uses a dynamically loaded EString which if the path is consistent is the current EString.

The problem is that at the self-recursive M3, loading the metamodel of everything requires a pre-existing definiton of String in order to support definition of its siblings. UML broke the cycle with a PrimitiveTypes package. EMF ducks the issue by just referencing #//EString, which might be right, but when you study the EMF code you will find a few areas where EDataType nsURIs are special cased to cope with the use of the 'wrong' one. This special casing does not extend to user metamodels and so we have the nightmare.

In my.ecore you should certainly refer to http://www.eclipse.org/emf/2002/Ecore#//EString since that is what EMF requires and will satisfactorily resolve to the Java singleton.

However if you load a genmodel there is no post-genmodel variant, just the pre-genmodel Ecore.genmodel in which you will find Ecore.ecore#//EString ensuring that your ResourceSet will have both a dynamically loaded Ecore.ecore and a statically loaded Java to provoke all the metamodel schizophrenia hazards.

You could avoid the misload by using a modified EMF -- very unattractive prospect.
You could avoid the misload by using a modified Ecore.genmodel -- fairly unattractive
You could modify the loader 's registrations to suppress the misload -- what StandaloneProjectMap does
You could modify all downstream usage to accommodate the misload -- very unattractive prospect

You should find that the OCL/ QVTd projects have many examples of models that support the solution that I have eventually struggled to come up with.

I just tried manually reloading QVTbase.genmodel and it makes no changes to the genmodel. The QVTbase.ecore is rewritten without using xmi:ids, but that is a different issue [1].

Regards

Ed Willink

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=570541
Re: Support of metamodels referencing other metamodels [message #1837043 is a reply to message #1837024] Thu, 21 January 2021 10:45 Go to previous message
Christopher Gerking is currently offline Christopher GerkingFriend
Messages: 69
Registered: April 2011
Member
Denis Nikiforov wrote on Thu, 21 January 2021 03:10
Actually it's a one more crazy stuff on GenModel :) Yes, reinitializtion fixes GenModel. But when you reopen the genmodel editor, the error appears again. I could ignore this error message and keep using GenModel. However, this error partially breakes code generation procedure, and GenModel generates a little bit different (wrong) code.

I see. Apparently using an nsURI to cross-reference other ecore files seems not to be fully supported by EMF, at least not when it comes to genmodels.

Thus we can only follow Ed's advise and integrate a workaround into QVTo. Continuing the discussion on https://bugs.eclipse.org/bugs/show_bug.cgi?id=570407.
Previous Topic:QVTo transformation from command line
Next Topic:allSubobjectsOfType works with some types.
Goto Forum:
  


Current Time: Thu Jun 17 06:52:31 GMT 2021

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

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

Back to the top