Sunday, April 1, 2012

Writing Eclipse Plugins Tutorial - Part 1

Eclipse is one of three most popular java development IDEs. One reason for its success is its extensibility. Writing eclipse plugins can be very fast and easy for anyone who knows what to do and already done it.

Unfortunately, doing something in Eclipse for the first time can be very time consuming and frustrating. Eclipse framework is huge, powerful and sometimes complicated. It may be difficult to figure out which features are available and how to use them.

This tutorial explains basics of all eclipse features needed to automate a simple java refactoring task. It shows how to add new items into the menu and how to analyze, modify and format java source code. It also shows how to use dialogs to communicate with users.

It is split into two parts. This post explains all needed theory. By the end of this part, you will already know enough about Eclipse framework to be able to finish the plugin with just a little searching. Practically speaking, we will create a plugin that adds new items into the menu and collects all information needed to perform the refactoring.

Next part of this tutorial will show how to create dialogs and how to modify java sources from the plugin. It was not released yet.

Table of Contents

Sample Plugin

We create sample plugin with two features:
  1. check non-null parameters - modifies selected method to check whether its parameters are not null,
  2. custom generate toString - adds toString method to selected class.

Both features will add a new item into the source menu. Check non-null parameters item will be enabled only if user selects a java method. The feature shows a dialog which allows user to choose a subset of method arguments. Selected method is then modified to check whether chosen arguments are null:
if (arg1==null || arg2==null || ... || argn==null)
  throw new IllegalStateException("The parameter may not be null.");

Custom generate toString item will be enabled only if user selects a java class. It will show a dialog with list of all its properties. The user selects which properties belongs to toString method. If user selected less than four properties, the feature adds following code to the class:
@Override
public String toString() {
  StringBuilder builder = new StringBuilder(this.getClass()
    .getSimpleName());
  builder.append(" [ ");
  builder.append(b).append(", ").append(c).append(" ]");
  return builder.toString();
}

If user selected less four of more properties, the feature adds following code to the class:
public String toString() {
  StringBuilder builder = new StringBuilder(this.getClass()
    .getSimpleName());
  builder.append(" [ \n");
  builder.append("    a" + ": ").append(a).append("\n");
  builder.append("    b" + ": ").append(b).append("\n");
  builder.append("    c" + ": ").append(c).append("\n");
  builder.append("    d" + ": ").append(d).append("\n");
  builder.append(" ]");
  return builder.toString();
}

That is all. The plugin is available on Github.

IDE

Each Eclipse release comes in multiple flavors. The version best suitable for plugin writers is called 'Eclipse for RCP and RAP Developers'. The RCP stands for 'rich client platform' which is just another name for Eclipse platform.

Download and install 'Eclipse for RCP and RAP Developers' from the download page.

Target Platform

First thing to do is to configure target platform. Target platform is another instance of eclipse. It represents the minimal configuration your plugin will work with. Your plugin will be compiled against the target platform. It will also be installed into it and will run inside it whenever you will want to test it.

The whole workspace can have only one active target platform. It is not project specific, although it would make more sense.

Easiest Target Platform
The easiest is to develop for the same eclipse version as you are running on. This is the default option. If this is the case, all you have to do is to add eclipse SDK into it.

Install Eclipse SDK:
  • Go to 'Help' -> 'Install New Software...'.
  • Choose your eclipse update site, in our case the 'The Eclipse Project Updates' http://download.eclipse.org/eclipse/updates/3. update site.
  • Check both Eclipse SDK and Eclipse Platform SDK.
  • Click next, accept license and finish the installation.

That is it. Nothing else is necessary, you are ready to create first plugin project.

Advanced Target Platform
It is possible to download and maintain the target platform separately. Use this option if you want to be compatible with an older release or if you want to have greater control over the target platform configuration.

If you are not interested, skip to the next chapter.

Create Target Platform
Find and download SDK of whatever you assume your users will have. You may use also a 'regular' version if you can not find the SDK. However, if you download SDK, you will have source code and javadocs available.

For example, our plugin requires Eclipse Indigo release. The version number of Eclipse Indigo is 3.7, therefore we have to download Eclipse 3.7 SDK. The complete list of even older Eclipse SDKs versions is available on archived releases page.

Our plugin will depend only on the eclipse itself, so all we have to do is to unpack downloaded SDK somewhere. If it would require additional plugins, we would have to hunt and download their SDKs too. We would also unpack them and copy into the same directory as eclipse SDK.

Configure Target Platform
Now, we have to configure our RCP eclipse to use prepared target platform.

Define and activate the target platform:
  • Go to 'Window' -> 'Preferences' -> 'Plug-in development' -> 'Target Platform'.
  • Click Add.
  • Choose 'Nothing: Start with an empty target definition' and click next.
  • Fill in target name.
  • Click Add, choose directory, browse to the unpacked eclipse SDK and finish.
  • Check new target platform as 'Active'.

Finally, go to 'Plug-in Development' preference page and check 'Include all plug-ins from target in Java search'.

Simple Plugin Project

This chapter shows how to create a simple plugin project and how to debug it. The simple plugin does nothing useful. It is only able to show a message to prove that it exist.

In the end of this chapter, we will remove the sample message and end up with an empty plugin skeleton.

Create Plugin Project
We will use Eclipse wizard to generate the plugin. Invoke the wizard from the package explorer:
  • right click in the package explorer,
  • choose 'New' -> 'Other..'.,
  • select 'Plug-in Project' and click Next.

The wizard has multiple pages. Configure the project name and target platform on the first one. You can use any project name as you want, but the convention is to name the project after the root java package. For example, as we want to put all classes into the org.meri.eclipse.defensiveapitools package, our project name will be org.meri.eclipse.defensiveapitools

The target platform field contains a version of Eclipse you are developing for. If someone wants to use your plugin, he will be required to download Eclipse with equal or bigger number. An old incompatible Eclipse will refuse to load it. We are fine with developing for current Eclipse, so we will choose 3.7.

Click 'Next'.

Second page contains basic project information. Fill in the id, plugin version, name and provider however you like. The first important parameter is the execution environment. The plugin will run only on the specified or never java. An eclipse running on older JVM will simply ignore it. We have chosen J2SE-1.6.

Verify that:
  • check-box 'Generate an activator, a Java ...' is checked,
  • check-box 'This plugin will make contributions to the UI' is checked,
  • the answer to 'Would you like to create a rich client platform application' is no.

Click 'Next'.

Choose 'Hello, World Command' template and click 'Finish'. This will create new plugin with sample menu item.

Debug The Plugin
The plugin works only inside a running Eclipse. Eclipse supports both manual and automatic JUnit testing. In both cases, the plugin is installed and run inside the target platform configured in the first chapter.

This chapter shows only how to do the manual testing. Refer to other resources to learn how to write junit tests for eclipse plugins.

Install and run the plugin:
  • right click on the plugin project,
  • click 'Debug As' -> 'Eclipse Application'.

The system will start new eclipse instance. Its main menu has a new entry called 'Sample Menu'.

Now, you have two running eclipse instances. One is for development and another is for testing. The testing eclipse runs inside the development one. All debugging tools are available. You can place breakpoints, inspect variables and so on:
  • open generated SampleHandler class in the development eclipse,
  • put breakpoint inside the execute method,
  • go back to the test eclipse,
  • choose 'Sample Menu' and 'Sample Command'

The execution will stop on the new breakpoint.

Clean the Plugin
We have seen that the plugin works, so we can remove generated sample menu from it.

Remove sample menu item and its handler:
  • Open plugin.xml file, go to extensions tab and remove all extensions.
  • Locate and delete generated SampleHandler class.

The plugin tag inside the plugin.xml should be empty now. Open plugin.xml file and go to the plugin.xml tab:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
</plugin>

Adapter Pattern

Eclipse is a huge framework and there is an infinite amount of plugins you can install into it. This creates a huge system of features and plugins that have to cooperate with each other. To keep this system as decoupled and as extensible as possible, Eclipse framework uses adapter design pattern. This pattern is so common that you will probably run into it no matter what plugin you will write.

This design pattern converts a class or interface into another class or interface. The class that performs the conversion is called an adapter. The pattern has two different flavors and eclipse framework supports both. The difference between those two flavors is in who creates the adapter. It can be done either directly by the object to be converted or by an independent adapter factory.

First sub-chapter shows how to write an adapter. Second sub-chapter is about objects able to create their own adapters and third is about independent adapter factories. Last sub-chapter puts everything together and shows how to convert an object of unknown type.

Adapter
Adapter is an object that converts one type into another type. It must represent the other type e.g., if it converts objects to a class, then it must extend that class. If it converts them to an interface, then it must implement that interface.

