Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » EcoreUtil.getURI(feature)(EcoreUtil.getURI(feature) returns an unusable uri)
EcoreUtil.getURI(feature) [message #1219575] Wed, 04 December 2013 17:28 Go to next message
Geoffry Roberts is currently offline Geoffry RobertsFriend
Messages: 29
Registered: March 2011
Junior Member
All,

I have an EMF document that I'm trying to persist. At one point in the persistence process, a FeatureMap is encountered where we loop through the contained entries to get a uri for each entry:

EStructuralFeature feature = entry.getEStructuralFeature();
EcoreUtil.getURI(feature);

The call to EcoreUtil.getURI(feature) returns a usable uri until a feature that contains embedded XML is encountered. At this point, a uri is returned that starts with "#///DocumentRoot/"<name of embedded xml node>.

Why does this happen?

What I would really like is to get this embedded xml returned as a string. Is there a way of getting this result?
Re: EcoreUtil.getURI(feature) [message #1219580 is a reply to message #1219575] Wed, 04 December 2013 18:04 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31780
Registered: July 2009
Senior Member
Geoffry,

Comments below.

On 04/12/2013 6:28 PM, Geoffry Roberts wrote:
> All,
>
> I have an EMF document that I'm trying to persist. At one point in
> the persistence process, a FeatureMap is encountered where we loop
> through the contained entries to get a uri for each entry:
>
> EStructuralFeature feature = entry.getEStructuralFeature();
> EcoreUtil.getURI(feature);
>
> The call to EcoreUtil.getURI(feature) returns a usable uri
Usable for what?
> until a feature that contains embedded XML is encountered. At this
> point, a uri is returned that starts with "#///DocumentRoot/"<name of
> embedded xml node>.
There is demand created metadata for processing things like wildcards
and such things aren't contained by a resource.
>
> Why does this happen?
> What I would really like is to get this embedded xml returned as a
> string. Is there a way of getting this result?
You can try org.eclipse.emf.ecore.xmi.XMLResource.OPTION_ROOT_OBJECTS
specifying the EObject you want to write out. You can use
org.eclipse.emf.ecore.xmi.XMLResource.save(Writer, Map<?, ?>) to write
directly to a StringWriter...


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EcoreUtil.getURI(feature) [message #1219599 is a reply to message #1219580] Wed, 04 December 2013 20:36 Go to previous messageGo to next message
Geoffry Roberts is currently offline Geoffry RobertsFriend
Messages: 29
Registered: March 2011
Junior Member
"Unusable" is what I am calling anything that starts with #///DocumentRoot/. The reason it is unusable is because when converted to a ExtensibleURIConverterImpl.normalize(URI uri) it returns as "file:///"<the directory from which the program was launched>--not good.

In the xml below, everything within the <text> node is generated as a FeatureMap. When looping throughout the contained entries the continued features return from EcoreUtil.getURI(feature); as #///DocumentRoot/.

<text>
<content styleCode="Bold">Henry Levin, the 7<sup>th</sup></content>
is a 67 year old male referred for further asthma management. Onset of asthma in his
<content revised="delete">twenties</content>
<content revised="insert">teens</content>.
He was hospitalized twice last year, and already twice this year. He has not been able to be
weaned off steroids for the past several months.
</text>

I hope this helps.
...
Re: EcoreUtil.getURI(feature) [message #1219609 is a reply to message #1219599] Wed, 04 December 2013 22:08 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31780
Registered: July 2009
Senior Member
Geoffry,

Comments below.

On 04/12/2013 9:36 PM, Geoffry Roberts wrote:
> "Unusable" is what I am calling anything that starts with
> #///DocumentRoot/.
Unusable for what purpose?
> The reason it is unusable is because when converted to a
> ExtensibleURIConverterImpl.normalize(URI uri) it returns as
> "file:///"<the directory from which the program was launched>--not good.
What are you doing with the URI?
>
> In the xml below, everything within the <text> node is generated as a
> FeatureMap. When looping throughout the contained entries the
> continued features return from EcoreUtil.getURI(feature); as
> #///DocumentRoot/.
>
> <text>
> <content styleCode="Bold">Henry Levin, the 7<sup>th</sup></content>
> is a 67 year old male referred for further asthma management. Onset
> of asthma in his
> <content revised="delete">twenties</content>
> <content revised="insert">teens</content>. He was hospitalized
> twice last year, and already twice this year. He has not been able to be
> weaned off steroids for the past several months. </text>
>
> I hope this helps.
It doesn't help me understand what you're hoping to do with the URI.
Nor does it respond in any way to what I suggested about getting an XML
snippet. Nor does any of this explain how the two issues are related.
> ..


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EcoreUtil.getURI(feature) [message #1219620 is a reply to message #1219609] Thu, 05 December 2013 00:26 Go to previous messageGo to next message
Geoffry Roberts is currently offline Geoffry RobertsFriend
Messages: 29
Registered: March 2011
Junior Member
Ed,

Thanks for being so patient. I appreciate it.

The application stores and EMF document into a document oriented database. When it stores data it also stores a uri(s) so the data can be retrieved into the proper EMF class(es). When I wrote that EcoreUtil.getURI(feature) was returning #///DocumentRoot I called it unusable because #///DocumentRoot normalizes into file:///<whatever>, which is not a uri for an EMF class. At store time all appears to be working, but at retrieval time #///DocumentRoot cannot be interpreted successfully and errors ensue. A FileNotFoundException is thrown with the message that file:///<whatever> is a directory. I have included two examples of usable uris so you see what they look like.

http://www.eclipse.org/emf/2003/XMLType#//XMLTypeDocumentRoot/text
http://www.openhealthtools.org/mdht/uml/hl7/datatypes#//EN/given

Perhaps my question should be why, when processing this embedded xml, am I not getting a usable uri?

Thanks again
Re: EcoreUtil.getURI(feature) [message #1219633 is a reply to message #1219620] Thu, 05 December 2013 06:04 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31780
Registered: July 2009
Senior Member
Geoffry,

When processing wildcards, the deserializer is using things like
org.eclipse.emf.ecore.util.ExtendedMetaData.demandFeature(String,
String, boolean) to create a feature and such demand created metadata
has no enclosing resource. You might consider using
org.eclipse.emf.ecore.util.ExtendedMetaData.getNamespace(EStructuralFeature)
in the case that the URI you get from EcoreUtil.getURI returns the empty
URI, but keep in mind that you "find" that feature again, you have to
demand create it again, and for that you need to know if it's an element
or an attribute to call demandFeature with the right arguments.

On 05/12/2013 1:26 AM, Geoffry Roberts wrote:
> Ed,
>
> Thanks for being so patient. I appreciate it.
> The application stores and EMF document into a document oriented
> database. When it stores data it also stores a uri(s) so the data can
> be retrieved into the proper EMF class(es). When I wrote that
> EcoreUtil.getURI(feature) was returning #///DocumentRoot I called it
> unusable because #///DocumentRoot normalizes into file:///<whatever>,
> which is not a uri for an EMF class. At store time all appears to be
> working, but at retrieval time #///DocumentRoot cannot be interpreted
> successfully and errors ensue. A FileNotFoundException is thrown with
> the message that file:///<whatever> is a directory. I have included
> two examples of usable uris so you see what they look like.
>
> http://www.eclipse.org/emf/2003/XMLType#//XMLTypeDocumentRoot/text
> http://www.openhealthtools.org/mdht/uml/hl7/datatypes#//EN/given
>
> Perhaps my question should be why, when processing this embedded xml,
> am I not getting a usable uri?
>
> Thanks again


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EcoreUtil.getURI(feature) [message #1220078 is a reply to message #1219575] Mon, 09 December 2013 14:40 Go to previous messageGo to next message
Geoffry Roberts is currently offline Geoffry RobertsFriend
Messages: 29
Registered: March 2011
Junior Member
Ed,

Your suggestion to use org.eclipse.emf.ecore.util.ExtendedMetaData.getNamespace(EStructuralFeature) when EcoreUtil.getURI(feature) returns an unusable, error producing URI works. In cases where EcoreUtil.getURI(feature) returns "#///DocumentRoot", ExtendedMetaData.getNamespace(EStructuralFeature) returns "hl7-org:v3"; which I can live with for now. Whether it will continue to serve in the unforeseen situations of the future, who knows?

Thanks for the help.
Re: EcoreUtil.getURI(feature) [message #1220086 is a reply to message #1219575] Mon, 09 December 2013 15:35 Go to previous messageGo to next message
Bryan Hunt is currently offline Bryan HuntFriend
Messages: 366
Registered: July 2009
Senior Member
Hi Ed,

Geoffry is attempting to use MongoEMF to serialize / deserialize his model. The code in question from MongoEMF is:

protected void buildFeatureMap(DBObject dbObject, EAttribute attribute, Object value)
{
  FeatureMap.Internal featureMap = (FeatureMap.Internal) value;
  Iterator<FeatureMap.Entry> iterator = featureMap.basicIterator();
  ArrayList<DBObject> dbFeatureMap = new ArrayList<DBObject>();

  while (iterator.hasNext())
  {
    DBObject dbEntry = new BasicDBObject();
    FeatureMap.Entry entry = iterator.next();
    EStructuralFeature feature = entry.getEStructuralFeature();
    dbEntry.put("key", EcoreUtil.getURI(feature).toString());           <<<-------------------- Get the URI here

    if (feature instanceof EAttribute)
    {
      EDataType eDataType = ((EAttribute) feature).getEAttributeType();

      if (!MongoUtils.isNativeType(eDataType))
        dbEntry.put("value", convertEMFValueToMongoDBValue(eDataType, entry.getValue()));
      else
         dbEntry.put("value", entry.getValue());
    }
    else
       dbEntry.put("value", buildReferencedObject((EReference) feature, (EObject) entry.getValue()));

    dbFeatureMap.add(dbEntry);
  }

  dbObject.put(attribute.getName(), dbFeatureMap);
}


Can we improve upon this solution to handle his case generically, or is this something that is model specific?

Bryan
Re: EcoreUtil.getURI(feature) [message #1220139 is a reply to message #1220086] Tue, 10 December 2013 05:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31780
Registered: July 2009
Senior Member
Bryan,

I assume you're using this URI so that later you can use
ResourceSet.getEObject to load the feature again, but this only works if
the feature isn't a demand created one. If it's demand created, you'll
really need to remember the namespace, the name, and whether it's an
element or an attribute, so you can call
org.eclipse.emf.ecore.util.BasicExtendedMetaData.demandFeature(String,
String, boolean) with the appropriate arguments. Note there are even
cases (an xsi:type within a wildcard's feature map's contents) where you
could end up with an EObject whose eClass() is created using
org.eclipse.emf.ecore.util.BasicExtendedMetaData.demandType(String, String).


On 09/12/2013 4:35 PM, Bryan Hunt wrote:
> Hi Ed,
>
> Geoffry is attempting to use MongoEMF to serialize / deserialize his
> model. The code in question from MongoEMF is:
>
>
> protected void buildFeatureMap(DBObject dbObject, EAttribute
> attribute, Object value)
> {
> FeatureMap.Internal featureMap = (FeatureMap.Internal) value;
> Iterator<FeatureMap.Entry> iterator = featureMap.basicIterator();
> ArrayList<DBObject> dbFeatureMap = new ArrayList<DBObject>();
>
> while (iterator.hasNext())
> {
> DBObject dbEntry = new BasicDBObject();
> FeatureMap.Entry entry = iterator.next();
> EStructuralFeature feature = entry.getEStructuralFeature();
> dbEntry.put("key", EcoreUtil.getURI(feature).toString());
> <<<-------------------- Get the URI here
>
> if (feature instanceof EAttribute)
> {
> EDataType eDataType = ((EAttribute) feature).getEAttributeType();
>
> if (!MongoUtils.isNativeType(eDataType))
> dbEntry.put("value", convertEMFValueToMongoDBValue(eDataType,
> entry.getValue()));
> else
> dbEntry.put("value", entry.getValue());
> }
> else
> dbEntry.put("value", buildReferencedObject((EReference) feature,
> (EObject) entry.getValue()));
>
> dbFeatureMap.add(dbEntry);
> }
>
> dbObject.put(attribute.getName(), dbFeatureMap);
> }
>
>
> Can we improve upon this solution to handle his case generically, or
> is this something that is model specific?
>
> Bryan


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EcoreUtil.getURI(feature) [message #1220237 is a reply to message #1220139] Tue, 10 December 2013 14:32 Go to previous messageGo to next message
Geoffry Roberts is currently offline Geoffry RobertsFriend
Messages: 29
Registered: March 2011
Junior Member
Ed,

By "demand created" do you mean created at runtime? If so, this is not the case in my situation. What I have are XML tags that are embedded within an element but are supposed to be treated as a String. This is what the designers (not me) envisioned. As a result, when EMF is used to process these documents (a very attractive thing to do from a technical standpoint), EMF creates a feature map treating them as elements. In the corresponding ecore, these embedded elements are not given a datatype. <thinking out loud>I wonder if this problem would go a way if they were given a type. We have ST, which, in Java, is implemented as String.</thinking out loud>

Thanks

Re: EcoreUtil.getURI(feature) [message #1220256 is a reply to message #1220237] Tue, 10 December 2013 16:50 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31780
Registered: July 2009
Senior Member
Geoffry,

Comments below.

On 10/12/2013 3:32 PM, Geoffry Roberts wrote:
> Ed,
> By "demand created" do you mean created at runtime? If so, this is
> not the case in my situation.
Yes it is.
> What I have are XML tags that are embedded within an element but are
> supposed to be treated as a String.
Treated by what?
> This is what the designers (not me) envisioned. As a result, when
> EMF is used to process these documents (a very attractive thing to do
> from a technical standpoint), EMF creates a feature map treating them
> as elements.
Because they are.
> In the corresponding ecore, these embedded elements are not given a
> datatype.
They're instances of AnyType.
> <thinking out loud>I wonder if this problem would go a way if they
> were given a type.
No.
> We have ST, which, in Java, is implemented as String.</thinking out loud>
If you saved such a thing as XML, the things like < would be encoded as
&lt; so they would not be embedded elements, they'd just be a value that
happens to look like XML when it's decoded.
>
> Thanks
>
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: EcoreUtil.getURI(feature) [message #1220264 is a reply to message #1220256] Tue, 10 December 2013 17:56 Go to previous message
Bryan Hunt is currently offline Bryan HuntFriend
Messages: 366
Registered: July 2009
Senior Member
Hi Ed,

Here's the other half of the MongoEMF code ...

protected void buildFeatureMap(DBCollection collection, Resource resource, EObject eObject, EAttribute attribute, List<DBObject> values)
{
  FeatureMap.Internal featureMap = (FeatureMap.Internal) eObject.eGet(attribute);

  for (DBObject entry : values)
  {
    EStructuralFeature feature = (EStructuralFeature) resource.getResourceSet().getEObject(URI.createURI((String) entry.get("key")), true);

    if (feature instanceof EAttribute)
    {
      EDataType eDataType = ((EAttribute) feature).getEAttributeType();
      featureMap.add(feature, convertMongoDBValueToEMFValue(eDataType, entry.get("value")));
    }
    else
    {
      EReference reference = (EReference) feature;
      DBObject dbReference = (DBObject) entry.get("value");
      EObject target = buildReferencedObject(collection, dbReference, resource, reference.isResolveProxies());
      featureMap.add(feature, target);
    }
  }
}
Previous Topic:[Eclipse Client Platform] EReference of Type "EObject" throws null pointer exception
Next Topic:[EMFStore] handling dangling references
Goto Forum:
  


Current Time: Mon Mar 08 01:21:31 GMT 2021

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

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

Back to the top