Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » XMI Cross Document Reference with ID only(How to de-/serialize the href for cross-document references with the object ID only.)
XMI Cross Document Reference with ID only [message #1694363] Mon, 04 May 2015 19:36 Go to next message
Phil F. is currently offline Phil F.Friend
Messages: 7
Registered: July 2010
Junior Member
Hi there,

I am currently looking into a problem concerning cross-document references.

I have a quite simple model with two classes (ClassA and ClassB). Both contain an ID. ClassB can reference multiple instances of ClassA. Furthermore as shown in the code I store all ClassA instances in resourceA and all ClassB instances in resourceB:

public class RefExample {

	public static void main(String[] args) {

		RefExampleFactory fac =  RefExampleFactory.eINSTANCE;
		
		ClassA classA1 =  fac.createClassA();
		ClassA classA2 =  fac.createClassA();
		classA1.setId(UUID.randomUUID().toString());
		classA2.setId(UUID.randomUUID().toString());
		
		ClassB classB = fac.createClassB();
		classB.setId(UUID.randomUUID().toString());
		classB.getClassRefs().add(classA1);
		classB.getClassRefs().add(classA2);		
		
		Map<String, Object> m = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
		m.put("refSample", new XMIResourceFactoryImpl());

		ResourceSet resSet = new ResourceSetImpl();

		Resource resourceA = resSet.createResource(URI.createURI("sample/ClassA.refSample"));
		Resource resourceB = resSet.createResource(URI.createURI("sample/ClassB.refSample"));

		resourceA.getContents().add(classA1);
		resourceA.getContents().add(classA2);
		
		resourceB.getContents().add(classB);

		try {
			resourceA.save(Collections.EMPTY_MAP);
			resourceB.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


Opening the resourceB in a text editor shows the following correct output Smile :

<?xml version="1.0" encoding="ASCII"?>
<cdr_ex:ClassB xmi:version="2.0" xmlns:xmi="..." xmlns:cdr_ex=".../v1" id="0f1b34a0-ce9f-4ab3-beff-ef58ff12ec49">
  <classRefs href="sample/ClassA.refSample#39dcdef5-b623-4c17-9c4a-7f8389cd15ec"/>
  <classRefs href="sample/ClassA.refSample#7d5cb689-8937-4c86-a35b-06bebee26337"/>
</cdr_ex:ClassB>


But what I would like to have is, that href does not contain the resource path but only the unique ID. For serialization I would like to just write the ID to the XMI file. For deserialization I would like to match the ID to all known IDs of all loaded resources. If the resource is not yet loaded in the ResourceSet I expect an exception or similar. So what I would like to deal with in the XMI is:

<?xml version="1.0" encoding="ASCII"?>
<cdr_ex:ClassB xmi:version="2.0" xmlns:xmi="..." xmlns:cdr_ex=".../v1" id="0f1b34a0-ce9f-4ab3-beff-ef58ff12ec49">
  <classRefs href="39dcdef5-b623-4c17-9c4a-7f8389cd15ec"/>
  <classRefs href="7d5cb689-8937-4c86-a35b-06bebee26337"/>
</cdr_ex:ClassB>


Does anyone have a good idea of how to implement this behavior?

Thanks
Re: XMI Cross Document Reference with ID only [message #1694396 is a reply to message #1694363] Tue, 05 May 2015 05:32 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
Phil,

Comments below.


On 04/05/2015 9:36 PM, Phil F. wrote:
> Hi there,
>
> I am currently looking into a problem concerning cross-document
> references.
>
> I have a quite simple model with two classes (ClassA and ClassB). Both
> contain an ID. ClassB can reference multiple instances of ClassA.
> Furthermore as shown in the code I store all ClassA instances in
> resourceA and all ClassB instances in resourceB:
>
>
> public class RefExample {
>
> public static void main(String[] args) {
>
> RefExampleFactory fac = RefExampleFactory.eINSTANCE;
>
> ClassA classA1 = fac.createClassA();
> ClassA classA2 = fac.createClassA();
> classA1.setId(UUID.randomUUID().toString());
> classA2.setId(UUID.randomUUID().toString());
>
> ClassB classB = fac.createClassB();
> classB.setId(UUID.randomUUID().toString());
> classB.getClassRefs().add(classA1);
> classB.getClassRefs().add(classA2);
>
> Map<String, Object> m =
> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap();
> m.put("refSample", new XMIResourceFactoryImpl());
>
> ResourceSet resSet = new ResourceSetImpl();
>
> Resource resourceA =
> resSet.createResource(URI.createURI("sample/ClassA.refSample"));
> Resource resourceB =
> resSet.createResource(URI.createURI("sample/ClassB.refSample"));
>
> resourceA.getContents().add(classA1);
> resourceA.getContents().add(classA2);
>
> resourceB.getContents().add(classB);
>
> try {
> resourceA.save(Collections.EMPTY_MAP);
> resourceB.save(Collections.EMPTY_MAP);
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
> }
>
>
> Opening the resourceB in a text editor shows the following correct
> output :) :
>
>
> <?xml version="1.0" encoding="ASCII"?>
> <cdr_ex:ClassB xmi:version="2.0" xmlns:xmi="..." xmlns:cdr_ex=".../v1"
> id="0f1b34a0-ce9f-4ab3-beff-ef58ff12ec49">
> <classRefs
> href="sample/ClassA.refSample#39dcdef5-b623-4c17-9c4a-7f8389cd15ec"/>
> <classRefs
> href="sample/ClassA.refSample#7d5cb689-8937-4c86-a35b-06bebee26337"/>
> </cdr_ex:ClassB>
>
>
> But what I would like to have is, that href does not contain the
> resource path but only the unique ID.
It's a cross document reference so that's pretty much contradictory...
> For serialization I would like to just write the ID to the XMI file.
> For deserialization I would like to match the ID to all known IDs of
> all loaded resources. If the resource is not yet loaded in the
> ResourceSet I expect an exception or similar. So what I would like to
> deal with in the XMI is:
>
>
> <?xml version="1.0" encoding="ASCII"?>
> <cdr_ex:ClassB xmi:version="2.0" xmlns:xmi="..." xmlns:cdr_ex=".../v1"
> id="0f1b34a0-ce9f-4ab3-beff-ef58ff12ec49">
> <classRefs href="39dcdef5-b623-4c17-9c4a-7f8389cd15ec"/>
> <classRefs href="7d5cb689-8937-4c86-a35b-06bebee26337"/>
> </cdr_ex:ClassB>
>
>
> Does anyone have a good idea of how to implement this behavior?
You'd need to specialize a bunch of things like XMLHelperImpl,
XMLSaveImpl, and XMLHandler. But I don't understand your ultimate
design goal; I doubt how you're trying to achieve it is ideal... After
all, how will you know which resources need to be loaded which total set
of resources needed to be loaded and in which order?
>
> Thanks
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XMI Cross Document Reference with ID only [message #1694784 is a reply to message #1694396] Thu, 07 May 2015 20:45 Go to previous messageGo to next message
Philipp M. Fischer is currently offline Philipp M. FischerFriend
Messages: 67
Registered: November 2010
Location: Germany
Member
Hi Ed,

thanks for your comments. You actually made me rethink my design goal. And, after looking into some more details of the EMF code I think I have to change my approach.

Nevertheless, I will try to explain what was initially intended: I discovered difficulties handling rename actions from an explorer/navigator view on an xmi serialized model. This means I renamed such a file, and opening another one which used to have references to it is failing to correctly load and reference the model. Accordingly I thought it might be a nice way of just loading all resources stored nested in a project. Then somehow index contained IDs and use this index to perform the cross referencing. But now I see, that I will have to load all models, hence won't be able to benefit from all the proxying in between and so on.
Re: XMI Cross Document Reference with ID only [message #1694805 is a reply to message #1694784] Fri, 08 May 2015 04:45 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
Phil,

Comments below.


On 07/05/2015 10:45 PM, Phil F. wrote:
> Hi Ed,
>
> thanks for your comments. You actually made me rethink my design goal.
:-)
> And, after looking into some more details of the EMF code I think I
> have to change my approach.
I see.
>
> Nevertheless, I will try to explain what was initially intended: I
> discovered difficulties handling rename actions from an
> explorer/navigator view on an xmi serialized model.
Yes, because of course all references will be using the original name
relative path to the resource.
> This means I renamed such a file, and opening another one which used
> to have references to it is failing to correctly load and reference
> the model.
Eclipse has things like refactoring participants that could kick in to
"refactor" things affected by the renaming...
> Accordingly I thought it might be a nice way of just loading all
> resources stored nested in a project.
Assuming the references are (always) in the same project...
> Then somehow index contained IDs and use this index to perform the
> cross referencing.
Yes given they use UUIDs, that should be enough to identify the target.
Note that you could serialize using an XMIResourceImpl with useUUIDs
overridden to be true such that you don't need to model and initialize
the ID in the model instances but rather allow the resource to assign
and manage them...
> But now I see, that I will have to load all models, hence won't be
> able to benefit from all the proxying in between and so on.
Indeed. Life is a tradeoff. I'm not sure how often or important
renaming/moving of resources is. This is of course a general problem,
e.g., a *.genmodel always refers to the *.ecore, but mostly people just
live with that problem. A refactoring participant (I've never written
a complete one myself) might be the best approach; that way the expense
of indexing could be deferred until it's actually needed...


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:Prefix for Enums
Next Topic:Editing a cdo model on a client programmatically
Goto Forum:
  


Current Time: Thu Apr 25 06:49:26 GMT 2024

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

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

Back to the top