Resource Helpers

For a long time there has been one issue with the GATE Developer interface that has really annoyed me; the inability to add new items to the right click menu of a resource (that you didn't develop) without creating a new visual resource and opening that viewer. This is the reason that you can't run an application in GATE without having the application editor open (the editor adds the run option to the menu). I know from a few conversations that this has annoyed other people in the past as well.

Last year I added support for opening MediaWiki documents to GATE. The MediaWiki markup is used on a lot of wikis, including Wikipedia, so having support for it in GATE is really useful as we often end up processing some or all of Wikipedia. There are two main ways you might encounter MediaWiki markup. Firstly you might just have a piece of text with the markup embedded in it (e.g. the text copied out of the page editor on Wikipedia), but you are more likely to have an XML file containing the content of multiple articles in a single file. I added support for both options to GATE, but the support for multiple articles in a single XML file doesn't work very well; you can get the article content, but you lose the title and any other associated metadata. What I really wanted was to add a new option to all corpus resources that would allow you to properly populate the corpus from a MediaWiki XML dump file, but of course I couldn't (at least not without creating a pointless visual resource, and then the option would only be visible if the corpus viewer was open).

A few days ago I was thinking about this problem again when I had a burst of inspiration and realised that there was a fairly easy way to add support, for what I'm calling Resource Helpers, to GATE. Essentially I'm re-using the idea of a GATE resource being a tool (usually used to add items to the Tools menu) to allow any resource to provide items for the right-click menu of any other resource. This did require some minor changes to the core GATE code, so if you want to try this yourself you will need to use a nightly build (or a recent SVN checkout). There will eventually be some details in the userguide, but in essence all you need to know can be gleaned from the following simple example:

package gate.test;

import gate.Document;
import gate.Resource;
import gate.creole.metadata.AutoInstance;
import gate.creole.metadata.CreoleResource;
import gate.gui.MainFrame;
import gate.gui.NameBearerHandle;
import gate.gui.ResourceHelper;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JOptionPane;

@CreoleResource(name = "Resource Helper Test Tool",
  tool = true,
  autoinstances = @AutoInstance)
public class HelperTest extends ResourceHelper {

  @Override
  protected List<Action> buildActions(final NameBearerHandle handle) {
    // a list to hold any actions we want to add
    List<Action> actions = new ArrayList<Action>();

    // if the resource isn't a document then we are finished
    if(!(handle.getTarget() instanceof Document)) return actions;

    // create a new action that will add a menu item labelled "Helper Test"
    // which will show a simple message dialog box
    actions.add(new AbstractAction("Helper Test") {
      @Override
      public void actionPerformed(ActionEvent arg0) {
        JOptionPane.showMessageDialog(MainFrame.getInstance(),
          "Testing the resource helper for " +
            ((Document)handle.getTarget()).getName());
      }
    });

    // return the list of actions
    return actions;
  }
}

If you already understand how tool support in GATE works, then this should be easy to follow, but basically we are creating a new GATE resource that is marked as a tool, and a single instance of which is automatically created. The resource extends ResourceHelper which forces us to implement the single buildActions method. The example implementation of buildActions shown here, simply checks to see if we are being asked to help a Document instance, and if so adds a single new menu item, labelled "Helper Test", which when clicked pops up a dialog box showing the name of the document.

The one thing to note is that the buildActions method is only ever called once per resource as the return value is cached for performance reasons. If you want to have a truly dynamic menu then you will need to also look at overriding the the getActions method of ResourceHelper, but that is beyond the scope of this post.

Having added this new functionality, as you will have already guessed, I've now added a new "Populate from MediaWiki XML Dump" option to every corpus instance, you just need to load the MediaWiki document format plugin for it to appear.

0 comments:

Post a Comment