Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 336488 - move DiagramEditor base classes to public API
Summary: move DiagramEditor base classes to public API
Status: CLOSED FIXED
Alias: None
Product: Graphiti
Classification: Modeling
Component: Core (show other bugs)
Version: 0.7.0   Edit
Hardware: All All
: P2 normal (vote)
Target Milestone: 0.9.0   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard: Juno M5 Theme_round_offs
Keywords:
Depends on: 364803
Blocks: 363677 365169
  Show dependency tree
 
Reported: 2011-02-07 05:56 EST by Henrik Rentz-Reichert CLA
Modified: 2012-06-29 04:16 EDT (History)
8 users (show)

See Also:
michael.wenz: juno+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henrik Rentz-Reichert CLA 2011-02-07 05:56:58 EST
Since overriding base class methods of the DiagramEditor is a common practice for customizations the org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal should be moved to public API (and much likely be renamed).
An example where this would be desirable is given in bug 333149.
Comment 1 Ali AKAR CLA 2011-03-04 06:19:23 EST
Graphiti users, looking for integrating Graphiti in their own workspace management, might need to override the DiagramEditorBehavior.

You can keep the DiagramEditorBehavior in an internal package and don't open it, but just change the way it's instantiated for the editor. (instantiate it in a protected method which can be overriden)
Comment 2 Torkild Resheim CLA 2011-03-07 05:06:54 EST
I've also found the need to place the DiagramEditor in a view instead of in an editor. This means copy/pasting a lot of stuff and change from EditorPart to ViewPart, which is pretty straightforward. In addition there are a lot of references to InternalDiagramEditor which is causing problems. Where possible these should be replaced with an interface.

I noticed DiagramEditorInternal is based on a GEF type which is clearly marked as a reference implementation only. A few protected methods in that implementation is also causing problems for me. So this should be changed.

