Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » remove objects from resource
remove objects from resource [message #410612] Mon, 02 July 2007 11:05 Go to next message
Christian Donhofer is currently offline Christian Donhofer
Messages: 94
Registered: July 2009
Member
hi all,

im trying to remove unnecessary objects from a resource. the following

code throws a ConcurrentModificationException.

//remove blocks of types not needed
for(Object o : render_resource.getContents()){
EObject eo = (EObject)o;
if(eo instanceof HypertextBlockImpl){
HypertextBlockImpl hb = (HypertextBlockImpl)eo;
boolean show = true;
for(String type : blocktypesList.keySet()){
if(type.equalsIgnoreCase(hb.getBlockMeta().getBlocktype().ge tName()) &&
blocktypesList.get(type)[0].equalsIgnoreCase("hide")
){
System.out.println("REMOVING BLOCK WITH TYPE "+type);
show = false;
}
}
//remove block
if(!show){
//tried EcoreUtil.remove() here too --> same exception
render_resource.getContents().remove(eo);
}
}
}

i also tried for(Object o :
EcoreUtil.copyAll(render_resource.getContents())){}
since that works in comparable situations, but of course not when trying
to delete something.

i know that it can't work like that, but somehow i can't find another
solution to this task - can somebody help me with that? =)

TIA, chris
Re: remove objects from resource [message #410613 is a reply to message #410612] Mon, 02 July 2007 11:10 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 4662
Registered: July 2009
Senior Member
Why not using an iterator?

Iterator it = render_resource.getContents();

while( it.hasNext() ) {
Object o = it.next();

// ....

it.remove();
}

Tom

Christian Donhofer schrieb:
> hi all,
>
> im trying to remove unnecessary objects from a resource. the following
>
> code throws a ConcurrentModificationException.
>
> //remove blocks of types not needed
> for(Object o : render_resource.getContents()){
> EObject eo = (EObject)o;
> if(eo instanceof HypertextBlockImpl){
> HypertextBlockImpl hb = (HypertextBlockImpl)eo;
> boolean show = true;
> for(String type : blocktypesList.keySet()){
> if(type.equalsIgnoreCase(hb.getBlockMeta().getBlocktype().ge tName()) &&
> blocktypesList.get(type)[0].equalsIgnoreCase("hide")
> ){
> System.out.println("REMOVING BLOCK WITH TYPE "+type);
> show = false;
> }
> }
> //remove block
> if(!show){
> //tried EcoreUtil.remove() here too --> same exception
> render_resource.getContents().remove(eo);
> }
> }
> }
>
> i also tried for(Object o :
> EcoreUtil.copyAll(render_resource.getContents())){}
> since that works in comparable situations, but of course not when trying
> to delete something.
>
> i know that it can't work like that, but somehow i can't find another
> solution to this task - can somebody help me with that? =)
>
> TIA, chris
Re: remove objects from resource [message #410615 is a reply to message #410613] Mon, 02 July 2007 11:36 Go to previous messageGo to next message
Christian Donhofer is currently offline Christian Donhofer
Messages: 94
Registered: July 2009
Member
On Mon, 02 Jul 2007 17:10:06 +0200 Tom Schindl wrote:

> Why not using an iterator?
>


unfortunately, that throws the same exception =/

cheers, chris


java.lang.reflect.InvocationTargetException
at org.eclipse.jface.operation.ModalContext.run(ModalContext.ja va:350)

[cut]

Caused by: java.util.ConcurrentModificationException
at org.eclipse.emf.common.util.BasicEList$EIterator.checkModCou nt(BasicEList.java:1327)
at org.eclipse.emf.common.util.BasicEList$EIterator.next(BasicE List.java:1275)
at xmirenderer.utils.RenderingProgressMonitor.run(RenderingProg ressMonitor.java:94)
at org.eclipse.jface.operation.ModalContext$ModalContextThread. run(ModalContext.java:113)




> Iterator it = render_resource.getContents();
>
> while( it.hasNext() ) {
> Object o = it.next();
>
> // ....
>
> it.remove();
> }
>
> Tom
>
Re: remove objects from resource [message #410619 is a reply to message #410612] Mon, 02 July 2007 11:52 Go to previous messageGo to next message
Aleksander Bandelj is currently offline Aleksander Bandelj
Messages: 98
Registered: July 2009
Member
Try iterating over copy of resource contents. eg.

for(Object o : new ArrayList( render_resource.getContents() ) )

-a

Christian Donhofer wrote:
> hi all,
>
> im trying to remove unnecessary objects from a resource. the following
>
> code throws a ConcurrentModificationException.
>
> //remove blocks of types not needed
> for(Object o : render_resource.getContents()){
> EObject eo = (EObject)o;
> if(eo instanceof HypertextBlockImpl){
> HypertextBlockImpl hb = (HypertextBlockImpl)eo;
> boolean show = true;
> for(String type : blocktypesList.keySet()){
> if(type.equalsIgnoreCase(hb.getBlockMeta().getBlocktype().ge tName()) &&
> blocktypesList.get(type)[0].equalsIgnoreCase("hide")
> ){
> System.out.println("REMOVING BLOCK WITH TYPE "+type);
> show = false;
> }
> }
> //remove block
> if(!show){
> //tried EcoreUtil.remove() here too --> same exception
> render_resource.getContents().remove(eo);
> }
> }
> }
>
> i also tried for(Object o :
> EcoreUtil.copyAll(render_resource.getContents())){}
> since that works in comparable situations, but of course not when trying
> to delete something.
>
> i know that it can't work like that, but somehow i can't find another
> solution to this task - can somebody help me with that? =)
>
> TIA, chris
>
Re: remove objects from resource [message #410620 is a reply to message #410612] Mon, 02 July 2007 12:09 Go to previous messageGo to next message
Christian Donhofer is currently offline Christian Donhofer
Messages: 94
Registered: July 2009
Member
hi again,

i found "half" of a solution, using this code:
//list of objects to remove
ArrayList<EObject> remove = new ArrayList<EObject>();
ArrayList<EStructuralFeature> remove_feat = new ArrayList<EStructuralFeature>();

java.util.Iterator it = render_resource.getContents().iterator();

//remove blocks of types not needed
while(it.hasNext()){
EObject eo = (EObject)it.next();
if(eo instanceof HypertextBlockImpl){
HypertextBlockImpl hb = (HypertextBlockImpl)eo;
boolean show = true;
for(String type : blocktypesList.keySet()){
if(type.equalsIgnoreCase(hb.getBlockMeta().getBlocktype().ge tName()) &&
blocktypesList.get(type)[0].equalsIgnoreCase("hide")
){
System.out.println("REMOVING BLOCK WITH TYPE "+type);
show = false;
}
}
//remove block
if(!show){
remove_feat.add((EStructuralFeature)eo.eContainingFeature()) ;
remove_feat.add((EStructuralFeature)eo.eContainmentFeature() );
for(Object cr : eo.eCrossReferences()){
EStructuralFeature ref = (EStructuralFeature)cr;
remove_feat.add(ref);
}
remove.add(eo);
}
}
}
//do actual removing
//features
for(EStructuralFeature e : remove_feat){
render_resource.getContents().remove(e);
}
//objects
for(EObject e : remove){

render_resource.getContents().remove(e);
}

with this code, though, it seems im not deleting all kinds of
references(which then causes serialization to fail). so what else do i
need to do to "cleanly" remove the objects from the resource?

cheers, chris
Re: remove objects from resource [message #410625 is a reply to message #410620] Mon, 02 July 2007 12:40 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25227
Registered: July 2009
Senior Member
Christian,

Because of bidirectional updates, there will often be reasons why a list
is modified indirectly. Iterating over a copy should help. Building a
collection of things to operate on and then doing the removal later is
also a good technique. Note that EcoreUtil.remove and EcoreUtil.delete
might do exactly the kind of thing you want. So you could first build a
collection of the object you want to remove and then use
EcoreUtil.remove/delete to remove them or delete all references to that.


Christian Donhofer wrote:
> hi again,
>
> i found "half" of a solution, using this code:
> //list of objects to remove
> ArrayList<EObject> remove = new ArrayList<EObject>();
> ArrayList<EStructuralFeature> remove_feat = new ArrayList<EStructuralFeature>();
>
> java.util.Iterator it = render_resource.getContents().iterator();
>
> //remove blocks of types not needed
> while(it.hasNext()){
> EObject eo = (EObject)it.next();
> if(eo instanceof HypertextBlockImpl){
> HypertextBlockImpl hb = (HypertextBlockImpl)eo;
> boolean show = true;
> for(String type : blocktypesList.keySet()){
> if(type.equalsIgnoreCase(hb.getBlockMeta().getBlocktype().ge tName()) &&
> blocktypesList.get(type)[0].equalsIgnoreCase("hide")
> ){
> System.out.println("REMOVING BLOCK WITH TYPE "+type);
> show = false;
> }
> }
> //remove block
> if(!show){
> remove_feat.add((EStructuralFeature)eo.eContainingFeature()) ;
> remove_feat.add((EStructuralFeature)eo.eContainmentFeature() );
> for(Object cr : eo.eCrossReferences()){
> EStructuralFeature ref = (EStructuralFeature)cr;
> remove_feat.add(ref);
> }
> remove.add(eo);
> }
> }
> }
> //do actual removing
> //features
> for(EStructuralFeature e : remove_feat){
> render_resource.getContents().remove(e);
> }
> //objects
> for(EObject e : remove){
>
> render_resource.getContents().remove(e);
> }
>
> with this code, though, it seems im not deleting all kinds of
> references(which then causes serialization to fail). so what else do i
> need to do to "cleanly" remove the objects from the resource?
>
> cheers, chris
>
>
Re: remove objects from resource [message #410633 is a reply to message #410625] Mon, 02 July 2007 13:09 Go to previous messageGo to next message
Christian Donhofer is currently offline Christian Donhofer
Messages: 94
Registered: July 2009
Member
hi ed,

thanks for your reply. since when does that delete method exist?
unfortunately, in the version we've been using for this project, it's not
yet present. anyway, google found me that ng-post containing this method:

public static void delete(EObject eObject)
{
EObject rootEObject = EcoreUtil.getRootContainer(eObject);
Resource resource = rootEObject.eResource();

Collection usages;
if (resource == null)
{
usages = UsageCrossReferencer.find(eObject, rootEObject);
}
else
{
ResourceSet resourceSet = resource.getResourceSet();
if (resourceSet == null)
{
usages = UsageCrossReferencer.find(eObject, resource);
}
else
{
usages = UsageCrossReferencer.find(eObject, resourceSet);
}
}
for (Iterator i = usages.iterator(); i.hasNext(); )
{
EStructuralFeature.Setting setting =
(EStructuralFeature.Setting)i.next();
if (setting.getEStructuralFeature().isChangeable())
{
EcoreUtil.remove(setting, eObject);
}
}


EcoreUtil.remove(eObject);
}

does this method equal the one you mean? if so, that doesn't solve my
problem, since i still get the DanglingHrefException when serializing.

if not, i'll try to get the EMF version that implements the method you
were suggesting.

cheers, chris

On Mon, 02 Jul 2007 12:40:56 -0400 Ed Merks wrote:

> Christian,
>
> Because of bidirectional updates, there will often be reasons why a list
> is modified indirectly. Iterating over a copy should help. Building a
> collection of things to operate on and then doing the removal later is
> also a good technique. Note that EcoreUtil.remove and EcoreUtil.delete
> might do exactly the kind of thing you want. So you could first build a
> collection of the object you want to remove and then use
> EcoreUtil.remove/delete to remove them or delete all references to that.
>
Re: remove objects from resource [message #410635 is a reply to message #410633] Mon, 02 July 2007 13:23 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25227
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------030505000208010200030204
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Christian,

The delete method should find all references to the object within the
resource set and clean those up. Perhaps it should be removing
references to recursively contained children as well, but it does only
what the Javadoc says, so you'd need to call it for the children too...


Christian Donhofer wrote:
> hi ed,
>
> thanks for your reply. since when does that delete method exist?
> unfortunately, in the version we've been using for this project, it's not
> yet present. anyway, google found me that ng-post containing this method:
>
> public static void delete(EObject eObject)
> {
> EObject rootEObject = EcoreUtil.getRootContainer(eObject);
> Resource resource = rootEObject.eResource();
>
> Collection usages;
> if (resource == null)
> {
> usages = UsageCrossReferencer.find(eObject, rootEObject);
> }
> else
> {
> ResourceSet resourceSet = resource.getResourceSet();
> if (resourceSet == null)
> {
> usages = UsageCrossReferencer.find(eObject, resource);
> }
> else
> {
> usages = UsageCrossReferencer.find(eObject, resourceSet);
> }
> }
> for (Iterator i = usages.iterator(); i.hasNext(); )
> {
> EStructuralFeature.Setting setting =
> (EStructuralFeature.Setting)i.next();
> if (setting.getEStructuralFeature().isChangeable())
> {
> EcoreUtil.remove(setting, eObject);
> }
> }
>
>
> EcoreUtil.remove(eObject);
> }
>
> does this method equal the one you mean? if so, that doesn't solve my
> problem, since i still get the DanglingHrefException when serializing.
>
> if not, i'll try to get the EMF version that implements the method you
> were suggesting.
>
> cheers, chris
>
> On Mon, 02 Jul 2007 12:40:56 -0400 Ed Merks wrote:
>
>
>> Christian,
>>
>> Because of bidirectional updates, there will often be reasons why a list
>> is modified indirectly. Iterating over a copy should help. Building a
>> collection of things to operate on and then doing the removal later is
>> also a good technique. Note that EcoreUtil.remove and EcoreUtil.delete
>> might do exactly the kind of thing you want. So you could first build a
>> collection of the object you want to remove and then use
>> EcoreUtil.remove/delete to remove them or delete all references to that.
>>
>>
>
>


--------------030505000208010200030204
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">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Christian,<br>
<br>
The delete method should find all references to the object within the
resource set and clean those up.
Re: remove objects from resource [message #410638 is a reply to message #410635] Mon, 02 July 2007 13:44 Go to previous messageGo to next message
Christian Donhofer is currently offline Christian Donhofer
Messages: 94
Registered: July 2009
Member
On Mon, 02 Jul 2007 13:23:38 -0400 Ed Merks wrote:

> Christian,
>
> The delete method should find all references to the object within the
> resource set and clean those up. Perhaps it should be removing
> references to recursively contained children as well, but it does only
> what the Javadoc says, so you'd need to call it for the children too...
>
>

well, i tried adding the children to the removallist too, like
remove.add(eo);
for(Iterator iter = eo.eAllContents(); iter.hasNext(); ){
remove.add((EObject)iter.next());
}

and then

for(EObject e : remove){
EcoreUtil.remove(e);
delete(e);
}

and still there seem to be some references, so i guess it's not
eAllContents i need to use to get all children...?

cheers, chris
Re: remove objects from resource [message #410640 is a reply to message #410638] Mon, 02 July 2007 14:30 Go to previous message
Ed Merks is currently offline Ed Merks
Messages: 25227
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------060606000004000701050407
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Christian,

If you look closely at the single argument delete method that you are
calling, you'll see that it needs to walk up the containers of the
argument to find the resource set, so if you've already removed the
object from its container, no resource set will be reachable and no
references will be cleaned up. The debugger is ever so helpful to see
how things are working dynamically...


Christian *Donhofer* wrote:
> On Mon, 02 Jul 2007 13:23:38 -0400 Ed Merks wrote:
>
>
>> Christian,
>>
>> The delete method should find all references to the object within the
>> resource set and clean those up. Perhaps it should be removing
>> references to recursively contained children as well, but it does only
>> what the Javadoc says, so you'd need to call it for the children too...
>>
>>
>>
>
> well, i tried adding the children to the removallist too, like
> remove.add(eo);
> for(Iterator iter = eo.eAllContents(); iter.hasNext(); ){
> remove.add((EObject)iter.next());
> }
>
> and then
>
> for(EObject e : remove){
> EcoreUtil.remove(e);
> delete(e);
> }
>
> and still there seem to be some references, so i guess it's not
> eAllContents i need to use to get all children...?
>
> cheers, chris
>


--------------060606000004000701050407
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">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Christian,<br>
<br>
If you look closely at the single argument delete method that you are
calling, you'll see that it needs to walk up the containers of the
argument to find the resource set, so if you've already removed the
object from its container, no resource set will be reachable and no
references will be cleaned up.
Previous Topic:Overriding EPackage with custom EFactory in ResourceSet
Next Topic:CompoundCommand
Goto Forum:
  


Current Time: Tue Oct 08 07:54:11 EDT 2013

Powered by FUDForum. Page generated in 0.02037 seconds