Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » TransactionalEditingDomain, separate model files, and the diagram
TransactionalEditingDomain, separate model files, and the diagram [message #869705] Thu, 03 May 2012 18:56 Go to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,

I am trying to understand a few concepts concerning the TransactionalEditingDomain and the model and diagram files. I hope that someone can give a brief explanation.

Right now I create a diagram and create a separate Resource for both the model file and the diagram. It goes something like this:
// This is in "CreateDiagram"
ResourceSet resourceSet = new ResourceSetImpl();
		TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(resourceSet);
...
AddDiagram operation = new AddDiagram(project, editingDomain, diagramName);



and then in AddDiagram

// created uri for diagram file above.... now create Resource
createdResource = editingDomain.getResourceSet().createResource(uri);
		createdResource.getContents().add(diagram);

// created uri for model file above ... now create Resource
createdModelResource = editingDomain.getResourceSet().createResource(uriModel);
// add previously created model element to resource
createdModelResource.getContents().add(sc);

// add same element to business objects related to diagram
PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink();
diagram.setLink(link);
link.getBusinessObjects().add(sc);

createdResource.setTrackingModification(true);
createdModelResource.setTrackingModification(true);
try{
	createdResource.save(Collections.EMPTY_MAP);
	createdModelResource.save(Collections.EMPTY_MAP);
}catch(IOException e) {  ...    }


Later on back in the original class (CreateDiagram)
// execute the AddDiagram operation
editingDomain.getCommandStack().execute(operation);
try {
	operation.getCreatedResource().save(null);
} catch (IOException e) {
   // catchy
}

// Dispose the editing domain to eliminate memory leak
editingDomain.dispose();

// Open the editor
String platformString = operation.getCreatedResource().getURI().toPlatformString(true);

IFile file = project.getParent().getFile(new Path(platformString));
IFileEditorInput input = new FileEditorInput(file);
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(input, DiagramEditor.DIAGRAM_EDITOR_ID);
		} catch (PartInitException e) {
			...
		}



When I want to add a new feature related to a model element I use something like:
getDiagram().eResource().getContents().add(newClass);

What I am trying to understand is what is maintaining the connection between the diagram, the editing domain, and the model?

It seems odd to me that the editingDomain is disposed. The only connection I can ascertain from all of this is the link between the business object (sc) above and the diagram. sc itself has no graphical component.

Is the editingDomain, or more to the point the ResourceSet, attached to the diagram more persistent than I am aware, or than it appears?

The getDiagram().eResource()... sort of implies that there is a single resource.
But upon doing this, the resource that the newClass is added to is the model file, not the diagram. Or so I am guessing that this is what occurs.

Does anyone have an intuitive sense of what is going on here? Or perhaps could point me in a good direction to figure this out?

Thanks in advance,
Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #869840 is a reply to message #869705] Fri, 04 May 2012 09:29 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1577
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Ok, I'll try...

What the editor gets is purely an URI that points to a diagram (or a
resource containing a diagram). It then creates a ResourceSet (RS) along
with a TransactionalEditingDomain (TED). There's always a
one-to-one-relation between the RS and the TED.

Then the editor tries to load the diagram by resolving the provided URI.
This adds a resource to the RS. A RS can contain an arbitrary number of
resources. If one tries to load an additional object (e.g. a domain object)
EMF resolves that and may add an additional resource to the RS (in case the
object is part of another resource file, that has not yet been loaded).

On creation of a new object, you need to make that object part of a
resource, either an existing one (meaning one that is already loaded into
the RS) or a new one (meaning one that needs to be loaded from disk or even
needs to be created as a file).

The model itself spans over all resources of the RS (and even beyond in case
there are references to objects residing in other resource files that have
not yet been accessed).

In Graphiti by default the TED is associated to exactly one diagram editor;
this is done to enable separation of work in progress in one editor from the
other (seeing changes done in another editor before they were saved, seems
awkward). Also the command stack (e.g. visible as undo/redo) is based on
that. Therefore the TED (and RS) is created with the editor and removed with
it.

The TED and the RS are not persisted at all the only thing that gets
persisted are the resource files.

I hope that sheds some light onto that.