I'm working on a patch so we can at least obtain our goals. If there is any interest I'd be happy to contribute it back. If so please let me know of any additional requirements.
Comment 3 Michael Wenz CLA 2011-03-07 11:05:06 EST
This topic is not yet fully discussed, nevertheless here are some more additional requirements:
- save/save as/isDirty handling need to be changeable
- DiagramEditor must be usable as a page of a multi page editor
- hook in initialization and dispose is needed
- No palette at all (extension of today's behavior)
- ...

There is surely more, this is just from the top of my mind.

Any contributions or participation in the discussion are of course highly welcome, but given the early state of the discussions and requirements gathering (this was not intented to be resolved with Graphiti 0.8.0 in Indigo) and the fact that M6 with its API freeze is quite close, I doubt that we will get this in for Indigo.

Nevertheless this is a top-level candidate for post-Indigo.

Michael
Comment 4 Torkild Resheim CLA 2011-03-09 07:42:25 EST
(In reply to comment #3)
> Any contributions or participation in the discussion are of course highly
> welcome, but given the early state of the discussions and requirements
> gathering (this was not intented to be resolved with Graphiti 0.8.0 in Indigo)
> and the fact that M6 with its API freeze is quite close, I doubt that we will
> get this in for Indigo.
We certainly don't expect anything ready for Indigo. However we do have a need for a few changes. So I've rewritten large chunks of org.eclipse.graphiti.ui so that the editor can now be instantiated both as an IViewPart and as an IEditorPart. Some work remains to make actions normally available in the main action bar appear in the view toolbar. If there is any interest I can open a separate bug on this one.

We will probably also have to do a few changes as described in other comments in order to suit our data-model and persistence mechanisms.
Comment 5 Tim Kaiser CLA 2011-03-09 08:09:40 EST
Sounds promising.
Can you share your coding with us?
Probably, it is better to share and discuss 
the view/editor extension in a seperate bugzilla.
Best, Tim
Comment 6 Michael Wenz CLA 2011-05-09 04:11:17 EDT
In order to implement an outline view for a diagram, it is necessary to access to following methods from DiagramEditorInternal. They (or some with corresponding functionalily) should be made public API. Here is a code snippet using those methods:

            if (diagramEditor.getConfigurationProvider() != null) { // diagram editor initialized?

            this.selectionSynchronizer = this.diagramEditor.getSelectionSynchronizerInternal();
            this.editDomain = this.diagramEditor.getEditDomain();
            this.keyHandler = this.diagramEditor.getCommonKeyHandler();
            this.actionRegistry = this.diagramEditor.getActionRegistryInternal();
            this.contextMenu = this.diagramEditor.getGraphicalViewer().getContextMenu();
Comment 7 Michael Wenz CLA 2011-05-10 10:57:09 EDT
Warning in the build:
Constructor for DiagramEditorContextMenuProvider with non-API parameter type IConfigurationProvider

should be fixed along with this.
Comment 8 Michael Wenz CLA 2011-05-24 05:14:46 EDT
Should be reworked together with this:
Rework DiagramEditorInput to a kind of DiagramFileEditorInput, holding only the reference to the diagram resource file.
Comment 9 Tim Kaiser CLA 2011-05-30 10:07:06 EDT
Another thing to consider:
We should really dig into how to support MultiPageEditors.
We should catch the case where DiagramEditorInternal.selectionChanged() is triggered by the editor itself -> call only super (which is not compatible with MultiPageEditorPart...)

See Bug 332964
Comment 10 Stephan Eberle CLA 2011-07-04 09:32:16 EDT
An intermediate solution would be to export the internal package as a hidden package, so users could at least overwrite it at their own risk. This is as well the solution all Eclipse Platform plugins do it. 
Users will get a warning that they are using internal API
Comment 11 Michael Wenz CLA 2011-07-04 09:41:11 EDT
That's already the case today. The package is exported (with x-friends set) so users can override at their own risk...

Michael
Comment 12 Stephan Eberle CLA 2011-07-08 11:37:22 EDT
(In reply to comment #11)
> That's already the case today. The package is exported (with x-friends set) so
> users can override at their own risk...

Ok great, thanks.

However, what we actually need to to is to customize 

private org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.behavior

Bevor this was possible thanks to the protected factory method 

org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.createDiagramEditorBehavior() 

which apparently has now disappeared. Also the getter method 

org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.getBehavior()

has become private.

Are there any changes to get that reverted and ensure the extensibility  wrt DiagramEditorBehavior?
Comment 13 Michael Wenz CLA 2011-07-14 08:56:22 EDT
(In reply to comment #12)
Extensibility wrt DiagramEditorBehavior is a little critical, since the class owns internal functionality that is necessary for Graphiti to work correctly. On the other hand I understand the need to change some of the behavioral aspects. We will have a look at this...

Could you provide more details on what you would like to achieve by using another implementation of DiagramEditorBehavior?

Michael


> However, what we actually need to to is to customize 
> private org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.behavior
> Bevor this was possible thanks to the protected factory method 
> org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.createDiagramEditorBehavior() 
> which apparently has now disappeared. Also the getter method 
> org.eclipse.graphiti.ui.internal.editor.DiagramEditorInternal.getBehavior()
> has become private.
> Are there any changes to get that reverted and ensure the extensibility  wrt
> DiagramEditorBehavior?
Comment 14 Michael Wenz CLA 2011-07-14 10:49:40 EDT
Target release is Eclipse Juno
Comment 15 Hernan Gonzalez CLA 2011-09-20 13:53:41 EDT
(In reply to comment #13)
> Could you provide more details on what you would like to achieve by using
> another implementation of DiagramEditorBehavior?
> 

In my case, I have difficulties in loading/saving in some other format (the particulars are not important here, but I'd like to work with the diagram just-in-memory, the model contains all the relevant information, that would be the only resource to be saved, and the diagram would be fully recreated at load time). The current call chain 

DiagramEditorInternal.save
   DiagramEditorBehavior.doSave
      GraphitiUiInternal.getEmfService().save(editingDomain)


does not seem very right to me. For one thing, I wonder why  EmfService() should implement a method that is only relevant for the editor (and that could need to be changed if my editor chooses another "format"), i think that should be inside the same DiagramEditorBehavior. The Graphiti services are practically static libraries, they should only implement common utility methods that no one would ever need to override/extend.
Besides, here you have a case in which I need to override the DiagramEditorBehavior.
I would prefer (with all the risks) that the behaviour field in the editor were lazily createdby the getBehaviour() (protected, overrideable).
Comment 16 Hernan Gonzalez CLA 2011-09-20 14:17:57 EDT
BTW (I'm assuming this is the place to discuss these DiagramEditor-related issues)  the DiagramEditorFactory would need some polishing. It mixes:

1. the implementation of a IElementFactory (declared in plugin.xml and referenced in DiagramEditorInput by class name instead of the usual -better practice, IMO- of using a static String ID)

	public String getFactoryId() {	return DiagramEditorFactory.class.getName();	}

2. a createEditorInput() which is more an adapter, that could be inside DiagramEditorinput

3.  a DiagramEditorMatchingStrategy as as inner static class (why ? )

(Besides, I think the DiagramEditorMatchingStrategy.matches() requires some optimization, I think that it first should try to compare URIS/Ifiles.
In some cases (as in mine) equality of files is enough.)

4. a static TransactionalEditingDomain createResourceSetAndEditingDomain() 
(this uses some internal class: GFWorkspaceCommandStackImpl, no objections)

Another argument to take 2. out of this class is that it's for it that this class is explicitly instantiated in DiagramEditorInternal - and it's rather ugly to see a "new XXXfactory()."
Comment 17 Hernan Gonzalez CLA 2011-09-20 16:58:49 EDT
Some suggestions about DiagramEditorInput:

 - It has four constructors, two of which duplicate code, should be refactored 

 - getEditingDomain()/setEditingDomain should be protected

 - getEObject(Class<EObject> adapter) is private, should be protected
   
-  getEObject(Class<EObject> adapter) searches only in the diagram hierarchy, this should be documented.

- same for  getEObject() : the documentation says "Returns the model object the editor input is working on." Actually it returns (typically) the diagram.
Comment 18 Michael Wenz CLA 2011-09-28 10:07:21 EDT
Check if storing the uri string in DiagramEditorInput could be exchanged with storing the URI, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357417#c4
Comment 20 Tim Kaiser CLA 2011-10-05 09:25:59 EDT
i targeted point 3 raised in comment 16 by Hernan:
- i moved the DiagramEditorMatchingStrategy to its own file
- if an editor input presenting an file is compared to the input of the diagram editor, only the files are compared
which works fine as long as the paradigm "one file- one diagram" is respected, but this paradigm is required by the framework elsewhere, too
Comment 21 Tim Kaiser CLA 2011-10-05 10:32:09 EDT
i targeted point 2 of comment 16 by Hernan:
- the DiagramEditorFactory was renamed to DiagramEditorInputFactory and has the single responsibility of recontsructing a DiagramEditorInput out of a memento
- DiagramEditorInput creation moved from DiagramEditorInput
Comment 22 Tim Kaiser CLA 2011-10-05 10:34:52 EDT
i targeted point 4 of comment 16 by Hernan:
- the respective method  createResourceSetAndEditingDomain()  was moved to a emfservice in the ui plugin

Also i removed the API warning for IConfigurationProvider parameter by substituting IDiagramTypeProvider for it

Clearly all these changes break our API contract, so we will be forced to go for 1.0.0 version upgrade
Comment 23 Tim Kaiser CLA 2011-11-16 11:03:19 EST
We have a branch called bug336488
containing the current state of the refactoring.
Comment 24 Michael Wenz CLA 2011-11-25 05:24:50 EST
I would like to split-off a part the the discussions and changes. The part about the listeners used inside the diagram editor and how they should be changed and optimized should be discussed in bug 364803: https://bugs.eclipse.org/bugs/show_bug.cgi?id=364803
Comment 25 Michael Wenz CLA 2011-12-21 09:18:47 EST
A couple of things happened in the bug branch in the meantime:
- The classes that are relevant to customers have been moved to a public non-internal package (DiagramEditorBehavior, EditorInput and related), DiagramEditorInternal has been integrated into DiagramEditor and got deleted
- Element delete listeners were deleted (not used any more)
- Command stack listeners were unified
- To reduce the size of DiagramEditor and DiagramEditorBehavior different functional aspects have been extracted to specialized (public) classes that can be exchanged/adapted by clients:
  . Palette: DefaultPaletteBehavior
  . Persistency (e.g. saving): DefaultPersistencyBehavior
  . Markers: DefaultMarkerBehavior
  . Refresh and update: DefaultRefreshBehavior
  . Listeners: functionality stays in DiagramEditorBehavior, but can be adapted by clients
  . ElementDeleteListener was extracted to own class
  . ResourceSetUpdateAdapter was extracted to own class
- Some smaller naming and visibility cleanup (method names)
Comment 26 Michael Wenz CLA 2011-12-21 09:20:58 EST
All these changes have been integrated back into the master branch; the branch bug336488 is closed, no changes should be done here any more:
commit 2c214bd8e547eccad243722b776f1fabb5a93989
Author: mwenz <michael.wenz@sap.com> 2011-12-20 17:23:11
Committer: mwenz <michael.wenz@sap.com> 2011-12-20 17:23:11
Parent: 5f12a30e54f110d17e2b663bb4ad459f72d7bed3 (Insert link to chapter Default Attribute Values of Graphics Algorithms)
Parent: f395d69eaa38dbd61d591fdbbcab8333a679d247 (Documentation for buffered selection methods)
Child: 5fe35d46ca429cdaf4f6e415d33845fc7f10af88 (Bug 336488: Re-applied changes from DiagramEditorInternal to DiagramEditor)
Branches: origin/master, master
Comment 27 Michael Wenz CLA 2011-12-22 11:03:51 EST
I have updated the JavaDoc for the involved classes
Comment 28 Michael Wenz CLA 2011-12-29 03:34:09 EST
Also the DiagramEditorInput and its related objects like the DiagramEditorInputFactory have been changed. The input is now a really lightweight object simply holding the URI of the diagram and a diagram type id; additionally it buffers the name of the diagram to be able to display it without having access to a TransactionalEditingDomain.
Especially the input does no longer have a reference to the TransactionalEditingDomain, this is now solely stored in the editor; benefit is there can no longer be any memory leaks because of input objects holding the domain. Also its now easier to open a diagram editor: simply create a DiagramEditorInput instance for the URI and the diagram type and use Eclipse's open editor functionality to open the editor.
Comment 29 Michael Wenz CLA 2011-12-29 04:48:22 EST
Hopefully this task is finished now: the editor has been reworked to have a better and hopefully more understandable API now. It has been split into several classes to achieve a better seperation of concerns and to avoid one huge DiagramEditor class. The different aspects have been seperated into several Default*Behavior classes clients can exchange to modify the default behavior.
The API has been cleaned up, unneeded methods have been removed, some methods have been made accessible to clients in cases where we see the need to modify teh behavior of the editor.
Also classes around the editor have have been reworked to be easier to understand. This especially affects the DiagramEditorInput.
Altogether we hope that the changes we did makes it easier for clients to change the editor behavior while being able to reuse most standard functionality. Another goal we wanted to achieve was to keep as much of the original functionality and methods available (although they probably moved to another class) to make adoption by clients as easy as possible.
Nevertheless this is a breaking change, so clients will need to adapt their coding after migrating to M5.
Comment 30 Michael Wenz CLA 2011-12-30 02:55:34 EST
I have created an integration build containing those changes. It is available from here:
Update site: http://download.eclipse.org/graphiti/updates/integration/0.9.0
Archive: http://download.eclipse.org/graphiti/archives/integration/0.9.0/org.eclipse.graphiti.site_0.9.0.v20111230-0727.zip

Please use it for early testing and to prepare the switch to the Juno M5 version of Graphiti.
Comment 31 Michael Wenz CLA 2012-01-30 03:30:50 EST
Update: After some feedback I removed the final tag from the method doSave in DiagramEditor. Clients should be able to simply override the method for easy migration of existing coding.
Nevertheless the recommend way would be to override saveDiagram in DefaultPersistencyBehavior instead.
Comment 32 Michael Wenz CLA 2012-02-01 06:28:31 EST
Finalizing for M5
Comment 33 Hernan Gonzalez CLA 2012-03-27 14:31:50 EDT
The current (for 0.9.0) implementation of DiagramEditor.init() limits extensibility:

public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		// Eclipse may call us with other inputs when a file is to be
		// opened. Try to convert this to a valid diagram input.
		if (!(input instanceof IDiagramEditorInput)) {
                           ...
			input = newInput;
		}

		getUpdateBehavior().createEditingDomain();

		try {
			super.init(site, input);
		} catch (RuntimeException e) {
			throw new PartInitException("Can not initialize editor", e); 
		}

		getUpdateBehavior().init();
		migrateDiagramModelIfNecessary();
	}

Because if a extended DiagramEditorXX wants to override this method (eg. for changing that magic of converting the editorinput class ) it will have problems calling the super.init() (from DiagramEditor's parent). 

(BTW: I dislike that strategy of converting the EditorInput, I doubt it's good practice, and its practically disallow any extension from changing calling more than once the setInput() method with any reasonable semantic - but I have already argued about that in the forum in the past)

Perhaps it would be nice to change that

public void init(IEditorSite site, IEditorInput input) throws PartInitException {
                preInit();
		try {
			super.init(site, input);
		} catch (RuntimeException e) {
			throw new PartInitException("Can not initialize editor", 	
                postInit();
}

so that the preInit()/postInit() methods can be overridden.
Comment 34 Michael Wenz CLA 2012-03-28 04:01:16 EDT
(In reply to comment #33)
> The current (for 0.9.0) implementation of DiagramEditor.init() limits
> extensibility:
> 
> Perhaps it would be nice to change that
> 
> public void init(IEditorSite site, IEditorInput input) throws PartInitException
> {
>                 preInit();
>         try {
>             super.init(site, input);
>         } catch (RuntimeException e) {
>             throw new PartInitException("Can not initialize editor",     
>                 postInit();
> }
> 
> so that the preInit()/postInit() methods can be overridden.

Agreed that preventing the conversion cannot be omitted easily. I introduced a protected method convertToDiagramEditorInput to enable that. The rest of the init methods behavior can already be influenced by overriding other methods, so I don't see the need for a change here.
Checked-in and pushed to Eclipse:
commit 715eb5b9727e10d4021c1cc0e0349f149dbb98fc
Author: mwenz <michael.wenz@sap.com> 2012-03-28 09:57:18
Committer: mwenz <michael.wenz@sap.com> 2012-03-28 09:57:18
Parent: 876486458f113a4dd4ada9d150bd3f8aebfb8673 (Bug 336488: Removed final from DiagramEditor.doSave method)
Branches: origin/master, master
Comment 35 Michael Wenz CLA 2012-04-11 10:48:22 EDT
Bookkeeping: Set target release
Comment 36 Michael Wenz CLA 2012-06-29 04:16:06 EDT
Part of Graphiti 0.9.0 (Eclipse Juno)