Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » Opened unchanged editors marked as dirty...(...when opening a new editor)
Opened unchanged editors marked as dirty... [message #1105230] Mon, 09 September 2013 10:46 Go to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 147
Registered: September 2011
Senior Member
Hi all,

I try to build some kind of modeling tool based on Graphiti with CDO as back end storage.

When I create a new element, I also create a new empty diagram and open the corresponding editor which is marked as dirty ('*').

I then successfully save my created element and its associated diagram in a dedicated resource in CDO.

To achieve this, I slightly modified the default update and persistency behaviors.
I use a 'CDO compliant' transactional editing domain and commit the opened CDO transaction when saving.

My problem occurs when I create a second element and its empty diagram.
Then the first opened editor is marked as dirty !?

Moreover, when I save the second editor and close my modeling tool, it doesn't ask for saving the first opened editor. So, even if marked, it seems it's not considered as dirty...

While browsing this forum, I found a reference to the bug 35109 "Unconditional Auto-refresh for Diagrams". It describes 3 situations in which an update can happen and how it is handled by Graphiti diagram type provider.

The third case "EMF object changes from within the same editing domain" corresponds to my situation.
But It's written that no update should happen on a saved editor...

Any idea of what's wrong and how to solve this ?

Kind regards
Re: Opened unchanged editors marked as dirty... [message #1107328 is a reply to message #1105230] Thu, 12 September 2013 04:50 Go to previous messageGo to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 147
Registered: September 2011
Senior Member
Hi again,

All my elements and associated diagrams are stored in a single CDOResource. I thought this could be the problem if all opened editors listen to the same resource modification to be marked as dirty or not.
But, even when storing each "pair" (element + diagram) in a dedicated resource, this problem is still there...

Any clue about some Graphiti internals that could explain this behavior ?

Regards,
Re: Opened unchanged editors marked as dirty... [message #1108228 is a reply to message #1107328] Fri, 13 September 2013 10:33 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1587
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Laurent,

I would expect the reason for this to be in specific behavior of the CDO
resources, but unfortunatly I don't have CDO experience.

You might have a look into the CDO Dawn project. I know they have Graphiti
example editors running on CDO.

Michael
Re: Opened unchanged editors marked as dirty... [message #1112214 is a reply to message #1108228] Thu, 19 September 2013 05:03 Go to previous messageGo to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 147
Registered: September 2011
Senior Member
Hi Michael,

Dawn implements its own "isDirty strategy" and overrides the corresponding method(s).
Before I do that, I would like to better understand what happens...

When opening my first diagram, no problem, it's not dirty.
DiagramBehavior#isDirty calls GFWorkspaceCommandStackImpl(WorkspaceCommandStackImpl)#isSaveNeeded :

	public boolean isSaveNeeded() {
		// We override the execute method and never call the super implementation
		//  so we have to implement the isSaveNeeded method ourselves.
		IUndoableOperation nextUndoableOperation = history.getUndoOperation(getDefaultUndoContext());
		
        if (nextUndoableOperation == null) {
            return savedContext != null;
        }
        
		return savedContext != null ? !nextUndoableOperation.hasContext(getSavedContext()) : true;
	}


nextUndoableOperation and savedContext are null, thus the method returns false which is coherent.

But, when opening a second diagram (regarding another EMF object of same type), nextUndoableOperation = EMFCommandOperation with 'update' label and encapsulating a EmfOnGefCommand !?
And the first opened editor becomes dirty...

In debug mode, I noticed this operation is also added to the operation history when opening the first editor but 'disappears' somehow before isSaveNeeded is called.

Actually this method is called a couple of times when opening each editor.
When opening the first one, I get like 4 calls all returning false.
When opening the second one, I get about 3 times true and a last call returning false !?

I also noticed that, when opening only one diagram displaying two emf objects with a containment relation (like 'service' and its 'operations'), the editor is always dirty. Whereas, for a diagram containing two objects without containment relationship (like two services), the opened editor is 'clean' until I open another one...

To sum up, this EmfOnGefCommand - a Graphiti object - appears to be the reason why an editor becomes dirty. Not knowing Graphiti internals, I'm confused. Any idea of what may happen ?

Regards,

Laurent
Re: Opened unchanged editors marked as dirty... [message #1113006 is a reply to message #1112214] Fri, 20 September 2013 10:03 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1587
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Laurent,

not sure, as I said I'm not an CDO expert...

Could it be that you reuse the same editing domain for both editors?

Michael
Re: Opened unchanged editors marked as dirty... [message #1113064 is a reply to message #1113006] Fri, 20 September 2013 11:31 Go to previous messageGo to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 147
Registered: September 2011
Senior Member
Indeed. I use the same transactionnal editing domain (TED) for both editors and also for my (CDO repository) explorer.
Moreover, this single TED handles a single CDO Resource containing all my business objects and their associated diagrams.

Should I use 3 different TEDs and resources for each the editors and the explorer ? Why is it so ?
Re: Opened unchanged editors marked as dirty... [message #1115793 is a reply to message #1113064] Tue, 24 September 2013 11:30 Go to previous message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 147
Registered: September 2011
Senior Member
Hi again,

Just to say that i created a TED for my explorer and also one per editor instance and it now works just fine.

Many thanks for your help Michael !

Some more details for anyone interested.
Hereafter an extension of DiagramEditor to use a CDO TED :
@SuppressWarnings("restriction")
public class GraphitiEditor extends DiagramEditor {
	private CDODiagramEditorInput input = null;
	
	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		this.input = (CDODiagramEditorInput) input;
		super.init(site, input);
	}

	@Override
	protected DiagramBehavior createDiagramBehavior() {
		return new DiagramBehavior(this) {
			/*
			 * Modify the default update behavior to use CDO compliant transactional editing domain
			 * @see org.eclipse.graphiti.ui.editor.DiagramBehavior#createUpdateBehavior()
			 */
			@Override
			protected DefaultUpdateBehavior createUpdateBehavior() {
				return new DefaultUpdateBehavior(this) {
					@Override
					protected void createEditingDomain() {
						TransactionalEditingDomain editingDomain =
								(new CDOTransactionalEditingDomainImpl.CDOFactoryImpl()).createEditingDomain();
						initializeEditingDomain(editingDomain);
					}
					
					@Override
					protected void disposeEditingDomain() {
						getEditingDomain().dispose();
					}
				};
			}
	
			@Override
			protected DefaultPersistencyBehavior getPersistencyBehavior() {
				return new DefaultPersistencyBehavior(this) {
					/*
					 * Make sure the resource containing the diagram is added to the TED before loading...
					 * @see org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior#loadDiagram(org.eclipse.emf.common.util.URI)
					 */
					@Override
					public Diagram loadDiagram(URI uri) {
						if (uri != null) {
							final TransactionalEditingDomain editingDomain = diagramBehavior.getEditingDomain();
							if (editingDomain != null) {
								// Adding the diagram resource to the TED
								IEclipseContext context = EclipseContextFactory.getServiceContext(Activator.getContext());
								CDOTransaction transaction = (CDOTransaction) context.get("openedCDOTransaction");
								Resource diagRes = transaction.getResource(uri.path());
								editingDomain.getResourceSet().getResources().add(diagRes);
								
								// Find object but using CDO API...
								EObject modelElement = null;
								try {
									modelElement = transaction.getObject(input.getDiagramId(), false);
									if (modelElement == null) {
										modelElement = transaction.getObject(input.getDiagramId(), true);
										if (modelElement == null) {
											return null;
										}
									}
								} catch (WrappedException e) {
									// Log only if debug tracing is active to avoid user
									// confusion (message is shown in the editor anyhow)
									T.racer().debug("Diagram with URI '" + uri.toString() + "' could not be loaded", e); //$NON-NLS-1$ //$NON-NLS-2$
									return null;
								}
								modelElement.eResource().setTrackingModification(true);
								return (Diagram) modelElement;
							}
						}
						return null;
					}
					
					/*
					 * Modify the default persistency behavior to add CDO transaction commit while saving the editor modifications
					 * @see org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior#save(org.eclipse.emf.transaction.TransactionalEditingDomain, java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
					 */
					@Override
					protected Set<Resource> save(TransactionalEditingDomain editingDomain, Map<Resource,Map<?,?>> saveOptions,
                            IProgressMonitor monitor) {
						Set<Resource> resSet = super.save(editingDomain, saveOptions, monitor);
						IEclipseContext context = EclipseContextFactory.getServiceContext(Activator.getContext());
						CDOTransaction transaction = (CDOTransaction) context.get("openedCDOTransaction");
						try {
							transaction.commit();
						} catch (ConcurrentAccessException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (CommitException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						return resSet;
					}
				};
			}
		};
	}
}


The used CDO Diagram Editor Input :
public class CDODiagramEditorInput implements IDiagramEditorInput, IEditorInput {
	
	private String providerId = null;
	private URI diagramURI = null;
	private CDOEditorInput cdoEditorInput = null;
	private CDOID diagramId = null;

	public CDODiagramEditorInput(CDOView view, URI resourceURI, boolean viewOwned, CDOID ID) {
		cdoEditorInput = CDOEditorUtil.createCDOEditorInput(view, resourceURI.path(), viewOwned);
		this.diagramURI = resourceURI;
		this.diagramId = ID;
	}
	
	/*
	 * From the diagram CDO ID, it's possible to get the editor TED in the eclipse context map.
	 */
	public CDOID getDiagramId() {
		return diagramId;
	}

	/*
	 * Compare diagrams in order not to open several Graphiti editors on the same content 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof CDODiagramEditorInput) {
			return ((CDODiagramEditorInput)obj).diagramId.equals(diagramId);
		}
		return false;
	}

	@Override
	public String getUriString() {
		return cdoEditorInput.getResourcePath();
	}

	@Override
	public URI getUri() {
		return this.diagramURI;
	}

	@Override
	public String getProviderId() {
		return this.providerId;
	}

	@Override
	public void setProviderId(String providerId) {
		this.providerId = providerId;
	}

	@Override
	public void updateUri(URI newURI) {
		this.diagramURI = newURI;
	}

	@Override
	public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
		return cdoEditorInput.getAdapter(adapter);
	}

	@Override
	public boolean exists() {
		return cdoEditorInput.exists();
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		return cdoEditorInput.getImageDescriptor();
	}

	@Override
	public String getName() {
		return cdoEditorInput.getName();
	}

	@Override
	public IPersistableElement getPersistable() {
		return cdoEditorInput.getPersistable();
	}

	@Override
	public String getToolTipText() {
		return cdoEditorInput.getToolTipText();
	}
}


And a link to the CDO TED code itself :
http://www.eclipse.org/forums/index.php/m/1121603/#msg_1121603

[Updated on: Mon, 30 September 2013 16:17]

Report message to a moderator

Previous Topic:Diagram background with gradient colors
Next Topic:Retrieving the business object linked to the container shape
Goto Forum:
  


Current Time: Thu Aug 28 07:31:13 EDT 2014

Powered by FUDForum. Page generated in 0.02318 seconds