Typically, an adapter converts object that has all needed functionality, but does not have the right API. Otherwise said, typical adapter contains very little logic. It only wraps the original object and delegates all work to it.

Following adapter is able to convert an implementation of Minus interface into the Plus interface:
public class MinusToPlusAdapter implements Plus {

  private final Minus adaptee;
  
  public MinusToPlusAdapter(Minus minus) {
    super();
    this.adaptee = minus;
  }

  @Override
  public int plus(int x, int y) {
    return adaptee.minus(x, -y);
  }

}

Adaptable Objects
In a simpler version of this design pattern, the object to be converted creates its own adapters.

We will show how to create adaptable objects compatible with eclipse framework. The rest of this sub-chapter lists advantages and disadvantages of this adapter pattern flavor.

Eclipse Implementation
An adaptable object must implement IAdaptable interface. The interface has only one method getAdapter(Class type). It returns either an adapter to the requested type or a null.

An adaptable object:
public class MinusImpl implements Minus, IAdaptable {

  public int minus(int x, int y) {
    return x - y;
  }

  public Object getAdapter(Class type) {
    if (Plus.class.equals(type))
      return new MinusToPlusAdapter(this);

    return null;
  }

}

The getAdapter method may or may not call the global adapter manager to create an adapter. Some Eclipse objects call it, some do not.

When To Use It
Adaptable objects are easy to use and debug. The pattern helps to keep class and interface hierarchies clean. It also provides some decoupling between converted type and required type.

Use it when:
  • Converted type already implements too many interfaces.
  • Converted type have to be compatible with two different features and each requires it to extend another class.
  • You want to keep the converted type and required interface/class separated.
  • The adapter needs access to private fields of methods.

Limitations
Plugin that relies only on this version of the pattern is not extensible. Third party plugins are not going to be able to add new adapters into it.

Third Party Adapter
Second version of this pattern uses an independent factory to create adapters.

We will show how to call adapter factories within eclipse framework. The rest of this sub-chapter lists advantages and disadvantages of this adapter pattern flavor.

Eclipse Implementation
Adapters are created by adapter factories. To achieve their independence, adapter factories are hidden behind global adapter manager. Client code never communicates directly with an adapter factory.

Adapter manager exposes a getAdapter(Object obj, Class type) method which delegates calls to installed adapter factories. This method returns either an adapter or a null.

Use adapter manager to create an adapter:
(Plus) Platform.getAdapterManager().getAdapter(minus, Plus.class);

Adapter factories are registered into adapter manager either programmatically or in plugin.xml. As our plugin does not need to do this, we will omit that information. Read either eclipse corner article or Eclipse Adapters tutorial for further information.

Note: the adapter factory is not allowed to call the getAdapter(Class type) method of converted object. It would cause an infinite loop, because the getAdapter method of an adaptable object may call adapter manager.

When To Use It
Adapter factories lead to high decoupling and extensibility. The decoupling of the original object and required type is absolute. There is no dependency between them. Instead, an independent adapter factory depends on both.

Asking an adapter manager for adapter makes your feature extensible. Anyone can contribute adapters to integrate his objects with your plugin.

Use it to:
  • make your plugin extensible by third party plugin writers,
  • integrate two plugins.

Limitations
The decoupling comes with a higher complexity. If something goes wrong, it may be difficult to find out where the faulty adapter came from. Similarly, finding out which adapters are available is more time consuming than in the 'adaptable objects' version of this pattern.

If you expect others to extend your plugin, document which adapters are expected. Document also adapter factories you are adding into the system. Hunting down all that information in xml files can be very time consuming.

Adapt an Object
The most correct way of adapting an object to the desired interface makes no assumptions about the adapter pattern version used by the object.

Follow three steps to adapt the object to the needed interface or class:
  • If the object implements or extends the desired interface, use the object.
  • If the object can adapt itself, use the adapter provided by the object.
  • Use the global adapter manager to adapt the object.

Adapt an object to a type, full implementation:
public static Object getAdapter(Object obj, Class type) {
  // if the object implements or extends the desired interface, use it
  if (type.isInstance(obj))
    return obj;

  // if the object is able to adapt itself, let it do it
  if (obj instanceof IAdaptable) {
    IAdaptable adaptable = (IAdaptable) obj;
    Object adapter = adaptable.getAdapter(type);
    if (adapter != null)
      return adapter;
  }

  // delegate to the global adapter manager
  return Platform.getAdapterManager().getAdapter(obj, type);
}

Abstract Syntax Tree vs Java Model

Eclipse framework uses two different hierarchies to represent java source code. First is called java model and second is called abstract syntax tree. These hierarchies are mostly independent and have different purposes and usage.

Java model hierarchy is lightweight, fault tolerant, fast to re-create and its abilities are limited. Abstract syntax tree provides full control over java source code, but is much slower to recreate. For these reasons, Eclipse framework uses java model hierarchy wherever possible. Abstract syntax tree is used only if necessary.

First sub-chapter shows how to enable these hierarchies in the plugin. Second sub-chapter contains overview of java model and last contains overview of abstract syntax tree.

Plugin Dependency
Both hierarchies belong to the org.eclipse.jdt.core plugin. We have to add jdt core plugin to plugin dependencies if we want to use them:
  • Open plugin.xml and go to the 'Dependencies' tab.
  • Click Add button in the Required Plug-ins section.
  • Select the org.eclipse.jdt.core plugin.

Eclipse will automatically add plugin dependency into Require-Bundle section of MANIFEST.MF file.

Java Model
Java model is a set of interfaces that represent java methods, classes, interfaces and other elements. It is lightweight, fault tolerant and fast to re-create.

Java model hierarchy provides basic information about java code structure. It is also able to make simple changes on it. For example, it is possible to use it to rename or add new methods, classes or interfaces.

The main disadvantage of the java model hierarchy is that it does not contain full information about underlying source code. For example, it does not contain methods bodies. As a result, it is not possible to perform more complicated source code changes.

The root of the java model hierarchy is IJavaElement interface. All interfaces that extend it belong to this hierarchy.

Abstract Syntax Tree
Abstract syntax tree is a set of classes that represent java methods, classes, interfaces and other elements. It provides full information about java code structure and is able to make any changes on it.

The main disadvantage of the abstract syntax tree hierarchy is that it is slower to re-create than java model. It is also less fault tolerant.

The root of the abstract syntax hierarchy is ASTNode class. All classes that extend it belong to this hierarchy.

User Interface

This chapter contains quick overview of eclipse user interface. We will explain only absolute basics of those parts of the UI that are going to be needed later in this post.

First sub-chapter is about the most prominent part of Eclipse UI: views and editors. Second sub-chapter deals with the selection service.

Parts, Views and Editors
Two most important visual components of Eclipse user interface are views and editors. Both editors and views can show any content and present it in any form. Both can be editable or read-only, but only editor is able to keep the content in an unsaved dirty state.

Common Properties
Both editors and views are called parts. Eclipse documentation uses the word part as a shortcut for 'an editor or a view'.

Each part must have unique id. Technically, the id is an arbitrary string. However, the convention followed by all official plugins is to prefix the id with the plugin name. As the plugin name is usually equal to plugin root package name, the convention guarantees id uniqueness.

Each part must implement IWorkbenchPart interface. The interface was extended twice, leading to IWorkbenchPart2 and IWorkbenchPart3 interfaces. You may either implement them directly, or extend the default implementation called WorkbenchPart.

All parts are adaptable. The interface IWorkbenchPart extends the IAdaptable interface. The default implementation delegates the getAdapter method to the global adapter manager.

Editors
An editor is typically used to edit or browse a document or input object. Changes made in editor are not stored immediately. An editor with changed content is in dirty state until the save operation is invoked. If the editor is closed without saving, all unsaved changes are lost. Its default implementation is called EditorPart.

All editors appear in the same region of the page and can not be minimized. There can be several instances of the same type of editor.

Editors toolbar is shown together with the global toolbar and their menu appears to be a part of the main menu.

A document or input object edited by the editor is identified using an instance of IEditorInput interface.

Views
A view is typically used to navigate a hierarchy of information, open an editor, or display additional information for the thing opened in an active editor. Modifications made in a view are saved immediately. Its default implementation is called ViewPart.

Views can be moved to any part of the page and can be minimized. There is generally only one instance of a given view per workbench page.

Each view has its own local toolbar and menu. They are also allowed to contribute buttons to the global toolbar and menu items to the main menu.

Selection
Eclipse selection system is fairly standard. Each view and editor generates its own selection. The framework has also a global selection. It usually contains selection of the active part.

