Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Inhibiting EMF Lazy Loading For Manual Proxy URI Update
Inhibiting EMF Lazy Loading For Manual Proxy URI Update [message #415506] Wed, 19 December 2007 00:45 Go to next message
David Lynch is currently offline David LynchFriend
Messages: 27
Registered: July 2009
Junior Member
Ed, a while back I asked you about how to deal with a situation regarding
how to update cross document references when the “target” document moves
from one place to another within the Eclipse workspace. You showed me how
to use the URI mapping capability, which was a dream come true:

getResourceSet().getURIConverter().getURIMap().put(aURIOld, aURINew);
EcoreUtil.resolveAll(getPrimaryResource());

This almost worked, but I ran into a snag. In our usage scenario, the
user wants to simply change the cross-document relationship from one
document to another.

Imagine that documents A, B, C are all in the same folder:

Current A->B
Desired A->C

When I use the URI mapping technique, I unload document B causing all of
the cross-references in A to become proxies. Then, using the mapping
technique, I tell EMF the old URI is B and the new URI is C. This works,
with one catch. In certain cases, C may not necessarily have all of the
target objects, causing certain proxies in A will remain unresolved
("broken" links). Those unresolved proxies still point to original
document B. The problem is that if I leave these unchanged, since B still
exists, when default mapping is reinstated and the user reloads A those
links suddenly become valid (i.e., they become valid A->B links). The
user’s intent is to completely sever the relationship between A and B, yet
these residual cases remain.

I was able to overcome this with a kludge where I manually update the URIs
in the unresolved proxies, but I ran into another problem with the mapping
approach. When mapping is used, the Resources in the ResourceSet have are
“spoofed” to reflect the original names (I presume that this is by
design). In other words, when mapping is in effect, in our example
resource “C” appears with URI name “B” in the ResourceSet. In fact, under
certain circumstances the original Resource object instance seems to be
reused (this occurs if B is merely unloaded as opposed to being removed
from the ResourceSet), and this causes problems for technical reasons that
are beyond the scope of this memo; suffice it to say that I need the A to
point to a *different* resource C, not C masquerading as B under the
original Resource instance.

The bottom line is that I need a way to update the proxy URIs manually.
If I can do this, I can overcome all of my issues. Here is my basic
coding:

Iterator litAll = getPrimaryResource().getAllContents();
while (litAll.hasNext())
{
EObject lEObject = (EObject)litAll.next();
List llistReferences = lEObject.eCrossReferences();
for (int liIndex = 0; liIndex < llistReferences.size(); liIndex++)
{
EObject lEObjectRef = (EObject)llistReferences.get(liIndex);
if (lEObjectRef.eIsProxy())
{
InternalEObject lInternalEObject =
(InternalEObject)lEObjectRef;
URI lURIOld = lInternalEObject.eProxyURI();
String lstrFragment = lURIOld.fragment();
URI lURINew = URI.createURI(aURINew.toString() + "#" +
lstrFragment);
lInternalEObject.eSetProxyURI(lURINew);
System.out.println("Fixed="+lEObject);
}
}
}

The problem with this coding is that the mere action of iterating through
the contents causes the proxies to be resolved automatically, and this is
not desired since my objective is to update the URIs *before* this
happens. Is there some way that I can suppress EMF lazy loading
temporarily so that I can manually replace all of the cross-document URIs,
allowing coding as illustrated above to work correctly?

Thanks in advance for all of your help.
Re: Inhibiting EMF Lazy Loading For Manual Proxy URI Update [message #415512 is a reply to message #415506] Wed, 19 December 2007 13:53 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------080302070509030609050607
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

David,

Comments below.

David Lynch wrote:
> Ed, a while back I asked you about how to deal with a situation
> regarding how to update cross document references when the ?target?
> document moves from one place to another within the Eclipse
> workspace. You showed me how to use the URI mapping capability, which
> was a dream come true:
>
> getResourceSet().getURIConverter().getURIMap().put(aURIOld, aURINew);
> EcoreUtil.resolveAll(getPrimaryResource());
>
> This almost worked, but I ran into a snag. In our usage scenario, the
> user wants to simply change the cross-document relationship from one
> document to another.
I see.
>
> Imagine that documents A, B, C are all in the same folder:
>
> Current A->B
> Desired A->C
>
> When I use the URI mapping technique, I unload document B causing all
> of the cross-references in A to become proxies. Then, using the
> mapping technique, I tell EMF the old URI is B and the new URI is C.
> This works, with one catch. In certain cases, C may not necessarily
> have all of the target objects, causing certain proxies in A will
> remain unresolved ("broken" links). Those unresolved proxies still
> point to original document B. The problem is that if I leave these
> unchanged, since B still exists, when default mapping is reinstated
> and the user reloads A those links suddenly become valid (i.e., they
> become valid A->B links). The user?s intent is to completely sever
> the relationship between A and B, yet these residual cases remain.
So you want to find broken proxies before you save I guess.
EcoreUtil.UnresolveProxyCrossReferencer can be useful for that.
>
> I was able to overcome this with a kludge where I manually update the
> URIs in the unresolved proxies, but I ran into another problem with
> the mapping approach. When mapping is used, the Resources in the
> ResourceSet have are ?spoofed? to reflect the original names (I
> presume that this is by design).
The URI of a resource is always based on the actual URI passed to the
getResource method and the URI used for save will be the actual URI of
the containing resource at the time you save. So I imagine you'd want
to rename the resources after they've been loaded and before you save.
> In other words, when mapping is in effect, in our example resource ?C?
> appears with URI name ?B? in the ResourceSet. In fact, under certain
> circumstances the original Resource object instance seems to be reused
> (this occurs if B is merely unloaded as opposed to being removed from
> the ResourceSet), and this causes problems for technical reasons that
> are beyond the scope of this memo; suffice it to say that I need the A
> to point to a *different* resource C, not C masquerading as B under
> the original Resource instance.
The mapping should make it look at the actual input stream for C, but
you'll need to do the renaming if the mapping is to become a permanent
thing reflected in the saved URIs.
>
> The bottom line is that I need a way to update the proxy URIs manually.
That's certainly doable...
> If I can do this, I can overcome all of my issues. Here is my basic
> coding:
>
> Iterator litAll = getPrimaryResource().getAllContents();
> while (litAll.hasNext())
> {
> EObject lEObject = (EObject)litAll.next();
> List llistReferences = lEObject.eCrossReferences();
> for (int liIndex = 0; liIndex < llistReferences.size();
> liIndex++)
> {
> EObject lEObjectRef =
> (EObject)llistReferences.get(liIndex); if
> (lEObjectRef.eIsProxy())
> {
> InternalEObject lInternalEObject =
> (InternalEObject)lEObjectRef;
> URI lURIOld = lInternalEObject.eProxyURI();
> String lstrFragment = lURIOld.fragment();
> URI lURINew = URI.createURI(aURINew.toString() + "#" +
> lstrFragment);
> lInternalEObject.eSetProxyURI(lURINew);
> System.out.println("Fixed="+lEObject);
I guess you are assuming that all problem proxies will be fore the
specific resource being renamed. This seems like a good approach
otherwise.
> }
> }
> }
> The problem with this coding is that the mere action of iterating
> through the contents causes the proxies to be resolved automatically,
> and this is not desired since my objective is to update the URIs
> *before* this happens. Is there some way that I can suppress EMF lazy
> loading temporarily so that I can manually replace all of the
> cross-document URIs, allowing coding as illustrated above to work
> correctly?
The list returned by eCrossReferences is an InternalEList, so I'd
recommend casting to that and calling basicList to get a view over which
you can iterate without resolving proxies.
>
> Thanks in advance for all of your help.
Eclipse accepts donations. :-P
<http://www.eclipse.org/donate/>

http://www.eclipse.org/donate/

>
>


--------------080302070509030609050607
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
David,<br>
<br>
Comments below.<br>
<br>
David Lynch wrote:
<blockquote
cite="mid:4d7fdd56e40160b518ba58490ab0a7d3$1@www.eclipse.org"
type="cite">Ed, a while back I asked you about how to deal with a
situation regarding how to update cross document references when the
&#65533;target&#65533; document moves from one place to another within the Eclipse
workspace.


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Inhibiting EMF Lazy Loading For Manual Proxy URI Update [message #415517 is a reply to message #415512] Wed, 19 December 2007 15:37 Go to previous messageGo to next message
David Lynch is currently offline David LynchFriend
Messages: 27
Registered: July 2009
Junior Member
Thanks Ed, your support and responsiveness have been second to none, I'm
going to lobby the firm I'm working for to make a donation, I think it's
the least we can do.
Re: Inhibiting EMF Lazy Loading For Manual Proxy URI Update [message #415518 is a reply to message #415512] Wed, 19 December 2007 15:53 Go to previous messageGo to next message
David Lynch is currently offline David LynchFriend
Messages: 27
Registered: July 2009
Junior Member
BTW Ed, I'm curious about the UnresolvedProxyCrossreferencer. I was
playing with that last night, and I found that it returned a Map. They
"key" of the Map appears to be the URI of the unresolved reference, while
the "value" seems to be an ArrayList, where each element of the list
specifies the instance of the object (whose reference is unresolved) plus
a feature specification which I'm assuming identifies the association
role. My question is simply this: how should I cast the "value" elements
(i.e., each element of the ArrayList) to make it convenient to access the
information inside? The actual implementation seems to be some internal
class (this is all gleaned from looking at it through the debugger).
Re: Inhibiting EMF Lazy Loading For Manual Proxy URI Update [message #415522 is a reply to message #415518] Wed, 19 December 2007 17:48 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
David,

Wow, your donation was by far the most generous yet! And of course
your comment about EMF was greatly appreciated. Thanks so much!!

The type is Map<EObject, Collection<EStructuralFeature.Setting>>. So
the objects in the collection are StructuralFeature.Setting instances
and there are some useful utility methods in EcoreUtil for working with
settings in addition to the methods on the API itself. (All
multi-valued references implement InternalEList, and
EStructuralFeature.Setting directly.)


David Lynch wrote:
> BTW Ed, I'm curious about the UnresolvedProxyCrossreferencer. I was
> playing with that last night, and I found that it returned a Map.
> They "key" of the Map appears to be the URI of the unresolved
> reference, while the "value" seems to be an ArrayList, where each
> element of the list specifies the instance of the object (whose
> reference is unresolved) plus a feature specification which I'm
> assuming identifies the association role. My question is simply this:
> how should I cast the "value" elements (i.e., each element of the
> ArrayList) to make it convenient to access the information inside?
> The actual implementation seems to be some internal class (this is all
> gleaned from looking at it through the debugger).
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:Problem: I cannot find the metamodel by URI in the register.
Next Topic:rool back on resource creation
Goto Forum:
  


Current Time: Sat Apr 20 01:45:30 GMT 2024

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

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

Back to the top