%% LaTeX Beamer presentation template (requires beamer package)
%% see http://latex-beamer.sourceforge.net/
%% idea contributed by H. Turgut Uyar
%% template based on a template by Till Tantau
%% this template is still evolving - it might differ in future releases!


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%  Uncomment version below for creating normal slides  %%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass[c]{beamer}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\mode<presentation>

\newif\ifsolutions

% Swap this to solutionstrue to include solution slides for the hands-on
% exercises
\solutionstrue
%\solutionsfalse

% Set up an \omitfromhandout command to specify slides that should be omitted
% when generating the handout.
\makeatletter
\newwrite\tf@ofh
\immediate\openout\tf@ofh\jobname.ofh
\makeatother

\newcommand{\omitfromhandout}{\addtocontents{ofh}{\thepage}}

\renewcommand<>{\omitfromhandout}[0]{{\only#1{\beameroriginal{\omitfromhandout}}}}

%\ Make sure the GATE theme is used
\usetheme{GATE}
\input{slides-preamble}
\setbeamerfont{alerted text}{series=\bfseries}

\title{Creating new Resource Types}
\subtitle{Module 8, part 2}

% - Use the \inst{?} command only if the authors have different
%   affiliation.
%\author{F.~Author\inst{1} \and S.~Another\inst{2}}
%\author{\inst{1}}

% - Use the \inst command only if there are several affiliations.
% - Keep it simple, no one is interested in your street address.
%\institute{University of Sheffield}

% This is only inserted into the PDF information catalog. Can be left
% out.
\subject{Creating new Resource Types}

% If you have a file called "university-logo-filename.xxx", where xxx
% is a graphic format that can be processed by latex or pdflatex,
% resp., then you can add a logo as follows:

%\pgfdeclareimage[height=2cm]{university-logo}{../../images/logo.png}
%\logo{\pgfuseimage{university-logo}}



% Delete this, if you do not want the table of contents to pop up at
% the beginning of each subsection:
\AtBeginSubsection[]
{
\begin{frame}<beamer>
\frametitle{Outline}
\tableofcontents[currentsection, currentsubsection]
\end{frame}
}

% If you wish to uncover everything in a step-wise fashion, uncomment
% the following command:

%\beamerdefaultoverlayspecification{<+->}

\begin{document}

\begin{frame}
\omitfromhandout
\titlepage
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{Outline}
\tableofcontents
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{CREOLE Metadata}
\subsection{CREOLE Recap}


\begin{frame}{CREOLE}
The GATE component model is called CREOLE ({\bf C}ollection of {\bf RE}usable
{\bf O}bjects for {\bf L}anguage {\bf E}ngineering).

\begin{block}{CREOLE uses the following terminology:}
\begin{itemize}
  \item {\bf CREOLE Plugins}: contain definitions for a set of resources.
  \item {\bf CREOLE Resources}: Java objects with associated configuration.
  \item {\bf CREOLE Configuration}: the metadata associated with Java classes
  that implement CREOLE resources.
\end{itemize}
\end{block}
\end{frame}%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{CREOLE Plugins}
CREOLE is organised as a set of plugins. 

\begin{block}{Each CREOLE plugin:}
\begin{itemize}
  \item is identified by a ``loction'' at which it can be found
  \item contains a special file called {\tt creole.xml};
  \item contains the definitions for a set of CREOLE resources.
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{CREOLE Plugins}

\begin{block}{A plugin can be located by...}
\begin{itemize}
  \item a directory URL (the old way)
  \item Maven coordinates (the new way)
  \item custom (outside scope of this talk)
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{CREOLE Plugins}
A typical {\tt creole.xml}:
\begin{lstlisting}[language=XML, basicstyle=\scriptsize\ttfamily, escapechar=|]
<CREOLE-DIRECTORY>
	<REQUIRES
		GROUP="uk.ac.gate.plugins"
		ARTIFACT="annie" 
		VERSION="8.6"/>
</CREOLE-DIRECTORY>
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{CREOLE Resources}
A CREOLE resource is a Java Bean with some additional metadata.
\begin{block}{A CREOLE resource class:}
\begin{itemize}
  \item must implement the \lstinline!gate.Resource! interface (or one of its
    sub-interfaces \lstinline!LanguageResource!,
    \lstinline!ProcessingResource!, \lstinline!VisualResource! or
    \lstinline!Controller!);
  \item must be annotated with \lstinline!@CreoleResource! to identify it as a
    resource class;
  \item must provide accessor methods for its parameters.
\end{itemize}
\end{block}
\end{frame}%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{CREOLE Annotations: @CreoleResource}
The \lstinline!@CreoleResource! annotation takes attributes giving metadata:
\begin{description}
  \item [name] (String) the name of the resource.
  \item [comment] (String) a descriptive comment about the resource 
  \item [helpURL] (String) a URL to a help document on the web for this resource.
  \item [icon] (String) the icon to use to represent the resource in GATE Developer. 
\end{description}
\begin{block}{Example}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
@CreoleResource (name = "Document Stats", 
                 comment = "Calculates document statistics.")
public class DocStats extends AbstractLanguageAnalyser {
...
}
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{CREOLE Annotations: @CreoleResource}
\begin{block}{Attributes for Visual Resources}
If the resource being configred is a Visual Resource, you can also use the
following attributes: 
\begin{description}
  \item [guiType] (GuiType enum) the type of GUI this resource defines.
  \item [resourceDisplayed] (String) the class name of the resource type that
  this VR displays, e.g. "gate.Corpus".
  \item [mainViewer] (boolean) is this VR the {\em most important} viewer for
  its displayed resource type?
\end{description}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Creating CREOLE Resources}

\subsection{Your First Language Analyser}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\begin{frame}[fragile, t]{\color{gate-dark-green} Exercise 1: Create an Empty
Processing Resource}
\begin{block}{Create a new GATE plugin containing a sample PR}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
mvn archetype:generate \
	-DarchetypeGroupId=uk.ac.gate \
	-DarchetypeArtifactId=gate-pr-archetype \
	-DarchetypeVersion=8.6
\end{lstlisting}
\end{block}
\begin{itemize}
  \item follow the on screen prompts
  \item make sure it compiles; \lstinline!mvn install!
  \item make sure you can load it into GATE
  \begin{itemize}
    \item use the group ID, artifact ID, and version number you specified to add it to the plugin manager
  \end{itemize}
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile, t]{\color{gate-dark-green} Exercise 1 (part 2):
Implementation}
\begin{block}{Implement:}
\begin{lstlisting}
public Resource init() 
  throws ResourceInstantiationException { }