If the plugin needs to know selected objects no matter where they come from, it has to use the global selection. If the plugin wants to integrate itself only with few views and editors, it may listen to their selections only.

This chapter shows how to interpret the selection once you get it. How to get the current selection is described in an Eclipse corner article.

Selected Objects
Current selection always implements the ISelection interface. That interface is extremely minimalistic. Its only method is able to tell whether the selection is empty of not.

To get more detailed information, you have to cast it to one of its subtypes. Two sub-types are interesting for our plugin:
  • ITextSelection - information about selected text. If no text is selected, contains the cursor position.
  • IStructuredSelection - contains a list of selected objects.

Structured selection can contain any types of objects. The best way to convert them to required classes or interfaces is to use the adapter pattern. Simple instanceof and cast may not be enough. Objects flying in eclipse are often adaptable to many types, but they implement or extend only some of them.

Eclipse Menus

Eclipse menu system is surprisingly rich and complicated. There are at least five menu types. The same or similarly looking menu can be invoked in multiple ways. To make it even more interesting, Eclipse has two different frameworks able to contribute new items into all those menus.

Each eclipse menu framework has its own chapter and those two chapters follow this one. This chapter contains only an overview of various menu types, an overview of the menu where our plugin adds its items and overview of those two menu frameworks.

Menus Types
Eclipse has five menu types:
  • Context menu - menu invoked by a mouse right click. Sometimes called also popup menu.
  • Main menu - menu always visible on the top of GUI.
  • Main toolbar - always visible toolbar available under the main menu.
  • View menu - menu available in a view. Click on a white down arrow in a view to invoke it.
  • View toolbar - a little toolbar available in most views.

Unlike views, editors do not have their own menu or toolbar. They always contribute to the main menu or to the main toolbar.

Source Menu
Source menu contains items like 'Organize Imports' or 'Generate Delegate methods...' and is a logical place for our two features. It was contributed by java development tools plugin (JDT).

This menu is located either in the main menu or in the context menu. Both locations show it only under some circumstances.

Main menu contains source menu item only if the active view or editor supports it. Following list contains examples of views and editors that causes the source menu to appear. Activate any of them to see it in main menu:
  • Java Editor,
  • Type Hierarchy View,
  • Package Explorer View,
  • Project Explorer View.

Context menu contains source menu item if at least one selected item represents java file, class, package method or other java item. Of course, that includes text selection inside java source editor. Activate context menu with source sub-menu:
  • open java source file in an editor and right click inside,
  • select java file or class in package explorer and right click.

The source menu can be invoked also with shortcut 'Alt+Shift+S'.

Menu Frameworks
Eclipse has two different frameworks able to contribute new items into menus:
  • the actions framework,
  • the command framework.

The actions framework is older and deprecated. The command framework is newer, flexible and little bit more complicated. It is superior and should be used for any new functionality.

The command framework is compatible with most, but not all menus. Some menus have not been rewritten yet, so you have to use the actions framework to contribute to them. For example, the source sub-menu in the main menu is compatible only with the actions framework.

Some menus are incompatible with both frameworks. The source menu invoked by the shortcut CTRLS + ALT + S is such menu. It is impossible to contribute to it.

Note: Impossible to contribute to menus are rare.

The Command Framework

The command framework is able to add items into most eclipse menus. It was designed as mini model view controller and separates UI from actions to be performed.

This chapter contains command framework basics. We will explain command framework components and use them to add new items into the source menu. Then, we will show how to make menu items enabled and disabled. New menu items are going to be enabled only if they would be useful on the current selection.

Overview
New addition to the menu is called a menu contribution. Each menu contribution needs to know where to draw new items, which items to draw and what should happen when someone clicks them.

Most Eclipse menus have unique id assigned. If you want to contribute to the menu, you have to find that id, compose so-called location URI from it and assign it to the menu contribution.

Among other things, each menu contribution can add separators and commands into the menu. Separators are those grey lines between different menu parts. Commands placed inside a menu represent clickable menu items. Each has a label, may have an icon and can be either enabled or disabled.

However, the command is not able to perform an action. It is only an abstract thing meant to separate GUI from the real action. Real work is done inside command handlers.

Menu Id
Menu id is an arbitrary string assigned to the menu or sub-menu. Each menu may have multiple ids. Finding menu id of an Eclipse menu can get very frustrating and difficult.

If you are lucky, the id will be revealed with the Plugin Spy available in Eclipse RCP. It is able to show information about menu items, UI elements and running Eclipse plugins. If you are unlucky, you will have to find the id on your own.

Top Level
Things are easy if you wish to add an item to the menu or toolbar top level.

List of general application menus:
  • The main Eclipse menu uses org.eclipse.ui.main.menu. The id refers only to the menu top level, e.g. the item will be placed together with 'File', 'Edit' and 'Help'.
  • The Eclipse toolbar uses org.eclipse.ui.main.toolbar.
  • The context menu uses org.eclipse.ui.popup.any id.

If you wish to contribute to menu or toolbar inside some view, use the view id. Luckily, the Plugin Spy can help to find the view id. Open the view in an RCP Eclipse and press 'Alt + Shift + F1'. Plugin Spy will open a popup with view information:

Sub-menu With Plugin Spy
Finding an id of a sub-menu can be more complicated because the Plugin Spy may not be able to find it.

Use 'Alt + Shift + F2' shortcut to start the Plugin Spy and open menu you want to contribute to. Click on any menu item and Plugin Spy will show various information about it.

Use Plugin Spy to get the source menu location URI:
  • open any java file in the development eclipse,
  • press 'Alt + Shift + F2',
  • right click inside the java file
  • hover over the 'Source' menu item,
  • click on the 'Clean Up...' item.

Eclipse will show following pop-up:

If the popup contains location URI, then we are almost there. Copy and paste it somewhere. Warning: Plugin Spy popup adds new line before and after copied text, so it may look like nothing was copied.

The part between : and ? is the menu id. For example, if the plugin spy shows
menu:org.eclipse.jdt.ui.source.menu?after=CleanUp
, the menu id is
org.eclipse.jdt.ui.source.menu

The Other Way
If the Plugin Spy does not show the location URI, it means that menu item or the menu itself was not rewritten into command framework yet. This is how Plugin Spy popup of an old menu item looks like:

Your best bet is to google around and look into plugin.xml of plugins that contribute to that menu. Chances are, that someone had the same problem and managed to solve it.

You can start with an old but still good list of context menus available on jdg2e. If the menu existed already in Eclipse 3.0, it is listed there along with its menu id. The source menu is not available in that table.

However, the id of its parent menu, e.g. the menu available if you right click in any java file, is #CompilationUnitEditorContext. This would be an acceptable second prize.

Plan B
While the contribution to top level menus with the command framework is easy, unknown menu ids make contributions to various sub-menus difficult or even impossible. If you have no luck finding it, you have to use the old actions framework.

Location URI
Location URI string has three parts: scheme, menu id and placement modifier:
<scheme>:<menu-id>[?<placement-modifier>]

Eclipse has three schemes:
  • menu - either main application menu or a view menu,
  • toolbar - either main application toolbar or a view toolbar,
  • popup - a context menu, e.g. any menu invoked by a right click.

The placement modifier is optional. It has the form <placement>=<id>. The placement part is either after or before. The id is either separator name, menu ID, or item ID. Be careful, if the menu does not contain specified id, it will ignore your contribution.

By convention, each menu should declare a special item with id 'additions'. This is where menu authors through that you should place your items. You do not have to respect their wish and some menus do not have such item. You can place your items wherever you like, even if the special additions item is in the menu.

Few examples:
  • menu:org.eclipse.ui.main.menu?after=file - add item to the main menu, between File and Edit sub-menus.
  • toolbar:org.eclipse.ui.main.toolbar - add item to the main toolbar.
  • menu:org.eclipse.ui.navigator.ProjectExplorer - add item to the menu available in the project explorer view.
  • toolbar:org.eclipse.ui.navigator.ProjectExplorer - add item to the toolbar available in the project explorer view.
  • popup:org.eclipse.ui.popup.any - add item to the context menu.

Place the item into the source menu without being picky about the exact location:
popup:org.eclipse.jdt.ui.source.menu

Note: We omitted the optional exact location in our location URI, because it can be tricky. If you wish to specify also the exact location, you have to be sure that selected place exists every time the menu is invoked. Unfortunately, just because the menu item looks the same, it does not mean that it really is the same menu item.

For example, if we would add ?after=CleanUp in the end of the previous location, our menu item would be placed right after the 'Clean Up...' item in the sources sub-menu invoked by right click in java editor. However, it would be invisible in the source sub-menu invoked by right click in package explorer view.

