Wednesday, April 3, 2013

Eclipse 4 Injecting a Resource Pool

Objective: Migrate of Eclipse 3.x shared images to e4

Requirements:
e4 Tooling (Eclipse Download)
e4 Tooling (Vogella Download) 

Example: The example can be obtained here
Level: Intermediate Basic e4, Understanding of OSGI and DI in e4, General Eclipse, RCP experience

Everything about Eclipse 4 is different than programming against the Eclipse 3.x. One example of this is about obtaining resources like images, colors and fonts.  Eclipse 4 is very good in exposing OSGI Services through Dependency injection and a service for getting resources is already defined in the e4 tooling.

To make this very concrete, here is an example of how to register resources which can be obtained through a so called IResourcePool.

What I needed was access to the shared images from the 3.x framework.
Typically these resources would be obtained with

ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
Image img = sharedImages.getImage(ISharedImages.IMG_OBJS_ERROR_TSK);

In e4 there is no PlatformUI singleton and as far as I investigated the images in IShatedImages are not available if pure e4 is chosen. So how do we deal with this? Well it turns out, the e4 tooling has a service which can be implemted to make resources available. How does it work?

The solution is like this:

First, define an OSGI service which looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.eclipse.e4.tools.resources.workbenchresourcess">
   <implementation class="org.eclipse.e4.tools.resources.WorkbenchResourceProvider"/>
      <service>
      <provide interface="org.eclipse.e4.tools.services.IResourceProviderService"/>
   </service>
   <properties entry="OSGI-INF/resources.properties"/>
</scr:component>


This file should be stored in a folder named OSGI-INF under the plugin root.
What it does.

  1. First it tells us that this service is an implementation of IResourceProviderService. This service is defined in org.eclipse.e4.tools.services so this plugin should be available through e4 tooling.
  2. The implementation of the service is named WorkbenchResourceProvider and looks like below. This class extends a convenient implementation, also from the e4 tooling named BasicResourceProvider. Our implementation only needs to define keys (static strings) which the service will use to find the resources. 
  3. The resources are found by binding the keys to a location in a file named resources.properties, which is also defined in the OSGI component. 
WorkbenchResourceProvider (This an extract, the example includes all keys which are in ISharedImages)

public class WorkbenchResourceProvider extends BasicResourceProvider {
 
 /**
     * Identifies the error overlay image.
     * @since 3.4
     */
    public final static String IMG_DEC_FIELD_ERROR = "IMG_DEC_FIELD_ERROR"; //$NON-NLS-1$

    /**
     * Identifies the warning overlay image.
     * @since 3.4
     */
    public final static String IMG_DEC_FIELD_WARNING = "IMG_DEC_FIELD_WARNING"; //$NON-NLS-1$

    /**
     * Identifies the default image used for views.
     */
    public final static String IMG_DEF_VIEW = "IMG_DEF_VIEW"; //$NON-NLS-1$

resources.properties
IMG_OBJS_ERROR_TSK=/icons/full/obj16/error_tsk.gif
IMG_OBJS_INFO_TSK=/icons/full/obj16/info_tsk.gif
IMG_OBJS_WARN_TSK=/icons/full/obj16/warn_tsk.gif

The example includes all images which are packaged with the plugin org.eclipse.ui
 Note: Not all keys are implemented in the resource.properties file. Please add missing keys at will.

How to use this service:

  1. Include the resources plugin as part of an rcp product or launch configuration. 
  2. Make sure the plugin is autostarted and that the start level is 0 or 1 so the service is available before the app tries to access it. 
  3. To use it in a class do the following: 

 @Inject
IResourcePool poolOfResources;
img = poolOfResources.getImageUnchecked(WorkbenchResourceProvider.IMG_OBJS_ERROR_TSK);


Perhaps the implementation of the resource service could be smarter and find the images by types as explained here this is also how the 3.x images are registered, but for now this works very well.


The example can be obtained here

Have fun!

What if it doesn't work

Very likely the OSGI service is not available when consulted. Make sure the service is available.
Note: Services can be consulted from the OSGI console.


What is the future of this

I don't know, but I think the resources from 3.x should be available for e4 apps. Follow the bug here

No comments:

Post a Comment