\end{lstlisting}
\ldots to print out a message;
\end{block}
\begin{block}{Implement:}
\begin{lstlisting}
public void execute() throws ExecutionException { }
\end{lstlisting}
\ldots to count the number of Token annotations in the input document, and set
the value as a feature on the document.
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile, t]{\color{gate-dark-green} Exercise 1: Solution}
\omitfromhandout<1>
{\color{gate-light-red} Try not to use this!}
\pause
\begin{lstlisting}[basicstyle=\tiny\ttfamily]
package module8;

import gate.Resource;
import gate.creole.*;
import gate.creole.metadata.*;

@CreoleResource
public class DocStats extends AbstractLanguageAnalyser {

  @Override
  public void execute() throws ExecutionException {
    int tokens = document.getAnnotations().get("Token").size(); 
    document.getFeatures().put("token_count", tokens);
  }

  @Override
  public Resource init() throws ResourceInstantiationException {
    System.out.println(getClass().getName() + " is initialising.");
    return this;
  }
}
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Best Practice}

\begin{frame}{Best Practice: Use Parameters!}
\begin{itemize}
  \item Do not hardcode values, specify them as parameters.
  \item Values that change internal data structures, built when the PR is
  created, should be {\tt init-time} parameters. These cannot be changed once
  the PR was created.
  \item Values that can be changed between executions should be {\tt run-time}
  parameters.
  \item Try to make as many parameters as possible into {\tt run-time}
  parameters!
  \item Provide {\em sensible defaults} for most parameters.
  \item If you have too many init-time parameters, use a config file instead!
  \item If you have too many run-time parameters, provide a Visual Resource!
  \item Make sure the parameters are well documented! 
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{Best Practice: Input/Output}
\begin{block}{Specify Input/Output!}
\begin{itemize}
  \item If your PR uses annotations, always specify input and output
  annotation sets:
  \item use a parameter {\tt inputASName} for the input annotation set name;
  \item use a parameter {\tt outputASName} for the output annotation set name;