Command
A command is an abstract thing that represents an action and has an unique id. It can be placed into the menu and you can assign a shortcut to it.

Commands are configured in plugin.xml file. Open it and go to extensions tab. Use the left part named 'All Extensions':
  • Click 'Add' and choose org.eclipse.ui.commands extension point.
  • Right click on the new extension point and choose 'New' -> 'command'.
  • Fill in the id. The convention is to use plugin name as prefix of the command id.
  • Fill in the name.

We created two commands. One named 'Generate Custom toString' and another is named 'Check Non-Null Parameter'. Their ids are:
  • org.meri.eclipse.defensiveapitools.generatetostring
  • org.meri.eclipse.defensiveapitools.checknonnullparameter

Eclipse automatically generates corresponding xml and places it to the plugin.xml file. Go to the plugin.xml tab to see it:
<extension 
      point="org.eclipse.ui.commands">
   <command
      id="org.meri.eclipse.defensiveapitools.generatetostring"
      name="Generate Custom toString">
   </command>
   <command
      id="org.meri.eclipse.defensiveapitools.checknonnullparameter"
      name="Check Non-Null Parameter">
   </command>
</extension>

Menu Contribution
Menu contribution is an addition to menu. It knows where to draw itself and contains list of items that should be drawn. All items placed into the menu contribution are shown together, in the order defined by their position in that list.

We will configure a new menu contribution and add two menu items and two separators in it. Adding other element types into it is analogical.

Menu Contribution
Menu items are configured in plugin.xml file. Open it and go to extensions tab. Use the left part named 'All Extensions':
  • Click 'Add' and choose org.eclipse.ui.menus extension point.
  • Right click on the new extension point and choose 'New' -> 'menuContribution'.
  • Fill in the locationURI.
  • Set allPopups to true.

Recall, that the source context menu location uri is:
  • popup:org.eclipse.jdt.ui.source.menu

Command
Add commands to the menu contribution:
  • Right click on the menu contribution and choose 'New' -> 'command'.
  • Click Browse and find previously created command.
  • Fill in label.

Eclipse automatically generates corresponding xml and places it to the plugin.xml file. Go to the plugin.xml tab to see it:
<extension
      point="org.eclipse.ui.menus">
   <menuContribution
         allPopups="true"
         locationURI="popup:org.eclipse.jdt.ui.source.menu">
      <command
            commandId="org.meri.eclipse.defensiveapitools.generatetostring"
            label="Generate Custom toString"
            style="push">
      </command>
      <command
            commandId="org.meri.eclipse.defensiveapitools.checknonnullparameter"
            label="Check Non-Null Parameter"
            style="push">
      </command>
   </menuContribution>
</extension>

Test the menu. Run or debug the plugin and open any java file in the test Eclipse. Right click and choose the Source sub-menu. The menu contains two new items. As our commands have no handlers assigned, both items are disabled.

Separator
Add separator to the menu contribution:
  • Right click on the menu contribution and choose 'New' -> 'separator'.
  • Set visible to true.
  • Fill in name.

The order of elements in the menu contribution defines the order of corresponding items in the menu. Drag and drop new separator to the place where you would like to see it.

Eclipse automatically generates corresponding xml and places it to the plugin.xml file. Go to the plugin.xml tab to see it:
<menuContribution
      allPopups="true"
      locationURI="popup:org.eclipse.jdt.ui.source.menu">
   <separator
         name="org.meri.eclipse.defensiveapitools.begin"
         visible="true">
   </separator>
   ... commands ...
   <separator
        name="org.meri.eclipse.defensiveapitools.end"
        visible="true">
   </separator>
</menuContribution>

Test the menu again. Run or debug the plugin and open any java file in the test Eclipse. Right click and choose the Source sub-menu. Our menu items are surrounded by menu separators.

Command Handler
The command handler is the class that executes an action whenever users clicks on the menu item. Once we assign it to the command, the menu item created in previous chapter will be enabled.

This section is divided into three part. First two sections show how to create and configure a dummy handler. Third section explains where the handler can get the information about currently selected items, active editor and other UI state.

Simplest Command Handler
A command handler must implement the IHandler2 interface. The easiest way to implement it is to extend the abstract AbstractHandler class. This class provides standard implementation of all necessary methods except the execute method.

The execute method is called whenever user invoked the command. It has one parameter which contains information about the current state of the application. The execute method must return null.

Our first command handler is very simple:
public class GenerateToStringHandler extends AbstractHandler {

 @Override
 public Object execute(ExecutionEvent event) throws ExecutionException {
  System.out.println("GenerateToStringHandler");
  // must return null
  return null;
 }

}

Basic Configuration
The only thing we have to configure is which commands should be handled by our handler.

Note: It is also possible to assign multiple handlers to one command, but we will not do it. It is an advanced topic discussed in additional resources.

As usually, command handlers are configured in plugin.xml file. Open it and go to extensions tab. Use the left part named 'All Extensions':
  • Click 'Add' and choose org.eclipse.ui.handlers extension point.
  • Right click on the new extension point and choose 'New' -> 'handler'.
  • Browse for the command id.
  • Browse for the class implementing the command handler.

Eclipse automatically generates corresponding xml and places it to the plugin.xml file. Go to the plugin.xml tab to see it:
<extension
      point="org.eclipse.ui.handlers">
   <handler
         class="org.meri.eclipse.defensiveapitools.generatetostring.GenerateToStringHandler"
         commandId="org.meri.eclipse.defensiveapitools.generatetostring">
   </handler>
   <handler
         class="org.meri.eclipse.defensiveapitools.checknonnullparameter.CheckNonNullParameterHandler"
         commandId="org.meri.eclipse.defensiveapitools.checknonnullparameter">
   </handler>
</extension>

Run or debug the plugin and open any java file in the test Eclipse. Right click and choose the Source sub-menu. The 'Generate Custom toString' menu item is enabled. If you click on it, the command handler will print 'GenerateToStringHandler' into console in RCP Eclipse.

Implementation
As we are going to invoke our feature from two different places, our command handler will delegate all real functionality to yet another class.

That another class will need some information about the context surrounding the command. Namely, 'Generate Custom toString' needs to know which class was selected and 'Check Non-Null Parameters' needs to know which method was selected.

Note: Eclipse generates mini-selection every time you place the cursor somewhere. You do not have to highlight the text inside editor.

The execute method obtains an instance of ExecutionEvent as a parameter. The execution event has reference to application context which contains various information about the state of the eclipse.

Use the HandlerUtil to get that information out of the execution event. Handler util is a static class and has a lot of getWHATEVER methods. We will need four of them:
  • getCurrentSelection - returns current selection,
  • getActivePartId - returns id of active view or editor,
  • getActiveEditorInput - returns object edited by the opened editor,
  • getActiveShell - returned object will be needed for our plugin dialog.

private static final String JAVA_EDITOR_ID = 
"org.eclipse.jdt.ui.CompilationUnitEditor";

public Object execute(ExecutionEvent event) throws ExecutionException {
  //this object is needed to render wizards, messages and so on 
  Shell activeShell = HandlerUtil.getActiveShell(event);
  //get selected items or text 
  ISelection currentSelection = HandlerUtil.getCurrentSelection(event);

  //identify active GUI part
  String activePartId = HandlerUtil.getActivePartId(event);
  if (JAVA_EDITOR_ID.equals(activePartId)) {
    //get edited file
    IEditorInput input = HandlerUtil.getActiveEditorInput(event);
    //currentSelection contains text selection inside input file
    //... locate class selected in that file ...
  } else {
    //currentSelection contains all selected classes 
    //... collect all selected classes ...
  }

  return null;
}

Enabling, Disabling and Visibility
The menu item does not have to be visible and enabled all the time. Most commands are not universally usable.

Both our features are going to be visible all the time. However, we will have them enabled only under some conditions. 'Check Non-Null Parameters' will be enabled:
  • inside java editor,
  • if the current selection contains only modifiable java methods.

'Generate Custom toString' will be enabled:
  • inside java editor,
  • if the current selection contains only modifiable java classes or source files.

First, shortest section shows where to configure visibility and enablement. Next one describes xml language used to define visibility and enable conditions. Third section uses that language to test active editor and fourth tests selected objects. Final two sections put everything together and show conditions needed for our plugin.

Visible vs Hidden
If you want to make the menu item invisible, use the visibleWhen tag on a command reference inside a menu contribution. If you want to make the item disabled, use the enabledWhen tag on the command handler. Both tags works exactly the same way.

