Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Repair broken inter-resource references
Repair broken inter-resource references [message #1772836] Sat, 16 September 2017 12:32 Go to next message
Jens Lideström is currently offline Jens LideströmFriend
Messages: 3
Registered: April 2017
Junior Member
I have an EMF model which is divided into different resources. Some object have references to objects in other resources.

Lets call a resource that contains objects with such references for the source resource, and the resource that contains the referenced objects for the target resource.

Sometimes in my application a target resource might be moved. (Users might move the resource files at will.) If that happens the references will be broken. EMF will not find the target resource file. When the source resource is loaded in my application the referenced objects in the moved resource become proxy objects.

Is there some way to "repair" the references in the loaded source resource so that they reference the target resource file with its new URI?

I have access to the new URI of the target resource file. The problem is: how do I set this new URI in the model that is loaded from the source resource file?

A successful repair operation should result in the following:

* When the source resource is saved, the references to the target resource file uses the new URI.
* The next time any of the referenced objects are resolved (with EcoreUtil.resolve) proper objects are loaded from the target file.

I hoped this would be as simple as calling Resource.setURI on the target resource in my resource set. But that apparently don't work.

Maybe I can iterate over all objects in the model, check for proxy objects with a InternalEObject.eProxyURI of the old target resource URI, and replace that with the new URI. But I haven't gotten that to work.

Is there some other way?
Re: Repair broken inter-resource references [message #1772877 is a reply to message #1772836] Mon, 18 September 2017 08:46 Go to previous messageGo to next message
Jens Lideström is currently offline Jens LideströmFriend
Messages: 3
Registered: April 2017
Junior Member
I managed to find and update all broken references in my model.

1) Remove the old target resource from the resource set
2) create a new one with the new target resource URI
3) I traverse all proxies using EcoreUtil.UnresolvedProxyCrossReferencer.find and
4) update all proxy that have the old target URI with the new URI, using InternalEObject.eSetProxyURI
5) use EcoreUtil.resolve on the proxy
6) replace the proxy object with the resolved objects in all features that UnresolvedProxyCrossReferencer.find returns.

Code:
getEditingDomain().getResourceSet().getResources().remove(res);
getEditingDomain().getResourceSet().getResource(newUri, true);

Map<EObject, Collection<Setting>> proxies = UnresolvedProxyCrossReferencer.find(getEditingDomain().getResourceSet());

for (Entry<EObject, Collection<Setting>> entry : proxies.entrySet()) {
	EObject proxy = entry.getKey();
	URI objUri = EcoreUtil.getURI(proxy);

	if (!objUri.trimFragment().equals(missingUri)) continue;
	
	((InternalEObject) proxy).eSetProxyURI(newUri.appendFragment(objUri.fragment()));
	EObject resolved = EcoreUtil.resolve(proxy, getEditingDomain().getResourceSet());

	if (resolved.eIsProxy()) continue;
	
	for (Setting sett : entry.getValue()) {
		if (sett.getEStructuralFeature().isMany()) {
			@SuppressWarnings("unchecked")
			EList<Object> l = (EList<Object>) sett.get(true);
			int proxyIx = l.indexOf(proxy);
			l.set(proxyIx, resolved);
		} else {
			sett.set(resolved);
		}
	}
}


I still don't know if this is a good approach. If anyone can spot any problems with it I'd be happy to here about them.
Re: Repair broken inter-resource references [message #1774291 is a reply to message #1772877] Thu, 12 October 2017 13:47 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 29119
Registered: July 2009
Senior Member
It seems okay. You probably don't need to do any explicit resolution or replacements. That should just happen automatically because you replace the proxy URI of each proxy so that next time it's access it will resolve to the new resource.
Previous Topic:EMF file URI#isPrefix()
Next Topic:NoClassDefFoundError: org/eclipse/emf/ecore/EPackage
Goto Forum:
  


Current Time: Thu Jan 18 12:08:10 GMT 2018

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

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