\end{itemize}
{\bf OR}
\begin{itemize}
  \item use a parameter named {\tt annotationSetName} (if the PR only
  modifies existing annotations).
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Defining Parameters}
Creole parameters are Java Bean properties (a pair of get/set methods), with
{\tt @CreoleParameter} annotations on the {\bf setter} method. Main
attributes include:
\begin{description}
  \item [comment] (String) an optional descriptive comment about the parameter.
  \item [defaultValue] (String) the optional default value for this parameter.
  \item [suffixes] (String) for URL/ResourceReference-valued parameters, a
    semicolon-separated list of default file suffixes that this parameter
    accepts.
\end{description}
\begin{block}{Example}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]

  @CreoleParameter(
          comment="The name for the input annotation set.")
  public void setInputASName(String inputAsName) {
    this.inputAsName = inputAsName;
  }
\end{lstlisting}

\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{CREOLE Annotations: Parameter Types}
You can also use the following annotations to mark the type of a CREOLE
parameter:
\begin{description}
\item[@Optional] for parameters that are not required.
\item[@RunTime] for run-time parameters. 
\end{description}
\begin{block}{Corrected Example}
\begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
  @Optional
  @RunTime
  @CreoleParameter(
      comment="The name for the input annotation set.")
  public void setInputASName(String inputAsName) {
    this.inputAsName = inputAsName;
  }
\end{lstlisting}
\end{block}
{\color{gate-light-green} TIP: }More info at
\href{http://gate.ac.uk/userguide/sec:creole-model:config}{http://gate.ac.uk/userguide/sec:creole-model:config}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}{\color{gate-dark-green} Exercise 2: Develop/Test Cycle }
Change the implementation from {\em Exercise 1} to:
\begin{itemize}
  \item add proper metadata on the resource class;
  \item use a parameter for the input annotation set;
  \item use a parameter for the {\tt Token} annotation type;
  \item make sure these parameters have good defaults, and documentation;
\end{itemize}
\begin{block}{Test it!}
\begin{itemize}
  \item Start GATE Developer, load a document, create an instance of the
  Unicode Tokeniser;
  \item load your CREOLE plugin, create an instance of your
  PR; create a Corpus Pipeline and add the two PRs to it;
  \item run the pipeline over the document and check it works.
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{\color{gate-dark-green} Exercise 3: Better Statistics}
Change the implementation from {\em Exercise 2} to also calculate counts for
all {\bf words}, all {\bf nouns}, all {\bf verbs}.

{\color{gate-light-green} TIPs:}\\
You will need to run a Sentence Splitter, and POS Tagger after the Tokeniser,
in order to get the part-of-speech information.

Definitions:
\begin{description}
  \item[word] \verb!{Token.kind=="word"}!
  \item[noun] POS tag starts with ``NN''
  \item[verb] POS tag starts with ``VB''
\end{description}
POS tag is \lstinline!tok.getFeatures().get("category")!

\begin{block}{Test it!}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{Ready Made Applications}

\begin{frame}{Ready Made Applications}
\begin{itemize}
\item Many CREOLE plugins contain one or more example applications
\begin{itemize}
\item they may be used to show how the processing resources can be used
\item some plugins might only contain applications, i.e. the language plugins
\end{itemize}
\item Making these applications easily available through the GUI will make your
      processing resources easier for others to use
\item Example applications can easily be added to the \emph{Ready Made Applications}
      menu by creating an instance of \lstinline!gate.creole.PackagedController!
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Packaged Controller API}
\begin{itemize}
\item Packaged Controllers extend the \lstinline!gate.creole.PackagedController! class
\begin{lstlisting}[texcl]
/** the location of the pipeline XGAPP file */
public ResourceReference getPipelineURL();

