Home » Modeling » EMF » Model changed while loading
Model changed while loading [message #544404] |
Fri, 02 July 2010 10:42  |
Eclipse User |
|
|
|
Hi,
I have the following code (see the end for the problem):
==================== CODE ===================
public void init(IEditorSite site, IEditorInput editorInput)
throws PartInitException {
super.init(site, editorInput);
URI uri;
if (model == null) {
if (editorInput instanceof LocalEditorInput) {
LocalEditorInput lei = (LocalEditorInput) editorInput;
uri = (URI) lei.getAdapter(URI.class);
} else {
uri = URI.createURI(editorInput.getName());
}
model = new Model(uri);
model.getResource().setTrackingModification(true);
doSaveAs("_tst0_"); // THIS IS HERE JUST FOR TESTING PURPOSES
}
}
where (I leave the whole class minus comments because I don't know what may be relevant):
public class Model {
protected ResourceSet resourceSet;
protected Resource resource;
protected Model() {
resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFacto ryMap().put(World.DEFAULT_EXTENSION, new WorldResourceFactoryImpl());
resourceSet.getPackageRegistry().put(WorldPackage.eNS_URI, WorldPackage.eINSTANCE);
resourceSet.getLoadOptions().put(XMLResource.OPTION_RECORD_U NKNOWN_FEATURE, Boolean.TRUE);
}
public Model(URI uri) {
this();
load(uri);
}
public Model(String fname) {
this();
if (fname == null) {
Resource resource = resourceSet.createResource(URI.createURI("http:///new" + World.DEFAULT_EXTENSION));
World root = WorldFactory.eINSTANCE.createWorld();
resource.getContents().add(root);
} else {
File file = new File(fname);
URI uri = file.isFile() ? URI.createFileURI(file.getAbsolutePath()) : URI.createURI(fname);
load(uri);
}
}
protected void load(URI uri) {
try {
resource = resourceSet.getResource(uri, true);
} catch (RuntimeException exception) {
System.err.println("Problem loading " + uri);
exception.printStackTrace();
}
check();
}
public Resource getResource() {
return resource;
}
public void save() throws IOException {
if (resource.isModified()) {
Map<String, String> opt = new HashMap<String, String>();
opt.put(XMLResource.OPTION_ENCODING, "UTF-8");
resource.save(opt);
}
}
public void saveAs(String fname) throws IOException {
File file = new File(fname);
URI uri = URI.createFileURI(file.getAbsolutePath());
resource.setURI(uri);
resource.setModified(true);
save();
}
public void save(OutputStream os) {
try {
resource.save(os, Collections.EMPTY_MAP);
} catch (IOException e) {
e.printStackTrace();
}
}
protected void check() {
if (resource instanceof XMLResource) {
XMLResource xr = (XMLResource) resource;
xr.getEObjectToExtensionMap().clear();
}
for (EObject eObject : resource.getContents()) {
Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
if (diagnostic.getSeverity() != Diagnostic.OK) {
printDiagnostic(diagnostic, "");
}
//walkModel(eObject, " ");
}
}
protected static void printDiagnostic(Diagnostic diagnostic, String indent) {
System.out.print(indent);
System.out.println(diagnostic.getMessage());
System.out.print(indent);
System.out.print("--");
int code = diagnostic.getCode();
EObject eo = (EObject) diagnostic.getData().get(0);
System.out.printf("code:%2d sender:%s ", code, eo.getClass());
switch (code) {
case 0:
//do nothing
break;
case 1: //missing required feature
EReferenceImpl eri = (EReferenceImpl) diagnostic.getData().get(1);
EClassifier ec = eri.getEType();
//EPackage ep = ec.getEPackage();
Class<?> chc = ec.getInstanceClass();
//EClass chec = ec.eClass();
System.out.printf("child class: %s ", chc);
if (chc.equals(Timeline.class)) {
EObject cho = WorldFactory.eINSTANCE.createTimeline();
eo.eSet(eri, cho);
System.out.print("done.");
break;
}
if (chc.equals(Actor.class)) {
if (eo instanceof Scene) {
Scene sc = (Scene) eo;
Actor a = sc.getActors().get(0);
sc.getActor().add(a);
System.out.print("done.");
break;
}
}
System.out.print("unknown.");
break;
default:
System.out.print("unhandled code");
}
System.out.println();
for (Diagnostic child : diagnostic.getChildren()) {
printDiagnostic(child, indent + " ");
}
}
protected static void walkModel(EObject eo, String indent) {
System.out.print(indent);
System.out.println(eo.eClass().getInstanceClassName());
for (EObject child : eo.eContents()) {
walkModel(child, indent + " ");
}
}
}
==================== PROBLEM ===================
Problem is this snippet changes the model.
What is saved in "_tst0_" differs (slightly) from what is in the original file.
In particular:
==================== EXAMPLE ===================
<?xml version="1.0" encoding="UTF-8"?>
<it.condarelli.writer.model.world:World xmlns:it.condarelli.writer.model.world="http:///it/condarelli/writer/model/world.ecore" author="Mauro Condarelli">
<timeline/>
<book title="La Missione">
<chapter title="Il Matrimonio" desc="bla bla.">
<scene title="Prologo" desc="bla bla." status="FirstEdit" actor="#//@actor.0 #//@actor.1">
...
</scene>
</chapter>
...
<chapter title="Gli Stati Guerrieri" desc="bla bla.">
<actor name="Reginald"/>
<scene title="Gli stati in guerra" desc="bla bla.." status="Draft" actor="#//@actor.0">
</scene>
</chapter>
...
</book>
<actor name="Jona" bio="" fullName="Jona il Mago" aka="Mago" major="true"/>
...
<actor name="Michele" bio="" desc="bla bla." fullName="Michele, apprendista fabbro di Mila" major="true"/>
</it.condarelli.writer.model.world:World>
.... becomes:
<?xml version="1.0" encoding="UTF-8"?>
<it.condarelli.writer.model.world:World xmlns:it.condarelli.writer.model.world="http:///it/condarelli/writer/model/world.ecore" author="Mauro Condarelli">
<timeline/>
<book title="La Missione">
<chapter title="Il Matrimonio" desc="bla bla.">
<scene title="Prologo" desc="bla bla." status="FirstEdit" actor="#//@actor.0 #//@actor.1">
...
</scene>
</chapter>
...
<chapter title="Gli Stati Guerrieri" desc="bla bla.">
<scene title="bla bla." status="Draft" actor="#//@actor.0">
...
</scene>
</chapter>
</book>
<actor name="Jona" bio="" fullName="Jona il Mago" aka="Mago" major="true"/>
...
<actor name="Michele" bio="" desc="bla bla." fullName="Michele, apprendista fabbro di Mila" major="true"/>
<actor name="Reginald"/>
</it.condarelli.writer.model.world:World>
Notice <actor name="Reginald"/> was moved from inside a Chapter to the World.
This happens with all actors every time I load a model (all other actors were created more locally!).
The model, as seen by my code is consistent with what's written to disk after loading ("_tst0_").
This is hardly surprising.
The mishap seems to happen during the check() pass even if "diagnostic.getSeverity() == Diagnostic.OK" all the times (1) and thus none of my code in printDiagnostic() is actually used.
==================== MODEL ===================
The model is as follows:
public interface World extends IBase {
...
/**
* @model opposite="world" containment="true"
*/
public EList<Book> getBook();
/**
* @model containment="true"
*/
public EList<Actor> getActor();
/**
* @model containment="true"
*/
public EList<Location> getLocation();
} // World
public interface Book extends IBase {
/**
* @model opposite="book"
*/
World getWorld();
...
/**
* @model containment="true" many="true"
*/
EList<Actor> getActor();
/**
* @model containment="true" many="true" opposite="book"
*/
EList<Chapter> getChapter();
/**
* @model containment="true" many="true"
*/
EList<Location> getLocation();
...
}
public interface Chapter extends IBase {
/**
* @model opposite="chapter"
*/
Book getBook();
/**
* @model containment="true"
*/
EList<Actor> getActor();
/**
* @model opposite="chapter" containment="true"
*/
EList<Scene> getScene();
...
}
So a defined Actor can be contained in several places... but gets moved to the outermost available container (World).
What can I check?
Regards
Mauro
|
|
|
Re: Model changed while loading [message #544414 is a reply to message #544404] |
Fri, 02 July 2010 11:32   |
Eclipse User |
|
|
|
Mauro,
Comments below.
Mauro Condarelli wrote:
> Hi,
> I have the following code (see the end for the problem):
>
>
> ==================== CODE ===================
>
> public void init(IEditorSite site, IEditorInput editorInput)
> throws PartInitException {
> super.init(site, editorInput);
> URI uri;
> if (model == null) {
> if (editorInput instanceof LocalEditorInput) {
> LocalEditorInput lei = (LocalEditorInput) editorInput;
> uri = (URI) lei.getAdapter(URI.class);
> } else {
> uri = URI.createURI(editorInput.getName());
> }
> model = new Model(uri);
> model.getResource().setTrackingModification(true);
> doSaveAs("_tst0_"); // THIS IS HERE JUST FOR TESTING PURPOSES
>
This will change the URI of the resource and change the editor to be
editing this.
> }
> }
>
> where (I leave the whole class minus comments because I don't know what may be relevant):
>
> public class Model {
> protected ResourceSet resourceSet;
> protected Resource resource;
>
> protected Model() {
> resourceSet = new ResourceSetImpl();
> resourceSet.getResourceFactoryRegistry().getExtensionToFacto ryMap().put(World.DEFAULT_EXTENSION, new WorldResourceFactoryImpl());
> resourceSet.getPackageRegistry().put(WorldPackage.eNS_URI, WorldPackage.eINSTANCE);
> resourceSet.getLoadOptions().put(XMLResource.OPTION_RECORD_U NKNOWN_FEATURE, Boolean.TRUE);
>
> }
>
> public Model(URI uri) {
> this();
> load(uri);
> }
> public Model(String fname) {
> this();
> if (fname == null) {
> Resource resource = resourceSet.createResource(URI.createURI("http:///new" + World.DEFAULT_EXTENSION));
> World root = WorldFactory.eINSTANCE.createWorld();
> resource.getContents().add(root);
> } else {
> File file = new File(fname);
> URI uri = file.isFile() ? URI.createFileURI(file.getAbsolutePath()) : URI.createURI(fname);
> load(uri);
> }
> }
> protected void load(URI uri) {
> try {
> resource = resourceSet.getResource(uri, true);
> } catch (RuntimeException exception) {
> System.err.println("Problem loading " + uri);
> exception.printStackTrace();
> }
> check();
> }
>
> public Resource getResource() {
> return resource;
> }
>
> public void save() throws IOException {
> if (resource.isModified()) {
> Map<String, String> opt = new HashMap<String, String>();
> opt.put(XMLResource.OPTION_ENCODING, "UTF-8");
> resource.save(opt);
> }
> }
> public void saveAs(String fname) throws IOException {
> File file = new File(fname);
> URI uri = URI.createFileURI(file.getAbsolutePath());
> resource.setURI(uri);
> resource.setModified(true);
> save();
> }
> public void save(OutputStream os) {
> try {
> resource.save(os, Collections.EMPTY_MAP);
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
>
> protected void check() {
> if (resource instanceof XMLResource) {
> XMLResource xr = (XMLResource) resource;
> xr.getEObjectToExtensionMap().clear();
> }
> for (EObject eObject : resource.getContents()) {
> Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
> if (diagnostic.getSeverity() != Diagnostic.OK) {
> printDiagnostic(diagnostic, "");
> }
> //walkModel(eObject, " ");
> }
>
> }
> protected static void printDiagnostic(Diagnostic diagnostic, String indent) {
> System.out.print(indent);
> System.out.println(diagnostic.getMessage());
> System.out.print(indent);
> System.out.print("--");
> int code = diagnostic.getCode();
> EObject eo = (EObject) diagnostic.getData().get(0);
> System.out.printf("code:%2d sender:%s ", code, eo.getClass());
> switch (code) {
> case 0:
> //do nothing
> break;
> case 1: //missing required feature
> EReferenceImpl eri = (EReferenceImpl) diagnostic.getData().get(1);
> EClassifier ec = eri.getEType();
> //EPackage ep = ec.getEPackage();
> Class<?> chc = ec.getInstanceClass();
> //EClass chec = ec.eClass();
> System.out.printf("child class: %s ", chc);
> if (chc.equals(Timeline.class)) {
> EObject cho = WorldFactory.eINSTANCE.createTimeline();
> eo.eSet(eri, cho);
> System.out.print("done.");
> break;
> }
> if (chc.equals(Actor.class)) {
> if (eo instanceof Scene) {
> Scene sc = (Scene) eo;
> Actor a = sc.getActors().get(0);
> sc.getActor().add(a);
> System.out.print("done.");
> break;
> }
> }
> System.out.print("unknown.");
> break;
> default:
> System.out.print("unhandled code");
> }
> System.out.println();
> for (Diagnostic child : diagnostic.getChildren()) {
> printDiagnostic(child, indent + " ");
> }
> }
> protected static void walkModel(EObject eo, String indent) {
> System.out.print(indent);
> System.out.println(eo.eClass().getInstanceClassName());
> for (EObject child : eo.eContents()) {
> walkModel(child, indent + " ");
> }
> }
> }
>
> ==================== PROBLEM ===================
>
> Problem is this snippet changes the model.
> What is saved in "_tst0_" differs (slightly) from what is in the original file.
>
Are they using the same resource factory to create the resource used for
saving?
> In particular:
>
> ==================== EXAMPLE ===================
>
> <?xml version="1.0" encoding="UTF-8"?>
> <it.condarelli.writer.model.world:World xmlns:it.condarelli.writer.model.world="http:///it/condarelli/writer/model/world.ecore" author="Mauro Condarelli">
> <timeline/>
> <book title="La Missione">
> <chapter title="Il Matrimonio" desc="bla bla.">
> <scene title="Prologo" desc="bla bla." status="FirstEdit" actor="#//@actor.0 #//@actor.1">
> ...
> </scene>
> </chapter>
> ...
> <chapter title="Gli Stati Guerrieri" desc="bla bla.">
> <actor name="Reginald"/>
> <scene title="Gli stati in guerra" desc="bla bla.." status="Draft" actor="#//@actor.0">
> </scene>
> </chapter>
> ...
> </book>
> <actor name="Jona" bio="" fullName="Jona il Mago" aka="Mago" major="true"/>
> ...
> <actor name="Michele" bio="" desc="bla bla." fullName="Michele, apprendista fabbro di Mila" major="true"/>
> </it.condarelli.writer.model.world:World>
>
> ... becomes:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <it.condarelli.writer.model.world:World xmlns:it.condarelli.writer.model.world="http:///it/condarelli/writer/model/world.ecore" author="Mauro Condarelli">
> <timeline/>
> <book title="La Missione">
> <chapter title="Il Matrimonio" desc="bla bla.">
> <scene title="Prologo" desc="bla bla." status="FirstEdit" actor="#//@actor.0 #//@actor.1">
> ...
> </scene>
> </chapter>
> ...
> <chapter title="Gli Stati Guerrieri" desc="bla bla.">
> <scene title="bla bla." status="Draft" actor="#//@actor.0">
> ...
> </scene>
> </chapter>
> </book>
> <actor name="Jona" bio="" fullName="Jona il Mago" aka="Mago" major="true"/>
> ...
> <actor name="Michele" bio="" desc="bla bla." fullName="Michele, apprendista fabbro di Mila" major="true"/>
> <actor name="Reginald"/>
> </it.condarelli.writer.model.world:World>
>
> Notice <actor name="Reginald"/> was moved from inside a Chapter to the World.
> This happens with all actors every time I load a model (all other actors were created more locally!).
> The model, as seen by my code is consistent with what's written to disk after loading ("_tst0_").
> This is hardly surprising.
> The mishap seems to happen during the check() pass even if "diagnostic.getSeverity() == Diagnostic.OK" all the times (1) and thus none of my code in printDiagnostic() is actually used.
>
>
>
> ==================== MODEL ===================
>
> The model is as follows:
>
> public interface World extends IBase {
> ...
> /**
> * @model opposite="world" containment="true"
> */
> public EList<Book> getBook();
> /**
> * @model containment="true"
> */
> public EList<Actor> getActor();
> /**
> * @model containment="true"
> */
> public EList<Location> getLocation();
> } // World
>
> public interface Book extends IBase {
> /**
> * @model opposite="book"
> */
> World getWorld();
> ...
> /**
> * @model containment="true" many="true"
> */
> EList<Actor> getActor();
> /**
> * @model containment="true" many="true" opposite="book"
> */
> EList<Chapter> getChapter();
> /**
> * @model containment="true" many="true"
> */
> EList<Location> getLocation();
> ...
> }
>
> public interface Chapter extends IBase {
> /**
> * @model opposite="chapter"
> */
> Book getBook();
> /**
> * @model containment="true"
> */
> EList<Actor> getActor();
> /**
> * @model opposite="chapter" containment="true"
> */
> EList<Scene> getScene();
> ...
> }
>
> So a defined Actor can be contained in several places... but gets moved to the outermost available container (World).
>
> What can I check?
>
I'm not sure what would be moving the thing. Maybe you can set a
breakpoint in eBasicSetContainer, or create a copy in it in your
ActorImpl so you can set a more specific breakpoint and then monitor who
this value is changing.
> Regards
> Mauro
>
|
|
|
Re: Model changed while loading [message #544461 is a reply to message #544414] |
Fri, 02 July 2010 14:07  |
Eclipse User |
|
|
|
On 02/07/2010 17.32, Ed Merks wrote:
> Mauro,
>> doSaveAs("_tst0_"); // THIS IS HERE JUST FOR TESTING PURPOSES
> This will change the URI of the resource and change the editor to be
> editing this.
Yes I know.
I am using this just for testing.
I am using the debugger and never really save (or exit normally).
>> What can I check?
> I'm not sure what would be moving the thing. Maybe you can set a
> breakpoint in eBasicSetContainer, or create a copy in it in your
> ActorImpl so you can set a more specific breakpoint and then monitor who
> this value is changing.
I added the following to my ActorImpl.java
@Override
protected void eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID) {
super.eBasicSetContainer(newContainer, newContainerFeatureID);
}
A breakpoint there was enough to pinpoint my error.
MANY THANKS!
Mauro
|
|
|
Goto Forum:
Current Time: Mon Sep 15 13:47:05 EDT 2025
Powered by FUDForum. Page generated in 0.16621 seconds
|