Hands-on with Eclipse Che: Developing the Bookmark Plugin

Tyler Jewell
Eclipse Che Blog
Published in
5 min readMay 18, 2016

Bookmark is the favorite reference for any object. In our case, it will be a reference to a file or folder for later retrieval in text editor or project explorer. One of the advantages of this feature is the ability to add files into the bookmarks and easily find them later — particularly helpful if you have a big project with thousands of files. Before starting to develop the new plugin, you should understand that architecturally, Eclipse Che consists of two parts: client side and server side. Client side is a GWT application written in Java, but then compiled into Javascript so not all Java functions are available. If you are not sure that some functionality correctly emulates in GWT, then you should check official documentation (JRE Emulation Reference).

Plugin Structure

To find out how plugins are arranged in the Eclipse Che, you can visit the official repository (plugins) and see how they have been made. There are few predefined plugins, butwe will start from the scratch. For this we will create an empty Maven project and define parent and dependency management in the pom.xml

and

Pay attention that we have used 4.2.0-RC1-SNAPSHOT version, so this plugin will be available in this version. This is due to the upgrades in the client side api which works with new resource management mechanism (operating with files/folders/projects).

As the Eclipse Che uses GWT library 2.7, client side can be written using only java 7. Otherwise the code will not compile.

Here you can see the complete pom.xml content:

In src/main/java we will create two base classes:

org.eclipse.che.ide.bookmarks.BookmarksExtension:

This class is responsible for the registering extension in the runtime. Note, that each extension in the Eclipse Che should be marked with Extension annotation.

And org.eclipse.che.ide.bookmarks.BookmarksGinModule:

This class is responsible for the registering base components in dependency management framework (Gin). Note, that each class which registers components to use in dependency management should be annotated with ExtensionGinModuleannotation.

Then, in src/main/resources we will create the following file:

org/eclipse/che/ide/bookmarks/Bookmarks.gwt.xml

Current file is included into GWT compilation to allow linking client side code with core application.

Then we should clone Eclipse Che (sources) and register our plugin into compilation phase by adding maven dependency in/che/assembly/assembly-ide-war/pom.xml and registering our Bookmarks.gwt.xml in GWT compilation by adding:

in /che/assembly/assembly-ide-war/src/main/resources/org/eclipse/che/ide/IDE.gwt.xml.

This is the minimum needed to create an empty plugin in Eclipse Che.

Developing the plugin

Lets create a few additional classes which will manage bookmarks.

Here are the descriptions of each subpackage:

  • org.eclipse.che.ide.bookmarks.actions contains classes which display actions on the UI. (Toggle Bookmark and Show Bookmarks)
  • org.eclipse.che.ide.bookmarks.event contains class of event that fires when bookmarks have been updated.
  • org.eclipse.che.ide.bookmarks.manager contains classes of presenter that displays the list of stored bookmarks. As the Eclipse Che’s client built using MVP pattern there is the presenter, the view and the implementation of view.
  • org.eclipse.che.ide.bookmarks.resource contains the resource marker and interceptor. Marker is the special object entity that provides additional information to the specific resource (file, folder or project). Interceptor is some kind of filter which modifies the resource on the loading stage.
  • org.eclipse.che.ide.bookmarks.storage contains the implementation of manager that operates with bookmarks.
  • org.eclipse.che.ide.bookmarks.tree contains the nodes which displays in bookmarks list.

Detailed view

Actions

Each plugin can customize Eclipse Che by adding new items to the menu and toolbars. Eclipse Che provides the classAction. Extending this class you can override method actionPerformed and perform any actions when user activates action from the UI. To create custom actions you should perform two steps:

  1. Define an action in plugin.
  2. Register the action.

Example of action:

By overriding updateInPerspective method, action can supply specific rules when it should be showed. By overridingactionPerformed method, action performs developer instructions. In this case we are showing the bookmark panel on the UI.

To register action class ActionManager should be used.

Example of registering actions and placing them into the system menu. Inorg.eclipse.che.ide.bookmarks.BookmarksExtension we will add the following code:

As the result you will see your registered actions on the UI:

Events

Event can send the signal that specific component has changed its own state or some action has been performed. To create custom event class GwtEvent should be extended, simultaneously, there is should be an event handler. Handler should extends EventHandler.

Example of GWT event based on org.eclipse.che.ide.bookmarks.event.BookmarksUpdatedEvent:

To handle specific events method EventBus#addHandler should be called. Note, that EventBus should be injected to be able to subscribe listening to the events.

Example of handling event:

Storage

As we need some kind of storage, we will create an interface with necessary methods and it’s implementation. This storage will be injected into other components which want to operate with the bookmarks.

Example of org.eclipse.che.ide.bookmarks.storage.BookmarksStorage:

See the javadoc of Path.

Example of implementation above interface, org.eclipse.che.ide.bookmarks.storage.BookmarksStorageImpl:

When path is added or removed from the storage, implementation sends a request to the PreferencesManagerasynchronously to save bookmarks and fires event org.eclipse.che.ide.bookmarks.event.BookmarksUpdatedEvent.

Finally, we will mark org.eclipse.che.ide.bookmarks.storage.BookmarksStorage with following annotation:

because we have the only one implementation.

Parts

In Eclipse Che each panel which is docked to specific region (Tooling, Information, Editor, Navigation) calls part. In our case, part will be responsible for displaying bookmarks and will be located in the right side of IDE, in tooling segment.

As Eclipse Che build uses MVP architecture, we need to create Presenter and View. Model will be our bookmark storage which has been described in the above section.

Example of org.eclipse.che.ide.bookmarks.manager.BookmarksPresenter:

Each part displayed in the Eclipse Che should extend BasePresenter.

Example of org.eclipse.che.ide.bookmarks.manager.BookmarksView:

Views should extend View. Action delegate classes should extend BaseActionDelegate.

Example of org.eclipse.che.ide.bookmarks.manager.BookmarksViewImpl:

View implementations should extend BaseView.

The result at this step you will see on below screenshot:

Nodes

There are two types of nodes which are used to display the results of stored bookmarks: Group node and Bookmark node.

Example of org.eclipse.che.ide.bookmarks.tree.BookmarkGroupNode:

Example of org.eclipse.che.ide.bookmarks.tree.BookmarkNode:

Finally we will modify the org.eclipse.che.ide.bookmarks.BookmarksGinModule by binding components:

Rebuild Eclipse Che with the plugin and see the result:

Conclusion

So, you can see that creating custom plugins to extend Eclipse Che functionality is not as difficult as it looks like. In one hour we have created a custom plugin that manages bookmarks for the files and folders to help the user to retrieve them faster in huge project.

The complete code of the given plugin you can find here.

--

--

Tyler Jewell
Eclipse Che Blog

MD @ Dell Tech Capital. BOD @ NS1, Orion Labs. Prev: CEO @ WSO2, CEO @ Codenvy (acq. by RHT). Invest @ Sauce Labs, Cloudant, ZeroTurnaround, InfoQ, Sourcegraph.