/** the menu under which the application appears */
public List<String> getMenu();
\end{lstlisting}
\item \lstinline!gate.creole.PackagedController! is also a GATE resource so we can provide
these values using CREOLE annotations
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Example: Chinese IE}
\begin{lstlisting}[basicstyle=\tiny\ttfamily]S
package chinese;

import gate.creole.PackagedController;
import gate.creole.metadata.AutoInstance;
import gate.creole.metadata.AutoInstanceParam;
import gate.creole.metadata.CreoleParameter;
import gate.creole.metadata.CreoleResource;

import java.net.URL;
import java.util.List;

@CreoleResource(name = "Chinese IE System", icon = "ChineseLanguage",
   autoinstances = @AutoInstance(parameters = {
      @AutoInstanceParam(name="pipelineURL", value="resources/chinese.gapp"),
      @AutoInstanceParam(name="menu", value="Chinese")}))
public class ChineseIE extends PackagedController {
   //all without writing any code!
}
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{\color{gate-dark-green} Exercise 4: Show Off Your New Plugin}
\begin{itemize}
  \item create, and save, an application that shows how to use your statistics PR
  \item create a \lstinline!gate.creole.PackagedController! instance to make the
        application available through the GUI.
\end{itemize}
You can use the Chinese IE example as a starting point.
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Advanced CREOLE}
\subsection{CREOLE Management}

\begin{frame}{The CREOLE and DataStore Registers}
\begin{block}{The CREOLE Register}
\begin{itemize}
  \item Stores all CREOLE data, including:
  \begin{itemize}
    \item which plugins are loaded;
    \item which types of CREOLE Resources have been defined;
    \item loaded instances of each resource type;
    \item which Visual Resources can display any resource type;
  \end{itemize}
  \item fires events when resources are loaded and deleted;
  \item forwards all events from the DataStore Register (see below).
\end{itemize}
\end{block}
\begin{block}{The DataStore Register}
\begin{itemize}
  \item is a \lstinline!java.util.Set! of DataStore objects.
  \item fires events when datastores are created, opened and closed. 
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{CREOLE Register and its Events}
\begin{lstlisting}[texcl]
//Obtain a pointer to the CREOLE Register
CreoleRegister cReg = Gate.getCreoleRegister();
//listen to CREOLE events
cReg.addCreoleListener(new CreoleListener() {
  public void resourceUnloaded(CreoleEvent e) { ... }
  public void resourceRenamed(Resource resource, 
      String oldName, String newName) { ... }
  public void resourceLoaded(CreoleEvent e) { ... }
  public void datastoreOpened(CreoleEvent e) { ... }
  public void datastoreCreated(CreoleEvent e) { ... }
  public void datastoreClosed(CreoleEvent e) { ... }
});
//remove a registered listener
cReg.removeCreoleListener(aListener);
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Other CREOLE APIs}
\begin{block}{Plugins Management}
\begin{lstlisting}[texcl]
try {
  //load a Maven based plugin
  cReg.registerPlugin(new Plugin.Maven(...));
  // register a single resource class without using creole.xml
  cReg.registerPlugin(
    new Plugin.Component(MyResource.class));
} catch(GateException e1) { ... }
//get all loaded plugins
cReg.getPlugins();
//remove a loaded plugin
cReg.unregisterPlugin( ... );
// register to get notified when plugins are loaded or unloaded
cReg.addPluginListener( ... );
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Other CREOLE APIs (continued)}
\begin{block}{Find Loaded Resources}
\begin{lstlisting}[texcl]
//find all resources of a given type
try {
  cReg.getAllInstances("gate.LanguageAnalyser");
} catch(GateException e1) { ... }
\end{lstlisting}
\end{block}

