Building a recordable plugin

From Bioclipse
Jump to: navigation, search
Development tutorial
Responsible author:jonalv
Bioclipse version:pre 2.4
Last updated:2011-07-21
Tags:


UPDATE: Use the Bioclipse SDK plugin instead which does all this and some other stuff for you automagicly!

Introduction

It is possible to record user events (such as user writing a script command or clicking some GUI) in Bioclipse2 and store this in an Action History from which it is possible to generate scripts and re-run events. We see this as progress towards the state where you can work in Bioclipse to drill down to desired functionality, and then just exchange the script with others.

Technologies

Spring

In order to easily be able to do the recording we will use Spring, more exactly AOP. This means that we can write our Manager class without caring about how it will be recordable.

Annotations

In order for a method to be recorded, the annotation @Recorded is put before the method declaration. Spring then matches only those methods decorated with this annotation.

OSGI

OSGI is a standard for a service platform that can be remotely managed. Eclipse uses equinox which is an implementation of the OSGI standard. Eclipse uses equinox to handle plugins. We will use the OSGI service registry as a container for our service objects (e. g. manager objects).

A minimal reference implementation

In _playground_ in the SVN repo there is a plugin net.bioclipse.springBasedPrototypePlugin which is a minimal plugin that publishes a manager. It can be used as a starting point. Here are a short description of the different parts of that plugin.

The Manager Classes

The methods that are to be recordable is implemented in one class but must also be defined in a corresponding interface.

The Spring configuration file

In the META-INF catalogue where the MANIFEST.MF file is located is a sub catalogue named spring. The spring extender plugin reads all xml files in this folder and instantiates the beans in them. I will not explain everything that can be written in this files but I will make an attempt to explain what is used in the context.xml in net.bioclipse.springBasedPrototypePlugin.

Here follows some explanation of what is going on:

 <osgi:reference id="recordingAdvice" 
                 interface="net.bioclipse.recording.IRecordingAdvice" />

Get the recording Advice service from the osgi service registry. It was put there by the net.bioclipse.recording plugin.

 <bean id="recordingAdvisor"
 		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
       <property name="advice"  ref="recordingAdvice" />
 		<property name="pattern" value=".*" />
 </bean>

Create a pointcut advice for the recording advice that will make sure the recording advice is run on all method calls

 <bean id="exampleManagerTarget" 
       class="net.bioclipse.springBasedPrototypePlugin.business.ExampleManager">
 </bean>

Instantiates our ExampleManager class

 <bean id="exampleManager" class="org.springframework.aop.framework.ProxyFactoryBean">
 	<property name="target" 
 	          ref="exampleManagerTarget" />
 	<property name="proxyInterfaces" 
 	          value="net.bioclipse.springBasedPrototypePlugin.business.IExampleManager" />
 	<property name="interceptorNames"
 	          value="recordingAdvisor" />
 </bean>

Creates the proxy that will make sure that the recording advice gets runned for all methods on our manager. Notice that the net.bioclipse.springBasedPrototypePlugin.business.IExampleManager is used as proxy interface.

 <osgi:service id="exampleManagerOSGI" 
               ref="exampleManager"
               interface="net.bioclipse.springBasedPrototypePlugin.business.IExampleManager" />

Publishes the example manager (the proxy) to the osgi service registry

The Activator

The Activator also contains a few special things. In the start method:

 finderTracker = new ServiceTracker( context, 
                                     IExampleManager.class.getName(), 
                                     null );
 finderTracker.open();

And in a method, getExampleManager():

 IExampleManager exampleManager = null;
 try {
 	exampleManager = (IExampleManager) finderTracker.waitForService(1000*30);
 } catch (InterruptedException e) {
 	throw new IllegalStateException("Could not get example manager", e);
 }
 if(exampleManager == null) {
 	throw new IllegalStateException("Could not get example manager");
 }
 return exampleManager;

What's going on here is that we are getting the ExampleManager the we published to the service registry in the last xml boc above. So this method returns a manager object and all calls to methods of it will be recorded.

The Manager Factory

Next we need to give this manager object to the scripting plugin so that it know about it. This is done through an extension point. This is is done by an Eclipse defined factory class which when asked to build the object to the extension point simply fetches the object from the OSGI container via the Activator and returns it.

The plugin.xml file

Finally in the plugin.xml we give the factory class as service to the scriptContribution extension point.


See also: How to make a manager