Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » GMF (Graphical Modeling Framework) » Cannot undo manual invocation of ViewUtil.destroy()
Cannot undo manual invocation of ViewUtil.destroy() [message #190830] Tue, 03 June 2008 20:52 Go to next message
Andrew J. Montalenti is currently offline Andrew J. MontalentiFriend
Messages: 23
Registered: July 2009
Junior Member
I am writing a custom GMF editor that is based upon the generated editor
from the GMF SDK. One of the issues I'm running into is what I've come to
label as 'orphaned node cleanup.'

In a non-synchronized diagram, when a model object is deleted from the
model but remains referenced from the diagram, the Node that acts as a
View on that model becomes null. (that is, view.getElement() == null) I
call this an 'orphaned Node' since its corresponding Model element is now
gone, so the Node is, essentially, meaningless. This has an affect on the
visual display of the EditPart -- for example, null connections are shown
with an 'x' over them.

(This has other problems for me outside of the aesthetic -- namely, that
some code that refreshes the connections assumes that there are no null
Nodes on the canvas, and throws a NullPointerException when orphaned Nodes
are encountered.)

So, I thought I'd be able to remedy this problem by executing code like
the following when relevant deletions are detected:

for (View view : diagram.getPersistedChildren()) {
if (view.getElement() != null) {
return;
}
// is an orphaned Node
int visualID = XXXVisualIDRegistry.getVisualID(view);
if (isTopLevelNode(view)) {
TransactionalEditingDomain editingDomain =
getEditingDomain();
// execute as GEF command
new ICommandProxy(new DeleteCommand(editingDomain,
view)).execute();
}
}

Under the hood, the GMF DeleteCommand just uses ViewUtil.destroy to kill
the orphaned Node.

This works as expected. When the code runs, the views are cleaned up.

However, the problem arises when I try to *undo* these actions. When I
undo up to the point of this command, I get the following stack trace:

!STACK 0
org.eclipse.emf.common.util.BasicEList$BasicIndexOutOfBounds Exception:
index=2, size=0
at org.eclipse.emf.common.util.BasicEList.get(BasicEList.java:5 35)
at
org.eclipse.emf.ecore.change.impl.ListChangeImpl.applyAndRev erse(ListChangeImpl.java:535)
at
org.eclipse.emf.ecore.change.impl.ChangeDescriptionImpl.preA pply(ChangeDescriptionImpl.java:474)
at
org.eclipse.emf.ecore.change.impl.ChangeDescriptionImpl.appl yAndReverse(ChangeDescriptionImpl.java:321)
at
org.eclipse.emf.transaction.util.CompositeChangeDescription. applyAndReverse(CompositeChangeDescription.java:105)
at
org.eclipse.emf.workspace.AbstractEMFOperation.doUndo(Abstra ctEMFOperation.java:525)
at
org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTr ansactionalCommand.doUndo(AbstractTransactionalCommand.java: 259)
at
org.eclipse.emf.workspace.AbstractEMFOperation.undo(Abstract EMFOperation.java:306)
at
org.eclipse.emf.workspace.CompositeEMFOperation.doUndo(Compo siteEMFOperation.java:364)
at
org.eclipse.emf.workspace.AbstractEMFOperation.undo(Abstract EMFOperation.java:306)
at
org.eclipse.gmf.runtime.common.core.command.CompositeCommand .doUndoWithResult(CompositeCommand.java:625)
at
org.eclipse.gmf.runtime.common.core.command.AbstractCommand. undo(AbstractCommand.java:215)
at
org.eclipse.gmf.runtime.common.core.command.CompositeCommand .doUndoWithResult(CompositeCommand.java:625)
at
org.eclipse.gmf.runtime.common.core.command.AbstractCommand. undo(AbstractCommand.java:215)
at
org.eclipse.core.commands.operations.DefaultOperationHistory .doUndo(DefaultOperationHistory.java:415)
at
org.eclipse.core.commands.operations.DefaultOperationHistory .undo(DefaultOperationHistory.java:1268)
at
org.eclipse.ui.operations.UndoActionHandler.runCommand(UndoA ctionHandler.java:78)
at
org.eclipse.ui.operations.OperationHistoryActionHandler$4.ru n(OperationHistoryActionHandler.java:314)
at
org.eclipse.jface.operation.ModalContext.runInCurrentThread( ModalContext.java:369)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.ja va:313)
at
org.eclipse.jface.dialogs.ProgressMonitorDialog.run(Progress MonitorDialog.java:495)
at
org.eclipse.ui.internal.operations.TimeTriggeredProgressMoni torDialog.access$6(TimeTriggeredProgressMonitorDialog.java:1 )
at
org.eclipse.ui.internal.operations.TimeTriggeredProgressMoni torDialog$2.run(TimeTriggeredProgressMonitorDialog.java:203)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:67)
at
org.eclipse.ui.internal.operations.TimeTriggeredProgressMoni torDialog.run(TimeTriggeredProgressMonitorDialog.java:216)
at
org.eclipse.ui.operations.OperationHistoryActionHandler.run( OperationHistoryActionHandler.java:329)
at
org.eclipse.gmf.runtime.common.ui.action.actions.global.Glob alUndoAction.doRun(GlobalUndoAction.java:245)

