Skip to main content



      Home
Home » Modeling » EMF » Invalid EMF references on customized save
Invalid EMF references on customized save [message #391149] Mon, 14 February 2005 18:25 Go to next message
Eclipse UserFriend
I’ve been trying to put together a custom serialization method for our EMF
model.

Currently, we have an EMF model spread across several files in order to
break down the model for editing purposes. However, at times we need an
XML representation of the complete model for XML transformations and other
needs.

I have written a custom ResourceImpl and XMLSaveImpl in order to over
write the Lookup method to redefine containment such that save will put
all the XML in one document represented by one resource.

After a little work, I thought all was well. But soon came to discover
that some of the references are not correct in the custom serialized
model. For example, I might have an XMI reference like (ref=”/3 /4”)
point to some nodes that are not correct. (Either the nodes are not
there, or they are the wrong type, and so forth)

I have also noticed that some references appear to point to old resource
files (the ones that this resource was created with, and should no longer
be necessary), for example (ref=”
Another_sub_file_from_emf_model.extension#/”) when that EObject is now
contained in the same resource and the hope was that the reference value
would have changed as well. (Such that the value would be something more
like ref=”/3” where 3 refers to a node in the same resource)

Or in other words, in … I have successfully looped through and copied all
the eObjects to an empty resource. However, when saving the resource the
referenced items (some times) do not point back inside the file.
(Although, they usually appear to do so besides the occasional reference
that is off a little, possibly these other references are off). In fact,
it appears that earlier references in the file are more likely to be
correct than latter references, … but I’m not sure why!?!?!?

So here is my question:
Any ideas why some references are off, while others are fine?

I’ve been racking my brain over this one, but I’m afraid I’m going to have
to brute force a custom XML document by looping through the EMF objects …
Any opinion on if that is going to be easier? This method was very slick
and perfect for what I need, except for the inaccurate references 

The blow code shows how I added the resource together:

private byte[] create(EObject rootObjectFromManyFileModel)
{

List<EObject> objectList = new ArrayList<EObject>();
ByteArrayOutputStream os = new ByteArrayOutputStream();

addChildObjects( rootObjectFromManyFileModel, objectList );

URI outputUri = null;
Resource newResource = new MyResourceImpl( null); // customized
resource to over write lookup method

newResource.getContents().addAll( objectList );

newResource.save( os, Collections.EMPTY_MAP );

int count = 0;
for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
{
EObject element = (EObject) iter.next();
}
return os.toByteArray();
}

private void addChildObjects(
EObject eObject,
List<EObject> objectList )
{
if (!objectList.contains( eObject ))
{
// Add the object
objectList.add( eObject );
System.out.println("Added object: " +
eObject.getClass().getName());

// Add referenced children
for (Iterator iterator = eObject.eCrossReferences().iterator();
iterator.hasNext();)
{
EObject child = (EObject) iterator.next();
addChildObjects( child,
objectList );
}
}
}
Re: Invalid EMF references on customized save [message #391159 is a reply to message #391149] Tue, 15 February 2005 07:05 Go to previous messageGo to next message
Eclipse UserFriend
Will,

The algorithm below will do really nasty things because once you do the
addAll to the resource, the cross referenced objects will be detached
from their container and attached to the resource, so your trees will be
often be broken into so many little separate pieces. Since there can be
cross references (potentially) even within the original resource, even
that tree will end up being broken up. Here's how I would imagine doing
this. Start with a list of resources containing just the one resource
that you want to save. Look at the nth resource in the list (starting at
0), walk the resource.getAllContents, which recursively visits every
contained EObject, for each EObject iterate over the eCrossReferences to
look at each referenced object, and for each referenced object, check if
its eResource in in the list and add it if it isn't. If you repeat this
for each resource, you'll end up with a list of all the resources that
are referenced. If you take the getContents of all but the first and add
them to the first, you'll have a resource containing the roots of all
the tree you want to save into a single resource.

Note that one of the many problems with your algorithm below is that it
doesn't look at the cross references of the cross references, so it
doesn't ensure that everything that's need will actually all be in one
resource...


Will wrote:

> I�ve been trying to put together a custom serialization method for our
> EMF model.
>
> Currently, we have an EMF model spread across several files in order
> to break down the model for editing purposes. However, at times we
> need an XML representation of the complete model for XML
> transformations and other needs.
>
> I have written a custom ResourceImpl and XMLSaveImpl in order to over
> write the Lookup method to redefine containment such that save will
> put all the XML in one document represented by one resource.
>
> After a little work, I thought all was well. But soon came to discover
> that some of the references are not correct in the custom serialized
> model. For example, I might have an XMI reference like (ref=�/3 /4�)
> point to some nodes that are not correct. (Either the nodes are not
> there, or they are the wrong type, and so forth)
>
> I have also noticed that some references appear to point to old
> resource files (the ones that this resource was created with, and
> should no longer be necessary), for example (ref=�
> Another_sub_file_from_emf_model.extension#/�) when that EObject is now
> contained in the same resource and the hope was that the reference
> value would have changed as well. (Such that the value would be
> something more like ref=�/3� where 3 refers to a node in the same
> resource)
>
> Or in other words, in � I have successfully looped through and copied
> all the eObjects to an empty resource. However, when saving the
> resource the referenced items (some times) do not point back inside
> the file. (Although, they usually appear to do so besides the
> occasional reference that is off a little, possibly these other
> references are off). In fact, it appears that earlier references in
> the file are more likely to be correct than latter references, � but
> I�m not sure why!?!?!?
>
> So here is my question:
> Any ideas why some references are off, while others are fine?
>
> I�ve been racking my brain over this one, but I�m afraid I�m going to
> have to brute force a custom XML document by looping through the EMF
> objects � Any opinion on if that is going to be easier? This method
> was very slick and perfect for what I need, except for the inaccurate
> references &#61514;
>
> The blow code shows how I added the resource together:
>
> private byte[] create(EObject rootObjectFromManyFileModel)
> {
>
> List<EObject> objectList = new ArrayList<EObject>();
> ByteArrayOutputStream os = new ByteArrayOutputStream();
>
> addChildObjects( rootObjectFromManyFileModel, objectList );
>
> URI outputUri = null;
> Resource newResource = new MyResourceImpl( null); // customized
> resource to over write lookup method
>
> newResource.getContents().addAll( objectList );
>
> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
> {
> EObject element = (EObject) iter.next();
> }
> return os.toByteArray();
> }
>
> private void addChildObjects(
> EObject eObject,
> List<EObject> objectList )
> {
> if (!objectList.contains( eObject ))
> {
> // Add the object
> objectList.add( eObject );
> System.out.println("Added object: " + eObject.getClass().getName());
>
> // Add referenced children
> for (Iterator iterator = eObject.eCrossReferences().iterator();
> iterator.hasNext();)
> {
> EObject child = (EObject) iterator.next();
> addChildObjects( child,
> objectList );
> }
> }
> }
>
>
>
>
>
Re: Invalid EMF references on customized save [message #391169 is a reply to message #391159] Tue, 15 February 2005 13:45 Go to previous messageGo to next message
Eclipse UserFriend
Ed,

Thanks for your help. Using your suggestions I was able to rid myself of
the references pointing to old resource files. However, I'm still getting
invalid references to items within the document (for example I get a "/7"
when it should be a "/9").

Any ideas why this still might be happening?

Here is the re-written code:

private Resource buildConsolidatedResource( URI newResourceUri,
Resource inputResource )
{
// create a list of resources to consolidate
List resourceList = new ArrayList<Resource>();
resourceList.add(inputResource);

// recursivly add referenced resources (method below)
addReferencedResources((Resource)resourceList.get(0), resourceList);

// copy contents to a consolidated resource (which has the
customized lookup method)
Resource consolidatedResource = new MyResourceImpl( newResourceUri );
for (Iterator iter = resourceList.iterator(); iter.hasNext();)
{
consolidatedResource.getContents().addAll( ((Resource)
iter.next()).getContents() );
}

return consolidatedResource;
}

private static void addReferencedResources(Resource resource, List
resourceList )
{
for (Iterator allContentsIterator = resource.getAllContents();
allContentsIterator.hasNext();)
{
EObject allContentsEObject = (EObject) allContentsIterator.next();
for (Iterator crossRefIterator =
allContentsEObject.eCrossReferences().iterator();
crossRefIterator.hasNext();)
{
Resource crossRefResource = ((EObject)
crossRefIterator.next()).eResource();
if (!resourceList.contains(crossRefResource))
{
resourceList.add(crossRefResource);
addReferencedResources(crossRefResource, resourceList);
}
}
}
}




Ed Merks wrote:

> Will,

> The algorithm below will do really nasty things because once you do the
> addAll to the resource, the cross referenced objects will be detached
> from their container and attached to the resource, so your trees will be
> often be broken into so many little separate pieces. Since there can be
> cross references (potentially) even within the original resource, even
> that tree will end up being broken up. Here's how I would imagine doing
> this. Start with a list of resources containing just the one resource
> that you want to save. Look at the nth resource in the list (starting at
> 0), walk the resource.getAllContents, which recursively visits every
> contained EObject, for each EObject iterate over the eCrossReferences to
> look at each referenced object, and for each referenced object, check if
> its eResource in in the list and add it if it isn't. If you repeat this
> for each resource, you'll end up with a list of all the resources that
> are referenced. If you take the getContents of all but the first and add
> them to the first, you'll have a resource containing the roots of all
> the tree you want to save into a single resource.

> Note that one of the many problems with your algorithm below is that it
> doesn't look at the cross references of the cross references, so it
> doesn't ensure that everything that's need will actually all be in one
> resource...


> Will wrote:

>> I?ve been trying to put together a custom serialization method for our
>> EMF model.
>>
>> Currently, we have an EMF model spread across several files in order
>> to break down the model for editing purposes. However, at times we
>> need an XML representation of the complete model for XML
>> transformations and other needs.
>>
>> I have written a custom ResourceImpl and XMLSaveImpl in order to over
>> write the Lookup method to redefine containment such that save will
>> put all the XML in one document represented by one resource.
>>
>> After a little work, I thought all was well. But soon came to discover
>> that some of the references are not correct in the custom serialized
>> model. For example, I might have an XMI reference like (ref=?/3 /4?)
>> point to some nodes that are not correct. (Either the nodes are not
>> there, or they are the wrong type, and so forth)
>>
>> I have also noticed that some references appear to point to old
>> resource files (the ones that this resource was created with, and
>> should no longer be necessary), for example (ref=?
>> Another_sub_file_from_emf_model.extension#/?) when that EObject is now
>> contained in the same resource and the hope was that the reference
>> value would have changed as well. (Such that the value would be
>> something more like ref=?/3? where 3 refers to a node in the same
>> resource)
>>
>> Or in other words, in ? I have successfully looped through and copied
>> all the eObjects to an empty resource. However, when saving the
>> resource the referenced items (some times) do not point back inside
>> the file. (Although, they usually appear to do so besides the
>> occasional reference that is off a little, possibly these other
>> references are off). In fact, it appears that earlier references in
>> the file are more likely to be correct than latter references, ? but
>> I?m not sure why!?!?!?
>>
>> So here is my question:
>> Any ideas why some references are off, while others are fine?
>>
>> I?ve been racking my brain over this one, but I?m afraid I?m going to
>> have to brute force a custom XML document by looping through the EMF
>> objects ? Any opinion on if that is going to be easier? This method
>> was very slick and perfect for what I need, except for the inaccurate
>> references &#61514;
>>
>> The blow code shows how I added the resource together:
>>
>> private byte[] create(EObject rootObjectFromManyFileModel)
>> {
>>
>> List<EObject> objectList = new ArrayList<EObject>();
>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>
>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>
>> URI outputUri = null;
>> Resource newResource = new MyResourceImpl( null); // customized
>> resource to over write lookup method
>>
>> newResource.getContents().addAll( objectList );
>>
>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>> {
>> EObject element = (EObject) iter.next();
>> }
>> return os.toByteArray();
>> }
>>
>> private void addChildObjects(
>> EObject eObject,
>> List<EObject> objectList )
>> {
>> if (!objectList.contains( eObject ))
>> {
>> // Add the object
>> objectList.add( eObject );
>> System.out.println("Added object: " + eObject.getClass().getName());
>>
>> // Add referenced children
>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>> iterator.hasNext();)
>> {
>> EObject child = (EObject) iterator.next();
>> addChildObjects( child,
>> objectList );
>> }
>> }
>> }
>>
>>
>>
>>
>>
Re: Invalid EMF references on customized save [message #391171 is a reply to message #391169] Tue, 15 February 2005 15:22 Go to previous messageGo to next message
Eclipse UserFriend
This is a multi-part message in MIME format.
--------------080304040109000602050709
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Will,

I don't have a good theory for that. The root index is computed by
ResourceImpl like this:

protected String getURIFragmentRootSegment(EObject eObject)
{
List contents = getContents();
return contents.size() > 1 ?
Integer.toString(getContents().indexOf(eObject)) :
"";
}

I.e., it really does represent the position within the resource contents
list of the root object and it being wrong seems to imply that the
contents are changing during the save.


Will wrote:

> Ed,
>
> Thanks for your help. Using your suggestions I was able to rid myself
> of the references pointing to old resource files. However, I'm still
> getting invalid references to items within the document (for example I
> get a "/7" when it should be a "/9").
>
> Any ideas why this still might be happening?
>
> Here is the re-written code:
>
> private Resource buildConsolidatedResource( URI newResourceUri,
> Resource inputResource )
> {
> // create a list of resources to consolidate
> List resourceList = new ArrayList<Resource>();
> resourceList.add(inputResource);
>
> // recursivly add referenced resources (method below)
> addReferencedResources((Resource)resourceList.get(0), resourceList);
>
> // copy contents to a consolidated resource (which has the
> customized lookup method)
> Resource consolidatedResource = new MyResourceImpl(
> newResourceUri );
> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
> {
> consolidatedResource.getContents().addAll( ((Resource)
> iter.next()).getContents() ); }
> return consolidatedResource;
> }
>
> private static void addReferencedResources(Resource resource, List
> resourceList )
> {
> for (Iterator allContentsIterator = resource.getAllContents();
> allContentsIterator.hasNext();)
> {
> EObject allContentsEObject = (EObject)
> allContentsIterator.next();
> for (Iterator crossRefIterator =
> allContentsEObject.eCrossReferences().iterator();
> crossRefIterator.hasNext();)
> {
> Resource crossRefResource = ((EObject)
> crossRefIterator.next()).eResource();
> if (!resourceList.contains(crossRefResource))
> {
> resourceList.add(crossRefResource);
> addReferencedResources(crossRefResource, resourceList);
> }
> }
> }
> }
>
>
>
>
> Ed Merks wrote:
>
>> Will,
>
>
>> The algorithm below will do really nasty things because once you do
>> the addAll to the resource, the cross referenced objects will be
>> detached from their container and attached to the resource, so your
>> trees will be often be broken into so many little separate pieces.
>> Since there can be cross references (potentially) even within the
>> original resource, even that tree will end up being broken up. Here's
>> how I would imagine doing this. Start with a list of resources
>> containing just the one resource that you want to save. Look at the
>> nth resource in the list (starting at 0), walk the
>> resource.getAllContents, which recursively visits every contained
>> EObject, for each EObject iterate over the eCrossReferences to look
>> at each referenced object, and for each referenced object, check if
>> its eResource in in the list and add it if it isn't. If you repeat
>> this for each resource, you'll end up with a list of all the
>> resources that are referenced. If you take the getContents of all but
>> the first and add them to the first, you'll have a resource
>> containing the roots of all the tree you want to save into a single
>> resource.
>
>
>> Note that one of the many problems with your algorithm below is that
>> it doesn't look at the cross references of the cross references, so
>> it doesn't ensure that everything that's need will actually all be in
>> one resource...
>
>
>
>> Will wrote:
>
>
>>> I?ve been trying to put together a custom serialization method for
>>> our EMF model.
>>>
>>> Currently, we have an EMF model spread across several files in order
>>> to break down the model for editing purposes. However, at times we
>>> need an XML representation of the complete model for XML
>>> transformations and other needs.
>>>
>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>> over write the Lookup method to redefine containment such that save
>>> will put all the XML in one document represented by one resource.
>>>
>>> After a little work, I thought all was well. But soon came to
>>> discover that some of the references are not correct in the custom
>>> serialized model. For example, I might have an XMI reference like
>>> (ref=?/3 /4?) point to some nodes that are not correct. (Either the
>>> nodes are not there, or they are the wrong type, and so forth)
>>>
>>> I have also noticed that some references appear to point to old
>>> resource files (the ones that this resource was created with, and
>>> should no longer be necessary), for example (ref=?
>>> Another_sub_file_from_emf_model.extension#/?) when that EObject is
>>> now contained in the same resource and the hope was that the
>>> reference value would have changed as well. (Such that the value
>>> would be something more like ref=?/3? where 3 refers to a node in
>>> the same resource)
>>>
>>> Or in other words, in ? I have successfully looped through and
>>> copied all the eObjects to an empty resource. However, when saving
>>> the resource the referenced items (some times) do not point back
>>> inside the file. (Although, they usually appear to do so besides the
>>> occasional reference that is off a little, possibly these other
>>> references are off). In fact, it appears that earlier references in
>>> the file are more likely to be correct than latter references, ? but
>>> I?m not sure why!?!?!?
>>>
>>> So here is my question:
>>> Any ideas why some references are off, while others are fine?
>>>
>>> I?ve been racking my brain over this one, but I?m afraid I?m going
>>> to have to brute force a custom XML document by looping through the
>>> EMF objects ? Any opinion on if that is going to be easier? This
>>> method was very slick and perfect for what I need, except for the
>>> inaccurate references &#61514;
>>>
>>> The blow code shows how I added the resource together:
>>>
>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>> {
>>>
>>> List<EObject> objectList = new ArrayList<EObject>();
>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>
>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>
>>> URI outputUri = null;
>>> Resource newResource = new MyResourceImpl( null); // customized
>>> resource to over write lookup method
>>>
>>> newResource.getContents().addAll( objectList );
>>>
>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>> {
>>> EObject element = (EObject) iter.next();
>>> }
>>> return os.toByteArray();
>>> }
>>>
>>> private void addChildObjects(
>>> EObject eObject,
>>> List<EObject> objectList )
>>> {
>>> if (!objectList.contains( eObject ))
>>> {
>>> // Add the object
>>> objectList.add( eObject );
>>> System.out.println("Added object: " + eObject.getClass().getName());
>>>
>>> // Add referenced children
>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>> iterator.hasNext();)
>>> {
>>> EObject child = (EObject) iterator.next();
>>> addChildObjects( child,
>>> objectList );
>>> }
>>> }
>>> }
>>>
>>>
>>>
>>>
>>>
>
>


--------------080304040109000602050709
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">
Will,<br>
<br>
I don't have a good theory for that.
Re: Invalid EMF references on customized save [message #391175 is a reply to message #391171] Tue, 15 February 2005 19:01 Go to previous messageGo to next message
Eclipse UserFriend
Ed,

From what I can tell, it seems to be having problems with forward
refereneces. At least when it starts running into problems.

I used the getURIFragment method to determin the URI fragment of the
resource, for example:

for (int i = 0; i < newResource.getContents().size(); i++)
{
EObject o = newResource.getEObject("/" + i);
System.out.println("/" + i + " " + o.getClass().getName());
}

I get result like:

/0 com.novell.porpoise.common.model.impl.ProjectImpl
/1 com.novell.porpoise.common.model.impl.DomainImpl
/2 com.novell.porpoise.common.model.impl.DomainImpl
/3 com.novell.porpoise.common.model.impl.DomainImpl
/4 com.novell.porpoise.common.model.impl.DomainImpl
... (and so on)

The XML (from the xmi file) appears to be created in the same element
order as the output from this debug. EXCEPT, when I start hitting the
invalid references in the XML, the ordering is different.

Either the XML elements are written out in the wrong order, or it seems
related to forward references (reference to elements not yet there?!?!?).

Also, I'm wondering if the my Lookup.featureKind(...) method is related to
that changes going on. Because I'm changing the containment in this
method, this could possibly change the number of elements in the complete
document ... I'm not sure, but somehow these items seem related.

This method, by the way, looks like:

protected int featureKind( EStructuralFeature f )
{
int kind = super.featureKind( f );
if ( f == ModelPackage.eINSTANCE.getProject_Domain()
|| f == ModelPackage.eINSTANCE.getDomain_DomainItems()
|| f == ModelPackage.eINSTANCE.getDriver_Policies()
)

{
switch (kind)
{
case OBJECT_HREF_MANY :
return OBJECT_CONTAIN_MANY;
case OBJECT_HREF_SINGLE :
return OBJECT_CONTAIN_SINGLE;
case OBJECT_HREF_SINGLE_UNSETTABLE :
return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
case OBJECT_HREF_MANY_UNSETTABLE :
return OBJECT_CONTAIN_MANY_UNSETTABLE;
}
}
return kind;
}



Ed Merks wrote:

> Will,

> I don't have a good theory for that. The root index is computed by
> ResourceImpl like this:

> protected String getURIFragmentRootSegment(EObject eObject)
> {
> List contents = getContents();
> return contents.size() > 1 ?
> Integer.toString(getContents().indexOf(eObject)) :
> "";
> }

> I.e., it really does represent the position within the resource contents
> list of the root object and it being wrong seems to imply that the
> contents are changing during the save.


> Will wrote:

>> Ed,
>>
>> Thanks for your help. Using your suggestions I was able to rid myself
>> of the references pointing to old resource files. However, I'm still
>> getting invalid references to items within the document (for example I
>> get a "/7" when it should be a "/9").
>>
>> Any ideas why this still might be happening?
>>
>> Here is the re-written code:
>>
>> private Resource buildConsolidatedResource( URI newResourceUri,
>> Resource inputResource )
>> {
>> // create a list of resources to consolidate
>> List resourceList = new ArrayList<Resource>();
>> resourceList.add(inputResource);
>>
>> // recursivly add referenced resources (method below)
>> addReferencedResources((Resource)resourceList.get(0), resourceList);
>>
>> // copy contents to a consolidated resource (which has the
>> customized lookup method)
>> Resource consolidatedResource = new MyResourceImpl(
>> newResourceUri );
>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>> {
>> consolidatedResource.getContents().addAll( ((Resource)
>> iter.next()).getContents() ); }
>> return consolidatedResource;
>> }
>>
>> private static void addReferencedResources(Resource resource, List
>> resourceList )
>> {
>> for (Iterator allContentsIterator = resource.getAllContents();
>> allContentsIterator.hasNext();)
>> {
>> EObject allContentsEObject = (EObject)
>> allContentsIterator.next();
>> for (Iterator crossRefIterator =
>> allContentsEObject.eCrossReferences().iterator();
>> crossRefIterator.hasNext();)
>> {
>> Resource crossRefResource = ((EObject)
>> crossRefIterator.next()).eResource();
>> if (!resourceList.contains(crossRefResource))
>> {
>> resourceList.add(crossRefResource);
>> addReferencedResources(crossRefResource, resourceList);
>> }
>> }
>> }
>> }
>>
>>
>>
>>
>> Ed Merks wrote:
>>
>>> Will,
>>
>>
>>> The algorithm below will do really nasty things because once you do
>>> the addAll to the resource, the cross referenced objects will be
>>> detached from their container and attached to the resource, so your
>>> trees will be often be broken into so many little separate pieces.
>>> Since there can be cross references (potentially) even within the
>>> original resource, even that tree will end up being broken up. Here's
>>> how I would imagine doing this. Start with a list of resources
>>> containing just the one resource that you want to save. Look at the
>>> nth resource in the list (starting at 0), walk the
>>> resource.getAllContents, which recursively visits every contained
>>> EObject, for each EObject iterate over the eCrossReferences to look
>>> at each referenced object, and for each referenced object, check if
>>> its eResource in in the list and add it if it isn't. If you repeat
>>> this for each resource, you'll end up with a list of all the
>>> resources that are referenced. If you take the getContents of all but
>>> the first and add them to the first, you'll have a resource
>>> containing the roots of all the tree you want to save into a single
>>> resource.
>>
>>
>>> Note that one of the many problems with your algorithm below is that
>>> it doesn't look at the cross references of the cross references, so
>>> it doesn't ensure that everything that's need will actually all be in
>>> one resource...
>>
>>
>>
>>> Will wrote:
>>
>>
>>>> I?ve been trying to put together a custom serialization method for
>>>> our EMF model.
>>>>
>>>> Currently, we have an EMF model spread across several files in order
>>>> to break down the model for editing purposes. However, at times we
>>>> need an XML representation of the complete model for XML
>>>> transformations and other needs.
>>>>
>>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>>> over write the Lookup method to redefine containment such that save
>>>> will put all the XML in one document represented by one resource.
>>>>
>>>> After a little work, I thought all was well. But soon came to
>>>> discover that some of the references are not correct in the custom
>>>> serialized model. For example, I might have an XMI reference like
>>>> (ref=?/3 /4?) point to some nodes that are not correct. (Either the
>>>> nodes are not there, or they are the wrong type, and so forth)
>>>>
>>>> I have also noticed that some references appear to point to old
>>>> resource files (the ones that this resource was created with, and
>>>> should no longer be necessary), for example (ref=?
>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject is
>>>> now contained in the same resource and the hope was that the
>>>> reference value would have changed as well. (Such that the value
>>>> would be something more like ref=?/3? where 3 refers to a node in
>>>> the same resource)
>>>>
>>>> Or in other words, in ? I have successfully looped through and
>>>> copied all the eObjects to an empty resource. However, when saving
>>>> the resource the referenced items (some times) do not point back
>>>> inside the file. (Although, they usually appear to do so besides the
>>>> occasional reference that is off a little, possibly these other
>>>> references are off). In fact, it appears that earlier references in
>>>> the file are more likely to be correct than latter references, ? but
>>>> I?m not sure why!?!?!?
>>>>
>>>> So here is my question:
>>>> Any ideas why some references are off, while others are fine?
>>>>
>>>> I?ve been racking my brain over this one, but I?m afraid I?m going
>>>> to have to brute force a custom XML document by looping through the
>>>> EMF objects ? Any opinion on if that is going to be easier? This
>>>> method was very slick and perfect for what I need, except for the
>>>> inaccurate references &#61514;
>>>>
>>>> The blow code shows how I added the resource together:
>>>>
>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>> {
>>>>
>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>
>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>
>>>> URI outputUri = null;
>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>> resource to over write lookup method
>>>>
>>>> newResource.getContents().addAll( objectList );
>>>>
>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>>> {
>>>> EObject element = (EObject) iter.next();
>>>> }
>>>> return os.toByteArray();
>>>> }
>>>>
>>>> private void addChildObjects(
>>>> EObject eObject,
>>>> List<EObject> objectList )
>>>> {
>>>> if (!objectList.contains( eObject ))
>>>> {
>>>> // Add the object
>>>> objectList.add( eObject );
>>>> System.out.println("Added object: " + eObject.getClass().getName());
>>>>
>>>> // Add referenced children
>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>> iterator.hasNext();)
>>>> {
>>>> EObject child = (EObject) iterator.next();
>>>> addChildObjects( child,
>>>> objectList );
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>
>>
Re: Invalid EMF references on customized save [message #391179 is a reply to message #391175] Wed, 16 February 2005 06:26 Go to previous messageGo to next message
Eclipse UserFriend
This is a multi-part message in MIME format.
--------------090009020903080002040403
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Will,

Given that you've moved the entire closure of objects into the one
resource, why are you doing the containment overrides? I would think
this would cause duplicate objects to serialize, so you must be doing
something to prevent that. The containment override will certainly
mess this code in ResourceImpl which relies on properly knowing the
inverse of containment to determine a path up the tree that can later
be followed to walk back down the tree. You'll need to change this code
to make eContainer appear "correct" based on who you are pretending is
the container:

public String getURIFragment(EObject eObject)
{
String id = EcoreUtil.getID(eObject);
if (id != null)
{
return id;
}
else
{
List uriFragmentPath = new ArrayList();
* for (EObject container = eObject.eContainer(); container !=
null; container = eObject.eContainer())
{

uriFragmentPath.add(((InternalEObject)container).eURIFragmen tSegment(eObject.eContainingFeature(),
eObject));
eObject = container;
}*

StringBuffer result = new StringBuffer("/");
result.append(getURIFragmentRootSegment(eObject));

for (ListIterator i =
uriFragmentPath.listIterator(uriFragmentPath.size()); i.hasPrevious(); )
{
result.append('/');
result.append((String)i.previous());
}
return result.toString();
}
}



Will wrote:

> Ed,
>
> From what I can tell, it seems to be having problems with forward
> refereneces. At least when it starts running into problems.
>
> I used the getURIFragment method to determin the URI fragment of the
> resource, for example:
>
> for (int i = 0; i < newResource.getContents().size(); i++)
> {
> EObject o = newResource.getEObject("/" + i);
> System.out.println("/" + i + " " + o.getClass().getName());
> }
>
> I get result like:
>
> /0 com.novell.porpoise.common.model.impl.ProjectImpl
> /1 com.novell.porpoise.common.model.impl.DomainImpl
> /2 com.novell.porpoise.common.model.impl.DomainImpl
> /3 com.novell.porpoise.common.model.impl.DomainImpl
> /4 com.novell.porpoise.common.model.impl.DomainImpl
> .. (and so on)
>
> The XML (from the xmi file) appears to be created in the same element
> order as the output from this debug. EXCEPT, when I start hitting the
> invalid references in the XML, the ordering is different.
>
> Either the XML elements are written out in the wrong order, or it
> seems related to forward references (reference to elements not yet
> there?!?!?).
>
> Also, I'm wondering if the my Lookup.featureKind(...) method is
> related to that changes going on. Because I'm changing the
> containment in this method, this could possibly change the number of
> elements in the complete document ... I'm not sure, but somehow these
> items seem related.
>
> This method, by the way, looks like:
>
> protected int featureKind( EStructuralFeature f )
> {
> int kind = super.featureKind( f );
> if ( f == ModelPackage.eINSTANCE.getProject_Domain()
> || f == ModelPackage.eINSTANCE.getDomain_DomainItems()
> || f ==
> ModelPackage.eINSTANCE.getDriver_Policies() )
> {
> switch (kind)
> {
> case OBJECT_HREF_MANY :
> return OBJECT_CONTAIN_MANY;
> case OBJECT_HREF_SINGLE :
> return OBJECT_CONTAIN_SINGLE;
> case OBJECT_HREF_SINGLE_UNSETTABLE :
> return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
> case OBJECT_HREF_MANY_UNSETTABLE :
> return OBJECT_CONTAIN_MANY_UNSETTABLE;
> }
> }
> return kind;
> }
>
>
>
> Ed Merks wrote:
>
>> Will,
>
>
>> I don't have a good theory for that. The root index is computed by
>> ResourceImpl like this:
>
>
>> protected String getURIFragmentRootSegment(EObject eObject)
>> {
>> List contents = getContents();
>> return contents.size() > 1 ?
>> Integer.toString(getContents().indexOf(eObject)) :
>> "";
>> }
>
>
>> I.e., it really does represent the position within the resource
>> contents list of the root object and it being wrong seems to imply
>> that the contents are changing during the save.
>
>
>
>> Will wrote:
>
>
>>> Ed,
>>>
>>> Thanks for your help. Using your suggestions I was able to rid
>>> myself of the references pointing to old resource files. However,
>>> I'm still getting invalid references to items within the document
>>> (for example I get a "/7" when it should be a "/9").
>>>
>>> Any ideas why this still might be happening?
>>>
>>> Here is the re-written code:
>>>
>>> private Resource buildConsolidatedResource( URI newResourceUri,
>>> Resource inputResource )
>>> {
>>> // create a list of resources to consolidate
>>> List resourceList = new ArrayList<Resource>();
>>> resourceList.add(inputResource);
>>>
>>> // recursivly add referenced resources (method below)
>>> addReferencedResources((Resource)resourceList.get(0),
>>> resourceList);
>>>
>>> // copy contents to a consolidated resource (which has the
>>> customized lookup method)
>>> Resource consolidatedResource = new MyResourceImpl(
>>> newResourceUri );
>>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>>> {
>>> consolidatedResource.getContents().addAll( ((Resource)
>>> iter.next()).getContents() ); }
>>> return consolidatedResource;
>>> }
>>>
>>> private static void addReferencedResources(Resource resource, List
>>> resourceList )
>>> {
>>> for (Iterator allContentsIterator = resource.getAllContents();
>>> allContentsIterator.hasNext();)
>>> {
>>> EObject allContentsEObject = (EObject)
>>> allContentsIterator.next();
>>> for (Iterator crossRefIterator =
>>> allContentsEObject.eCrossReferences().iterator();
>>> crossRefIterator.hasNext();)
>>> {
>>> Resource crossRefResource = ((EObject)
>>> crossRefIterator.next()).eResource();
>>> if (!resourceList.contains(crossRefResource))
>>> {
>>> resourceList.add(crossRefResource);
>>> addReferencedResources(crossRefResource, resourceList);
>>> }
>>> }
>>> }
>>> }
>>>
>>>
>>>
>>>
>>> Ed Merks wrote:
>>>
>>>> Will,
>>>
>>>
>>>
>>>> The algorithm below will do really nasty things because once you do
>>>> the addAll to the resource, the cross referenced objects will be
>>>> detached from their container and attached to the resource, so your
>>>> trees will be often be broken into so many little separate pieces.
>>>> Since there can be cross references (potentially) even within the
>>>> original resource, even that tree will end up being broken up.
>>>> Here's how I would imagine doing this. Start with a list of
>>>> resources containing just the one resource that you want to save.
>>>> Look at the nth resource in the list (starting at 0), walk the
>>>> resource.getAllContents, which recursively visits every contained
>>>> EObject, for each EObject iterate over the eCrossReferences to look
>>>> at each referenced object, and for each referenced object, check if
>>>> its eResource in in the list and add it if it isn't. If you repeat
>>>> this for each resource, you'll end up with a list of all the
>>>> resources that are referenced. If you take the getContents of all
>>>> but the first and add them to the first, you'll have a resource
>>>> containing the roots of all the tree you want to save into a single
>>>> resource.
>>>
>>>
>>>
>>>> Note that one of the many problems with your algorithm below is
>>>> that it doesn't look at the cross references of the cross
>>>> references, so it doesn't ensure that everything that's need will
>>>> actually all be in one resource...
>>>
>>>
>>>
>>>
>>>> Will wrote:
>>>
>>>
>>>
>>>>> I?ve been trying to put together a custom serialization method for
>>>>> our EMF model.
>>>>>
>>>>> Currently, we have an EMF model spread across several files in
>>>>> order to break down the model for editing purposes. However, at
>>>>> times we need an XML representation of the complete model for XML
>>>>> transformations and other needs.
>>>>>
>>>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>>>> over write the Lookup method to redefine containment such that
>>>>> save will put all the XML in one document represented by one
>>>>> resource.
>>>>>
>>>>> After a little work, I thought all was well. But soon came to
>>>>> discover that some of the references are not correct in the custom
>>>>> serialized model. For example, I might have an XMI reference like
>>>>> (ref=?/3 /4?) point to some nodes that are not correct. (Either
>>>>> the nodes are not there, or they are the wrong type, and so forth)
>>>>>
>>>>> I have also noticed that some references appear to point to old
>>>>> resource files (the ones that this resource was created with, and
>>>>> should no longer be necessary), for example (ref=?
>>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject is
>>>>> now contained in the same resource and the hope was that the
>>>>> reference value would have changed as well. (Such that the value
>>>>> would be something more like ref=?/3? where 3 refers to a node in
>>>>> the same resource)
>>>>>
>>>>> Or in other words, in ? I have successfully looped through and
>>>>> copied all the eObjects to an empty resource. However, when saving
>>>>> the resource the referenced items (some times) do not point back
>>>>> inside the file. (Although, they usually appear to do so besides
>>>>> the occasional reference that is off a little, possibly these
>>>>> other references are off). In fact, it appears that earlier
>>>>> references in the file are more likely to be correct than latter
>>>>> references, ? but I?m not sure why!?!?!?
>>>>>
>>>>> So here is my question:
>>>>> Any ideas why some references are off, while others are fine?
>>>>>
>>>>> I?ve been racking my brain over this one, but I?m afraid I?m going
>>>>> to have to brute force a custom XML document by looping through
>>>>> the EMF objects ? Any opinion on if that is going to be easier?
>>>>> This method was very slick and perfect for what I need, except for
>>>>> the inaccurate references &#61514;
>>>>>
>>>>> The blow code shows how I added the resource together:
>>>>>
>>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>>> {
>>>>>
>>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>>
>>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>>
>>>>> URI outputUri = null;
>>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>>> resource to over write lookup method
>>>>>
>>>>> newResource.getContents().addAll( objectList );
>>>>>
>>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>>>> {
>>>>> EObject element = (EObject) iter.next();
>>>>> }
>>>>> return os.toByteArray();
>>>>> }
>>>>>
>>>>> private void addChildObjects(
>>>>> EObject eObject,
>>>>> List<EObject> objectList )
>>>>> {
>>>>> if (!objectList.contains( eObject ))
>>>>> {
>>>>> // Add the object
>>>>> objectList.add( eObject );
>>>>> System.out.println("Added object: " + eObject.getClass().getName());
>>>>>
>>>>> // Add referenced children
>>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>>> iterator.hasNext();)
>>>>> {
>>>>> EObject child = (EObject) iterator.next();
>>>>> addChildObjects( child,
>>>>> objectList );
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>>>
>
>


--------------090009020903080002040403
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">
Will,<br>
<br>
Given that you've moved the entire closure of objects into the one
resource, why are you doing the containment overrides?
Re: Invalid EMF references on customized save [message #391220 is a reply to message #391179] Thu, 17 February 2005 18:54 Go to previous messageGo to next message
Eclipse UserFriend
Ed,

OK ... That last post may have been what I was looking for. So I'm happy
boy right now. I'm still hitting some issues, but I think it's some model
design issues I'll try to get ironed out.

Also, ... I'm getting reference that read more like:
ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be more
like: ref="/23"

Both make sense ... However, the latter result is preferred because of
"fun" transformation issues with XSLT.
Is it possible to force the reference to be just the element order in the
document??? (like the second reference)

By the way, In answer to your question about "why are you doing the
containment overrides?" ... We'll basically based on an earlier threads on
this message board I was left to think this was the best solution.
Because our model has classes that refer to other classes (with no
containment) in order to imply that that these classes are to be stored in
different files (but may actually "logically" contain the related class).
However, when we need an XML doc to represent the whole model, this custom
save will pull it back together in one file. And from what I see, having
the related eObjects all in the same resource does not necessarily change
the XML containment ... but somehow EMF is still able to treat the items
separately (and the end result is that saving would only write out one of
the eObjects "unless" containment is redefined) ... I hope that mess of a
paragraph made sense.

- Will



Ed Merks wrote:

> Will,

> Given that you've moved the entire closure of objects into the one
> resource, why are you doing the containment overrides? I would think
> this would cause duplicate objects to serialize, so you must be doing
> something to prevent that. The containment override will certainly
> mess this code in ResourceImpl which relies on properly knowing the
> inverse of containment to determine a path up the tree that can later
> be followed to walk back down the tree. You'll need to change this code
> to make eContainer appear "correct" based on who you are pretending is
> the container:

> public String getURIFragment(EObject eObject)
> {
> String id = EcoreUtil.getID(eObject);
> if (id != null)
> {
> return id;
> }
> else
> {
> List uriFragmentPath = new ArrayList();
> * for (EObject container = eObject.eContainer(); container !=
> null; container = eObject.eContainer())
> {

>
uriFragmentPath.add(((InternalEObject)container).eURIFragmen tSegment(eObject.eContainingFeature(),
> eObject));
> eObject = container;
> }*

> StringBuffer result = new StringBuffer("/");
> result.append(getURIFragmentRootSegment(eObject));

> for (ListIterator i =
> uriFragmentPath.listIterator(uriFragmentPath.size()); i.hasPrevious(); )
> {
> result.append('/');
> result.append((String)i.previous());
> }
> return result.toString();
> }
> }



> Will wrote:

>> Ed,
>>
>> From what I can tell, it seems to be having problems with forward
>> refereneces. At least when it starts running into problems.
>>
>> I used the getURIFragment method to determin the URI fragment of the
>> resource, for example:
>>
>> for (int i = 0; i < newResource.getContents().size(); i++)
>> {
>> EObject o = newResource.getEObject("/" + i);
>> System.out.println("/" + i + " " + o.getClass().getName());
>> }
>>
>> I get result like:
>>
>> /0 com.novell.porpoise.common.model.impl.ProjectImpl
>> /1 com.novell.porpoise.common.model.impl.DomainImpl
>> /2 com.novell.porpoise.common.model.impl.DomainImpl
>> /3 com.novell.porpoise.common.model.impl.DomainImpl
>> /4 com.novell.porpoise.common.model.impl.DomainImpl
>> .. (and so on)
>>
>> The XML (from the xmi file) appears to be created in the same element
>> order as the output from this debug. EXCEPT, when I start hitting the
>> invalid references in the XML, the ordering is different.
>>
>> Either the XML elements are written out in the wrong order, or it
>> seems related to forward references (reference to elements not yet
>> there?!?!?).
>>
>> Also, I'm wondering if the my Lookup.featureKind(...) method is
>> related to that changes going on. Because I'm changing the
>> containment in this method, this could possibly change the number of
>> elements in the complete document ... I'm not sure, but somehow these
>> items seem related.
>>
>> This method, by the way, looks like:
>>
>> protected int featureKind( EStructuralFeature f )
>> {
>> int kind = super.featureKind( f );
>> if ( f == ModelPackage.eINSTANCE.getProject_Domain()
>> || f == ModelPackage.eINSTANCE.getDomain_DomainItems()
>> || f ==
>> ModelPackage.eINSTANCE.getDriver_Policies() )
>> {
>> switch (kind)
>> {
>> case OBJECT_HREF_MANY :
>> return OBJECT_CONTAIN_MANY;
>> case OBJECT_HREF_SINGLE :
>> return OBJECT_CONTAIN_SINGLE;
>> case OBJECT_HREF_SINGLE_UNSETTABLE :
>> return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
>> case OBJECT_HREF_MANY_UNSETTABLE :
>> return OBJECT_CONTAIN_MANY_UNSETTABLE;
>> }
>> }
>> return kind;
>> }
>>
>>
>>
>> Ed Merks wrote:
>>
>>> Will,
>>
>>
>>> I don't have a good theory for that. The root index is computed by
>>> ResourceImpl like this:
>>
>>
>>> protected String getURIFragmentRootSegment(EObject eObject)
>>> {
>>> List contents = getContents();
>>> return contents.size() > 1 ?
>>> Integer.toString(getContents().indexOf(eObject)) :
>>> "";
>>> }
>>
>>
>>> I.e., it really does represent the position within the resource
>>> contents list of the root object and it being wrong seems to imply
>>> that the contents are changing during the save.
>>
>>
>>
>>> Will wrote:
>>
>>
>>>> Ed,
>>>>
>>>> Thanks for your help. Using your suggestions I was able to rid
>>>> myself of the references pointing to old resource files. However,
>>>> I'm still getting invalid references to items within the document
>>>> (for example I get a "/7" when it should be a "/9").
>>>>
>>>> Any ideas why this still might be happening?
>>>>
>>>> Here is the re-written code:
>>>>
>>>> private Resource buildConsolidatedResource( URI newResourceUri,
>>>> Resource inputResource )
>>>> {
>>>> // create a list of resources to consolidate
>>>> List resourceList = new ArrayList<Resource>();
>>>> resourceList.add(inputResource);
>>>>
>>>> // recursivly add referenced resources (method below)
>>>> addReferencedResources((Resource)resourceList.get(0),
>>>> resourceList);
>>>>
>>>> // copy contents to a consolidated resource (which has the
>>>> customized lookup method)
>>>> Resource consolidatedResource = new MyResourceImpl(
>>>> newResourceUri );
>>>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>>>> {
>>>> consolidatedResource.getContents().addAll( ((Resource)
>>>> iter.next()).getContents() ); }
>>>> return consolidatedResource;
>>>> }
>>>>
>>>> private static void addReferencedResources(Resource resource, List
>>>> resourceList )
>>>> {
>>>> for (Iterator allContentsIterator = resource.getAllContents();
>>>> allContentsIterator.hasNext();)
>>>> {
>>>> EObject allContentsEObject = (EObject)
>>>> allContentsIterator.next();
>>>> for (Iterator crossRefIterator =
>>>> allContentsEObject.eCrossReferences().iterator();
>>>> crossRefIterator.hasNext();)
>>>> {
>>>> Resource crossRefResource = ((EObject)
>>>> crossRefIterator.next()).eResource();
>>>> if (!resourceList.contains(crossRefResource))
>>>> {
>>>> resourceList.add(crossRefResource);
>>>> addReferencedResources(crossRefResource, resourceList);
>>>> }
>>>> }
>>>> }
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>> Ed Merks wrote:
>>>>
>>>>> Will,
>>>>
>>>>
>>>>
>>>>> The algorithm below will do really nasty things because once you do
>>>>> the addAll to the resource, the cross referenced objects will be
>>>>> detached from their container and attached to the resource, so your
>>>>> trees will be often be broken into so many little separate pieces.
>>>>> Since there can be cross references (potentially) even within the
>>>>> original resource, even that tree will end up being broken up.
>>>>> Here's how I would imagine doing this. Start with a list of
>>>>> resources containing just the one resource that you want to save.
>>>>> Look at the nth resource in the list (starting at 0), walk the
>>>>> resource.getAllContents, which recursively visits every contained
>>>>> EObject, for each EObject iterate over the eCrossReferences to look
>>>>> at each referenced object, and for each referenced object, check if
>>>>> its eResource in in the list and add it if it isn't. If you repeat
>>>>> this for each resource, you'll end up with a list of all the
>>>>> resources that are referenced. If you take the getContents of all
>>>>> but the first and add them to the first, you'll have a resource
>>>>> containing the roots of all the tree you want to save into a single
>>>>> resource.
>>>>
>>>>
>>>>
>>>>> Note that one of the many problems with your algorithm below is
>>>>> that it doesn't look at the cross references of the cross
>>>>> references, so it doesn't ensure that everything that's need will
>>>>> actually all be in one resource...
>>>>
>>>>
>>>>
>>>>
>>>>> Will wrote:
>>>>
>>>>
>>>>
>>>>>> I?ve been trying to put together a custom serialization method for
>>>>>> our EMF model.
>>>>>>
>>>>>> Currently, we have an EMF model spread across several files in
>>>>>> order to break down the model for editing purposes. However, at
>>>>>> times we need an XML representation of the complete model for XML
>>>>>> transformations and other needs.
>>>>>>
>>>>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>>>>> over write the Lookup method to redefine containment such that
>>>>>> save will put all the XML in one document represented by one
>>>>>> resource.
>>>>>>
>>>>>> After a little work, I thought all was well. But soon came to
>>>>>> discover that some of the references are not correct in the custom
>>>>>> serialized model. For example, I might have an XMI reference like
>>>>>> (ref=?/3 /4?) point to some nodes that are not correct. (Either
>>>>>> the nodes are not there, or they are the wrong type, and so forth)
>>>>>>
>>>>>> I have also noticed that some references appear to point to old
>>>>>> resource files (the ones that this resource was created with, and
>>>>>> should no longer be necessary), for example (ref=?
>>>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject is
>>>>>> now contained in the same resource and the hope was that the
>>>>>> reference value would have changed as well. (Such that the value
>>>>>> would be something more like ref=?/3? where 3 refers to a node in
>>>>>> the same resource)
>>>>>>
>>>>>> Or in other words, in ? I have successfully looped through and
>>>>>> copied all the eObjects to an empty resource. However, when saving
>>>>>> the resource the referenced items (some times) do not point back
>>>>>> inside the file. (Although, they usually appear to do so besides
>>>>>> the occasional reference that is off a little, possibly these
>>>>>> other references are off). In fact, it appears that earlier
>>>>>> references in the file are more likely to be correct than latter
>>>>>> references, ? but I?m not sure why!?!?!?
>>>>>>
>>>>>> So here is my question:
>>>>>> Any ideas why some references are off, while others are fine?
>>>>>>
>>>>>> I?ve been racking my brain over this one, but I?m afraid I?m going
>>>>>> to have to brute force a custom XML document by looping through
>>>>>> the EMF objects ? Any opinion on if that is going to be easier?
>>>>>> This method was very slick and perfect for what I need, except for
>>>>>> the inaccurate references &#61514;
>>>>>>
>>>>>> The blow code shows how I added the resource together:
>>>>>>
>>>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>>>> {
>>>>>>
>>>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>>>
>>>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>>>
>>>>>> URI outputUri = null;
>>>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>>>> resource to over write lookup method
>>>>>>
>>>>>> newResource.getContents().addAll( objectList );
>>>>>>
>>>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>>>>> {
>>>>>> EObject element = (EObject) iter.next();
>>>>>> }
>>>>>> return os.toByteArray();
>>>>>> }
>>>>>>
>>>>>> private void addChildObjects(
>>>>>> EObject eObject,
>>>>>> List<EObject> objectList )
>>>>>> {
>>>>>> if (!objectList.contains( eObject ))
>>>>>> {
>>>>>> // Add the object
>>>>>> objectList.add( eObject );
>>>>>> System.out.println("Added object: " + eObject.getClass().getName());
>>>>>>
>>>>>> // Add referenced children
>>>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>>>> iterator.hasNext();)
>>>>>> {
>>>>>> EObject child = (EObject) iterator.next();
>>>>>> addChildObjects( child,
>>>>>> objectList );
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
Re: Invalid EMF references on customized save [message #391234 is a reply to message #391220] Fri, 18 February 2005 07:01 Go to previous messageGo to next message
Eclipse UserFriend
Will,

If both make sense, then it sounds like you could first test in
getURIFragment if the object is directly in Resource.getContents before
walking up the pseudo containment tree, and to use the index in that
case. That last paragraph confused me a little. An XMLResourceImpl
will only let you save one root element but an XMIRsourceImpl lets you
save many because it automatically introduces a single pseudo root to
hold all the contents. To do this same thing with an XMLResourceImpl,
you'd have to define a single root object that can contain many
children. Is this related to your question? ;-)


Will wrote:

> Ed,
>
> OK ... That last post may have been what I was looking for. So I'm
> happy boy right now. I'm still hitting some issues, but I think it's
> some model design issues I'll try to get ironed out.
>
> Also, ... I'm getting reference that read more like:
> ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be
> more like: ref="/23"
>
> Both make sense ... However, the latter result is preferred because of
> "fun" transformation issues with XSLT.
> Is it possible to force the reference to be just the element order in
> the document??? (like the second reference)
>
> By the way, In answer to your question about "why are you doing the
> containment overrides?" ... We'll basically based on an earlier
> threads on this message board I was left to think this was the best
> solution. Because our model has classes that refer to other classes
> (with no containment) in order to imply that that these classes are to
> be stored in different files (but may actually "logically" contain the
> related class). However, when we need an XML doc to represent the
> whole model, this custom save will pull it back together in one file.
> And from what I see, having the related eObjects all in the same
> resource does not necessarily change the XML containment ... but
> somehow EMF is still able to treat the items separately (and the end
> result is that saving would only write out one of the eObjects
> "unless" containment is redefined) ... I hope that mess of a paragraph
> made sense.
>
> - Will
>
>
>
> Ed Merks wrote:
>
>> Will,
>
>
>> Given that you've moved the entire closure of objects into the one
>> resource, why are you doing the containment overrides? I would think
>> this would cause duplicate objects to serialize, so you must be doing
>> something to prevent that. The containment override will certainly
>> mess this code in ResourceImpl which relies on properly knowing the
>> inverse of containment to determine a path up the tree that can
>> later be followed to walk back down the tree. You'll need to change
>> this code to make eContainer appear "correct" based on who you are
>> pretending is the container:
>
>
>> public String getURIFragment(EObject eObject)
>> {
>> String id = EcoreUtil.getID(eObject);
>> if (id != null)
>> {
>> return id;
>> }
>> else
>> {
>> List uriFragmentPath = new ArrayList();
>> * for (EObject container = eObject.eContainer(); container !=
>> null; container = eObject.eContainer())
>> {
>
>
>>
>
> uriFragmentPath.add(((InternalEObject)container).eURIFragmen tSegment(eObject.eContainingFeature(),
>
>
>> eObject));
>> eObject = container;
>> }*
>
>
>> StringBuffer result = new StringBuffer("/");
>> result.append(getURIFragmentRootSegment(eObject));
>
>
>> for (ListIterator i =
>> uriFragmentPath.listIterator(uriFragmentPath.size());
>> i.hasPrevious(); )
>> {
>> result.append('/');
>> result.append((String)i.previous());
>> }
>> return result.toString();
>> }
>> }
>
>
>
>
>> Will wrote:
>
>
>>> Ed,
>>>
>>> From what I can tell, it seems to be having problems with forward
>>> refereneces. At least when it starts running into problems.
>>>
>>> I used the getURIFragment method to determin the URI fragment of the
>>> resource, for example:
>>>
>>> for (int i = 0; i < newResource.getContents().size(); i++)
>>> {
>>> EObject o = newResource.getEObject("/" + i);
>>> System.out.println("/" + i + " " + o.getClass().getName());
>>> }
>>>
>>> I get result like:
>>>
>>> /0 com.novell.porpoise.common.model.impl.ProjectImpl
>>> /1 com.novell.porpoise.common.model.impl.DomainImpl
>>> /2 com.novell.porpoise.common.model.impl.DomainImpl
>>> /3 com.novell.porpoise.common.model.impl.DomainImpl
>>> /4 com.novell.porpoise.common.model.impl.DomainImpl
>>> .. (and so on)
>>>
>>> The XML (from the xmi file) appears to be created in the same
>>> element order as the output from this debug. EXCEPT, when I start
>>> hitting the invalid references in the XML, the ordering is different.
>>>
>>> Either the XML elements are written out in the wrong order, or it
>>> seems related to forward references (reference to elements not yet
>>> there?!?!?).
>>>
>>> Also, I'm wondering if the my Lookup.featureKind(...) method is
>>> related to that changes going on. Because I'm changing the
>>> containment in this method, this could possibly change the number of
>>> elements in the complete document ... I'm not sure, but somehow
>>> these items seem related.
>>>
>>> This method, by the way, looks like:
>>>
>>> protected int featureKind( EStructuralFeature f )
>>> {
>>> int kind = super.featureKind( f );
>>> if ( f == ModelPackage.eINSTANCE.getProject_Domain()
>>> || f ==
>>> ModelPackage.eINSTANCE.getDomain_DomainItems()
>>> || f ==
>>> ModelPackage.eINSTANCE.getDriver_Policies() )
>>> {
>>> switch (kind)
>>> {
>>> case OBJECT_HREF_MANY :
>>> return OBJECT_CONTAIN_MANY;
>>> case OBJECT_HREF_SINGLE :
>>> return OBJECT_CONTAIN_SINGLE;
>>> case OBJECT_HREF_SINGLE_UNSETTABLE :
>>> return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
>>> case OBJECT_HREF_MANY_UNSETTABLE :
>>> return OBJECT_CONTAIN_MANY_UNSETTABLE;
>>> }
>>> }
>>> return kind;
>>> }
>>>
>>>
>>>
>>> Ed Merks wrote:
>>>
>>>> Will,
>>>
>>>
>>>
>>>> I don't have a good theory for that. The root index is computed by
>>>> ResourceImpl like this:
>>>
>>>
>>>
>>>> protected String getURIFragmentRootSegment(EObject eObject)
>>>> {
>>>> List contents = getContents();
>>>> return contents.size() > 1 ?
>>>> Integer.toString(getContents().indexOf(eObject)) :
>>>> "";
>>>> }
>>>
>>>
>>>
>>>> I.e., it really does represent the position within the resource
>>>> contents list of the root object and it being wrong seems to imply
>>>> that the contents are changing during the save.
>>>
>>>
>>>
>>>
>>>> Will wrote:
>>>
>>>
>>>
>>>>> Ed,
>>>>>
>>>>> Thanks for your help. Using your suggestions I was able to rid
>>>>> myself of the references pointing to old resource files. However,
>>>>> I'm still getting invalid references to items within the document
>>>>> (for example I get a "/7" when it should be a "/9").
>>>>>
>>>>> Any ideas why this still might be happening?
>>>>>
>>>>> Here is the re-written code:
>>>>>
>>>>> private Resource buildConsolidatedResource( URI newResourceUri,
>>>>> Resource inputResource )
>>>>> {
>>>>> // create a list of resources to consolidate
>>>>> List resourceList = new ArrayList<Resource>();
>>>>> resourceList.add(inputResource);
>>>>>
>>>>> // recursivly add referenced resources (method below)
>>>>> addReferencedResources((Resource)resourceList.get(0),
>>>>> resourceList);
>>>>>
>>>>> // copy contents to a consolidated resource (which has the
>>>>> customized lookup method)
>>>>> Resource consolidatedResource = new MyResourceImpl(
>>>>> newResourceUri );
>>>>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>>>>> {
>>>>> consolidatedResource.getContents().addAll( ((Resource)
>>>>> iter.next()).getContents() ); }
>>>>> return consolidatedResource;
>>>>> }
>>>>>
>>>>> private static void addReferencedResources(Resource resource,
>>>>> List resourceList )
>>>>> {
>>>>> for (Iterator allContentsIterator =
>>>>> resource.getAllContents(); allContentsIterator.hasNext();)
>>>>> {
>>>>> EObject allContentsEObject = (EObject)
>>>>> allContentsIterator.next();
>>>>> for (Iterator crossRefIterator =
>>>>> allContentsEObject.eCrossReferences().iterator();
>>>>> crossRefIterator.hasNext();)
>>>>> {
>>>>> Resource crossRefResource = ((EObject)
>>>>> crossRefIterator.next()).eResource();
>>>>> if (!resourceList.contains(crossRefResource))
>>>>> {
>>>>> resourceList.add(crossRefResource);
>>>>> addReferencedResources(crossRefResource, resourceList);
>>>>> }
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Ed Merks wrote:
>>>>>
>>>>>> Will,
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> The algorithm below will do really nasty things because once you
>>>>>> do the addAll to the resource, the cross referenced objects will
>>>>>> be detached from their container and attached to the resource, so
>>>>>> your trees will be often be broken into so many little separate
>>>>>> pieces. Since there can be cross references (potentially) even
>>>>>> within the original resource, even that tree will end up being
>>>>>> broken up. Here's how I would imagine doing this. Start with a
>>>>>> list of resources containing just the one resource that you want
>>>>>> to save. Look at the nth resource in the list (starting at 0),
>>>>>> walk the resource.getAllContents, which recursively visits every
>>>>>> contained EObject, for each EObject iterate over the
>>>>>> eCrossReferences to look at each referenced object, and for each
>>>>>> referenced object, check if its eResource in in the list and add
>>>>>> it if it isn't. If you repeat this for each resource, you'll end
>>>>>> up with a list of all the resources that are referenced. If you
>>>>>> take the getContents of all but the first and add them to the
>>>>>> first, you'll have a resource containing the roots of all the
>>>>>> tree you want to save into a single resource.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Note that one of the many problems with your algorithm below is
>>>>>> that it doesn't look at the cross references of the cross
>>>>>> references, so it doesn't ensure that everything that's need will
>>>>>> actually all be in one resource...
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Will wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> I?ve been trying to put together a custom serialization method
>>>>>>> for our EMF model.
>>>>>>>
>>>>>>> Currently, we have an EMF model spread across several files in
>>>>>>> order to break down the model for editing purposes. However, at
>>>>>>> times we need an XML representation of the complete model for
>>>>>>> XML transformations and other needs.
>>>>>>>
>>>>>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>>>>>> over write the Lookup method to redefine containment such that
>>>>>>> save will put all the XML in one document represented by one
>>>>>>> resource.
>>>>>>>
>>>>>>> After a little work, I thought all was well. But soon came to
>>>>>>> discover that some of the references are not correct in the
>>>>>>> custom serialized model. For example, I might have an XMI
>>>>>>> reference like (ref=?/3 /4?) point to some nodes that are not
>>>>>>> correct. (Either the nodes are not there, or they are the wrong
>>>>>>> type, and so forth)
>>>>>>>
>>>>>>> I have also noticed that some references appear to point to old
>>>>>>> resource files (the ones that this resource was created with,
>>>>>>> and should no longer be necessary), for example (ref=?
>>>>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject
>>>>>>> is now contained in the same resource and the hope was that the
>>>>>>> reference value would have changed as well. (Such that the value
>>>>>>> would be something more like ref=?/3? where 3 refers to a node
>>>>>>> in the same resource)
>>>>>>>
>>>>>>> Or in other words, in ? I have successfully looped through and
>>>>>>> copied all the eObjects to an empty resource. However, when
>>>>>>> saving the resource the referenced items (some times) do not
>>>>>>> point back inside the file. (Although, they usually appear to do
>>>>>>> so besides the occasional reference that is off a little,
>>>>>>> possibly these other references are off). In fact, it appears
>>>>>>> that earlier references in the file are more likely to be
>>>>>>> correct than latter references, ? but I?m not sure why!?!?!?
>>>>>>>
>>>>>>> So here is my question:
>>>>>>> Any ideas why some references are off, while others are fine?
>>>>>>>
>>>>>>> I?ve been racking my brain over this one, but I?m afraid I?m
>>>>>>> going to have to brute force a custom XML document by looping
>>>>>>> through the EMF objects ? Any opinion on if that is going to be
>>>>>>> easier? This method was very slick and perfect for what I need,
>>>>>>> except for the inaccurate references &#61514;
>>>>>>>
>>>>>>> The blow code shows how I added the resource together:
>>>>>>>
>>>>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>>>>> {
>>>>>>>
>>>>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>>>>
>>>>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>>>>
>>>>>>> URI outputUri = null;
>>>>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>>>>> resource to over write lookup method
>>>>>>>
>>>>>>> newResource.getContents().addAll( objectList );
>>>>>>>
>>>>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>>>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>>>>>> {
>>>>>>> EObject element = (EObject) iter.next();
>>>>>>> }
>>>>>>> return os.toByteArray();
>>>>>>> }
>>>>>>>
>>>>>>> private void addChildObjects(
>>>>>>> EObject eObject,
>>>>>>> List<EObject> objectList )
>>>>>>> {
>>>>>>> if (!objectList.contains( eObject ))
>>>>>>> {
>>>>>>> // Add the object
>>>>>>> objectList.add( eObject );
>>>>>>> System.out.println("Added object: " +
>>>>>>> eObject.getClass().getName());
>>>>>>>
>>>>>>> // Add referenced children
>>>>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>>>>> iterator.hasNext();)
>>>>>>> {
>>>>>>> EObject child = (EObject) iterator.next();
>>>>>>> addChildObjects( child,
>>>>>>> objectList );
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
Re: Invalid EMF references on customized save [message #391299 is a reply to message #391220] Wed, 23 February 2005 12:06 Go to previous messageGo to next message
Eclipse UserFriend
I'm getting reference that read like:
ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be more
like: ref="/23"

Is it possible to force the references to be just the element order in the
document??? (like the second reference, and not include @ or class names)

(See below for more detail)

Will wrote:

> Ed,

> OK ... That last post may have been what I was looking for. So I'm happy
> boy right now. I'm still hitting some issues, but I think it's some model
> design issues I'll try to get ironed out.

> Also, ... I'm getting reference that read more like:
> ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be more
> like: ref="/23"

> Both make sense ... However, the latter result is preferred because of
> "fun" transformation issues with XSLT.
> Is it possible to force the reference to be just the element order in the
> document??? (like the second reference)

> By the way, In answer to your question about "why are you doing the
> containment overrides?" ... We'll basically based on an earlier threads on
> this message board I was left to think this was the best solution.
> Because our model has classes that refer to other classes (with no
> containment) in order to imply that that these classes are to be stored in
> different files (but may actually "logically" contain the related class).
> However, when we need an XML doc to represent the whole model, this custom
> save will pull it back together in one file. And from what I see, having
> the related eObjects all in the same resource does not necessarily change
> the XML containment ... but somehow EMF is still able to treat the items
> separately (and the end result is that saving would only write out one of
> the eObjects "unless" containment is redefined) ... I hope that mess of a
> paragraph made sense.

> - Will



> Ed Merks wrote:

>> Will,

>> Given that you've moved the entire closure of objects into the one
>> resource, why are you doing the containment overrides? I would think
>> this would cause duplicate objects to serialize, so you must be doing
>> something to prevent that. The containment override will certainly
>> mess this code in ResourceImpl which relies on properly knowing the
>> inverse of containment to determine a path up the tree that can later
>> be followed to walk back down the tree. You'll need to change this code
>> to make eContainer appear "correct" based on who you are pretending is
>> the container:

>> public String getURIFragment(EObject eObject)
>> {
>> String id = EcoreUtil.getID(eObject);
>> if (id != null)
>> {
>> return id;
>> }
>> else
>> {
>> List uriFragmentPath = new ArrayList();
>> * for (EObject container = eObject.eContainer(); container !=
>> null; container = eObject.eContainer())
>> {

>>
>
uriFragmentPath.add(((InternalEObject)container).eURIFragmen tSegment(eObject.eContainingFeature(),
>> eObject));
>> eObject = container;
>> }*

>> StringBuffer result = new StringBuffer("/");
>> result.append(getURIFragmentRootSegment(eObject));

>> for (ListIterator i =
>> uriFragmentPath.listIterator(uriFragmentPath.size()); i.hasPrevious(); )
>> {
>> result.append('/');
>> result.append((String)i.previous());
>> }
>> return result.toString();
>> }
>> }



>> Will wrote:

>>> Ed,
>>>
>>> From what I can tell, it seems to be having problems with forward
>>> refereneces. At least when it starts running into problems.
>>>
>>> I used the getURIFragment method to determin the URI fragment of the
>>> resource, for example:
>>>
>>> for (int i = 0; i < newResource.getContents().size(); i++)
>>> {
>>> EObject o = newResource.getEObject("/" + i);
>>> System.out.println("/" + i + " " + o.getClass().getName());
>>> }
>>>
>>> I get result like:
>>>
>>> /0 com.novell.porpoise.common.model.impl.ProjectImpl
>>> /1 com.novell.porpoise.common.model.impl.DomainImpl
>>> /2 com.novell.porpoise.common.model.impl.DomainImpl
>>> /3 com.novell.porpoise.common.model.impl.DomainImpl
>>> /4 com.novell.porpoise.common.model.impl.DomainImpl
>>> .. (and so on)
>>>
>>> The XML (from the xmi file) appears to be created in the same element
>>> order as the output from this debug. EXCEPT, when I start hitting the
>>> invalid references in the XML, the ordering is different.
>>>
>>> Either the XML elements are written out in the wrong order, or it
>>> seems related to forward references (reference to elements not yet
>>> there?!?!?).
>>>
>>> Also, I'm wondering if the my Lookup.featureKind(...) method is
>>> related to that changes going on. Because I'm changing the
>>> containment in this method, this could possibly change the number of
>>> elements in the complete document ... I'm not sure, but somehow these
>>> items seem related.
>>>
>>> This method, by the way, looks like:
>>>
>>> protected int featureKind( EStructuralFeature f )
>>> {
>>> int kind = super.featureKind( f );
>>> if ( f == ModelPackage.eINSTANCE.getProject_Domain()
>>> || f == ModelPackage.eINSTANCE.getDomain_DomainItems()
>>> || f ==
>>> ModelPackage.eINSTANCE.getDriver_Policies() )
>>> {
>>> switch (kind)
>>> {
>>> case OBJECT_HREF_MANY :
>>> return OBJECT_CONTAIN_MANY;
>>> case OBJECT_HREF_SINGLE :
>>> return OBJECT_CONTAIN_SINGLE;
>>> case OBJECT_HREF_SINGLE_UNSETTABLE :
>>> return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
>>> case OBJECT_HREF_MANY_UNSETTABLE :
>>> return OBJECT_CONTAIN_MANY_UNSETTABLE;
>>> }
>>> }
>>> return kind;
>>> }
>>>
>>>
>>>
>>> Ed Merks wrote:
>>>
>>>> Will,
>>>
>>>
>>>> I don't have a good theory for that. The root index is computed by
>>>> ResourceImpl like this:
>>>
>>>
>>>> protected String getURIFragmentRootSegment(EObject eObject)
>>>> {
>>>> List contents = getContents();
>>>> return contents.size() > 1 ?
>>>> Integer.toString(getContents().indexOf(eObject)) :
>>>> "";
>>>> }
>>>
>>>
>>>> I.e., it really does represent the position within the resource
>>>> contents list of the root object and it being wrong seems to imply
>>>> that the contents are changing during the save.
>>>
>>>
>>>
>>>> Will wrote:
>>>
>>>
>>>>> Ed,
>>>>>
>>>>> Thanks for your help. Using your suggestions I was able to rid
>>>>> myself of the references pointing to old resource files. However,
>>>>> I'm still getting invalid references to items within the document
>>>>> (for example I get a "/7" when it should be a "/9").
>>>>>
>>>>> Any ideas why this still might be happening?
>>>>>
>>>>> Here is the re-written code:
>>>>>
>>>>> private Resource buildConsolidatedResource( URI newResourceUri,
>>>>> Resource inputResource )
>>>>> {
>>>>> // create a list of resources to consolidate
>>>>> List resourceList = new ArrayList<Resource>();
>>>>> resourceList.add(inputResource);
>>>>>
>>>>> // recursivly add referenced resources (method below)
>>>>> addReferencedResources((Resource)resourceList.get(0),
>>>>> resourceList);
>>>>>
>>>>> // copy contents to a consolidated resource (which has the
>>>>> customized lookup method)
>>>>> Resource consolidatedResource = new MyResourceImpl(
>>>>> newResourceUri );
>>>>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>>>>> {
>>>>> consolidatedResource.getContents().addAll( ((Resource)
>>>>> iter.next()).getContents() ); }
>>>>> return consolidatedResource;
>>>>> }
>>>>>
>>>>> private static void addReferencedResources(Resource resource, List
>>>>> resourceList )
>>>>> {
>>>>> for (Iterator allContentsIterator = resource.getAllContents();
>>>>> allContentsIterator.hasNext();)
>>>>> {
>>>>> EObject allContentsEObject = (EObject)
>>>>> allContentsIterator.next();
>>>>> for (Iterator crossRefIterator =
>>>>> allContentsEObject.eCrossReferences().iterator();
>>>>> crossRefIterator.hasNext();)
>>>>> {
>>>>> Resource crossRefResource = ((EObject)
>>>>> crossRefIterator.next()).eResource();
>>>>> if (!resourceList.contains(crossRefResource))
>>>>> {
>>>>> resourceList.add(crossRefResource);
>>>>> addReferencedResources(crossRefResource, resourceList);
>>>>> }
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Ed Merks wrote:
>>>>>
>>>>>> Will,
>>>>>
>>>>>
>>>>>
>>>>>> The algorithm below will do really nasty things because once you do
>>>>>> the addAll to the resource, the cross referenced objects will be
>>>>>> detached from their container and attached to the resource, so your
>>>>>> trees will be often be broken into so many little separate pieces.
>>>>>> Since there can be cross references (potentially) even within the
>>>>>> original resource, even that tree will end up being broken up.
>>>>>> Here's how I would imagine doing this. Start with a list of
>>>>>> resources containing just the one resource that you want to save.
>>>>>> Look at the nth resource in the list (starting at 0), walk the
>>>>>> resource.getAllContents, which recursively visits every contained
>>>>>> EObject, for each EObject iterate over the eCrossReferences to look
>>>>>> at each referenced object, and for each referenced object, check if
>>>>>> its eResource in in the list and add it if it isn't. If you repeat
>>>>>> this for each resource, you'll end up with a list of all the
>>>>>> resources that are referenced. If you take the getContents of all
>>>>>> but the first and add them to the first, you'll have a resource
>>>>>> containing the roots of all the tree you want to save into a single
>>>>>> resource.
>>>>>
>>>>>
>>>>>
>>>>>> Note that one of the many problems with your algorithm below is
>>>>>> that it doesn't look at the cross references of the cross
>>>>>> references, so it doesn't ensure that everything that's need will
>>>>>> actually all be in one resource...
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Will wrote:
>>>>>
>>>>>
>>>>>
>>>>>>> I?ve been trying to put together a custom serialization method for
>>>>>>> our EMF model.
>>>>>>>
>>>>>>> Currently, we have an EMF model spread across several files in
>>>>>>> order to break down the model for editing purposes. However, at
>>>>>>> times we need an XML representation of the complete model for XML
>>>>>>> transformations and other needs.
>>>>>>>
>>>>>>> I have written a custom ResourceImpl and XMLSaveImpl in order to
>>>>>>> over write the Lookup method to redefine containment such that
>>>>>>> save will put all the XML in one document represented by one
>>>>>>> resource.
>>>>>>>
>>>>>>> After a little work, I thought all was well. But soon came to
>>>>>>> discover that some of the references are not correct in the custom
>>>>>>> serialized model. For example, I might have an XMI reference like
>>>>>>> (ref=?/3 /4?) point to some nodes that are not correct. (Either
>>>>>>> the nodes are not there, or they are the wrong type, and so forth)
>>>>>>>
>>>>>>> I have also noticed that some references appear to point to old
>>>>>>> resource files (the ones that this resource was created with, and
>>>>>>> should no longer be necessary), for example (ref=?
>>>>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject is
>>>>>>> now contained in the same resource and the hope was that the
>>>>>>> reference value would have changed as well. (Such that the value
>>>>>>> would be something more like ref=?/3? where 3 refers to a node in
>>>>>>> the same resource)
>>>>>>>
>>>>>>> Or in other words, in ? I have successfully looped through and
>>>>>>> copied all the eObjects to an empty resource. However, when saving
>>>>>>> the resource the referenced items (some times) do not point back
>>>>>>> inside the file. (Although, they usually appear to do so besides
>>>>>>> the occasional reference that is off a little, possibly these
>>>>>>> other references are off). In fact, it appears that earlier
>>>>>>> references in the file are more likely to be correct than latter
>>>>>>> references, ? but I?m not sure why!?!?!?
>>>>>>>
>>>>>>> So here is my question:
>>>>>>> Any ideas why some references are off, while others are fine?
>>>>>>>
>>>>>>> I?ve been racking my brain over this one, but I?m afraid I?m going
>>>>>>> to have to brute force a custom XML document by looping through
>>>>>>> the EMF objects ? Any opinion on if that is going to be easier?
>>>>>>> This method was very slick and perfect for what I need, except for
>>>>>>> the inaccurate references &#61514;
>>>>>>>
>>>>>>> The blow code shows how I added the resource together:
>>>>>>>
>>>>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>>>>> {
>>>>>>>
>>>>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>>>>
>>>>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>>>>
>>>>>>> URI outputUri = null;
>>>>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>>>>> resource to over write lookup method
>>>>>>>
>>>>>>> newResource.getContents().addAll( objectList );
>>>>>>>
>>>>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>>>>> for (Iterator iter = newResource.getAllContents(); iter.hasNext();)
>>>>>>> {
>>>>>>> EObject element = (EObject) iter.next();
>>>>>>> }
>>>>>>> return os.toByteArray();
>>>>>>> }
>>>>>>>
>>>>>>> private void addChildObjects(
>>>>>>> EObject eObject,
>>>>>>> List<EObject> objectList )
>>>>>>> {
>>>>>>> if (!objectList.contains( eObject ))
>>>>>>> {
>>>>>>> // Add the object
>>>>>>> objectList.add( eObject );
>>>>>>> System.out.println("Added object: " + eObject.getClass().getName());
>>>>>>>
>>>>>>> // Add referenced children
>>>>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>>>>> iterator.hasNext();)
>>>>>>> {
>>>>>>> EObject child = (EObject) iterator.next();
>>>>>>> addChildObjects( child,
>>>>>>> objectList );
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
Re: Invalid EMF references on customized save [message #391303 is a reply to message #391299] Wed, 23 February 2005 14:46 Go to previous message
Eclipse UserFriend
This is a multi-part message in MIME format.
--------------040002020206030106020608
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Will,

You can override these two methods in your ResourceImpl to have complete
control over how the fragment looks for that resource:

String getURIFragment(EObject eObject)
EObject getEObject(String uriFragment)

Note that "/23" means select the 24th object in Resource.getContents(),
i.e., it only selects root objects.


Will wrote:

> I'm getting reference that read like:
> ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be
> more like: ref="/23"
>
> Is it possible to force the references to be just the element order in
> the document??? (like the second reference, and not include @ or class
> names)
>
> (See below for more detail)
>
> Will wrote:
>
>> Ed,
>
>
>> OK ... That last post may have been what I was looking for. So I'm
>> happy boy right now. I'm still hitting some issues, but I think it's
>> some model design issues I'll try to get ironed out.
>
>
>> Also, ... I'm getting reference that read more like:
>> ref="/0/@domain/@domainItems.3/@driverSets.0" when they used to be
>> more like: ref="/23"
>
>
>> Both make sense ... However, the latter result is preferred because
>> of "fun" transformation issues with XSLT.
>> Is it possible to force the reference to be just the element order in
>> the document??? (like the second reference)
>
>
>> By the way, In answer to your question about "why are you doing the
>> containment overrides?" ... We'll basically based on an earlier
>> threads on this message board I was left to think this was the best
>> solution. Because our model has classes that refer to other classes
>> (with no containment) in order to imply that that these classes are
>> to be stored in different files (but may actually "logically" contain
>> the related class). However, when we need an XML doc to represent
>> the whole model, this custom save will pull it back together in one
>> file. And from what I see, having the related eObjects all in the
>> same resource does not necessarily change the XML containment ... but
>> somehow EMF is still able to treat the items separately (and the end
>> result is that saving would only write out one of the eObjects
>> "unless" containment is redefined) ... I hope that mess of a
>> paragraph made sense.
>
>
>> - Will
>
>
>
>
>> Ed Merks wrote:
>
>
>>> Will,
>>
>
>>> Given that you've moved the entire closure of objects into the one
>>> resource, why are you doing the containment overrides? I would
>>> think this would cause duplicate objects to serialize, so you must
>>> be doing something to prevent that. The containment override will
>>> certainly mess this code in ResourceImpl which relies on properly
>>> knowing the inverse of containment to determine a path up the tree
>>> that can later be followed to walk back down the tree. You'll need
>>> to change this code to make eContainer appear "correct" based on who
>>> you are pretending is the container:
>>
>
>>> public String getURIFragment(EObject eObject)
>>> {
>>> String id = EcoreUtil.getID(eObject);
>>> if (id != null)
>>> {
>>> return id;
>>> }
>>> else
>>> {
>>> List uriFragmentPath = new ArrayList();
>>> * for (EObject container = eObject.eContainer(); container !=
>>> null; container = eObject.eContainer())
>>> {
>>
>
>>>
>>
>>
> uriFragmentPath.add(((InternalEObject)container).eURIFragmen tSegment(eObject.eContainingFeature(),
>
>
>>> eObject));
>>> eObject = container;
>>> }*
>>
>
>>> StringBuffer result = new StringBuffer("/");
>>> result.append(getURIFragmentRootSegment(eObject));
>>
>
>>> for (ListIterator i =
>>> uriFragmentPath.listIterator(uriFragmentPath.size());
>>> i.hasPrevious(); )
>>> {
>>> result.append('/');
>>> result.append((String)i.previous());
>>> }
>>> return result.toString();
>>> }
>>> }
>>
>
>
>
>>> Will wrote:
>>
>
>>>> Ed,
>>>>
>>>> From what I can tell, it seems to be having problems with forward
>>>> refereneces. At least when it starts running into problems.
>>>>
>>>> I used the getURIFragment method to determin the URI fragment of
>>>> the resource, for example:
>>>>
>>>> for (int i = 0; i < newResource.getContents().size(); i++)
>>>> {
>>>> EObject o = newResource.getEObject("/" + i);
>>>> System.out.println("/" + i + " " + o.getClass().getName());
>>>> }
>>>>
>>>> I get result like:
>>>>
>>>> /0 com.novell.porpoise.common.model.impl.ProjectImpl
>>>> /1 com.novell.porpoise.common.model.impl.DomainImpl
>>>> /2 com.novell.porpoise.common.model.impl.DomainImpl
>>>> /3 com.novell.porpoise.common.model.impl.DomainImpl
>>>> /4 com.novell.porpoise.common.model.impl.DomainImpl
>>>> .. (and so on)
>>>>
>>>> The XML (from the xmi file) appears to be created in the same
>>>> element order as the output from this debug. EXCEPT, when I start
>>>> hitting the invalid references in the XML, the ordering is different.
>>>>
>>>> Either the XML elements are written out in the wrong order, or it
>>>> seems related to forward references (reference to elements not yet
>>>> there?!?!?).
>>>>
>>>> Also, I'm wondering if the my Lookup.featureKind(...) method is
>>>> related to that changes going on. Because I'm changing the
>>>> containment in this method, this could possibly change the number
>>>> of elements in the complete document ... I'm not sure, but somehow
>>>> these items seem related.
>>>>
>>>> This method, by the way, looks like:
>>>>
>>>> protected int featureKind( EStructuralFeature f )
>>>> {
>>>> int kind = super.featureKind( f );
>>>> if ( f == ModelPackage.eINSTANCE.getProject_Domain()
>>>> || f ==
>>>> ModelPackage.eINSTANCE.getDomain_DomainItems()
>>>> || f ==
>>>> ModelPackage.eINSTANCE.getDriver_Policies() )
>>>> {
>>>> switch (kind)
>>>> {
>>>> case OBJECT_HREF_MANY :
>>>> return OBJECT_CONTAIN_MANY;
>>>> case OBJECT_HREF_SINGLE :
>>>> return OBJECT_CONTAIN_SINGLE;
>>>> case OBJECT_HREF_SINGLE_UNSETTABLE :
>>>> return OBJECT_CONTAIN_SINGLE_UNSETTABLE;
>>>> case OBJECT_HREF_MANY_UNSETTABLE :
>>>> return OBJECT_CONTAIN_MANY_UNSETTABLE;
>>>> }
>>>> }
>>>> return kind;
>>>> }
>>>>
>>>>
>>>>
>>>> Ed Merks wrote:
>>>>
>>>>> Will,
>>>>
>>>>
>>>>
>>>>> I don't have a good theory for that. The root index is computed
>>>>> by ResourceImpl like this:
>>>>
>>>>
>>>>
>>>>> protected String getURIFragmentRootSegment(EObject eObject)
>>>>> {
>>>>> List contents = getContents();
>>>>> return contents.size() > 1 ?
>>>>> Integer.toString(getContents().indexOf(eObject)) :
>>>>> "";
>>>>> }
>>>>
>>>>
>>>>
>>>>> I.e., it really does represent the position within the resource
>>>>> contents list of the root object and it being wrong seems to imply
>>>>> that the contents are changing during the save.
>>>>
>>>>
>>>>
>>>>
>>>>> Will wrote:
>>>>
>>>>
>>>>
>>>>>> Ed,
>>>>>>
>>>>>> Thanks for your help. Using your suggestions I was able to rid
>>>>>> myself of the references pointing to old resource files.
>>>>>> However, I'm still getting invalid references to items within the
>>>>>> document (for example I get a "/7" when it should be a "/9").
>>>>>>
>>>>>> Any ideas why this still might be happening?
>>>>>>
>>>>>> Here is the re-written code:
>>>>>>
>>>>>> private Resource buildConsolidatedResource( URI newResourceUri,
>>>>>> Resource inputResource )
>>>>>> {
>>>>>> // create a list of resources to consolidate
>>>>>> List resourceList = new ArrayList<Resource>();
>>>>>> resourceList.add(inputResource);
>>>>>>
>>>>>> // recursivly add referenced resources (method below)
>>>>>> addReferencedResources((Resource)resourceList.get(0),
>>>>>> resourceList);
>>>>>>
>>>>>> // copy contents to a consolidated resource (which has the
>>>>>> customized lookup method)
>>>>>> Resource consolidatedResource = new MyResourceImpl(
>>>>>> newResourceUri );
>>>>>> for (Iterator iter = resourceList.iterator(); iter.hasNext();)
>>>>>> {
>>>>>> consolidatedResource.getContents().addAll( ((Resource)
>>>>>> iter.next()).getContents() ); }
>>>>>> return consolidatedResource;
>>>>>> }
>>>>>>
>>>>>> private static void addReferencedResources(Resource resource,
>>>>>> List resourceList )
>>>>>> {
>>>>>> for (Iterator allContentsIterator =
>>>>>> resource.getAllContents(); allContentsIterator.hasNext();)
>>>>>> {
>>>>>> EObject allContentsEObject = (EObject)
>>>>>> allContentsIterator.next();
>>>>>> for (Iterator crossRefIterator =
>>>>>> allContentsEObject.eCrossReferences().iterator();
>>>>>> crossRefIterator.hasNext();)
>>>>>> {
>>>>>> Resource crossRefResource = ((EObject)
>>>>>> crossRefIterator.next()).eResource();
>>>>>> if (!resourceList.contains(crossRefResource))
>>>>>> {
>>>>>> resourceList.add(crossRefResource);
>>>>>> addReferencedResources(crossRefResource,
>>>>>> resourceList);
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Ed Merks wrote:
>>>>>>
>>>>>>> Will,
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> The algorithm below will do really nasty things because once you
>>>>>>> do the addAll to the resource, the cross referenced objects will
>>>>>>> be detached from their container and attached to the resource,
>>>>>>> so your trees will be often be broken into so many little
>>>>>>> separate pieces. Since there can be cross references
>>>>>>> (potentially) even within the original resource, even that tree
>>>>>>> will end up being broken up. Here's how I would imagine doing
>>>>>>> this. Start with a list of resources containing just the one
>>>>>>> resource that you want to save. Look at the nth resource in the
>>>>>>> list (starting at 0), walk the resource.getAllContents, which
>>>>>>> recursively visits every contained EObject, for each EObject
>>>>>>> iterate over the eCrossReferences to look at each referenced
>>>>>>> object, and for each referenced object, check if its eResource
>>>>>>> in in the list and add it if it isn't. If you repeat this for
>>>>>>> each resource, you'll end up with a list of all the resources
>>>>>>> that are referenced. If you take the getContents of all but the
>>>>>>> first and add them to the first, you'll have a resource
>>>>>>> containing the roots of all the tree you want to save into a
>>>>>>> single resource.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> Note that one of the many problems with your algorithm below is
>>>>>>> that it doesn't look at the cross references of the cross
>>>>>>> references, so it doesn't ensure that everything that's need
>>>>>>> will actually all be in one resource...
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> Will wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>> I?ve been trying to put together a custom serialization method
>>>>>>>> for our EMF model.
>>>>>>>>
>>>>>>>> Currently, we have an EMF model spread across several files in
>>>>>>>> order to break down the model for editing purposes. However, at
>>>>>>>> times we need an XML representation of the complete model for
>>>>>>>> XML transformations and other needs.
>>>>>>>>
>>>>>>>> I have written a custom ResourceImpl and XMLSaveImpl in order
>>>>>>>> to over write the Lookup method to redefine containment such
>>>>>>>> that save will put all the XML in one document represented by
>>>>>>>> one resource.
>>>>>>>>
>>>>>>>> After a little work, I thought all was well. But soon came to
>>>>>>>> discover that some of the references are not correct in the
>>>>>>>> custom serialized model. For example, I might have an XMI
>>>>>>>> reference like (ref=?/3 /4?) point to some nodes that are not
>>>>>>>> correct. (Either the nodes are not there, or they are the wrong
>>>>>>>> type, and so forth)
>>>>>>>>
>>>>>>>> I have also noticed that some references appear to point to old
>>>>>>>> resource files (the ones that this resource was created with,
>>>>>>>> and should no longer be necessary), for example (ref=?
>>>>>>>> Another_sub_file_from_emf_model.extension#/?) when that EObject
>>>>>>>> is now contained in the same resource and the hope was that the
>>>>>>>> reference value would have changed as well. (Such that the
>>>>>>>> value would be something more like ref=?/3? where 3 refers to a
>>>>>>>> node in the same resource)
>>>>>>>>
>>>>>>>> Or in other words, in ? I have successfully looped through and
>>>>>>>> copied all the eObjects to an empty resource. However, when
>>>>>>>> saving the resource the referenced items (some times) do not
>>>>>>>> point back inside the file. (Although, they usually appear to
>>>>>>>> do so besides the occasional reference that is off a little,
>>>>>>>> possibly these other references are off). In fact, it appears
>>>>>>>> that earlier references in the file are more likely to be
>>>>>>>> correct than latter references, ? but I?m not sure why!?!?!?
>>>>>>>>
>>>>>>>> So here is my question:
>>>>>>>> Any ideas why some references are off, while others are fine?
>>>>>>>>
>>>>>>>> I?ve been racking my brain over this one, but I?m afraid I?m
>>>>>>>> going to have to brute force a custom XML document by looping
>>>>>>>> through the EMF objects ? Any opinion on if that is going to be
>>>>>>>> easier? This method was very slick and perfect for what I need,
>>>>>>>> except for the inaccurate references &#61514;
>>>>>>>>
>>>>>>>> The blow code shows how I added the resource together:
>>>>>>>>
>>>>>>>> private byte[] create(EObject rootObjectFromManyFileModel)
>>>>>>>> {
>>>>>>>>
>>>>>>>> List<EObject> objectList = new ArrayList<EObject>();
>>>>>>>> ByteArrayOutputStream os = new ByteArrayOutputStream();
>>>>>>>>
>>>>>>>> addChildObjects( rootObjectFromManyFileModel, objectList );
>>>>>>>>
>>>>>>>> URI outputUri = null;
>>>>>>>> Resource newResource = new MyResourceImpl( null); // customized
>>>>>>>> resource to over write lookup method
>>>>>>>>
>>>>>>>> newResource.getContents().addAll( objectList );
>>>>>>>>
>>>>>>>> newResource.save( os, Collections.EMPTY_MAP ); int count = 0;
>>>>>>>> for (Iterator iter = newResource.getAllContents();
>>>>>>>> iter.hasNext();)
>>>>>>>> {
>>>>>>>> EObject element = (EObject) iter.next();
>>>>>>>> }
>>>>>>>> return os.toByteArray();
>>>>>>>> }
>>>>>>>>
>>>>>>>> private void addChildObjects(
>>>>>>>> EObject eObject,
>>>>>>>> List<EObject> objectList )
>>>>>>>> {
>>>>>>>> if (!objectList.contains( eObject ))
>>>>>>>> {
>>>>>>>> // Add the object
>>>>>>>> objectList.add( eObject );
>>>>>>>> System.out.println("Added object: " +
>>>>>>>> eObject.getClass().getName());
>>>>>>>>
>>>>>>>> // Add referenced children
>>>>>>>> for (Iterator iterator = eObject.eCrossReferences().iterator();
>>>>>>>> iterator.hasNext();)
>>>>>>>> {
>>>>>>>> EObject child = (EObject) iterator.next();
>>>>>>>> addChildObjects( child,
>>>>>>>> objectList );
>>>>>>>> }
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>
>


--------------040002020206030106020608
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">
Will,<br>
<br>
You can override these two methods in your ResourceImpl to have
complete control over how the fragment looks for that resource:<br>
<blockquote>String getURIFragment(EObject eObject)<br>
EObject getEObject(String uriFragment)<br>
</blockquote>
Note that "/23" means select the 24th object in Resource.getContents(),
i.e., it only selects root objects.<br>
<br>
<br>
Will wrote:
<blockquote cite="midcvid60$1nu$1@www.eclipse.org" type="cite">I'm
getting reference that read like:
ref=<a class="moz-txt-link-rfc2396E" href="mailto:/0/@domain/@domainItems.3/@driverSets.0">"/0/@domain/@domainItems.3/@driverSets.0 "</a> when they used to be more
like: ref="/23"
<br>
<br>
Is it possible to force the references to be just the element order in
the document??? (like the second reference, and not include @ or class
names)
<br>
<br>
(See below for more detail)
<br>
<br>
Will wrote:
<br>
<br>
<blockquote type="cite">Ed,
<br>
</blockquote>
<br>
<blockquote type="cite">OK ... That last post may have been what I
was looking for. So I'm happy boy right now.
Previous Topic:Overriding deserialisation for some attributes in myResourceImpl extends XMLResourceImpl
Next Topic:EMF standalone deployment licensing issues
Goto Forum:
  


Current Time: Fri Oct 31 10:27:03 EDT 2025

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

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

Back to the top