Dangling EObjects (are in NO resource) during serialization [message #424476] |
Mon, 27 October 2008 22:38 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NO_SPAM.ibm.com
Hi,
During serialization, if an EObject (ObjA) has a reference to another
EObject (ObjB) and ObjB is not in any resource, then the default
XMLSaveImpl/XMLHelperImpl tries to treat ObjB as an object within the
same resource as ObjA. This actually creates an invalid reference.
Usually it creates just "/", and so it returns the first root object in
the resource, which is not the correct one, and probably not even of a
valid type for the feature. Then the when trying to then later read this
back in an InvalidValueException is thrown. Which can be a pain.
Shouldn't it instead be treated as a DanglingHRef so that we can use the
appropriate OPTIONS flag to handle this during serialization, just like
any other dangling reference?
By the way the reason it is not in any resource is that ObjB was simply
removed from the resource. There are times where it is not easy to catch
all the references to this object because they are one-way and there is
no back pointer to ObjA to find it. So it is easier to let the Options
handle it.
--
Thanks,
Rich Kulp
|
|
|
Re: Dangling EObjects (are in NO resource) during serialization [message #424477 is a reply to message #424476] |
Mon, 27 October 2008 22:44 |
Ed Merks Messages: 33136 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
--------------040200040708040909030604
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Rich,
Comments below.
Rich Kulp wrote:
> Hi,
>
> During serialization, if an EObject (ObjA) has a reference to another
> EObject (ObjB) and ObjB is not in any resource, then the default
> XMLSaveImpl/XMLHelperImpl tries to treat ObjB as an object within the
> same resource as ObjA. This actually creates an invalid reference.
> Usually it creates just "/", and so it returns the first root object
> in the resource, which is not the correct one, and probably not even
> of a valid type for the feature. Then the when trying to then later
> read this back in an InvalidValueException is thrown. Which can be a
> pain.
>
> Shouldn't it instead be treated as a DanglingHRef so that we can use
> the appropriate OPTIONS flag to handle this during serialization, just
> like any other dangling reference?
It sounds like related to ResourceImpl producing /-1 rather than /
public String getURIFragment(EObject eObject)
{
String id = EcoreUtil.getID(eObject);
if (id != null)
{
return id;
}
else
{
InternalEObject internalEObject = (InternalEObject)eObject;
if (internalEObject.eDirectResource() == this ||
unloadingContents != null &&
unloadingContents.contains(internalEObject))
{
return "/" + getURIFragmentRootSegment(eObject);
}
else
{
List<String> uriFragmentPath = new ArrayList<String>();
boolean isContained = false;
for (InternalEObject container =
internalEObject.eInternalContainer(); container != null; container =
internalEObject.eInternalContainer())
{
uriFragmentPath.add(container.eURIFragmentSegment(internalEO bject.eContainingFeature(),
internalEObject));
internalEObject = container;
if (container.eDirectResource() == this ||
unloadingContents != null && unloadingContents.contains(container))
{
isContained = true;
break;
}
}
* if (!isContained)
{
return "/-1";
}*
Which is then handled as a dangling reference:
protected String getURIFragment(Resource containingResource,
EObject object)
{
if (roots != null && containingResource == resource &&
!EcoreUtil.isAncestor(roots, object))
{
URI uriResult = handleDanglingHREF(object);
return uriResult == null || !uriResult.hasFragment() ? null :
uriResult.fragment();
}
else
{
String result = containingResource.getURIFragment(object);
if (result.length() > 0 && result.charAt(0) != '/')
{
String query = getURIFragmentQuery(containingResource, object);
if (query != null)
{
result += "?" + query + "?";
}
}
*else if ("/-1".equals(result))*
{
if (object.eResource() != containingResource)
{
URI uriResult = handleDanglingHREF(object);
return uriResult == null || !uriResult.hasFragment() ?
null : uriResult.fragment();
}
}
>
> By the way the reason it is not in any resource is that ObjB was
> simply removed from the resource. There are times where it is not easy
> to catch all the references to this object because they are one-way
> and there is no back pointer to ObjA to find it. So it is easier to
> let the Options handle it.
Perhaps specialized ResourceImpls are part of the equation. I recall
this changing a few years ago...
--------------040200040708040909030604
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Rich,<br>
<br>
Comments below.<br>
<br>
Rich Kulp wrote:
<blockquote cite="mid:ge5fsa$adg$1@build.eclipse.org" type="cite">Hi,
<br>
<br>
During serialization, if an EObject (ObjA) has a reference to another
EObject (ObjB) and ObjB is not in any resource, then the default
XMLSaveImpl/XMLHelperImpl tries to treat ObjB as an object within the
same resource as ObjA. This actually creates an invalid reference.
Usually it creates just "/", and so it returns the first root object in
the resource, which is not the correct one, and probably not even of a
valid type for the feature. Then the when trying to then later read
this back in an InvalidValueException is thrown. Which can be a pain.
<br>
<br>
Shouldn't it instead be treated as a DanglingHRef so that we can use
the appropriate OPTIONS flag to handle this during serialization, just
like any other dangling reference?
<br>
</blockquote>
It sounds like related to ResourceImpl producing /-1 rather than /<br>
<blockquote><small> public String getURIFragment(EObject eObject)<br>
{<br>
String id = EcoreUtil.getID(eObject);<br>
if (id != null)<br>
{<br>
return id;<br>
}<br>
else<br>
{<br>
InternalEObject internalEObject = (InternalEObject)eObject;<br>
if (internalEObject.eDirectResource() == this ||
unloadingContents != null &&
unloadingContents.contains(internalEObject))<br>
{<br>
return "/" + getURIFragmentRootSegment(eObject);<br>
}<br>
else<br>
{<br>
List<String> uriFragmentPath = new
ArrayList<String>();<br>
boolean isContained = false;<br>
for (InternalEObject container =
internalEObject.eInternalContainer(); container != null; container =
internalEObject.eInternalContainer())<br>
{<br>
uriFragmentPath.add(container.eURIFragmentSegment(internalEO bject.eContainingFeature(),
internalEObject));<br>
internalEObject = container;<br>
if (container.eDirectResource() == this || unloadingContents
!= null && unloadingContents.contains(container))<br>
{<br>
isContained = true;<br>
break;<br>
}<br>
}<br>
<br>
<b> if (!isContained)<br>
{<br>
return "/-1";<br>
}</b></small><br>
</blockquote>
<br>
Which is then handled as a dangling reference:<br>
<blockquote><small> protected String getURIFragment(Resource
containingResource, EObject object)</small><br>
<small> {</small><br>
<small> if (roots != null && containingResource ==
resource && !EcoreUtil.isAncestor(roots, object))</small><br>
<small> {</small><br>
<small> URI uriResult = handleDanglingHREF(object);</small><br>
<small> return uriResult == null || !uriResult.hasFragment() ?
null : uriResult.fragment();</small><br>
<small> }</small><br>
<small> else</small><br>
<small> {</small><br>
<small> String result =
containingResource.getURIFragment(object);</small><br>
<small> if (result.length() > 0 && result.charAt(0)
!= '/')</small><br>
<small> {</small><br>
<small> String query = getURIFragmentQuery(containingResource,
object);</small><br>
<small> if (query != null)</small><br>
<small> {</small><br>
<small> result += "?" + query + "?";</small><br>
<small> }</small><br>
<small> }</small><br>
<small> <b>else if ("/-1".equals(result))</b></small><br>
<small> {</small><br>
<small> if (object.eResource() != containingResource)</small><br>
<small> {</small><br>
<small> URI uriResult = handleDanglingHREF(object);</small><br>
<small> return uriResult == null || !uriResult.hasFragment()
? null : uriResult.fragment();</small><br>
<small> }</small><br>
<small> }</small><br>
</blockquote>
<blockquote cite="mid:ge5fsa$adg$1@build.eclipse.org" type="cite"><br>
By the way the reason it is not in any resource is that ObjB was simply
removed from the resource. There are times where it is not easy to
catch all the references to this object because they are one-way and
there is no back pointer to ObjA to find it. So it is easier to let the
Options handle it.
<br>
</blockquote>
Perhaps specialized ResourceImpls are part of the equation. I recall
this changing a few years ago...<br>
</body>
</html>
--------------040200040708040909030604--
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.01643 seconds