\begin{block}{Resource Types}
\begin{lstlisting}[texcl]
cReg.getPrTypes();  //get PR types (class  names)
cReg.getLrTypes();  //get LR types (class  names)
cReg.getVrTypes();  //get VR types (class  names)
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Other CREOLE APIs (continued)}
\begin{block}{CREOLE Metadata}
\begin{lstlisting}[texcl]
//Obtain the Resource Data about a resource
ResourceData rData = cReg.get("resource.class.name");
//get the list of instances 
List<Resource> instances = rData.getInstantiations();
//get the list of parameters
ParameterList pList = rData.getParameterList();
//get the Init-time / Run-time parameters
List<List<Parameter>> someParams;
someParams = pList.getRuntimeParameters();
someParams = pList.getInitimeParameters();
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{\color{gate-dark-green} Exercise 5: CREOLE Metadata}
\begin{itemize}
  \item load the ANNIE application;
  \item find out which plugins are loaded;
  \item find out which PR \textbf{instances} exist;
  \item find out which PR types are known to the system;
	\item find out what parameters they have.
\end{itemize}

\begin{block}{You may find this useful:}
\begin{lstlisting}[texcl]
  Gate.init();
  Plugin annie = new Plugin.Maven(
    "uk.ac.gate.plugins", "annie", "8.6");
  Gate.getCreoleRegister().registerPlugin(annie);

  ResourceReference xgapp = new ResourceReference(
    annie, "resources/ANNIE_with_defaults.gapp"); 

  PersistenceManager.loadObjectFromUri(xgapp.toURI());
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Corpus-level processing}

\begin{frame}[fragile]{Corpus-level processing}
\begin{itemize}
\item When running a PR over a corpus of more than one document, you may want
  to do some additional pre- and post-processing before the first and after the
  last document.
\item To do this, implement \lstinline!gate.creole.ControllerAwarePR!
\item Three callback methods called at key points in the execution of the {\em
  controller that contains the PR}:
  \begin{itemize}
  \item \lstinline!controllerExecutionStarted!
  \item \lstinline!controllerExecutionFinished!
  \item \lstinline!controllerExecutionAborted!
  \end{itemize}
\item Parameter is the \lstinline!Controller!.
\item ``aborted'' callback also receives the Throwable that caused the abort.
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Corpus-level processing}
\begin{itemize}
\item So if the controller is a \lstinline!CorpusController!, these correspond
  to:
  \begin{itemize}
  \item before the first document
  \item after the last document
  \item when something goes wrong
  \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{ControllerAwarePR example}
\begin{lstlisting}[texcl]
@CreoleResource(name="Example Analyser")
public class ExampleAnalyser
     extends AbstractLanguageAnalyser
     implements ControllerAwarePR {
  public void controllerExecutionStarted(Controller c) {
    if(c instanceof CorpusController) {
      System.out.println("Processing corpus " +
          ((CorpusController)c).getCorpus().getName());
    }
    else {
      System.out.println(
          "Running in a simple pipeline");
    }
  }

  // controllerExecutionFinished is similar
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]{\color{gate-dark-green} Exercise 6: Corpus statistics}
Add corpus statistics to your DocStats PR:
\begin{itemize}
\item Add private fields to keep a running total count of words (and
  nouns/verbs).
\item Implement \lstinline!ControllerAwarePR!.
\item In the ``started'' callback, initialize these totals to 0.
\item In the ``finished'' callback
  \begin{itemize}
  \item check whether you are running in \lstinline!CorpusController!
  \item if so, put the total counts into features on the controller's
    \lstinline!Corpus!.
  \end{itemize}