Open plugin.xml in an editor and go to the extensions tab. Right click either on the reference inside a menu contribution or command handler and choose either visibleWhen or enabledWhen.

Expression Language
If you right click on visibleWhen or enabledWhen tag, Eclipse will show a list of possible sub-tags. All those tags are part of xml boolean expression language and we will use them to define a condition. If the condition is satisfied, the menu item will be visible or enabled. If the condition is not satisfied, the menu item is either disabled or invisible.

One warning: not each tag shown on the list is directly usable. In this case, Eclipse simply shows all tags that defines a condition.

Usage of all listed tags is described on Eclipse help page. We will explain only five tags needed for our conditions:
  • or - logical or,
  • with - specify the object under condition,
  • iterate - iterator over a collection,
  • equals - compares object under condition with a value,
  • adapt - adapts object under condition to the specified one.

Or
The element or does logical or. Its child tags must represent conditions. If at least one of them returns true, the result is true.

With
The element with specifies the object under condition. This tag can access various variables that describe Eclipse state. Each variable has a name. All childs of the with tag will test their condition against the value of the specified variable.

This tag has one mandatory property variable. Use it to specify the variable name. We will use two variables:
  • activeMenuSelection - collection of all objects selected by the user,
  • activePartId - the id of currently active GUI part (view, editor, preference page ...).

As any plugin can add its own variable, the complete list of all variables is impossible to find. The list of default variables is available on Eclipse wiki page.

Iterate
The element iterate is usable only inside the with tag and only if this tag specified a collection as the object under the test. Its child tags must represent conditions. Iterate iterates through all objects inside the collection and runs all child conditions on those objects.

The iterate tag has two arguments: operator and ifempty. The first argument value can be either and or or. Selected operator will be applied to evaluated conditions results. If no operator is specified, the iterator uses and.

The ifempty can be either true or false. This value will be returned if the collection under test is empty. If not specified then true is returned when the operator equals and and false is return if the operator equals or.

Equals
The element equals compares the object under test with its value argument. As the object under test may not be a string, the value argument is converted into the object. The exact conversion algorithm is described in Eclipse manual.

Adapt
The element adapt adapts the object under test to the interface or class specified in its type argument. It may have child tags that may process it further, but we will use it solely to check whether the object under test is adaptable to the desired interface.

Test Current Editor
If the menu was invoked from java editor, then id of the active part is the same as id of java editor. Therefore, we have to get java editor id and compare it to the value of activePartId expression variable.

To get the id, open any java file in RCP eclipse and press ALT + SHIFT + F1. Plugin Spy will show popup with various information about active GUI part. According to this popup, the java editor id is org.eclipse.jdt.ui.CompilationUnitEditor.

Combine the with and equals tags to compare the id:
<with variable="activePartId">
  <equals value="org.eclipse.jdt.ui.CompilationUnitEditor" />
</with>

Test Selected Objects
Current selection can contain multiple items and all of them should represent something we can work with. The adapter pattern and java model hierarchy have been designed exactly for these kind of situation.

Three interfaces from java model hierarchy are relevant to our features:
  • org.eclipse.jdt.core.IMethod - represents java methods,
  • org.eclipse.jdt.core.IType - represents java classes and interfaces,
  • org.eclipse.jdt.core.ICompilationUnit - represents java source file.

Therefore, we will iterate over the activeMenuSelection variable and check whether each selected object is adaptable to one of needed types. If no item is selected, the condition should return false.

A method is selected if it is possible to adapt all selected objects into the IMethod interface:
<with variable="activeMenuSelection">
  <iterate ifEmpty="false" operator="and">
    <adapt type="org.eclipse.jdt.core.IMethod" />
  </iterate>
</with>

A java source file or a class is selected if it is possible to adapt all selected objects into either ICompilationUnit or ITypeinterface:
<with variable="activeMenuSelection">
  <iterate ifEmpty="false" operator="and">
    <or>
      <adapt type="org.eclipse.jdt.core.IType" />
      <adapt type="org.eclipse.jdt.core.ICompilationUnit" />
    </or>
  </iterate>
</with>

Note 1: Unfortunately, the xml expression language is not expressive enough to distinguish between classes and interfaces. An instance of IType interface represents class if its isClass method returns true, but xml language does not support method calls.

Note 2: We are cheating little bit here. It is not possible to modify compiled java methods and classes inside jar packages, but they are adaptable to java model interfaces too. Those objects are modifiable only if the method getCompilationUnit does not return null. As with the previous note, this is not possible to check from the xml expression language. Fortunately, we are contributing to the source sub-menu which is available only on modifiable java elements, so we do not have to solve this problem.

Note 3: In both cases, the correct solution would be to create own with variable and handle both problems in java. This is possible and easy, but out of scope of this article. If you wish to know how to do it, read the post on Lars Vogel blog.

Check Non-Null Parameters Enablement
To reiterate, the menu item 'Check Non-Null Parameters' will be enabled:
  • inside java editor,
  • if the current selection contains only modifiable java methods.

Use or to combine conditions created in previous chapters. This is the final condition:
<enabledWhen>
  <or>
    <with variable="activePartId">
      <equals value="org.eclipse.jdt.ui.CompilationUnitEditor" />
    </with>
    <with variable="activeMenuSelection">
      <iterate ifEmpty="false" operator="and">
        <adapt type="org.eclipse.jdt.core.IMethod" />
      </iterate>
    </with>
  </or>
</enabledWhen>

Generate Custom toString Enablement
Recall, that the menu item 'Generate Custom toString' will be enabled:
  • inside java editor,
  • whenever java class is selected,
  • whenever java file is selected.

Use or to combine conditions created in previous chapters. This is the final condition:
<enabledWhen>
  <or>
    <with variable="activePartId">
      <equals value="org.eclipse.jdt.ui.CompilationUnitEditor" />
    </with>
    <with variable="activeMenuSelection">
      <iterate ifEmpty="false" operator="and">
        <or>
          <adapt type="org.eclipse.jdt.core.IType" />
          <adapt type="org.eclipse.jdt.core.ICompilationUnit" />
        </or>
      </iterate>
    </with>
  </or>
</enabledWhen>

Expression Language - Additional Resources
The complete explanation on how those conditions work is out of scope of this post. If you wish to read more, the basic and short article is on eclipse-tips blog and a detailed one is on Lars Vogel blog.

The detailed post explains also how to reuse conditions and how to create new with variable. It is definitely worth reading, especially if you plan to do something complicated.

Command Framework - Additional Resources
We simplified things a little in this chapter. The full functionality and possibilities of the command framework are out of scope of this article.

If you wish to know more, good tutorials are available on Lars Vogel blog or in IBM library.

The Actions Framework

Theoretically speaking, the actions framework is old and has been deprecated. The newer commands framework should be used for most purposes. Unfortunately, not all menus have been rewritten yet.

If the menu you are interested in has not been rewritten yet, you have to use the old actions framework to contribute to it.

As most menus are already compatible with the new command framework, we will show only the part of actions framework that is able to contribute to the source sub-menu in main menu. If you wish to read more about the actions framework, the last sub-chapter links to more detailed articles.

Overview
Two most important elements in the actions framework are action and action delegate. An action is assigned to menu items and knows the menu where it should be drawn. Action delegate is a class that does all the work whenever a menu item is invoked.

Each action delegate can be assigned to any number of actions. However, each action can have only one action delegate.

Items and menus definitions are kept either inside an action set or inside something called a contribution. There is not much difference between them, both action set and contribution contain list of actions and sub-menus to be drawn within menu system.

Eclipse framework has three types of actions contributions and each is able to specify a simple condition that must be satisfied to have a visible action:
  • viewerContribution - an action is available only inside specified view,
  • objectContribution - an action is available only if specified object type has been selected,
  • editorContribution - an action is available only inside editor menu or toolbar.

Note: it is also possible to assign a condition to an action. Action conditions are powerful, but out of scope of this article.

Both contribution and action set are placed directly inside an extension point. Each menu type has its own extension point:
  • org.eclipse.ui.actionSets - main menu or main toolbar,
  • org.eclipse.ui.popupMenus - context menu,
  • org.eclipse.ui.viewActions - local menu or toolbar in a view,
  • org.eclipse.ui.editorActions - local menu or toolbar in an editor (recall that the editors menu is shown inside the main menu/toolbar),
  • org.eclipse.ui.perspectiveExtensions - we will ignore that.

So, we have to create action delegate class, identify the menu we want to contribute to and configure an action inside a action set.

Implementing Action Delegate
Action delegate implementation depends on where you want to place the associated action. Menus supply the action delegate with additional information that depends on the menu type. Therefore, each menu type requires it to implement different interface.