Michael
Re: TransactionalEditingDomain, separate model files, and the diagram [message #869886 is a reply to message #869840] Fri, 04 May 2012 11:59 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Thanks for the response, as always, Michael.

The reason I am digging into this is that I noticed that when the copy and paste is implemented one can copy in between diagrams as expected. However, in the case where the diagram and model file are distinct files (Resources), when a paste occurs between diagrams the model element is removed from the first (source) model file and added to the second (the target model file). Which is presumably desired, or at least expected, behavior. Except that it puts the original diagram into a really bad state.

Hence I am trying to determine if I can create a second diagram that either maintains the element in both model files (which will probably cause no end of consistency issues) or attach the model file from the original diagram to the new diagram.
I think in both circumstances I will have to have a special version of the "CreateDiagram" functionality. Is there any best practices with respect to this kind of behavior, or is it fundamentally discouraged one way or another?

Thanks again for your response. It clarified the issue for me.
Thanks,
Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #870423 is a reply to message #869886] Tue, 08 May 2012 02:39 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1577
Registered: July 2009
Location: Walldorf, Germany
Senior Member
What you describe as behavior for copy/paste accross resource borders sounds
at least strange. The expectation is that the source object remains
unchanged during that. Basically what the Graphiti base functionality in
copy/paste does, is to get a copy of the original object into the clipboard
and then create a new object in the target (all on the level of domain
objects); after that the visualization is added.

Michael
Re: TransactionalEditingDomain, separate model files, and the diagram [message #870535 is a reply to message #870423] Tue, 08 May 2012 11:02 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi Michael,
It seemed a bit off to me as well. The copy and paste routines are pretty much as in the tutorial. The only difference is the way resources are set-up in the diagram creation. Much of that code was posted earlier. I will confirm that the copy/paste are operating and defined as in the tutorial.

In my current case there is no connection between the two diagrams or their resources (this is what I would like to implement eventually). Basically, as I see it, copy/paste is operating like cut/paste. It is not until I paste though that the change in the source resource file is seen.

Thanks for the response.
Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #873346 is a reply to message #870535] Thu, 17 May 2012 22:52 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,
I finally had the chance to get back to this and was wondering if anyone could throw some guidance my way.

I have implemented a custom feature which when run creates a new diagram. This
new diagram was implemented to use the same model file as the original. As I conjectured in my last note, it did cause all sorts of problems.

I have a set up similar to the tutorial in that I call a create diagram method that sets up the TransactionalEditingDomain and an operation to add the new diagram.

This part seems to work OK. The new diagram gets created and I can add elements to the new diagram that show up in the original diagrams model file... temporarily...
This is where the issues begin.

When I add elements to the new diagram I begin to get errors. The first is if I return to the original diagram (bring that diagram back to being active) I get a "File Conflict" error stating "There are unsaved changes that conflict with changes made outside the editor. Do you wish to discard this editor's changes?"

One thing I noted was that as soon as I opened the new diagram the state of the original went to unsaved (dirty?). Anytime I save one diagram, the other goes into the unsaved state.

Anyhow, the issues sort of cascade from there. If I close the diagram and re-open it the elements are in a dirty state and no longer exist in the model file.

Here is how I set up the diagram and the model file.

		protected void doExecute() {
			//Create the diagram and its file
			Diagram diagram = Graphiti.getPeCreateService().createDiagram("egsndiagram", diagramName, true);
			IFolder diagramFolder = project.getFolder("src/diagrams/");
			IFile diagramFile = diagramFolder.getFile(diagramName + ".diagram");
			URI uri = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);
			
			IFile diagramFileModel = diagramFolder.getFile(modelName);
			URI uriModel = URI.createPlatformResourceURI(diagramFileModel.getFullPath().toString(), true);
			
			createdResource = editingDomain.getResourceSet().createResource(uri);
			createdResource.getContents().add(diagram);
			
			
			//final SafetyCase sc = XxegsnFactory.eINSTANCE.createSafetyCase();
			PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink();
			
			diagram.setLink(link);
			createdModelResource = editingDomain.getResourceSet().getResource(uriModel, true);
			EList<EObject> elist = createdModelResource.getContents();
			SafetyCase sc = null;
			for (EObject eo: elist){
				if(eo instanceof SafetyCase){
					sc = (SafetyCase) eo;
				}
			}
			link.getBusinessObjects().add(sc);
			
			IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram,
					"diagram.EgsndiagramTypeProvider"); 
			
			IFeatureProvider featureProvider = dtp.getFeatureProvider();
			createdResource.setTrackingModification(true);
			createdModelResource.setTrackingModification(true);
			try{
				createdResource.save(Collections.EMPTY_MAP);
				createdModelResource.save(Collections.EMPTY_MAP);
			}catch(IOException e) {}
		}