\item You can leave the ``aborted'' callback empty (or just print a message).
\end{itemize}
\end{frame}

\ifsolutions
\addtocounter{framenumber}{-1}\framenumbersfalse
\begin{frame}[fragile]
\omitfromhandout
\frametitle{\color{gate-dark-green} Exercise 6: Solution}
\begin{lstlisting}[texcl,basicstyle=\tiny\ttfamily]
package module8;
// imports omitted for space reasons

@CreoleResource(name = "Corpus statistics")
public class CorpusStats extends AbstractLanguageAnalyser
                            implements ControllerAwarePR {
  private int totalTokens;

  public void execute() throws ExecutionException {
    int tokens = document.getAnnotations().get("Token").size(); 
    document.getFeatures().put("token_count", tokens);
    totalTokens += tokens; // keep a running total
  }
    
  public void controllerExecutionStarted(Controller c) {
    totalTokens = 0;
  }

  public void controllerExecutionFinished(Controller c) {
    if(c instanceof CorpusController) {
      ((CorpusController)c).getCorpus().getFeatures()
          .put("token_count", totalTokens);
    }
  }

  // controllerExecutionAborted omitted
}
\end{lstlisting}
\end{frame}
\framenumberstrue
\fi

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Adding actions to the GUI}

\begin{frame}[fragile]{Adding actions to the GUI}
\begin{itemize}
\item Any (language, processing or visual) resource can contribute
  \emph{actions} to the GATE developer GUI.
\item These appear as items on the resource's right-click menu.  For example:
  \begin{itemize}
  \item The ``Run'' option for controllers comes from the controller editor VR
  \item The ``Save as\ldots'' and ``Delete ontology data'' options for an
    ontology LR come from the LR itself.
  \end{itemize}
\item This is done by implementing the interface
  \lstinline!gate.gui.ActionsPublisher!
\item One method, returning a \lstinline!List! of
  \lstinline!javax.swing.Action! objects.
\end{itemize}
\end{frame}

\begin{frame}[fragile]{\color{gate-dark-green} Exercise 7: ActionsPublisher}
Implement cumulative statistics for your DocStats PR:
\begin{itemize}
\item keep a running total as before, but rather than resetting it in
  \lstinline!controllerExecutionStarted!, provide an action to reset it
  explicitly.
\item provide another action to display the current total.
\end{itemize}
\end{frame}

\ifsolutions
\addtocounter{framenumber}{-1}\framenumbersfalse
\begin{frame}[fragile]
\omitfromhandout
\frametitle{\color{gate-dark-green} Exercise 7: Solution}
\begin{lstlisting}[texcl,basicstyle=\tiny\ttfamily]
package module8;
// imports omitted for space reasons

@CreoleResource(name = "Cumulative statistics")
public class CumulativeStats extends AbstractLanguageAnalyser
                             implements ActionsPublisher {
  // totalTokens and execute() method exactly as in exercise 6

  public List<Action> getActions() {
    if(actions == null) {
      actions.add(new AbstractAction("Reset counter") {
        public void actionPerformed(ActionEvent e) {
          totalTokens = 0;
        }
      });

      actions.add(new AbstractAction("Show current total") {
        public void actionPerformed(ActionEvent e) {
          JOptionPane.showMessageDialog(
            MainFrame.getInstance(), totalTokens + " token(s) since last reset.");
        }
      });
    }
    return actions;
  }

  private List<Action> actions;
}
\end{lstlisting}
\end{frame}
\framenumberstrue
\fi

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section*{}

\begin{frame}[c]
\begin{block}{\Huge Thank you!}
\end{block}
\begin{block}{\Huge \color{gate-light-red} Questions?}
\end{block}