Common
Each action delegate must implement IActionDelegate interface. That interface was later extended with some lifecycle methods, so if you need to initialize your action delegate or know when it is disposed, implement also IActionDelegate2 interface.

Which method is invoked when a menu item is clicked depends on implemented interfaces. An action delegate that does NOT implement IActionDelegate2 interface must place all the work inside the run method. However, an action delegate that implements the IActionDelegate2 interface must place all the work inside the runWithEvent. In this case, the run method is never called.

Menu Types and Sub-Interfaces
Which sub-interfaces of IActionDelegate interface you should use depends on where do you want to place the action. Some parent menus send additional information about active parts and the action delegate must be able to acquire it.

List of eclipse menus and expected action delegate interfaces:
  • main menu or toolbar - IWorkbenchWindowActionDelegate,
  • view menu or toolbar - IViewActionDelegate,
  • view context menu - IViewActionDelegate or IObjectActionDelegate,
  • editor menu or toolbar - IEditorActionDelegate,
  • editor context menu - IObjectActionDelegate.

Selection
Parent menu uses the method selectionChanged to inform the action delegate about current selection changes. However, selection changes are sent to the action delegate only after it was invoked for the first time. All prior selection changes are ignored.

The selectionChanged method is called for the first time right before the first call of run or runWithEvent method.

Implementation
We are ready to implement our action delegates. As it was with the command handler in command framework, our action delegate will only collect information about current editor and selected objects or text. The real work is delegated to yet another class.

As we want to put our action to the main menu, we have to implement the IWorkbenchWindowActionDelegate interface. Main menu sends changes of current selection it to its action delegates, so all we have to do is to store it:
private ISelection selection;

public void selectionChanged(IAction action, ISelection selection) {
  this.selection = selection;
}

Getting current editor is little bit more complicated. Main menu does not inform its items about active UI parts. However, it sends them an instance of IWorkbenchWindow upon initialization. Fortunately, the workbench window object is aware of almost everything that is going on in the eclipse.

The explanation of the workbench window object would take too much space and it is not that important. The important is, that it provides access to all kind of information about eclipse user interface.

Use workbench window to get active editor and its id:
private IWorkbenchWindow window;

public void init(IWorkbenchWindow window) {
  this.window = window;
}

private String getActivePartId() {
  return window.getPartService().getActivePartReference().getId();
}

private IEditorPart getActiveEditor() {
  return window.getActivePage().getActiveEditor();
}

Finally, we are ready to implement the run method:
public class GenerateToStringActionDelegate implements IWorkbenchWindowActionDelegate {

  private static final String JAVA_EDITOR_ID = 
"org.eclipse.jdt.ui.CompilationUnitEditor";

  public void run(IAction action) {
    //this object is needed to render wizards, messages and so on 
    Shell activeShell = window.getShell();
    //get selected items or text 
    ISelection currentSelection = selection;
    //identify active GUI part
    String activePartId = getActivePartId();
    //java editor must be handled differently than view selection 
    if (JAVA_EDITOR_ID.equals(activePartId)) {
      //get edited file
      IEditorInput input = getActiveEditor().getEditorInput();
      //currentSelection now contains text selection inside input file
      //... locate class selected in that file ...
    } else {
      //currentSelection now contains all classes inside 
      //... collect all selected classes ...
    }

    System.out.println("GenerateToStringActionDelegate");
  }

}

MenubarPath and ToolbarPath
Before you configure the action, you have to find the menu or toolbar path. It identifies a menu or toolbar where your action will be shown.

Each menu or sub-menu has its name and menu or toolbar path navigates those names. It starts with the top level menu name and continues with all sub-menu names. The final part is optional and specifies a location in the final menu. If it is missing, the item is placed to the end of the specified menu.

For example, the menu path #menuName/subMenuName/additions should be read as "place the item in the end of the additions group which is located inside the sub-menu subMenuName of the #menuName menu".

Or, the menu path #menuName/subMenuName/ should be read as "place the item in the end of the sub-menu subMenuName of the #menuName menu".

Important: Menu ids are the same as described in the command framework chapter. The id of the source menu id is org.eclipse.jdt.ui.source.menu. As the main source menu is a top level menu, menubarPath is:
org.eclipse.jdt.ui.source.menu/

Configuring an Action
Action configuration is quite simple. Add an extension point, put either action set or contribution into it and place the action.

Which one of five extension points should be used depends on the menu. We want to add an action to the main menu, so we have to use the action sets extension point.

Open plugin.xml file and go to extensions tab. Use the left part named 'All Extensions'. First, configure an action set:
  • Click 'Add' and choose org.eclipse.ui.actionSets extension point.
  • Right click on the new extension point and choose 'New' -> 'actionSet'.
  • Fill in the action set id. The convention is to use plugin name as its prefix. Important: This field has some strange limitations. We could not really figure them out, so all we can say is that:
    • org.meri.eclipse.defensiveapitools.mainmenucontrib works
    • org.meri.eclipse.defensiveapitools.sourcemenu works,
    • org.meri.eclipse.defensiveapitools.mainsource does not work,
    • org.meri.eclipse.defensiveapitools.actionset does not work.
    In any case, if nothing shows up in the menu, try to change this id.
  • Fill in label. It can be anything.
  • Set visible to true.

Second, add actions to the action set:
  • Right click on the action set and choose 'New' -> 'action'.
  • Fill in the action id. The convention is to use plugin name as id prefix.
  • Fill in label. It can be anything.
  • Fill in either menubarPath or toolbarPath.
  • Scroll down and browse for the action delegate in class field.

Eclipse automatically generates corresponding xml and places it to the plugin.xml file. Go to the plugin.xml tab to see it:
<extension
      point="org.eclipse.ui.actionSets">
   <actionSet
         id="org.meri.eclipse.defensiveapitools.sourcemenu"
         label="Defensive API Tools "
         visible="true">
      <action
            class="org.meri.eclipse.defensiveapitools.generatetostring.GenerateToStringActionDelegate"
            id="org.meri.eclipse.defensiveapitools.generatecustomtostring"
            label="Generate Custom toString"
            menubarPath="org.eclipse.jdt.ui.source.menu/"
            style="push">
      </action>
      <action
            class="org.meri.eclipse.defensiveapitools.checknonnullparameter.CheckNonNullParameterActionDelegate"
            id="org.meri.eclipse.defensiveapitools.checknonnullparameters"
            label="Check Non-Null Parameters"
            menubarPath="org.eclipse.jdt.ui.source.menu/"
            style="push">
      </action>
   </actionSet>
</extension>

Run or debug the plugin and open any java file in the test Eclipse. Click on the Source main menu item. The menu contains two new items. Click on the Generate Custom toString' menu item, the action delegate will print 'GenerateToStringActionDelegate' into console in RCP Eclipse.

Additional Resources
Walkthrough of all types of actions contributions is available in an eclipse corner article. Easy to read FAQ article explains actions in the main menu.

Actions framework supports also complicated conditions and filters to show actions only under some circumstances. If you have a reason to use that, the best starting point is in eclipse documentation.

Useful Resources

Everything directly related to chapters in this post was already linked. We will add only a link on a very good series with various eclipse development tips.

If you have a problem and can not find an answer, you can also ask questions on official freenode #eclipse IRC channel.

To Be Continued

Although we added only some new items into the menu so far, almost everything needed to finish the plugin is already there. If you do not insist on having the generated code formatted, you should be able to finish the generate toString feature just by browsing through java model hierarchy API.

Next part of this tutorial will show how to finish both features, including the formatting of the generated code. It will also explain how to create and work with abstract syntax tree and how to create a dialog to communicate with user.

105 comments:

Anonymous said...

*** Akuratne podrobny a zrozumitelny navod. Diky moc!

Meri said...

@Anonymous: Dakujem, nemas za co :)

Anonymous said...

Hi, Nice post ! Where is the continuation ?

Meri said...

The second part was not written yet, unfortunately. The free Stanford crypto course took most of my time lately and I signed up also for another course which should start soon.

The next couple of posts are going to be something that requires less time to write and is related to the courses. This topic is too big to be done while doing the courses. I hope to come back to it in 3-4 months.

Mansoor said...

This is an excellent post for any beginners struggling to understand and get started for plug-in creation. It helped me a lot in understanding different concepts in the Eclipse PDE framework.

Although you have told us that you are busy with some course stuff, still, I would request and insist on getting the second part ASAP :)

Many thanks.

Meri said...

Hi Mansoor,

thank you for the comment. I'm glad to hear that the post was helpful for somebody. It has motivating effect on me :).

