Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mdt-papyrus.dev] [General] Need to clarify how Commands should be executed

Hello,

I have a few recomendations to make, taking in account my own experience with papyrus editor :

1. About the editing domain to use to construct commands :
The same editing domain must always be used, otherwise, you can result in actions which are stored in different domains and different stacks, which leads to several operation history which manage the same diagram but different operations.

 I think a good recomendation is using
org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart.getEditingDomain()
when you have an edit part at hand, or the static method
org.eclipse.papyrus.core.utils.EditorUtils.getTransactionalEditingDomain()
otherwise.

For example of the wrong case with several editing domains, you can have a look at most actions in the old Model Explorer view :
 - create a node in a diagram form the editor
 - create another one
 - delete from diagram the first one
 - delete from the model explorer view the second one
-> you can undo the model deletion from the model explorer by right click>undo on the root element
 and
 -> you can undo the graphical deletion from the undo action of the diagram
 In such a case, the user gets lost between these two different stacks.


2. About EMF Transaction :
 Always use a transactional command and domain when you can.
 The avantages of the EMF Transaction framework are :
- operations will be validated (emf validation called by gmf framework on editing domain). This validation can check a model (see ocl constraints for a simple example) and reject modifications. - operations in a same transaction, will be rejected (in case validation fails), or undone , or will fail (in case an exception occurs) all at the same time. This avoids having unconsistent models with half-executed actions.


3. About the call for the action's execution :
3.A.
Changes which impact the diagram opr the model should call
org.eclipse.gmf.runtime.diagram.ui.parts.DiagramCommandStack.execute(ICommand, IProgressMonitor) This method encloses the IOperationHistory.execute method, but catches raised exceptions to avoid the diagram exploding in front of the user.

Make a single call per action, by constructing a compound (or composite) command.

The diagram command stack can be obtained from an edit part with
getDiagramEditDomain().getDiagramCommandStack();

One can also use, in case there is no edit part at his disposition :
CommandStack stack = (CommandStack)EditorUtils.getMultiDiagramEditor().getAdapter(CommandStack.class);
    if(stack != null) {
      stack.execute(org.eclipse.gef.commands.Command);
    }
Which is in fact hiding a call to the same method by inheritance. But I find it less satisfying. Mainly because it can be confused with
org.eclipse.emf.edit.domain.EditingDomain.getCommandStack().execute(...)
which MUST NOT be used (often called with the wrong editing domain, see 1.).


3.B.
You may call directly (for advanced users)
org.eclipse.gmf.runtime.diagram.core.util.ViewUtil.setStructuralFeatureValue(View, EStructuralFeature, Object) (for graphical changes)
or use
org.eclipse.emf.common.command.CompoundCommand.execute()
in case your operation must not be undone nor logged in the history

There are very few examples of such a case. In fact, I have met only two cases so far : - When the figure is being updated in an edit part thanks to a listener on the model (generally through the usage of org.eclipse.papyrus.diagram.common.helper.NotificationHelper). In such a case, the graphic change is only a consequence of the model change, and undoing the model change will modify the figure again through the same listener. - In a validator registered with org.eclipse.emf.validation.constraintProviders extension point. You can make a corrector, which will correct the model at each modification instead of simply validate and reject an unvalid modification. Any other way will raise an exception since the operation being validated/corrected is in post-commit state. This corrector approach works only in case you have redundant information in the model (for examples, an call behavior action's pins are heavily synchronized with the behavior's parameters ; when parameters are modified, you can deduce that the same modifications must occur on the corresponding pin).


4. About implementing new commands.
 Try using transactionnal commands, by implementing
org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand. I know they may seem painfull to implement, but it ensures a better model consistency and its the only way to respect point 2.
In most case, extending
 org.eclipse.gmf.runtime.common.core.command.CompositeCommand
to add classic commands (AddCommand, SetPropertyCommand, ...) to make the job works fine and avoid any coding error.



If you have remarks or comments on this message, do not hesitate to react. I am not telling my approach is the absolute truth.

Regards,
Vincent.


Ed Willink a écrit :
Hi Tristan

I'm not sure that anyone knows EMF Transaction very well. I used it because it seemed to solve the diverse Command incompatibilities, and to allow multiple views of Resources to synchronize across editors. It places interesting games with eSet() to make sure that a remarkable amount happens transparently, endeavouring to get the best of both worlds.

I recommend reading the tutorials and only dismissing EMF Transaction after forming a clear view as to how the same functionality should be performed better and if so considering how an EMF Transaction 2 can evolve.

I'm sure that you, like me a couple of years ago, just want to get past this tedious Command problem to do something more interesting. However if you don't address the problem clearly now, you and others will be forever fighting the inadequacy of your partial solution.

    Regards

        Ed Willink

On 27/05/2010 10:13, Tristan FAURE wrote:
Hi all,
I don't really know the EMF Transaction Framework. But one of the advantage of using the editing domain is that the eadapters installed on editing domain are notified after commands execution.
Is it the same for IOperationHistory.execute ?

Regards
Tristan

Le 27/05/2010 10:35, Cedric Dumoulin a écrit :

  Hi Ed,

Thanks for your feedback. I will study all of that, and try to propose a solution for Papyrus asap.

  Cedric

Ed Willink wrote:
Hi Cedric

This is a very painful area, that I sort of got to the bottom of for the QVTd editor framework.

I think you need to go with IOperationHistory to stand any chance of general consistency.

EMF Transaction provides an enhanced Command handling that IIRC uses IOperationHistory.

You might care to check out org.eclipse.m2m2/org.eclipse.qvtd and look for all IOperationHistory usage to see where I though I needed to change things. Of course that was nearly two years ago and might not have been the correct solution then let alone now.

When using IOperationHistory make sure you install the Platform Examples which include a useful OperationHistory viewer. I send in a few Bugzillas to projects that were not giving good Operation descriptions.

That said, the entire EMF model synchronmisation issue deserves revisiting. Xtext is not using any standard approach and we need Xtext maintained models to be properly synchronized.

    Regards

        Ed Willink

On 25/05/2010 13:03, Cedric Dumoulin wrote:

 Hi all,

I have opened a bug (314250) to try to clarify how Commands should be executed in Papyrus.
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=314250)

Actually, commands seem to be executed using different mechanisms:
- org.eclipse.emf.edit.domain.EditingDomain.getCommandStack().execute(...) - org.eclipse.core.commands.operations.IOperationHistory.execute(IUndoableOperation, IProgressMonitor, IAdaptable)

We need to propose a standard mechanism to be used in Papyrus.
Before that, we need to clarify what are the pro and cons of each approach. This should enable the undo/redo operations for all commands (bug 314252).

 If you have any idea/clue/proposal, please comment it !

 Cedric

_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev



No virus found in this incoming message.
Checked by AVG - www.avg.com Version: 9.0.819 / Virus Database: 271.1.1/2894 - Release Date: 05/24/10 19:26:00


------------------------------------------------------------------------

_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev


_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev


_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev


No virus found in this incoming message.
Checked by AVG - www.avg.com Version: 9.0.819 / Virus Database: 271.1.1/2899 - Release Date: 05/27/10 07:25:00



------------------------------------------------------------------------

_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev



Back to the top