\begin{block}{More answers at:}
\large
\begin{itemize}
  \item \url{http://gate.ac.uk} (Our website)
  \item \url{http://gate.ac.uk/mail/} (Our mailing list)
\end{itemize}
\end{block}
\end{frame}

\section*{Extra Material: Your First Visual Resource}

\begin{frame}[fragile]{Visual Resources}
\begin{itemize}
  \item  Visual Resources provide UI elements (Swing components) for building
  user interfaces.
  \item They are classes that implement the \lstinline!gate.VisualResource!
  interface.
  \item They are associated with a type of resource via CREOLE metadata (which
  is used as a model for the view represented by the VR).
  \item The abstract class \lstinline!gate.creole.AbstractVisualResource! can
  be used a starting point.
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Visual Resource API}
\begin{block}{Visual Resource API}
Visual resources extend the \lstinline!gate.Resource! interface, with :
\begin{lstlisting}[texcl]
/** set the object to be displayed */
public void setTarget(Object target);
\end{lstlisting}
\end{block}
\begin{block}{AbstractVisualResource}
\begin{itemize}
  \item extends \lstinline!javax.swing.JPanel!;
  \item implements all the methods required by \lstinline!gate.Resource!;
  \item extending classes only need to implement:
  \begin{itemize}
    \item \lstinline!public Resource init()!: initialise the resource (i.e.
    build the required UI elements);
    \item \lstinline!public void setTarget(Object target)!: sets the model for
    this view.
  \end{itemize}
\end{itemize}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{Visual Resource CREOLE Metadata}
\begin{itemize}
  \item A Visual Resource is associated with a given type of object that it can
  display (or edit, configure). This association is done via CREOLE metadata on
  the VR implementation.
  \item From the API, the VR is populated by calling
  \lstinline!setTarget(Object target)!.
  \item In GATE Developer, the appropriate VR types are instantiated
  on demand when a resource is double-clicked in the tree. E.g., when a
  Document is double-clicked, all VR registered as capable of displaying
  \lstinline!gate.Document!  targets are instantiated.
\end{itemize}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{VR Metadata Example}
\begin{block}{CREOLE Annotations:}
\begin{lstlisting}
@CreoleResource(name="Statistics Viewer", 
        comment="Shows document statistics",
        resourceDisplayed="gate.Document",
        guiType=GuiType.LARGE,
        mainViewer=true)
public class StatsViewer extends AbstractVisualResource
\end{lstlisting}
\end{block}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{\color{gate-dark-green} Exercise A: Show the Statistics}
\begin{itemize}
  \item Create a VR that, given a document, can show the statistics produced by
  the DocStats language analyser.
  \item add CREOLE metadata to associate the new VR with the interface
  \lstinline!gate.Document!;
\end{itemize}
You can use a simple \lstinline!JTextPane! to show a \lstinline!.toString()!
value for the document's features.
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{frame}[fragile]{\color{gate-dark-green} Exercise A: Solution (metadata omitted)}
\omitfromhandout<1>
{\color{gate-light-red} Try not to use this!}
\pause
\begin{lstlisting}[basicstyle=\tiny\ttfamily]
package module8;
import javax.swing.*;
import gate.*;
import gate.creole.*;
import gate.event.FeatureMapListener;
@CreoleResource(name="Statistics Viewer", resourceDisplayed="gate.Document",
        guiType=GuiType.LARGE, mainViewer=true)
public class StatsViewer extends AbstractVisualResource 
    implements FeatureMapListener{
  private JTextPane textPane;
  private FeatureMap targetFeatures;
  public Resource init() throws ResourceInstantiationException {
    textPane = new JTextPane();
    add(new JScrollPane(textPane));
    return this;
  }
  public void setTarget(Object target) {
    if(targetFeatures != null) targetFeatures.removeFeatureMapListener(this);
    targetFeatures = ((Document)target).getFeatures();
    targetFeatures.addFeatureMapListener(this);
    featureMapUpdated();
  }
  public void featureMapUpdated() {
    textPane.setText(targetFeatures.toString()); 
  } 
}
\end{lstlisting}
\end{frame}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\end{document}