I was little surprised by interest in this topic and I did not expected people to care about the second part being released soon.

It is true that starting with Eclipse plugins is difficult.

The next question is for anyone reading this discussion: are there any Eclipse related topics that would be more interesting for you than others?

Anonymous said...

Nice post !

Do u recommend any book about writing eclipse plugins, which takes a tour of the whole API in detail ?

Anonymous said...

Your post is so helpful. I was struggling with finding proper, understandable tutorial to Eclipse Plugin Development when I found this :). Looking forward to read your 2nd part :). Thank you for your knowledge sharing

Mansoor said...

Hi Meri,
I hope that you would release the second part soon then :)

And to answer your question, I would be interested in "how to extend JDT" in eclipse.
Specifically I am trying to create a plugin which provides the facility/option of some uneditable areas in the normal Java file while editing in default Java Editor (provided by JDT). There is no particular extension point for adding small features/additions in the default Java Editor (CompilationUnitEditor). Although I know that I should load my plugin through "org.eclipse.ui.startup" extension point.
Can you please guide me in this regard.
Thanks.

Meri said...

I used two books:
* Contributing to Eclipse: Principles, Patterns, and Plug-Ins By Erich Gamma, Kent Beck (published 2003)
* Eclipse Rich Client Platform: Designing, Coding, and Packaging Java Applications By Jeff McAffer, Jean-Michel Lemieux (published 2005)

If I recall right, the first explains more about APIs and internals while the second one is mostly about GUI.

Meri said...

Hi Mansoor,

I have never done something like that. I do not even know whether it is easy or hard to do.

Eclipse plugins tend to be locked down, it may be hard to modify them. Eclipse keeps backward compatibility, so once they expose an API they have to maintain it. Plenty of useful functionality is hidden in internal packages and private classes.

But at worst, you may clone the default compilation unit editor and add new features to the clone.

Hari said...

Hi,

I'm getting this error '(Path: 'org.eclipse.jdt.ui.source.menu' is invalid)' when I tried using Action Framework from ur post.

Do u have any solution for this ?

Meri said...

Hi Hari,

does the menu item works correctly? If not, what Eclipse version do you use?

My menu item works correctly, but produces similar error log. I found only one helpful discussion about this problem. That discussion suggests also workaround, but I did not tried it.

Ahmed Yehia said...

Hi Meri,

You have done a gr8 job !!
Waiting for part 2 :)

Sachin said...

Hi Meri can you tell me How to create a Simple Plugin to automate bug fix before running a piece of simple code like "Hello World". Am new to Java Plugins.

Thanks

Anonymous said...

Hi Meri,
Can you tell me why there is no 'main method'? if there is no main method, how is the execution sequece determined.

Regards
Ria

Anonymous said...

Hello ,
Thanks for your valuable topic :)
I have two questions please
how can I add the menu to the right click of the the project menu ?
The second is how can I search for a file in an open project ?

Regards

Abhinandan said...

Great article...
Can you answer this question I posted ?
http://stackoverflow.com/questions/12986625/eclipse-plugin-development-adding-a-menu-on-right-click-on-tab-of-editor

Meri said...

@Anonymous I'm not sure what do you mean by "right click of the project menu"? What exactly should I do to see it?

As for search there are two APIs you can have a look at:

* org.eclipse.search.ui - search related user interface,
* org.eclipse.jdt.core.search - search itself.

I did not found any good tutorial on how to use them. This is all I found:
* intro documentation
* bug discussion 1
* bug discussion 2

If these are not enough, you will have to look into existing code to see how they work.

Good luck :)

Meri said...

@Abhinandan I'm sorry, but I never tried to do that. Fortunately, somebody else knew and answered in the meantime.

Anonymous said...

Hey Meri, thanks for the great tutorial!

I have a bunch of request/response XML that gets printed out in the console of my eclipse running a J2EE app. How difficult do you think it would be to create a plugin that essentially sifts through the console output searching for the start and end of every XML document that may be there, and concurrently opens a new tab in eclipse printing out the very same XML IN proper indented format?

-SJ

Meri said...

Hi,

that should not be difficult at all. You need to:
* read what is written into console,
* open xml editor for each found xml.

Console: Add org.eclipse.ui.console into yours plu-in dependencies. Its API is described here.

You can use the console grep project as an example, it is open source.

Editor: Once you have xml, opening an editor should be more or less easy. Here is short tutorial on how to do it.

Anonymous said...

Dear Meri,

Thanks so much for the prompt response! I'll try to put this together in a week's time when I get some free time this weekend and the next. Thanks also for pointing out the plugin dependencies and the tutorial!

Will keep you updated on progress!
Cheers,
SJ

Unknown said...

Your article is by far the best I've found so far on the net. Simple Steps through a minefield full of confusing details. Thank you.

Anonymous said...

Dear Meri,

Congratulations for the post. It's well written and very well structured. The concepts are explained at the right time along with examples that evolve at the right pace. It's an excellent tutorial for a complicated subject. Had this tutorial being ranked higher on Google it would save a lot of time for a lot of developers out there.

Cheers

JustAnotherBlogger said...

Hi,
This is a very nice tutorial.
With regard to editors i have a question.
How does editors does processing, say when it highlights a particular area does it line by line read all the contents in the file??

Anonymous said...

Hello hari....

Great tutorial so far I have read on eclipse -plugins.
I am waiting for your second part.

Anonymous said...

Hello Meri, there is any change that you alredy finish the part 2 of this tutorial, is perfect for me I am a beginner trying to understand all about the plugin development in Eclipse. Thanks a lot for all your contribution in advance.....

Meri said...

@Anonymous Sorry, it is not coming out in the near future. What I wrote was lost in hard drive crash and I got distracted by other projects. It takes a lot of time to write these things, so even if you would start again now, it would take months.

Good news is that changing Abstract Syntax Tree or Java Model is easier then dealing with GUI parts. The core is well documented and there are good articles about AST out there. If you put "eclipse framework Abstract Syntax Tree" or "eclipse framework Java Model" into google, the good article should on first or second page.

You can start here:
* Very good introduction which also lists a lot of resources is in Lars Vogel post. The post itself is a very good introduction.
* Detailed post about AST on Eclipse Corner.

Anonymous said...

this is not ur post and u have copied from some other blog..

Ramya said...

Hi it is very usefull for me i can understand this concept very well.Thank you.

Francis Shibin said...

Excellent post.
I am very new to this part of the word. I was just thinking of a specific requirement. When the developer clicks on the 'Run' button I need to run some script first after the script is completed the java project should start the compilation with the input received from the script. How can I do this? Is that possible? Thanks in advance

Unknown said...

Interesting post. Thanks for sharing with us.

Popup builder for magento

James Sand said...

well, you have written a masterpiece and i must appreciate the work you are doing. You are spreading this type of information which is very much valuable for the people. Much Appreciated. Keep posting this type of information.
Seo Expert In pakistan
Wijdan Shahid

Krogerexperiencee said...

hey i loved your site layout and especially the way you wrote everything. I must say that you keep posting this type of information so that we may see the latest news.
tellthebell

Anna said...

Thanks for sharing a ton of information. Being a digital marketing agency we are always keen to know new technologies and stuff for our clients. Seo experts in Pakistan

umeranees said...

Keep rocking!
great article, I was very impressed about it, wish you would have stayed next click umeranees

ReviewitbySaba said...

wow.. that's looks too easy... Thank you for sharing

Hunza Tour Packages

jerrysproductreviews said...

Thanks for the time you put into this article. This was an investment of your time that is of good use to your readers. www.vudu.com/watchfree

iphongthuy.net said...

iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet
iphongthuynet

wardah said...

"""I loved the post, keep posting interesting posts. I will be a regular reader...

hairclinic.pk

khadija said...

"I loved the post, keep posting interesting posts. I will be a regular reader...

hair transplant in pakistan

wardah said...

"""I loved the post, keep posting interesting posts. I will be a regular reader...

hair transplant pakistan

wardah said...