Is there any way to get the two diagrams to play nicely with the same model resource? Or does anyone have a better way of doing this? My only requirement is that the model file has to be treated as a whole for later analysis.


Thanks,
Joe

Re: TransactionalEditingDomain, separate model files, and the diagram [message #884770 is a reply to message #873346] Mon, 11 June 2012 15:42 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,

So I am still struggling with coming up with a good structure for linking two diagrams. I have constructed a model that works OK up until modifications are made on a diagram that affects the relative position of the elements in the model resource. Then everything seems to go out of state.

Again, what I am trying to do is have multiple diagrams that are related to the same
model instance.
So I might have the following structure
D1 -- Diagram 1 (the original)
D2 -- Diagram 2 (spawned from the first and related by an element on the first which is also graphically represented on the second)
(D3 ... Dn -- however many other diagrams that follow the same scenario as D2)
M -- A model resource which contains all the elements and relations for Diagram 1 and Diagram 2

So the scenario I am currently implementing is that
Diagram 1 has a resource set that contains a Diagram resource (Rd1) and a model resource (Mr) loaded into its TransactionalEditingDomain (TED).

Diagram 2 has a resource set that contains a Diagram resource (Rd2) and a model resource generated from the same persisted file as Mr.

Everything seems to work fine if I only add elements to Rd2 and hence Mr.

However if I start to edit, in particular remove, elements from Rd1 then Rd2 goes out of state. This is due to the relative nature of the element relationships between the diagram resource and the model resource (i.e. making such references to nodes in a relative way from the diagram resource. In the persisted version this shows up as //@node.2 for instance). If I were to, for instance delete a node from Rd1 which appeared above elements connected to Rd2, then the ordering in Rd2 is off and the Rd2 element refers to the wrong element in the model resource (Mr).

Now, I suspect there is a way to get the diagram (D2 for instance) to listen to these changes. I am not certain how to set up the listener just yet. Does anyone have any thoughts on this?

However there is also the question on how to reflect these changes to the diagram D2 when these changes are made in D1 if D2 is not open?


So does anyone have a better scenario than this for making connections between diagrams? And for keeping the model instances (and references between the model and diagram) fresh?


Thanks!

Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #885158 is a reply to message #884770] Tue, 12 June 2012 10:42 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1577
Registered: July 2009
Location: Walldorf, Germany
Senior Member
There might be an EMF way to help here: did you have a look at using IDs to
identify your model objects on EMF model level? That would EMF cause to use
"named references" (to the the ID attribute of your object) instead of
references based on indices that seems to cuase the trouble here.

Michael
Re: TransactionalEditingDomain, separate model files, and the diagram [message #886889 is a reply to message #885158] Fri, 15 June 2012 15:39 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi Michael,

I asked a question (in a different forum) about creating the named references a long time ago but no one had an answer for me. I did figure it out though and it did take care of some of my issues.

So from what I have read in this forum (in the backlog) what I am trying to do should, theoretically, work. I am still confronted by a few issues though.

Again, I am trying to have two diagram editors access and modify the same resource.
Now one thing that I am doing is when I generate the second diagram I am creating a separate resource for that diagram and link the top level element (SafetyCase element) to the diagram. I use an existing display element to connect the two diagrams. The element is a GA/Container linked to a business object. I call the element the pivot point.
			PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink();
			
			diagram.setLink(link);
			createdModelResource = editingDomain.getResourceSet().getResource(uriModel, true);
			EList<EObject> elist = createdModelResource.getContents();
			SafetyCase sc = null;
			for (EObject eo: elist){
				if(eo instanceof SafetyCase){
					sc = (SafetyCase) eo;
				}
			}
			link.getBusinessObjects().add(sc);


I am not certain if I am doing this incorrectly.

Here is some the errant behavior that I am seeing:
Whenever I launch a new diagram:
a) The state of the original diagram is dirty (unsaved)
b) When I return to the original diagram I get the following "File Conflict" message: "There are unsaved changes that conflict with changes made outside the editor. Do you wish to discard this editors changes?"

Clicking yes or no will modify the "state" depending on what was just done.
For instance if I click yes right after creating the new diagram, saving it and returning to the original diagram, it will remove the graphical changes that I have made (basically an extra GA that shows it is a "connected node") but still allow the element on the new and old diagram to be connected to the same BO. If I say No it
leaves the new GA but the BO is removed from the Resource and hence neither element is connected either to each other or any element at all.


I am not certain if I need to be modifying or adding any hooks to other listeners (or where even to add those hooks or changes in general)? Is there anything else that you can think of that I can fiddle around with that would keep the three resources (both of the diagram resources and the model resources (which is really two separate resources itself) ) playing nicely with each other?

Thanks,
Joe

PS. Michael, we submitted and had accepted a workshop paper using this graphiti based tool. We would like to acknowledge your help in the final version if that is acceptable to you. You can send me a private message if you want.
Re: TransactionalEditingDomain, separate model files, and the diagram [message #888922 is a reply to message #886889] Mon, 18 June 2012 15:53 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,
Thought about this a bit over the weekend and have a few other questions or thoughts.

I am concerned with the fact that I am basically using a separate instance of the resource. In other words since I am opening and loading the resource twice (or more, once in each separate diagram that is associated with the original) this is where my conflict is arising. Is there a way to essentially pass the model resource back and forth each time a diagram becomes active? ie When a diagram becomes the active editor disconnect the resource from one diagram and connect it to the new one?

Would it even be necessary to disconnect it from the original?

Thanks,
Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #892382 is a reply to message #888922] Wed, 27 June 2012 19:32 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,
Sorry to keep on harping on this but I have still not figured out a way to get the
two editors to play nicely together with the same resource.
From everything that I am aware of this should be possible.
(reference this discussion from Tim Kaiser here)

In the setup for my new diagram I set tracking to true but yet I still receive warnings each time I make a change and switch back and forth between editors. (namely the "There are unsaved changes that conflict with changes made outside the editor. Do you wish to discard this editor's changes?" warning.) I get these warnings even if there is no element that is referenced between both diagrams.

Is there any way to force a save of the resource (and all related resources) from the editor (diagram) in question after modifying a resource? (Noting that some of these Features and their underlying elements are edited from a generated properties view.)

Or if my situation is not quite clear please let me know as I am more than willing to expand on it.

Thanks,
Joe

Re: TransactionalEditingDomain, separate model files, and the diagram [message #892645 is a reply to message #892382] Thu, 28 June 2012 19:48 Go to previous messageGo to next message
Josef Pohl is currently offline Josef Pohl
Messages: 82
Registered: January 2012
Member
Hi there,
Well in my continuing dialog....
I tried a change today that loaded the same (in memory) resource into the new diagram. This seems to have made a profound difference although I can still derive a model/diagram interaction that creates a dirty diagram. Basically I can add elements to a diagram and unless I assure that the new diagram is saved before leaving it (switching back to the original) I will periodically get the Warning about a file conflict and asking if I want to discard the changes. Seemingly I want to typically answer "No", that I do not want to discard the changes. Even so periodically the changes to the diagram (the added features) will no longer have any business object associated with it.

So my question is this:
Is there a way to automatically save the resource when a diagram becomes inactive?

I realize that this will mess with Graphiti's undo functionality (well, wipe it out at any rate) but that is something I can live with.

Thanks,
Joe
Re: TransactionalEditingDomain, separate model files, and the diagram [message #893023 is a reply to message #892645] Mon, 02 July 2012 06:38 Go to previous message
Michael Wenz is currently offline Michael Wenz
Messages: 1577
Registered: July 2009
Location: Walldorf, Germany
Senior Member
You could register an Eclipse IPartListener for the DiagramEditor and
trigger the save on partDeactivated(). Should work but I haven't tried that.

Michael
Previous Topic:Overriding the DiagramEditor class
Next Topic:Viewing invisible rectangles in old diagrams
Goto Forum:
  


Current Time: Thu Jul 31 23:55:31 EDT 2014

Powered by FUDForum. Page generated in 0.01993 seconds