Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Exception when resolving Cross References
Exception when resolving Cross References [message #1776544] Fri, 17 November 2017 14:11 Go to next message
Adam Bialas is currently offline Adam BialasFriend
Messages: 15
Registered: July 2016
Junior Member
Hi,

I have a problem with resolving cross references. In more details:

I have one resource in which I hold two types of EObjects. Each of types has an ID property (one of the attributes is an ID) so it means they will be referenced from other resources with path and ID as a fragment. Now for different object type I set same ID value. Of course I get validation marker and warning but I can save a file without problem.
Now from another resource, I have a cross reference to one of types described above. Objects are assigned as elements of EcoreEList. Now when I try to open this resource I get exception because EcoreEList try to resolve cross references and it assumes there is only one object with this ID (problem is in EcoreEList class, method protected EObject resolve(int index, EObject eObject)).

Is it possible to somehow fix it?

Adam

Re: Exception when resolving Cross References [message #1776551 is a reply to message #1776544] Fri, 17 November 2017 15:34 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29548
Registered: July 2009
Senior Member
Sorry ID's must be unique regardless of the type of the object involved. You might specialize the resource implementation's getURIFragment/getEObjectByID to add information to the ID about the type.
Re: Exception when resolving Cross References [message #1776643 is a reply to message #1776551] Sun, 19 November 2017 21:29 Go to previous messageGo to next message
Adam Bialas is currently offline Adam BialasFriend
Messages: 15
Registered: July 2016
Junior Member
Hi Ed,

I know IDs should be unique but sometimes it is impossible to force a user to enter unique IDs (forbid saving file with duplicate IDs is not the best solution from user point of view).
I found out that I have this problem especially inside ECrossReferenceEList when it tries to resolve objects which belongs to it via proxy. I thought that maybe customizing this implementation can fix this problem (I can check type of list element and compare with resolved one). However, I do not want to customize each class which has multiple cross reference which are contained in ECrossReferenceEList. Is it possible to do it on core or genmodel level to have it more generic?

Adam
Re: Exception when resolving Cross References [message #1776674 is a reply to message #1776643] Mon, 20 November 2017 08:42 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29548
Registered: July 2009
Senior Member
That's why I'm not generally a big fan of IDs that are under user control. It's clear the user should be forced to make them unique, and if they don't, it clearly will always lead to problems. I would suggest something more like specializing the resource implementation as I mentioned above (to add type information to the actual ID used while saving without changing the actual value in the model). Alternatively you can use a save option such as org.eclipse.emf.ecore.xmi.XMLResource.OPTION_RESOURCE_HANDLER to implement org.eclipse.emf.ecore.xmi.impl.BasicResourceHandler.preSave(XMLResource, OutputStream, Map<?, ?>) to correct any problem (make IDs unique) that the user refuses to correct. Another possible approach is to specialize the property descriptor for the ID features so that when the ID is displayed to the user the "type prefix/suffix/decoration" is stripped and is added back in automatically when the user enters the value.
Re: Exception when resolving Cross References [message #1776677 is a reply to message #1776674] Mon, 20 November 2017 08:54 Go to previous messageGo to next message
Adam Bialas is currently offline Adam BialasFriend
Messages: 15
Registered: July 2016
Junior Member
Hi Ed,

I followed your approach with customizing Resource getEObjectByID(String id) and getURIFragment(EObject eObject). It works correctly but now, in case of duplicates (means the wrong type is returned for given ID) I return null so the cross reference is not resolved. I am going to change it - the solution I want to implement is to search in whole resource content and check object type and id and return the correct one. But searching the whole content will definitelly have an impact on performance. Is there any way to get all EObject with given ID? Map intrinsicIDToEObjectMap contains only one object because of ID as a key.

Adam
Re: Exception when resolving Cross References [message #1776680 is a reply to message #1776677] Mon, 20 November 2017 10:05 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29548
Registered: July 2009
Senior Member
No, the only way to get all objects with a given ID is the second half of the getEObjectByID method, i.e., the only way is to walk the tree. Of course during the tree walk you can build multiple maps or reuse the intrinsic map but with keys that encode the type. This is the only place where you must visit the whole tree and have an opportunity to build a map or maps to avoid repeatedly walking the whole tree...
Re: Exception when resolving Cross References [message #1776867 is a reply to message #1776680] Wed, 22 November 2017 11:31 Go to previous messageGo to next message
Adam Bialas is currently offline Adam BialasFriend
Messages: 15
Registered: July 2016
Junior Member
Thank you for remarks - I was able to do some fixes. However, during implementation, I found some maps like idToEObjectMap or eObjectToIDMap. How they can be used (because in my case they are always empty)?

adam
Re: Exception when resolving Cross References [message #1776870 is a reply to message #1776867] Wed, 22 November 2017 11:59 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 6042
Registered: July 2009
Senior Member
Hi

idToEObjectMap or eObjectToIDMap are very useful IF you want to exploit or take control of the xmi:id allocation. xmi:id values really must be locally (within the file) unique. The maps are populated when a resource with explicit xmi:id's is loaded.

EMF has a default policy using moderately readable hierarchical names that has the benefits of avoiding the need for xmi:id declarations at the expense of potentially long xmi:idref values that are intolerant of non-trivial manual XMI file editing.

You can use an alternate policy by populating the maps yourself during the XMISaveImpl activities.

xmi:ids should not be confused with 'UML' IDs. An xmi:id is not part of the model; it is a model serialization detail. A model stored in an OO database might not use xmi:ids at all.

Regards

Ed Willink
Previous Topic:[Xcore] wrapping an existing enum
Next Topic:Problems with EMF compare representations.aird
Goto Forum:
  


Current Time: Mon Sep 24 13:09:34 GMT 2018

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

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

Back to the top