"""I loved the post, keep posting interesting posts. I will be a regular reader...

hair transplant in pakistan

wardah said...

I loved the post, keep posting interesting posts. I will be a regular reader...

Rent a car from Saifal Muluk lake

wardah said...

"I loved the post, keep posting interesting posts. I will be a regular reader...

Rent a car from Islamabad to Kashmir tour"

Uzair Hassan said...

"I loved the post, keep posting interesting posts. I will be a regular reader...

Rent a car from Islamabad to Kashgar

wardah said...

I loved the post, keep posting interesting posts. I will be a regular reader...

SEO Company London

Uzair Hassan said...

I loved the post, keep posting interesting posts. I will be a regular reader...

seo master

Uzair Hassan said...

"I loved the post, keep posting interesting posts. I will be a regular reader...

Seo Magician co uk

Anna said...

I’m really impressed with your blog article, such great & useful knowledge you mentioned here

Eye lens price in Pakistan

Abdul Hanan said...

Really it is a very nice topic and Very significant Information for us, I have think the representation of this Information is actually super one. . Google Shopping Ads

Arsalan said...

very good post.

new metro city kharian

jack tony said...

I really like your work and thanks a lot because its help me a lot Instagram affiliate marketing

Sana Shaheen said...

Great Article, i was really confused about this but because of the information provided i can easily make a decision now. new metro city

Neutral News said...

How can I add the menu to the right click on the project menu? new metro city

Advanceroofingservices said...

Your blog is great! I really enjoyed reading it, it has helped me very muchRoofing Contractor / Contractors Bronx

Arsalan said...

beautiful Post.
Bahria Town Peshawar

Atif Zaman said...

Please share with us wonderful stuffs like this..
Travel and Tour master

Malik Editors said...

Dell Inspiron 15 3567 Core i5 Laptop

Anonymous said...

Pakistan travel agencies and other several travel activities have been stopped but I wish things get better so we can travel again.

Muhammad said...

Positive site, where did u think of the data on this posting? I'm satisfied I found it however, sick be inquiring soon to discover what extra posts you incorporate.Rent a car Rawalpindi

Muhammad said...

On the other hand, if you think you are knowledgeable about the city’s structure, you can opt for rent a car in Pakistan without driver and enjoy the ride around the city with your family on your own.Karachi to Islamabad rent a car Rent a car for Wedding in Islamabad



Muhammad said...

We offer quality Rent a car in Islamabad service at the most economical rates. We guarantee 100% customer satisfaction. This also helps us to retain our customers.

ramesh1313 said...

Nice information Android

Muhammad Kashif said...


Car Rental Islamabad Rent Car Islamabad offers one of the most professional car rental services throughout Islamabad.

lens pk said...

I was reading your contents and writing and found a lot of information. Keep posting such contents for us.
bella amber

Annapolis Taxi Cabs said...


This is very good information, i would like to thanks for this blog. Thanks for sharing...
Car Rental Islamabad,Rent a Car in Islamabad,Rent a Car Islamabad

Muhammad said...

Hey, great blog, but I don’t understand how to add your site in my rss reader. Can you Help me please?Rent a car Islamabad

RCI Motors said...

You should take part in a contest for one of the best blogs on the web. I will recommend this site! Rent a Car Islamabad With Driver

Anonymous said...

I completely enjoyed reading your article.Thanks for sharing such a informative content. keep sharing such information! I'm also sharing some information if you are looking for the hunza valley tour packages then Pak Voyager provides Best tour packages
hunza valley tour packages
get in touch for more services...

Barret said...

Thank Your for sharing such a useful experience .. t If you want to visit Pakistan.. do Visit Hunza with Hunza Tour Packages we provide the best Tour services in Pakistan
Let's go

Anonymous said...

I completely enjoyed reading your article.Thanks for sharing such an informative content. keep sharing such information! I'm also sharing some information if you are looking for the Swat Valley tour Packages then Pak Voyager provides Best tour packages
Swat Valley tour Packages
get in touch for more services...

Rent a car said...

Great job!
Visit : Rent a Car Islamabad

Rent a car said...

loved the post, keep posting interesting posts. I will be a regular reader..

This is very good information, i would like to thanks for this blog. Thanks for sharing...
Rent a Car Islamabad,Insured Car Rental Islamabad

Anonymous said...

advanceautoparts-com-survey

Nino Nurmadi , S.Kom said...

Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom
Nino Nurmadi, S.Kom

RENTLY said...

visit our website https://www.rently.pk/
Rently guarantees best car rental experience at lowest possible rates ever. So, rent a car for wedding in Karachi with driver through Rently. Our well-groomed and professional drivers make sure your experience remains par excellence. Our whole process is secure, easy and with no hassle. Cars are always delivered at your doorstep.

Rent Luxury Limo said...

Rent Luxury Limo provide you with the best limo service in Washington DC, Maryland, Virginia, California, New York and New Jersey.
Limo Feet

aarondevin said...

What is Kroger Feedback survey? it a survey conducted by kroger to know visiters feedback about their store, Participate in kroger survey online and win amazing gifcards and coupons which later you can claim at the store.

Luxury Car rentals islamabad said...

"""Why Hamdan car rental service?
rent a car islamabad
Hamdan car rental service is providing the best service all over Pakistan Karachi Lahore Islamabad Multan Faisalabad Peshawar Quetta Sukkur Sahiwal Abbottabad Mansehra Haripur Murree Naran Kagan Hunza Gilgit Balochistan Chicha Watani Hyderabad China Border Kashmir Malakand And More Areas. Hamdan Rent Car is available with the largest flat service in Pakistan. Rent a car in islamabad"""

vstlove said...


I am very impressed with your post because this post is very beneficial for me and provide a new knowledge to me
instance Plugin

Anonymous said...

If you are running a business or a company and have access to a website, whether small, medium, or big, you need to perform SEO – Search Engine Optimization to grow your business organically. With the correct tactics and techniques, you can steadily improve your business’s online presence, even if it’s domestically or globally. However, designing a website or a web portal is easy with the help of tools and technologies. The hurdles come when your website needs organic reach. For this purpose, you need the digital marketing companies ​to check the technical SEO of your website schema markups pages, loading speed, H tags and offer you the best SEO – search engine optimization services. “Additionally, Bright Edge stated in one of its articles, 53.3 % of traffic on the website comes from organic research, and 50% of revenue comes from this organic traffic. Get a read on seo companies in Pakistan

Freeappforyou said...

thanks for share this informatin with us CHAUFFEUR SERVICES

rohit said...

I did go through the article and would appreciate the efforts of the writer to share such an insightful and well-researched article. keep doing it
best hr management software

moeezrentacar said...

Welcome to Moeez, rent-a-car place where every traveler can hire a perfect car to travel across the cities of Pakistan in style and comfort. We deal in all kind of cars to make your trip comfortable.


https://moeezrentacar.com/

Couponsavinguae said...

Thank you for posting this blog and I hope keep posting it.

royaltaxipk said...

Very nice article and straight to the point. I don’t know if this is truly the best place to ask but do you folks have any idea where to get some professional writers? Thank you
XLi for rent in Islamabad

Anonymous said...

W offer thes best Hunza valley tour packages

Anonymous said...

We offer the best Neelum valley tour packages

Couponsavinguae said...

Thank you for sharing this post and i hope keep posting it.

Digital Tech said...

This is very good information, i would like to thanks for this blog. Thanks for sharing...
Read more:best tour packages in karachi

Anonymous said...

Good post
Hunza is a very beautiful place to visit in Pakistan. We also offer the best Hunza valley tour packages at Tour My Pakistan

Royal Car Rentals said...

Thanks for sharing your content here. We are here to help you to Rent a Car Islamabad.
. and all over the main cities of Pakistan.

Anonymous said...

it is so informative keep posting interesting posts
carpet in dubai

Anonymous said...

I have read your article and I am really impressed by your way of writing but let me tell you that Advocate Khurram Shahbaz is the best family lawyer in Lahore because he has the vast knowledge about the family laws of Pakistan.

Meshwork Digital said...

Choose from a wide range of color and transparent comfort contact lenses of the highest quality. Cosmetic and prescription lenses are available.

Mamoon Khan said...

3. Hotel Staff Uniforms in Rawalpindi:
Impress your guests with elegant and professionally designed hotel staff uniforms. We offer a wide selection of styles and colors to match the ambiance of your establishment, providing your staff with comfort and confidence to excel in their roles.

SAMIKSHA said...

ADULT SERVICES IN THIRUVANATHAPURAM

SAMIKSHA said...

ADULT SERVICES IN SILLIGURI

SAMIKSHA said...

ADULT SERVICES IN SILLIGURI

SAMIKSHA said...

NURU MASSAGE IN DELHI

Anna Thomas said...

Eclipse's extensibility is undoubtedly a key factor in its popularity among Java developers. Just as seamlessly as Eclipse plugins enhance your IDE, the best interior Fit-Out Company in UAE can elevate your living or workspace, effortlessly bringing your vision to life.

Anonymous said...

Everything is temporary except travelling so don't waste your time on useless things and travel with https://www.exploria.pk/tours/

orbeezgunreview said...

It was nice and the plugin is really helpful as i am using it on my site Orbeezgunreview

Post a Comment