Does anyone know what's going on here?

Thanks,
Andrew
Re: Cannot undo manual invocation of ViewUtil.destroy() [message #190844 is a reply to message #190830] Tue, 03 June 2008 20:53 Go to previous messageGo to next message
Andrew J. Montalenti is currently offline Andrew J. MontalentiFriend
Messages: 23
Registered: July 2009
Junior Member
Apologies for poor formatting on the code sample -- tab expansion:

for (View view : diagram.getPersistedChildren()) {
if (view.getElement() != null) {
return;
}
// is an orphaned Node
int visualID = XXXVisualIDRegistry.getVisualID(view);
if (isTopLevelNode(view)) {
TransactionalEditingDomain editingDomain = getEditingDomain();
// execute as GEF command
new ICommandProxy(new DeleteCommand(editingDomain, view)).execute();
}
}
Re: Cannot undo manual invocation of ViewUtil.destroy() [message #190950 is a reply to message #190830] Wed, 04 June 2008 12:36 Go to previous messageGo to next message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Andrew,

I think you can make this command undo-transparent (exclude it from the undo
stack) - just like CanonicalEditPolicy does with all it's commands - see
CanonicalEditPolicy.executeCommand().

-----------------
Alex Shatalin
Re: Cannot undo manual invocation of ViewUtil.destroy() [message #191124 is a reply to message #190950] Wed, 04 June 2008 22:17 Go to previous messageGo to next message
Andrew J. Montalenti is currently offline Andrew J. MontalentiFriend
Messages: 23
Registered: July 2009
Junior Member
Hi Alex,

Thanks for the tip. Unfortunately, it didn't work around the issue.

Like you suggested, I wrapped my action in an AbstractEMFOperation that
had the TransactionalOption set to suppress undo. That is:

Map<String, Boolean> options = new HashMap<String, Boolean>();
options.put(Transaction.OPTION_UNPROTECTED, Boolean.TRUE);

TransactionalEditingDomain editingDomain = getEditingDomain();

AbstractEMFOperation op =
new AbstractEMFOperation(editingDomain, "Un-undo'able view delete",
options) {
@Override
protected IStatus doExecute(IProgressMonitor monitor,
IAdaptable info) throws ExecutionException {
ViewUtil.destroy(view);
return Status.OK_STATUS;
}
};

try {
op.execute(null, null);
}
catch (ExecutionException e) {
logf(CRITICAL, "Could not execute destroy view command");
}

Nonetheless, I still get the same stack trace as before.

Upon further debugging, I realized that the stack trace is occuring in
AbstractEMFOperation#doUndo, but that the concrete AbstractEMFOperation
that is failing is of type CreateCommand.

Could it be that my error is actually related to trying to undo the
*creation* of a view when that view has been manually deleted from the
semantic model? I tested and confirmed that this is the case. The
problem is that the CreateCommand expects the View to be present in the
diagram in order for its doUndo method to work properly. Since my code is
deleting that view, the CreateCommand.doUndo is failing.

Would I be right in stating that the only way for me to work around this
issue would be to provide an alternative CreateCommand that has a more
cautious doUndo implementation? One that, for example, checks to ensure
that a corresponding View exists on the canvas before attempting to
destroy as part of the Undo Create process?

Thanks,
Andrew
Re: Cannot undo manual invocation of ViewUtil.destroy() [message #191239 is a reply to message #191124] Thu, 05 June 2008 16:50 Go to previous message
Alexander Shatalin is currently offline Alexander ShatalinFriend
Messages: 2928
Registered: July 2009
Senior Member
Hello Andrew,

I suppose this CreateCommand is a command used to create instance of this
View before "manual delete" command execution.
Can you check this in the debugger? If you create node, move it, execute
manual delete and undo then the failing command should be "set location"
(move node) one.

If yes then It make sence to investigate the question why delete element
command was not on top of the command stack..

-----------------
Alex Shatalin
Previous Topic:How to enlarge teh compartment and the inside node at the same time?
Next Topic:[Announce] GMF 2.1.0RC3 is available
Goto Forum:
  


Current Time: Thu Apr 25 07:05:12 GMT 2024

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

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

Back to the top