Chapter 15
Developing GATE [#]
This chapter describes the protocols to follow and other information for those involved in developing GATE.
15.1 Creating new plugins [#]
GATE provides a flexible structure where new resources can be plugged in very easily. There are three types of resources: Language Resource (LR), Processing Resource (PR) and Visual Resource (VR). In the following subsections we describe the necessary steps to write new PRs and VRs, and to add plugins to the nightly build. The guide on writing new LRs will be available soon.
15.1.1 Where to keep plugins in the GATE hierarchy
Each new resource added as a plugin should contain its own subfolder under the %GATEHOME%/plugins folder. A plugin can have one or more resources declared in its creole.xml file. Creole.xml specifies one or more resources and required parameters for each such resources. The file should reside under the subfolder created for the plugin. More information on creole.xml and how to declare parameters and attributes is explained later.
15.1.2 Writing a new PR [#]
Class Definition
Below we show a template class definition, which can be used in order to write a new Processing Resource.
package example; /** * Processing Resource */ public class NewPlugin extends AbstractProcessingResource implements ProcessingResource { /* * this method gets called whenever an object of this * class is created either from GATE GUI or if * initiated using Factory.createResource() method. */ public Resource init() throws ResourceInstantiationException { // here initialize all required variables, and may // be throw an exception if the value for any of the // mandatory parameters is not provided if(this.rulesURL == null) throw new ResourceInstantiationException("rules URL is null"); return this; } /* * this method should provide the actual functionality of the PR * (from where the main execution begins). This method * gets called when user click on the RUN button in the * GATE GUIs application window. */ public void execute() throws ExecutionException { // write code here } /* this method is called to reinitialize the resource */ public void reInit() throws ResourceInstantiationException { // reinitialization code } /* * There are two types of parameters * 1. Init time parameters values for these parameters need to be * provided at the time of initializing a new resource and these values are * not supposed to be changed. * 2. Runtime parameters - values for these parameters are provided at the time * of executing the PR. These are runtime parameters and can be * changed before starting the execution * (i.e. before you click on the "RUN" button in the GATE GUI) * It is must to provide setter and getter methods for every such * parameter declared in the creole.xml. * * for example to set a value for outputAnnotationSetName */ String outputAnnotationSetName; //getter and setter methods /* get<parameter name with first letter Capital> */ public String getOutputAnnotationSetName() { return outputAnnotationSetName; } public void setOuputAnnotationSetName(String setName) { this.outputAnnotationSetName = setName; } /** Init-time parameter */ URL rulesURL; // getter and setter methods public URL getRulesURL() { return rulesFile; } public void setRulesURL(URL rulesURL) { this.rulesURL = rulesURL; } } |
PR Creole Entry
When writing a new resource entry in the creole.xml file, the user should provide details of the class that implements the new PR and its runtime and inittime parameters. The user can also specify other things such as the icon to be used in the resource tree, along with the resource name and the jar it belongs to.
<?xml version="1.0"?> <CREOLE-DIRECTORY> <CREOLE> <RESOURCE> <!-- Name of the PR that appears in GATE PR List --> <NAME>An Example Plugin</NAME> <!-- Jar where to look for the resource --> <JAR>newplugin.jar</JAR> <!-- Underlying class that implements the New Plugin --> <CLASS>example.NewPlugin</CLASS> <!-- Comment that appears when mouse hovers over the PR Name --> <COMMENT>An example plugin that demonstrates how to write a new PR</COMMENT> <!-- Declaring various parameters--> <!-- PR need a document, which should be a runtime parameter --> <!-- Unless specified pa[sec:misc-creole:miniparrameters are manadatory --> <PARAMETER NAME="document" COMMENT="The document to be processed" RUNTIME="true">gate.Document</PARAMETER> <PARAMETER NAME="rulesURL" COMMENT="example of an inittime parameter" DEFAULT="resources/morph/default.rul" RUNTIME="false"> java.net.URL</PARAMETER> <PARAMETER NAME="outputAnnotationSetName" COMMENT="name of the annotationSet used for output" RUNTIME="true" OPTIONAL="true">java.lang.String</PARAMETER> </RESOURCE> </CREOLE> </CREOLE-DIRECTORY> |
Option Menu
Each resource (LR,PR) has some predefined actions associated with it. These actions appear in an options menu that appears in the GATE GUI when the user right clicks on any of the resources. For example if the selected resource is a Processing Resource, there will be at least four actions available in its options menu: 1. Close 2. Hide this view 3. Rename and 4. Reinitialize. New actions in addition to the predefined actions can be added by implementing the gate.gui.ActionsPublisher interface. Then the user has to implement the following method.
public List getActions() { return actions; } |
Here the variable actions should contain a list of instances of type javax.swing.AbstractAction. A string passed in the constructor of an AbstractAction object appears in the Options Menu. Adding a null element adds a separator in the menu.
Listeners
There are at least four important listeners which should be implemented in order to listen to the various relevant events happening in the background. These include:
- CreoleListener
Creole-register keeps information about instances of various resources and refreshes itself on new additions and deletions. In order to listen to these events, a class should implement the gate.event.CreoleListener. Implenting CreoleListener requires users to implement the following methods:
- public void resourceLoaded(CreoleEvent creoleEvent);
- public void resourceUnloaded(CreoleEvent creoleEvent);
- public void resourceRenamed(Resource resource, String oldName, String newName);
- public void datastoreOpened(CreoleEvent creoleEvent);
- public void datastoreCreated(CreoleEvent creoleEvent);
- public void datastoreClosed(CreoleEvent creoleEvent);
- DocumentListener
A traditional GATE document contains text and a set of annotationSets. To get notified about changes in any of these resources, a class should implement the gate.event.DocumentListener. This requires users to implement the following methods:
- public void contentEdited(DocumentEvent event);
- public void annotationSetAdded(DocumentEvent event);
- public void annotationSetRemoved(DocumentEvent event);
- AnnotationSetListener
As the name suggests, Annewplugin.texnotationSet is a set of annotations. To listen to the addition and deletion of annotations, a class should implement the gate.event.AnnotationSetListener and therefore the following methods:
- public void annotationAdded(AnnotationSetEvent event);
- public void annotationRemoved(AnnotationSetEvent event);
- AnnotationListener
Each annotation has a featureMap associated with it, which contains a set of feature names and their respective values. To listen to the changes in annotation, one needs to implement the gate.event.AnnotationListener and implement the following method:
- public void annotationUpdated(AnnotationEvent event);
15.1.3 Writing a new VR [#]
Each resource (PR and LR) can have its own associated visual resource. When double clicked, the resource’s respective visual resource appears in the GATE GUI. The GATE GUI is divided into three visible parts (See Figure 15.1). One of them contains a tree that shows the loaded instances of resources. The one below this is used for various purposes - such as to display document features and that the execution is in progress. This part of the GUI is referred to as ”small”. The third and the largest part of the GUI is referred to as ”large”. One can specify which one of these two should be used for displaying a new visual resource in the creole.xml.
|
Class Definition
Below we show a template class definition, which can be used in order to write a new Visual Resource.
package example.gui;
/* * An example Visual Resource for the New Plugin * Note that here we extends the AbstractVisualResource class */ public class NewPluginVR extends AbstractVisualResource { /* * An Init method called when the GUI is initialized for the first time */ public Resource init() { // initialize GUI Components return this; } /* * Here target is the PR class to which this Visual Resource Belongs to * this method is called after the init() method */ public void setTarget(Object target) { // check if the target is an instance of what you expected // and initialize local data structures if required } } |
Every document has its own document viewer associated with it. It comes with a single component that shows the text of the original document. GATE provides a way to attach new GUI plugins to the document viewer. For example AnnotationSet viewer, AnnotationList viewer and Co-Reference editor. These are the examples of DocumentViewer plug-ins shipped as part of the core GATE build. These plugins can be displayed either on the right or on top of the document viewer. They can also replace the text viewer in the center (See figure 15.1). A separate button is added at the top of the document viewer which can be pressed to display the GUI plug-in.
Below we show a template class definition, which can be used to develop a new DocumentViewer plugin.
/* * Note that the class needs to extends the AbstractDocumentView class */ public class DocumentViewerPlugin extends AbstractDocumentView { /* Implementers should override this method and use it for populating the GUI. */ public void initGUI() { // write code to initialize GUI } /* Returns the type of this view */ public int getType() { // it can be any of the following constants // from the gate.gui.docview.DocumentView // CENTRAL, VERTICAL, HORIZONTAL } /* Returns the actual UI component this view represents. */ public Component getGUI() { // return the top level GUI component } /* This method will be called whenever the view becomes active.*/ public void registerHooks() { // register listeners } /* This method will be called whenever this view becomes inactive. */ public void unregisterHooks() { // do nothing } } |
VR Creole Entry
As mentioned earlier, a VR needs to be associated with some PR or LR and therefore the creole entry for Visual Resource should specify the visual resource it belongs to. Below we extend the creole.xml explained in the previous section by adding an entry for the NewPluginVR.
<?xml version="1.0"?>
<CREOLE-DIRECTORY> <CREOLE> <RESOURCE> <!-- Name of the PR that appears in GATE PR List --> <NAME>An Example Plugin</NAME> <!-- Jar where to look for the resource --> <JAR>newplugin.jar</JAR> <!-- Underlying class that implements the New Plugin --> <CLASS>example.NewPlugin</CLASS> <!-- Comment that appears when mouse hovers over the PR Name --> <COMMENT>An example plugin that demonstrates how to write a new PR</COMMENT> <!-- Declaring various parameters--> <!-- PR need a document, which should be a runtime parameter --> <!-- Unless specified parameters are manadatory --> <PARAMETER NAME="document" COMMENT="The document to be processed" RUNTIME="true">gate.Document</PARAMETER> <PARAMETER NAME="rulesURL" COMMENT="example of an inittime parameter" DEFAULT="resources/morph/default.rul" RUNTIME="false"> java.net.URL</PARAMETER> <PARAMETER NAME="outputAnnotationSetName" COMMENT="name of the annotationSet used for output" RUNTIME="true" OPTIONAL="true">java.lang.String</PARAMETER> </RESOURCE> <!-- New PluginVR entry --> <RESOURCE> <NAME>Visual Resource for New Plugin</NAME> <!-- Jar where to look for the resource --> <JAR>newplugin.jar</JAR> <!-- Class that implements the VR --> <CLASS>example.gui.NewPluginVR</CLASS> <!-- type values can be "large" or "small" --> <GUI TYPE="large"> <MAIN_VIEWER /> <!-- Target it belongs to (i.e. Name of the class this new VR associated with --> <RESOURCE_DISPLAYED>example.NewPlugin </RESOURCE_DISPLAYED> </GUI> </RESOURCE> </CREOLE> </CREOLE-DIRECTORY> |
15.1.4 Adding plugins to the nightly build [#]
As of November 2005, GATE plugins are now built every night as part of the nightly build process.
If you add a new plugin and want it to be part of the build process, you should create a build.xml file with targets ”build”, ”test”, ”distro.prepare” and ”clean”. The build target should build the JAR file, test should run any unit tests, distro.prepare should clean up any intermediate files (e.g. the classes/ directory) and leave just what’s in Subversion, plus the compiled JAR file. The clean target should clean up everything, including the compiled JAR and any generated sources, etc. You should also add your plugin to ”plugins.to.build” in the top-level build.xml to include it in the build. This is by design - not all the plugins have build files, and of the ones that do, not all are suitable for inclusion in the nightly build (viz. SUPPLE, section 9.12).
Note that if you are currently building gate by doing ”ant jar”, be aware that this does not build the plugins. Running just ”ant” or ”ant all” will do so.
There are some changes you will notice as a result of all this:
- You may suddenly find some plugins stop working when you update to the latest svn revision, as their JAR files have been removed. Solution: update the top-level GATE build.xml file and then run ”bin/ant plugins.build” in the GATE directory to rebuild the missing JARs.
- If you have your own modified version of any of the affected plugins you will get a conflict for the JAR file when you update, saying something like ”move away MiniparWrapper.jar, it is in the way”. Solution: rename the offending JAR file, then svn update again and finally rename it back.
15.2 Updating this User Guide [#]
The GATE User Guide is maintained in the GATE subversion repository at SourceForge. If you
are a developer at Sheffield you do not need to check out the userguide explicitly, as it will appear
under the tao directory when you check out sale. For others, you can check it out as follows:
svn checkout https://svn.sourceforge.net/svnroot/gate/userguide/trunk userguide
The user guide is written in LATEX and translated to PDF using pdflatex and to HTML using tex4ht. The main file that ties it all together is tao_main.tex, which defines the various macros used in the rest of the guide and \inputs the other .tex files, one per chapter.
15.2.1 Building the User Guide [#]
You will need:
- A standard POSIX shell environment including GNU Make. On Windows this generally means Cygwin, on Mac OS X the XCode developer tools and on Unix the relevant packages from your distribution.
- A copy of the userguide sources (see above).
- A LATEX installation, including pdflatex if you want to build the PDF version, and tex4ht if you want to build the HTML. MiKTeX should work for Windows, TeTeX (available in fink) for Mac OS X, or your choice of package for Unix.
- The BibTeX database big.bib. It must be located in the directory above where you have checked out the userguide, i.e. if the guide sources are in /home/bob/svn/userguide then big.bib needs to go in /home/bib/svn. Sheffield developers will find that it is already in the right place, under sale, others will need to download it from http://gate.ac.uk/sale/big.bib.
- A bit of luck.
Once these are all assembled it should be a case of running make to perform the actual build. To build just the PDF do make tao.pdf, for just the HTML do make index.html.
The PDF build generally works without problems, but the HTML build is known to hang on some machines for no apparent reason. If this happens to you try again on a different machine.
15.2.2 Making changes to the User Guide [#]
To make changes to the guide simply edit the relevant .tex files, make sure the guide still builds (at least the PDF version), and check in your changes to the source files only. Please do not check in your own built copy of the guide, the official user guide builds are produced by a nightly cron job in Sheffield running on a known-good system.
If you add a section or subsection you should use the \sect or \subsect commands rather than the normal LaTeX \section or \subsection. These shorthand commands take an optional first parameter, which is the label to use for the section and should follow the pattern of existing labels. The label is also set as an anchor in the HTML version of the guide. For example a new section for the “Fish” plugin would go in misc-creole.tex with a heading of:
\sect[sec:misc-creole:fish]{The Fish Plugin}
|
and would have the persistent URL http://gate.ac.uk/cgi-bin/userguide/sec:misc-creole:fish.
If your changes are to document a bug fix or a new (or removed) feature then you should also add an entry to the change log in changes.tex. You should include a reference to the full documentation for your change, in the same way as the existing changelog entries do. You should find yourself adding to the changelog every time except where you are just tidying up or rewording existing documentation.
Finally, you’ll have to wait until the next morning (UK time) for your changes to be reflected in the online version of the guide.