Wednesday, October 16, 2013

Using Command Parameter Value Convertes with Eclipse e4

This post describes how value converters for command parameters can be used in e4.

In e4, commands can have parameters. Each parameter has a value. When you specify theses values in the application model they are all strings.

Suppose you want to pass an Integer value for a command parameter. In your handler you would like to get the value injected as an Integer instance so that you do not need to perform the conversion in the handlers @CanExecute or @Execute method.

The necessary conversion can be done by the e4 framework before the handler is invoked. Take the following approach.

Implement the converter

Create a new class that inherits from org.eclipse.core.commands.AbstractParameterValueConverter. Implement the abstract methods. These are:

Object convertToObject(String parameterValue) and String convertToString(Object parameterValue)

In the convertToObject method convert the string value of the command parameter to an instance of the type you require. For String to Integer conversion this could be done by simple calling Integer.valueOf(parameterValue). The signature of the method declares to throw ParameterValueConversionException in case the conversion fails. Create an instance of this exception and throw it in case the parameter value cannot be converted. Unfortunately, this exception is currently (Kepler 4.3.1)  swallowed in the eclipse e4 framework so you won't have any idea why things are not working. You might want to log the problem for this reason right in the converter.

Now comes the tricky part. The convertToString method does not do the reverse of the convertToObject method (I thought so at first). It is called with the string value and needs to return a string. For simple String to Integer conversion you can just return the same string that is passed to the method. You might want to treat a null value different and return the string "null" for example.

Register the  converter

In the bundle that supplies the value converter extend the org.eclipse.ui.commands extension point and add a commandParameterType.

The commandParameterType has three properties: id, type and converter.

Choose an id that is specific to your bundle name. For the type enter the class name of the objects you want to convert the string value to, e.g. java.lang.Interger. The converter property takes the fully qualified class name of the class that is called to convert the value (the one you implemented before). The class must be in a package that is exported by the bundle.

Specify the TypeID for the Command Parameter

The last step is to specify the TypeID  for the command parameter in the application model. Each command parameter has a property TypeID that usually does not need to be filled with a value. If you want to make use of the converter just registered enter the ID of the commandParameterType you registered through the extension point above. Do not enter the type of the objects you want to convert to (e.g. java.lang.Integer).

Now the command parameter values should be converted automatically. Make sure to adjust the signature of your handler methods so that they are found and called.

For debugging purposed you can set a breakpoint in org.eclipse.core.commands.ParameterizedCommand.generateCommand(Command, Map) and of course in your converter class.