Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » EAnnotation serialization
EAnnotation serialization [message #660105] Wed, 16 March 2011 20:11 Go to next message
Edgar Mueller is currently offline Edgar Mueller
Messages: 62
Registered: March 2011
Member
Hi,

I have built a custom ECore, where I have an EMap that stores EObjects
with a given ID.
Now, when I'm traversing a given EAnnotation, each component of the
annotation is put in the map, i.e. the source attribute and the like.
Upon serializing my custom ECore to a XMI resource, references to the
components of the annotation are written into the file in the EMF
XPath-like syntax. Unfortunately, when referencing the EAnnotation, it
seems that the source URI is used within the serialization, i.e. some
references look like follows:

" //@modelElement/EString/%http%253A%252F%252F%252Forg%252Fecl ipse%252Femf%252Fecore%252Futil%252FExtendedMetaData%/@detai ls.0 "

Unfortunately, after loading my custom ECore object from the resource
again, some keys of the map are null, i.e. the EAnnotation attributes,
which have been referenced with a String like above. I think this is due
the escaped URI in the rerference string, whereas the URI is unescaped
in the eAnnotations source attribute itself. Encoding the source URI
before serializing solves the problem, but this doesn't seem as it's the
way to go.

I'm wondering whether this behavior is intentional. Are EAnnotations
generally not meant to be referenced? And if not, is there any easy
solution to this? Or am I missing something here?

Thanks for any help
Edgar
Re: EAnnotation serialization [message #660111 is a reply to message #660105] Wed, 16 March 2011 20:58 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Edgar,

Comments below.

Edgar Mueller wrote:
> Hi,
>
> I have built a custom ECore, where I have an EMap that stores EObjects
> with a given ID.
> Now, when I'm traversing a given EAnnotation, each component of the
> annotation is put in the map, i.e. the source attribute and the like.
> Upon serializing my custom ECore to a XMI resource, references to the
> components of the annotation are written into the file in the EMF
> XPath-like syntax. Unfortunately, when referencing the EAnnotation,
> it seems that the source URI is used within the serialization, i.e.
> some references look like follows:
>
> " //@modelElement/EString/%http%253A%252F%252F%252Forg%252Fecl ipse%252Femf%252Fecore%252Futil%252FExtendedMetaData%/@detai ls.0 "
>
It looks like it's been encoded more than once. When I try something
similar, I get

<eAnnotations
source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData"

references=" #//DocumentRoot/file/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fec ore%2Futil%2FExtendedMetaData%/@details.3 ">
>
> Unfortunately, after loading my custom ECore object from the resource
> again, some keys of the map are null, i.e. the EAnnotation attributes,
> which have been referenced with a String like above. I think this is
> due the escaped URI in the rerference string,
The double escaping definitely seems bad, but I'm not sure where that
comes from...
> whereas the URI is unescaped in the eAnnotations source attribute
> itself. Encoding the source URI before serializing solves the problem,
> but this doesn't seem as it's the way to go.
>
> I'm wondering whether this behavior is intentional. Are EAnnotations
> generally not meant to be referenced?
No, it should work.
> And if not, is there any easy solution to this? Or am I missing
> something here?
To try the above, I used the references property of on annotation to
refer to the details entry of another in the same file. I can't think
of where we'd encode it a second time. EModelElementImpl does the
encoding and decoding in eURIFragmentSegment and
eObjectForURIFragmentSegment. Maybe you can set a breakpoint in the
former and see where the fragment ends up and is encoded a second time...
>
> Thanks for any help
> Edgar
Re: EAnnotation serialization [message #660132 is a reply to message #660111] Thu, 17 March 2011 00:21 Go to previous messageGo to next message
Edgar Mueller is currently offline Edgar Mueller
Messages: 62
Registered: March 2011
Member
Thanks for your reply, Ed.
The double escaped string is my bad, I'm sorry about that (the additional encoding was performed by me, please see notes below).
But this does not alter the problem.
Following your advice I've tried to reproduce my problem with the following code snippet:

EClassifier c = EcoreFactory.eINSTANCE.createEClass();
EAnnotation a = EcoreFactory.eINSTANCE.createEAnnotation();
a.setSource("http:///org/eclipse/emf/ecore/util/ExtendedMetaData");
a.getDetails().put("foo", "bar");
a.getDetails().put("foo2", "bar2");
c.getEAnnotations().add(a);

EAnnotation b = EcoreFactory.eINSTANCE.createEAnnotation();
b.getReferences().add((EObject) a.getDetails().get(1));

ResourceSet resourceSet = new ResourceSetImpl();

final Resource resource = resourceSet.createResource(URI.createFileURI(System.getPrope rty( "user.home")
+ File.separator + "foo.tmp"));

resource.getContents().add(c);
resource.getContents().add(b);

resource.save(null);
resource.unload();
resource.load(null);
EAnnotation b2 = (EAnnotation) resource.getContents().get(1);
// fails
assertEquals(b.getReferences().size(), b2.getReferences().size());

The serialized file looks ok:

<?xml version="1.0" encoding="ASCII"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore ">
<ecore:EClass>
<eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="foo" value="bar"/>
<details key="foo2" value="bar2"/>
</eAnnotations>
</ecore:EClass>
<ecore:EAnnotation references=" /0/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExten dedMetaData%/@detai ls.1"/>
</xmi:XMI>

Following your hints I checked the eObjectForURIFragmentSegment method and it seems that is not called at all when loading the resource.
But if the source is double-escaped (via a.setSource(URLEncoder.encode("http:///org/eclipse/emf/ecore/util/ExtendedMetaData"), "ASCII")) it will be called and the test case above is completed successfully.
Digging further I now think I get the problem, but I still don't know whether it's intended (I think it might be related to the device component of a URI).
When I'm manually escaping the URL the colon in the URL is escaped as well. The if clause

else if (id.indexOf(':', 0) != -1)

in XMLHandler#setValueFromId(EObject, EReference, String) is evaluated to false and the references will be loaded as expected.
If I'm not escaping the URL then the colon remains in the URL, therefore the above if-clause evaluates to true and

setFeatureValue(object, eReference, null, -2);

will be called.
Does this make any sense?

Thanks
Re: EAnnotation serialization [message #660263 is a reply to message #660132] Thu, 17 March 2011 15:23 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------090804040505040309070602
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Edgar,

When EcoreResourceFactoryImpl is used to create the resource (as
expected for Ecore serializations), we end up with this:

<ecore:EAnnotation
references=" #/0/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExte ndedMetaData%/@details.1 "/>

The processing for references (setValueFromId) looks for a # to
determine if it's a URI fragment. If not, it looks for a : to determine
if the string is a QName. So without the leading # it thinks its
dealing with a QName. I suppose we could change the code in
EModelElementImpl that does the encoding of the fragment to also encode
":" to avoid this possibility. But I have to wonder why it's necessary
to serialize Ecore without the options normally used by
EcoreResourceFactoryImpl?


Edgar Mueller wrote:
> Thanks for your reply, Ed. The double escaped string is my bad, I'm
> sorry about that (the additional encoding was performed by me, please
> see notes below).
> But this does not alter the problem.
> Following your advice I've tried to reproduce my problem with the
> following code snippet:
>
> EClassifier c = EcoreFactory.eINSTANCE.createEClass();
> EAnnotation a = EcoreFactory.eINSTANCE.createEAnnotation();
> a.setSource("http:///org/eclipse/emf/ecore/util/ExtendedMetaData");
> a.getDetails().put("foo", "bar");
> a.getDetails().put("foo2", "bar2");
> c.getEAnnotations().add(a);
>
> EAnnotation b = EcoreFactory.eINSTANCE.createEAnnotation();
> b.getReferences().add((EObject) a.getDetails().get(1));
>
> ResourceSet resourceSet = new ResourceSetImpl();
>
> final Resource resource =
> resourceSet.createResource(URI.createFileURI(System.getPrope rty(
> "user.home")
> + File.separator + "foo.tmp"));
>
> resource.getContents().add(c);
> resource.getContents().add(b);
>
> resource.save(null);
> resource.unload();
> resource.load(null);
> EAnnotation b2 = (EAnnotation) resource.getContents().get(1);
> // fails
> assertEquals(b.getReferences().size(), b2.getReferences().size());
>
> The serialized file looks ok:
>
> <?xml version="1.0" encoding="ASCII"?>
> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore ">
> <ecore:EClass>
> <eAnnotations
> source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
> <details key="foo" value="bar"/>
> <details key="foo2" value="bar2"/>
> </eAnnotations>
> </ecore:EClass>
> <ecore:EAnnotation references="
> /0/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExten
> dedMetaData%/@detai ls.1"/>
> </xmi:XMI>
>
> Following your hints I checked the eObjectForURIFragmentSegment method
> and it seems that is not called at all when loading the resource.
> But if the source is double-escaped (via
> a.setSource(URLEncoder.encode("http:///org/eclipse/emf/ecore/util/ExtendedMetaData"),
> "ASCII")) it will be called and the test case above is completed
> successfully.
> Digging further I now think I get the problem, but I still don't know
> whether it's intended (I think it might be related to the device
> component of a URI).
> When I'm manually escaping the URL the colon in the URL is escaped as
> well. The if clause
>
> else if (id.indexOf(':', 0) != -1)
>
> in XMLHandler#setValueFromId(EObject, EReference, String) is evaluated
> to false and the references will be loaded as expected. If I'm not
> escaping the URL then the colon remains in the URL, therefore the
> above if-clause evaluates to true and
> setFeatureValue(object, eReference, null, -2);
>
> will be called.
> Does this make any sense?
> Thanks

--------------090804040505040309070602
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Edgar,<br>
<br>
When EcoreResourceFactoryImpl is used to create the resource (as
expected for Ecore serializations), we end up with this:<br>
<blockquote>&lt;ecore:EAnnotation
references="#/0/%<a class="moz-txt-link-freetext" href=" http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExtendedM etaData%/@details.1 "> http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExtendedM etaData%/@details.1 </a>"/&gt;<br>
</blockquote>
The processing for references (setValueFromId) looks for a # to
determine if it's a URI fragment.  If not, it looks for a : to
determine if the string is a QName.  So without the leading # it thinks
its dealing with a QName.  I suppose we could change the code in
EModelElementImpl that does the encoding of the fragment to also encode
":" to avoid this possibility.  But I have to wonder why it's necessary
to serialize Ecore without the options normally used by
EcoreResourceFactoryImpl?<br>
<br>
<br>
Edgar Mueller wrote:
<blockquote cite="mid:ilrjq2$r71$1@news.eclipse.org" type="cite">Thanks
for your reply, Ed. The double escaped string is my bad, I'm sorry
about that (the additional encoding was performed by me, please see
notes below).
<br>
But this does not alter the problem.
<br>
Following your advice I've tried to reproduce my problem with the
following code snippet:
<br>
<br>
    EClassifier c = EcoreFactory.eINSTANCE.createEClass();
<br>
    EAnnotation a = EcoreFactory.eINSTANCE.createEAnnotation();
<br>
    a.setSource(<a class="moz-txt-link-rfc2396E" href="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">"http:///org/eclipse/emf/ecore/util/ExtendedMetaData"</a>);
<br>
    a.getDetails().put("foo", "bar");
<br>
    a.getDetails().put("foo2", "bar2");
<br>
    c.getEAnnotations().add(a);
<br>
<br>
    EAnnotation b = EcoreFactory.eINSTANCE.createEAnnotation();
<br>
    b.getReferences().add((EObject) a.getDetails().get(1));
<br>
<br>
    ResourceSet resourceSet = new ResourceSetImpl();
<br>
<br>
    final Resource resource = 
resourceSet.createResource(URI.createFileURI(System.getPrope rty(
"user.home")
<br>
        + File.separator + "foo.tmp"));
<br>
<br>
    resource.getContents().add(c);
<br>
    resource.getContents().add(b);
<br>
<br>
    resource.save(null);
<br>
    resource.unload();
<br>
    resource.load(null);
<br>
    EAnnotation b2 = (EAnnotation) resource.getContents().get(1);
<br>
    // fails
<br>
    assertEquals(b.getReferences().size(), b2.getReferences().size());
<br>
<br>
The serialized file looks ok:
<br>
<br>
&lt;?xml version="1.0" encoding="ASCII"?&gt;
<br>
&lt;xmi:XMI xmi:version="2.0" xmlns:xmi=<a class="moz-txt-link-rfc2396E" href="http://www.omg.org/XMI">"http://www.omg.org/XMI"</a>
xmlns:ecore=<a class="moz-txt-link-rfc2396E" href="http://www.eclipse.org/emf/2002/Ecore   ">"http://www.eclipse.org/emf/2002/Ecore    "</a>&gt;
<br>
 &lt;ecore:EClass&gt;
<br>
 &lt;eAnnotations
source=<a class="moz-txt-link-rfc2396E" href="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">"http:///org/eclipse/emf/ecore/util/ExtendedMetaData"</a>&gt;
<br>
 &lt;details key="foo" value="bar"/&gt;
<br>
 &lt;details key="foo2" value="bar2"/&gt;
<br>
 &lt;/eAnnotations&gt;
<br>
 &lt;/ecore:EClass&gt;
<br>
 &lt;ecore:EAnnotation references="
/0/%<a class="moz-txt-link-freetext" href="http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExten ">http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExten</a >
dedMetaData%/@detai    ls.1"/&gt;
<br>
&lt;/xmi:XMI&gt;
<br>
<br>
Following your hints I checked the eObjectForURIFragmentSegment method
and it seems that is not called at all when loading the resource.
<br>
But if the source is double-escaped (via
a.setSource(URLEncoder.encode(<a class="moz-txt-link-rfc2396E" href="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">"http:///org/eclipse/emf/ecore/util/ExtendedMetaData"</a>),
"ASCII")) it will be called and the test case above is completed
successfully.
<br>
Digging further I now think I get the problem, but I still don't know
whether it's intended (I think it might be related to the device
component of a URI).
<br>
When I'm manually escaping the URL the colon in the URL is escaped as
well. The if clause
<br>
<br>
     else if (id.indexOf(':', 0) != -1)
<br>
<br>
in XMLHandler#setValueFromId(EObject, EReference, String) is evaluated
to false and the references will be loaded as expected. If I'm not
escaping the URL then the colon remains in the URL, therefore the above
if-clause evaluates to true and <br>
     setFeatureValue(object, eReference, null, -2);
<br>
<br>
will be called.
<br>
Does this make any sense? <br>
Thanks
<br>
</blockquote>
</body>
</html>

--------------090804040505040309070602--
Re: EAnnotation serialization [message #660306 is a reply to message #660263] Thu, 17 March 2011 18:05 Go to previous messageGo to next message
Edgar Mueller is currently offline Edgar Mueller
Messages: 62
Registered: March 2011
Member
Ok, I see, thanks for clarifying that. The thing is, that we are
currently using XMI Resources to serialize our models, but we would also
like to reference ECore from within the same file. So using
ECoreResourceFactoryImpl does not seem to be an option.

Am 17.03.2011 16:23, schrieb Ed Merks:
> Edgar,
>
> When EcoreResourceFactoryImpl is used to create the resource (as
> expected for Ecore serializations), we end up with this:
>
> <ecore:EAnnotation
> references=" #/0/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExte ndedMetaData%/@details.1 "/>
>
> The processing for references (setValueFromId) looks for a # to
> determine if it's a URI fragment. If not, it looks for a : to determine
> if the string is a QName. So without the leading # it thinks its
> dealing with a QName. I suppose we could change the code in
> EModelElementImpl that does the encoding of the fragment to also encode
> ":" to avoid this possibility. But I have to wonder why it's necessary
> to serialize Ecore without the options normally used by
> EcoreResourceFactoryImpl?
>
Re: EAnnotation serialization [message #660315 is a reply to message #660306] Thu, 17 March 2011 20:07 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26141
Registered: July 2009
Senior Member
Edgar,

Comments below.

Edgar Mueller wrote:
> Ok, I see, thanks for clarifying that. The thing is, that we are
> currently using XMI Resources to serialize our models,
And by models, you mean your own model instances as opposed to Ecore
instances.
> but we would also like to reference ECore from within the same file.
So you're nesting Ecore instances into the same files as your instances?
> So using ECoreResourceFactoryImpl does not seem to be an option.
Note that it creates XMIResourceImpls like this:

public Resource createResource(URI uri)
{
XMLResource result =
new XMIResourceImpl(uri)
{
@Override
protected boolean useIDs()
{
return eObjectToIDMap != null || idToEObjectMap != null;
}
};
result.setEncoding("UTF-8");


result.getDefaultSaveOptions().put(XMLResource.OPTION_USE_EN CODED_ATTRIBUTE_STYLE,
Boolean.TRUE);
result.getDefaultSaveOptions().put(XMLResource.OPTION_LINE_W IDTH, 80);
result.getDefaultSaveOptions().put(XMLResource.OPTION_URI_HA NDLER,
new URIHandlerImpl.PlatformSchemeAware());
return result;
}

So what we're mostly talking about is using
OPTION_USE_ENCODED_ATTRIBUTE_STYLE to serialized the resources that
contain Ecore. All the options here are good general purpose ones in
any case...
>
> Am 17.03.2011 16:23, schrieb Ed Merks:
>> Edgar,
>>
>> When EcoreResourceFactoryImpl is used to create the resource (as
>> expected for Ecore serializations), we end up with this:
>>
>> <ecore:EAnnotation
>>
>> references=" #/0/%http:%2F%2F%2Forg%2Feclipse%2Femf%2Fecore%2Futil%2FExte ndedMetaData%/@details.1 "/>
>>
>>
>> The processing for references (setValueFromId) looks for a # to
>> determine if it's a URI fragment. If not, it looks for a : to determine
>> if the string is a QName. So without the leading # it thinks its
>> dealing with a QName. I suppose we could change the code in
>> EModelElementImpl that does the encoding of the fragment to also encode
>> ":" to avoid this possibility. But I have to wonder why it's necessary
>> to serialize Ecore without the options normally used by
>> EcoreResourceFactoryImpl?
>>
Re: EAnnotation serialization [message #660556 is a reply to message #660315] Sat, 19 March 2011 10:37 Go to previous message
Edgar Mueller is currently offline Edgar Mueller
Messages: 62
Registered: March 2011
Member
Thanks Ed! The option you mentioned helped me to solve the problem.
Previous Topic:GSoC 2011 Ideas for EMF
Next Topic:swt emf hibernate databinding
Goto Forum:
  


Current Time: Sat Oct 25 01:48:35 GMT 2014

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

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