Changeset 3366


Ignore:
Timestamp:
May 23, 2007, 12:56:38 PM (14 years ago)
Author:
Nicklas Nordborg
Message:

References #551. Added section about core and web client interaction with plug-ins.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/src/docbook/developerdoc/plugin_developer.xml

    r3329 r3366  
    2929<chapter id="plugin_developer">
    3030  <?dbhtml dir="plugin_developer"?>
    31   <title>Plugin developer</title>
     31  <title>Plug-in developer</title>
    3232  <sect1 id="plugin_developer.organize">
    33     <title>How to organize your plugin project</title>
     33    <title>How to organize your plug-in project</title>
    3434   
    3535    <sect2 id="plugin_developer.organize.ant">
    3636      <title>Using Ant</title>
    3737      <para>
    38         Here is a simple example of how you might organize your project using ant (
    39         <ulink url="http://ant.apache.org">http://ant.apache.org</ulink>
    40         ) as the build tool. This is just a recommendation that we have found to be working
     38        Here is a simple example of how you might organize your project using ant
     39        (<ulink url="http://ant.apache.org">http://ant.apache.org</ulink>) as the build
     40        tool. This is just a recommendation that we have found to be working
    4141        well. You may choose to do it another way.
    4242      </para>
     
    4545        <title>Directory layout</title>
    4646        <para>
     47       
     48          Create a directory on your computer where you want
     49          to store your plug-in project. This directory is the
     50          <filename class="directory"><replaceable>pluginname</replaceable>/</filename>
     51          directory in the listing below. You should also create some subdirectories:
     52         
    4753          <literallayout>
    4854<filename class="directory"><replaceable>pluginname</replaceable>/</filename>
     
    5359          The
    5460          <filename class="directory">bin/</filename>
    55           directory is empty to start with. It will contain the compiled code. The
    56           <filename class="directory">lib/</filename>
    57           directory contains the JAR files your plugin uses (including the
    58           <filename>BASE2Core.jar</filename>
    59           ). The
     61          directory is empty to start with. It will contain the compiled code.
     62          In the <filename class="directory">lib/</filename>
     63          directory you should put <filename>BASE2Core.jar</filename>
     64          and other library files your plug-in depends on. The
    6065          <filename class="directory">src/</filename>
    61           directory contains your source code.
     66          directory contains your source code. In this directory you should create
     67          subdirectories corresponding to the package name of your plug-in
     68          class(es). See <ulink url="http://en.wikipedia.org/wiki/Java_package"
     69          >http://en.wikipedia.org/wiki/Java_package</ulink> for information
     70          about conventions for naming packages.
    6271        </para>
    6372      </sect3>
     
    6877          In the root of your directory, create the build file:
    6978          <filename>build.xml</filename>
    70           . Here is an example that will compile your plugin and put it in a JAR file.
     79          . Here is an example that will compile your plug-in and put it in a JAR file.
    7180        </para>
    7281        <example id="plugin_developer.organize.build.file">
     
    96105   &lt;target
    97106      name="build.plugin" 
    98       description="Compiles the plugin and put in jar"
     107      description="Compiles the plug-in and put in jar"
    99108      &gt;
    100109      &lt;javac
     
    113122    &lt;/target&gt;
    114123&lt;/project&gt;
    115           </programlisting>
     124</programlisting>
    116125        </example>
    117126        <para>
    118           If your plugin depends on other JAR files than the
    119           <filename>Base2Core.jar</filename>
    120           you should list them in the
    121           <filename>MANIFEST.MF</filename>
    122           file. Otherwise you should remove the manifest attribute of the jar tag in the build
    123           file.
     127          If your plug-in depends on other JAR files than the
     128          <filename>BASE2Core.jar</filename> you must create a file called
     129          <filename>MANIFEST.MF</filename> in the project root directory.
     130          List the other JAR files as in the following example.
     131          If your plug-in doesn't depend on other JAR files, remove the
     132          <sgmltag class="attribute">manifest</sgmltag>
     133          attribute of the <sgmltag class="starttag">jar</sgmltag> tag.
    124134          <programlisting>
    125135Manifest-Version: 1.0
    126136Class-Path: OtherJar.jar ASecondJar.jar
    127           </programlisting>
     137</programlisting>
    128138        </para>
    129139      </sect3>
    130140       
    131141      <sect3 id="plugin_developer.organize.ant.build">
    132         <title>Building the plugin</title>
     142        <title>Building the plug-in</title>
    133143        <para>
    134           Compile the plugin simply by typing
     144          Compile the plug-in simply by typing
    135145          <command>ant</command>
    136146          in the console window. If all went well the
     
    139149        </para>
    140150        <para>
    141           To install the plugin copy the JAR file to the server including the dependent JAR
    142           files (if any). Place all files together in the same directory. Then follow the
    143           instructions in chapter
    144           <xref linkend="plugins.installation" />.
     151          To install the plug-in copy the JAR file to the server including the dependent JAR
     152          files (if any). Place all files together in the same directory. For more
     153          information read
     154          <xref linkend="plugins.installation" />
    145155        </para>
    146156      </sect3>
     
    149159    <sect2 id="plugin_developer.organize.eclipse">
    150160      <title>With Eclipse</title>
    151       <para></para>
     161      <para>TODO</para>
    152162    </sect2>
    153163   
    154     <sect2 id="plugin_developer.organize.installing">
    155       <title>Packaging and installing the plugin</title>
    156       <para>
    157         We recommend that each plugin or group of related plugins are compiled separately. To be
    158         able to use the plugin it must be put in a JAR file. Place the JAR file on the server
    159         <emphasis>outside</emphasis>
    160         the web servers classpath, ie. not in the
    161         <filename class="directory">WEB-INF/lib</filename>
    162         . Our recommendation is to place the plugin JAR in
    163         <filename class="directory">
    164           <replaceable>&lt;base-dir&gt;</replaceable>
    165           /plugins/
    166           <replaceable>&lt;name-of-plugin&gt;</replaceable>
    167           /
    168         </filename>
    169       </para>
    170          
    171       <para>
    172         The main benefit from placing the JAR file outside the classpath is that
    173         Base uses it's own classloader that supports unloading of the classes as well.
    174         This means that you may replace the JAR file with a new version without
    175         restarting the web server.
    176       </para>
    177     </sect2>
    178164  </sect1>
    179165
    180166  <sect1 id="plugin_developer.api">
    181     <title>The Plugin API</title>
     167    <title>The Plug-in API</title>
    182168    <para>
    183169    </para>
     
    185171    <sect2 id="plugin_developer.api.interfaces">
    186172   
    187       <title>The plugin interfaces</title>
     173      <title>The main plug-in interfaces</title>
    188174      <para>
    189         The Base2 core defined two interfaces that are vital for implementing plugins.
     175        The Base2 core defines two interfaces and one
     176        abstract class that are vital for implementing plug-ins:
    190177        <itemizedlist spacing="compact">
    191178          <listitem>
     
    199186            </simpara>
    200187          </listitem>
     188          <listitem>
     189            <simpara>
     190              <classname>net.sf.basedb.core.plugin.AbstractPlugin</classname>
     191            </simpara>
     192          </listitem>
    201193        </itemizedlist>
    202         It is required that the
    203         <interfacename>Plugin</interfacename>
    204         interface is implemented, but the
    205         <interfacename>InteractivePlugin</interfacename>
    206         is optional, and is only needed if you want user interaction.
     194       
     195        A plug-in is always required to implement the
     196        <interfacename>Plugin</interfacename> interface.
     197        The <interfacename>InteractivePlugin</interfacename>
     198        interface is optional, and is only needed if you want user interaction.
     199        The <classname>AbstractPlugin</classname> is a useful base class
     200        that your plug-in can use as a superclass. It provides default implementations
     201        for some of the interface methods and also has utility methods for
     202        validating and storing job and configuration parameter values. Another
     203        reason to use this class as a superclass is that it will shield your
     204        plug-in from future changes to the Plug-in API. For example, if
     205        we decide that a new method is needed in the <interfacename>Plugin</interfacename>
     206        interface we will also try to add a default implementation in
     207        the <classname>AbstractPlugin</classname> class.
    207208      </para>
    208209 
     210      <important>
     211        <para>
     212        A plug-in must also have public no-argument contructor. Otherwise, BASE will not
     213        be able to create instances of the class.
     214        </para>
     215      </important>
     216     
    209217      <sect3 id="plugin_developer.api.interfaces.plugin">
    210218        <title>net.sf.basedb.core.plugin.Plugin</title>
    211         <para>This interface defines seven methods and must be implemented by all plugins.</para>
     219        <para>This interface defines seven methods and must be implemented by all plug-ins.</para>
    212220        <variablelist>
    213221          <varlistentry>
     
    222230            <listitem>
    223231              <para>
    224                 Return information about the plugin, i.e. the name, version, and a short
    225                 description about what the plugin does. The
     232                Return information about the plug-in, i.e. the name, version, and a short
     233                description about what the plug-in does. The
    226234                <classname>About</classname>
    227235                object also has fields for naming the author and various other contact
    228236                information. The returned information is copied by the core at
    229237                installation time into the database. The only required information is
    230                 the name of the plugin. All other fields may have null values.
     238                the name of the plug-in. All other fields may have null values.
    231239              </para>
    232240              <example id="net.sf.basedb.core.plugin.Plugin.getAbout">
     
    249257   return about;
    250258}
    251                 </programlisting>
     259</programlisting>
    252260              </example>
    253261            </listitem>
     
    264272            <listitem>
    265273              <para>
    266                 Return information about the main type of plugin. The
     274                Return information about the main type of plug-in. The
    267275                <classname>MainType</classname>
    268                 is an enumeration which defines five possible values:
     276                is an enumeration with five possible values:
    269277                <itemizedlist>
    270278                  <listitem>
    271279                    <para>
    272                       <constant>ANALYZE</constant>
    273                       : An analysis plugin
     280                      <constant>ANALYZE</constant>:
     281                      An analysis plug-in
    274282                    </para>
    275283                  </listitem>
    276284                  <listitem>
    277285                    <para>
    278                       <constant>EXPORT</constant>
    279                       : A plugin the exports data
     286                      <constant>EXPORT</constant>:
     287                      A plug-in the exports data
    280288                    </para>
    281289                  </listitem>
    282290                  <listitem>
    283291                    <para>
    284                       <constant>IMPORT</constant>
    285                       : A plugin that imports data
     292                      <constant>IMPORT</constant>:
     293                      A plug-in that imports data
    286294                    </para>
    287295                  </listitem>
    288296                  <listitem>
    289297                    <para>
    290                       <constant>INTENSITY</constant>
    291                       : A plugin that calculates the original spot intensities
     298                      <constant>INTENSITY</constant>:
     299                      A plug-in that calculates the original spot intensities
    292300                      from raw data
    293301                    </para>
     
    295303                  <listitem>
    296304                    <para>
    297                       <constant>OTHER</constant>
    298                       : Any other type of plugin
     305                      <constant>OTHER</constant>:
     306                      Any other type of plug-in
    299307                    </para>
    300308                  </listitem>
     
    302310                The returned value is stored in the database but is otherwise not used
    303311                by the core. Client applications (such as the web client) will probably
    304                 use this information to group the plugins, i.e., a button labeled Export
    305                 will let you select among the export plugins.
     312                use this information to group the plug-ins, i.e., a button labeled
     313                <guibutton>Export</guibutton>
     314                will let you select among the export plug-ins.
    306315              </para>
    307316              <example id="net.sf.basedb.core.plugin.Plugin.getMainType">
     
    312321   return Plugin.MainType.OTHER;
    313322}
    314                 </programlisting>
     323</programlisting>
    315324              </example>
    316325            </listitem>
     
    327336            <listitem>
    328337              <para>
    329                 If this method returns true the plugin can have different
     338                If this method returns true the plug-in can have different
    330339                configurations, (i.e.
    331                 <classname>PluginConfiguration</classname>
    332                 ). Note that this method may return true even if the
     340                <classname>PluginConfiguration</classname>).
     341                Note that this method may return true even if the
    333342                <interfacename>InteractivePlugin</interfacename>
    334343                interface isn't implemented. The
     
    350359            <listitem>
    351360              <para>
    352                 If this method returns true a Job can't be created without a
    353                 configuration. The
     361                If this method returns true the plug-in must have a configuration
     362                to be able to run. For example, some of the core import plug-ins
     363                must have information about the file format to be able to import
     364                any data.
     365                The
    354366                <classname>AbstractPlugin</classname>
    355367                returns false for this method which is the old way before the
     
    376388                  <parameter>job</parameter>
    377389                </methodparam>
     390                <exceptionname>BaseException</exceptionname>
    378391              </methodsynopsis>
    379392            </term>
    380393            <listitem>
    381394              <para>
    382                 Prepare the plugin for execution (or configuration). If the plugin needs
     395                Prepare the plug-in for execution (or configuration). If the plug-in needs
    383396                to do some initialization this is the place to do it. A typical
    384397                implementation however only stores the passed parameters in instance
     
    387400              <para>
    388401                The parameters passed to this method has vital information that is
    389                 needed to execute the plugin. The
     402                needed to execute the plug-in. The
    390403                <classname>SessionControl</classname>
    391404                is a central core object which holds information about the logged in
    392                 user and allows you to create
     405                user and are used to create
    393406                <classname>DbControl</classname>
    394                 objects which allows a plugin to connect to the database to read, add or
     407                objects which allows a plug-in to connect to the database to read, add or
    395408                update information. The two
    396409                <classname>ParameterValues</classname>
    397                 objects contains information about the parameters to the plugin. The
    398                 configuration object holds all parameters stored together with a
    399                 <classname>PluginConfiguration</classname>
    400                 object in the database. The job object holds all parameters that are
    401                 stored together with a Job object in the database.
    402               </para>
    403               <para>
    404                 The difference between a plugin configuration and a job parameter is
     410                objects contains information about the configuration and job
     411                parameters to the plug-in.
     412                The <varname>configuration</varname> object holds all parameters stored
     413                together with a <classname>PluginConfiguration</classname>
     414                object in the database. If the plug-in is started without
     415                a configuration this object is null.
     416                The <varname>job</varname> object holds all parameters that are
     417                stored together with a <classname>Jon</classname> object in the
     418                database. This object is null if the plug-in is started without a job.
     419              </para>
     420              <para>
     421                The difference between a configuration parameter and a job parameter is
    405422                that a configuration is usually something an administrator sets up,
    406                 while a job is an actual execution of a plugin. For example a
    407                 configuration for an import plugin holds the regular expressions needed
     423                while a job is an actual execution of a plug-in. For example, a
     424                configuration for an import plug-in holds the regular expressions needed
    408425                to parse a text file and find the headers, sections and data lines,
    409426                while the job holds the file to parse.
     
    412429                The
    413430                <classname>AbstractPlugin</classname>
    414                 contains an implementation of this method make the passed parameters
    415                 available as protected instance variables. We recommend plugin
    416                 developers to let their plugins extend this class since it also has some
    417                 other useful methods. For example for validating parameters resulting
    418                 from user interaction and to store these values in the database.
     431                contains an implementation of this method that saves the passed objects
     432                in protected instance variables. If you override this method
     433                we recommend that you also call <code>super.init()</code>.
    419434              </para>
    420435              <example id="net.sf.basedb.core.plugin.Plugin.init">
    421                 <title>The <classname>AbstractPlugin</classname> implementation of this method</title>
     436                <title>The <classname>AbstractPlugin</classname> implementation of this Plugin.init()</title>
    422437                <programlisting>
    423438protected SessionControl sc = null;
     
    425440protected ParameterValues job = null;
    426441/**
    427    Store copies of the session control, plugin and job configuration. These
     442   Store copies of the session control, plug-in and job configuration. These
    428443   are available to subclasses in the {@link #sc}, {@link #configuration}
    429444   and {@link #job} variables. If a subclass overrides this method it is
     
    438453   this.job = job;
    439454}
    440                 </programlisting>
     455</programlisting>
    441456              </example>
    442457            </listitem>
     
    460475                  <parameter>progress</parameter>
    461476                </methodparam>
    462                 <exceptionname>BaseException</exceptionname>
    463477              </methodsynopsis>
    464478            </term>
    465479            <listitem>
    466480              <para>
    467                 Runs the plugin. The
    468                 <classname>Request</classname>
    469                 parameter has no useful information and can be ignored. It was
    470                 originally used for passing parameters to the plugin but this is now
    471                 found in the two
    472                 <classname>ParameterValues</classname>
    473                 objects passed to the init method.
    474               </para>
    475               <para>
    476                 The
    477                 <classname>ProgressReporter</classname>
    478                 can be used by a plugin to report it's progress back to the core. The
     481                Runs the plug-in. The <varname>request</varname>
     482                parameter is of historical interest only. It has no useful information
     483                and can be ignored.
     484              </para>
     485              <para>
     486                The <varname>progress</varname> parameter
     487                can be used by a plug-in to report it's progress back to the core. The
    479488                core will usually send the progress information to the database, which
    480                 allows users to see exactly how the plugin is progressing from the web
     489                allows users to see exactly how the plug-in is progressing from the web
    481490                interface. This parameter can be null, but if it isn't we recommend all
    482                 plugins to use it. However, it should be used sparingly, since each call
     491                plug-ins to use it. However, it should be used sparingly, since each call
    483492                to set the progress results in a database update. If the execution
    484493                involves several thousands of items it is a bad idea to update the
    485494                progress after processing each one of them. A good starting point is to
    486495                divide the work into 100 pieces each representing 1% of the work, i.e.,
    487                 if the plugin should export 100 000 items it should report progress
     496                if the plug-in should export 100 000 items it should report progress
    488497                after every 1000 items.
    489498              </para>
    490499              <para>
    491                 The
    492                 <classname>Response</classname>
    493                 parameter is used to tell the core if the plugin was successful or
     500                The <varname>response</varname>
     501                parameter is used to tell the core if the plug-in was successful or
    494502                failed. Not setting a response is considered a failure by the core. From
    495503                the run method it is only allowed to use the
     
    497505                or the
    498506                <methodname>setError()</methodname>
    499                  methods.
    500               </para>
     507                methods.
     508              </para>
     509             
     510              <note>
     511                It is also considered bad practice to let exceptions escape
     512                out from this method. Always use <code>try...catch</code>
     513                to catch exceptions and use <code>response.setError()</code>
     514                to reporter the error back to the core.
     515              </note>
     516             
    501517              <example id="net.sf.basedb.core.plugin.Plugin.run">
    502518                <title>
    503                   Here is a skeleton that we recommend each plugin to use in it's
     519                  Here is a skeleton that we recommend each plug-in to use in it's
    504520                  implementation of the
    505521                  <methodname>run()</methodname>
     
    514530   try
    515531   {
    516       // Insert code for plugin here
     532      // Insert code for plug-in here
    517533
    518534      // Commit the work
    519535      dc.commit();
    520       response.setDone("Plugin ended successfully");
     536      response.setDone("Plug-in ended successfully");
    521537   }
    522538   catch (Throwable t)
     
    532548   }
    533549}
    534                 </programlisting>
     550</programlisting>
    535551              </example>
    536552            </listitem>
     
    547563            <listitem>
    548564              <para>
    549                 Clean up all resources after executing the plugin. This method mustn't
     565                Clean up all resources after executing the plug-in. This method mustn't
    550566                throw any exceptions.
    551567              </para>
     
    554570                  The
    555571                  <classname>AbstractPlugin</classname>
    556                   contains an implementation of this method which simply sets the
     572                  contains an implementation of the <methodname>done()</methodname>
     573                  method simply sets the
    557574                  parameters passed to the
    558575                  <methodname>init()</methodname>
     
    580597        <title>net.sf.basedb.core.plugin.InteractivePlugin</title>
    581598        <para>
    582           If you want the plugin to be able to interact with the user you must also implement
    583           this interface. This is probably the case for most plugins. Among the plugins
    584           supplied with the core of Base the
     599          If you want the plug-in to be able to interact with the user you must also implement
     600          this interface. This is probably the case for most plug-ins. Among the core plug-ins
     601          shipped with BASE the
    585602          <classname>SpotImageCreator</classname>
    586           is one plugin that doesn't interact with the user. Instead, the web client has
     603          is one plug-in that doesn't interact with the user. Instead, the web client has
    587604          special JSP pages that handles all the interaction, creates a job for it and sets
    588           the parameters. This, kind of hardcoded, approach can be used for other plugins as
     605          the parameters. This, kind of hardcoded, approach can be used for other plug-ins as
    589606          well, but then it usually requires modification of the client application as well.
    590607        </para>
     
    592609          The
    593610          <interfacename>InteractivePlugin</interfacename>
    594           has three main tasks: tell a client application where the plugin should be plugged
    595           in, ask users for parameters, and validate and store those parameters. It requires
    596           the implementation of four method.
     611          has three main tasks:
     612         
     613          <orderedlist>
     614          <listitem>
     615            <para>
     616            Tell a client application where the plug-in should be plugged
     617            in.
     618            </para>
     619          </listitem>
     620          <listitem>
     621            <para>
     622            Ask the users for configuration and job parameters.
     623            </para>
     624          </listitem>
     625         
     626          <listitem>
     627            <para>
     628            Validate parameter values entered by the user and store those in the
     629            database.
     630            </para>
     631          </listitem>
     632          </orderedlist>
     633          This requires that the following methods are
     634          implemented.
    597635        </para>
     636       
    598637        <variablelist>
    599638          <varlistentry>
     
    608647            <listitem>
    609648              <para>
    610                 Return information about where the plugin should be plugged in. Each
     649                Return information about where the plug-in should be plugged in. Each
    611650                place is identified by a
    612651                <classname>GuiContext</classname>
     
    614653                <classname>Item</classname>
    615654                and a
    616                 <classname>Type</classname>
    617                 . The item is one of the objects defined by the
     655                <classname>Type</classname>.
     656                The item is one of the objects defined by the
    618657                <classname>net.sf.basedb.core.Item</classname>
    619658                enumeration and the type is either
    620659                <constant>Type.LIST</constant>
    621660                or
    622                 <constant>Type.ITEM</constant>
    623                 .
     661                <constant>Type.ITEM</constant>, which corresponde to the
     662                list view and the single-item view in the web client.
    624663              </para>
    625664              <para>
    626665                For example, the
    627                 <varname>GuiContext</varname>
    628                 <literal>= (</literal>
    629                 <constant>Item.REPORTER</constant>
    630                 <literal>,</literal>
    631                 <constant>Type.LIST</constant>
    632                 <literal>)</literal>
    633                 tells a client application that this plugin can be plugged in whenever a
     666                <varname>GuiContext</varname> =
     667                (<constant>Item.REPORTER</constant>,
     668                <constant>Type.LIST</constant>)
     669                tells a client application that this plug-in can be plugged in whenever a
    634670                list of reporters is displayed. The
    635                 <varname>GuiContext</varname>
    636                 = (
    637                 <constant>Item.REPORTER</constant>
    638                 ,
    639                 <constant>Type.ITEM</constant>
    640                 ) tells a client application that this plugin can be plugged in whenever
     671                <varname>GuiContext</varname> =
     672                (<constant>Item.REPORTER</constant>,
     673                <constant>Type.ITEM</constant>)
     674                tells a client application that this plug-in can be plugged in whenever
    641675                a single reporter is displayed. The first case may be appropriate for a
    642                 plugin that imports or exports reporters. The second case may be used by
    643                 a plugin that updates the reporter information from an external source
     676                plug-in that imports or exports reporters. The second case may be used by
     677                a plug-in that updates the reporter information from an external source
    644678                (well, it may make sense to use this in the list case as well).
    645679              </para>
    646680              <para>
    647681                The returned information is copied by the core at installation time to
    648                 make it easy to ask for all plugins for a certain
    649                 <classname>GuiContext</classname>
    650                 .
     682                make it easy to ask for all plug-ins for a certain
     683                <classname>GuiContext</classname>.
    651684              </para>
    652685              <para>
     
    654687                <classname>Set</classname>
    655688                which is returned by this method. It is important that the returned set
    656                 can't be modified, since it may be a security issue if a bad behaving
     689                can't be modified. It may be a security issue if a misbehaving
    657690                client application does that.
    658691              </para>
     
    663696                </title>
    664697                <programlisting>
    665 // From the net.sf.basedb.plugins.RawDataFlatFileImporter plugin
     698// From the net.sf.basedb.plugins.RawDataFlatFileImporter plug-in
    666699private static final Set&lt;GuiContext&gt; guiContexts =
    667700   Collections.singleton(new GuiContext(Item.RAWBIOASSAY, GuiContext.Type.ITEM));
     
    671704   return <returnvalue>guiContexts</returnvalue>;
    672705}
    673                 </programlisting>
     706</programlisting>
    674707              </example>
    675708            </listitem>
     
    694727              <para>
    695728                This method is called to check if a particular item is usable for the
    696                 plugin, when the context type is
    697                 <constant>Type.ITEM</constant>
    698                 , i.e. the user has selected a specific sample and the the client
    699                 application is now displaying information about that sample. Thus, our
    700                 <varname>GuiContext</varname>
    701                 = (
    702                 <constant>Item.SAMPLE</constant>
    703                 ,
    704                 <constant>Type.ITEM</constant>
    705                 ). Now, the client application asks for a list of plugins supporting
     729                plug-in. This method is only invoked from the single-item view.
     730                Thus, <code>context.getType()</code> always returns
     731                <constant>Type.ITEM</constant>, and <code>context.getItem()</code>
     732                returns a value corresponding to the type of item that is passed
     733                in the <varname>item</varname> parameter. Here is an example:
     734               
     735                <informalexample>
     736                <para>
     737                The user has selected a specific sample and the the client
     738                application is now displaying information about that sample.
     739                Thus, our
     740                <varname>GuiContext</varname> =
     741                (<constant>Item.SAMPLE</constant>,
     742                <constant>Type.ITEM</constant>).
     743               
     744                Now, the client application asks for a list of plug-ins supporting
    706745                this context and for each one in the list calls this method with the
    707                 current sample as the item parameter. The plugin should answer if it can
    708                 do whatever it is supposed to do by returning null or a string
    709                 containing a message why it can't.
     746                current sample as the value of the <varname>item</varname> parameter.
     747                </para>
     748                </informalexample>
     749
     750                If the plug-in can do whatever it is supposed to do it should
     751                return null, otherwise it should return a string with a message
     752                explaining why it can't.
    710753              </para>
    711754              <para>
    712755                Here is a real example from the
    713756                <classname>RawDataFlatFileImporter</classname>
    714                 plugin which imports raw data to a
    715                 <classname>RawBioAssay</classname>
    716                 . Thus,
    717                 <varname>GuiContext</varname>
    718                 = (
    719                 <constant>Item.RAWBIOASSAY</constant>
    720                 ,
    721                 <constant>Type.ITEM</constant>
    722                 ), but the plugin can only import data if there isn't any already, and
    723                 if the raw bioassay has the same raw data type as the plugin has been
     757                plug-in which imports raw data to a
     758                <classname>RawBioAssay</classname>.
     759               
     760                Thus,
     761                <varname>GuiContext</varname> =
     762                (<constant>Item.RAWBIOASSAY</constant>,
     763                <constant>Type.ITEM</constant>),
     764               
     765                but the plug-in can only import data if there isn't any already, and
     766                if the raw bioassay has the same raw data type as the plug-in has been
    724767                configured for.
    725768              </para>
     
    760803   return message;   
    761804}
    762                 </programlisting>
     805</programlisting>
    763806              </example>
    764807            </listitem>
     
    783826            <listitem>
    784827              <para>
    785                 Ask the plugin for parameters that needs to be entered by the user. The
     828                Ask the plug-in for parameters that needs to be entered by the user. The
    786829                <classname>GuiContext</classname>
    787830                parameter is one of the contexts returned by the
    788831                <methodname>getGuiContexts</methodname>
    789                 method. The command is string telling the plugin what command was
     832                method. The command is string telling the plug-in what command was
    790833                executed. There are two predefined commands but as you will see the
    791                 plugin may define it's own commands. The two predefined commands are
     834                plug-in may define it's own commands. The two predefined commands are
    792835                defined in the
    793836                <classname>net.sf.basedb.core.plugin.Request</classname>
     
    801844                      <para>
    802845                        Used when an administrator is initiating a configuration
    803                         of the plugin.
     846                        of the plug-in.
    804847                      </para>
    805848                    </listitem>
     
    811854                    <listitem>
    812855                      <para>
    813                         Used when a user has selected the plugin for running a
     856                        Used when a user has selected the plug-in for running a
    814857                        job.
    815858                      </para>
     
    817860                  </varlistentry>
    818861                </variablelist>
    819                 Given this information the plugin must return a
     862                Given this information the plug-in must return a
    820863                <classname>RequestInformation</classname>
    821864                object. This is simply a title, a description and a list of parameters.
     
    827870              <example id="net.sf.basedb.core.plugin.InteractivePlugin.getRequestInformation">
    828871                <title>
    829                   When running an import plugin it needs to ask for the file to import
     872                  When running an import plug-in it needs to ask for the file to import
    830873                  from and if existing items should be updated or not
    831874                </title>
    832                 <programlisting>
     875                <programlisting >
    833876// The complete request information
    834877private RequestInformation configure Job;
     
    893936   return configureJob;
    894937}
    895                 </programlisting>
     938</programlisting>
    896939              </example>
    897940              <para>
    898                 As you can see it takes some code to put together a
     941                As you can see it takes a lot of code to put together a
    899942                <classname>RequestInformation</classname>
    900                 object. For each parameter needed you need one
     943                object. For each parameter you need one
    901944                <classname>PluginParameter</classname>
    902945                object and one
    903946                <classname>ParameterType</classname>
    904                 object. Actually, a
     947                object. To make life a little easier, a
    905948                <classname>ParameterType</classname>
    906949                can be reused for more than one
    907                 <classname>PluginParameter</classname>
    908                 .
     950                <classname>PluginParameter</classname>.
    909951              </para>
    910952             
     
    914956PluginParameter two = new PluginParameter("two", "Two", "Second string", stringPT);
    915957// ... and so on
    916               </programlisting>
     958</programlisting>
    917959              <para>
    918960                The
     
    9911033                      Asks for any other item. This parameter type requires
    9921034                      that a list of options is supplied, except when the item
    993                       type asked for matches the current GuiContext, in which
     1035                      type asked for matches the current <classname>GuiContext</classname>, in which
    9941036                      case the currently selected item is used as the
    9951037                      parameter value.
     
    10041046                    <para>
    10051047                      Ask for a path to a file or directory. The path may be
    1006                       non-existing and should be used when a plugin needs an
     1048                      non-existing and should be used when a plug-in needs an
    10071049                      output destination, i.e., the file to export to, or a
    10081050                      directory where the output files should be placed.
     
    10151057                <classname>PluginParameter</classname>
    10161058                with a null name and
    1017                 <classname>ParameterType</classname>
    1018                 . In that case, the core will not ask for input from the user, instead
     1059                <classname>ParameterType</classname>.
     1060                In this case, the web client will not ask for input from the user, instead
    10191061                it is used as a section header, allowing you to group parameters into
    10201062                different sections which increase the readability of the input
     
    10331075parameters.add(firstParameterInSecondSection);
    10341076parameters.add(secondParameteInSecondSection);
    1035               </programlisting>
     1077</programlisting>
    10361078            </listitem>
    10371079          </varlistentry>
     
    10581100            <listitem>
    10591101              <para>
    1060                 Sends parameter values entered by the user for processing by the plugin.
    1061                 Typically the plugin should validate that the parameter values are
     1102                Sends parameter values entered by the user for processing by the plug-in.
     1103                The plug-in must validate that the parameter values are
    10621104                correct and then store them in database.
    10631105              </para>
    1064               <para>
     1106             
     1107              <important>
     1108                <para>
    10651109                No validation is done by the core, except converting the input to the
    1066                 correct object type, i.e. if the parameter asked for a
     1110                correct object type, i.e. if the plug-in asked for a
    10671111                <classname>Float</classname>
    1068                 the input string is parsed and converted to a Float. If you have
    1069                 extended the
     1112                the input string is parsed and converted to a
     1113                <classname>Float</classname>. If you have extended the
    10701114                <classname>AbstractPlugin</classname>
    1071                 class it is very easy to validate the parameters using it's
     1115                class it is very easy to validate the parameters with the
    10721116                <methodname>validateRequestParameters()</methodname>
    10731117                method. This method takes the same list of
    1074                 <classname>PluginParameter</classname>
    1075                 's used in the
     1118                <classname>PluginParameter</classname>:s
     1119                as used in the
    10761120                <classname>RequestInformation</classname>
    10771121                object and uses that information for validation. It returns null or a
    10781122                list of
    1079                 <exceptionname>Throwable</exceptionname>
    1080                 .
    1081               </para>
    1082               <para>
    1083                 When the parameters have been validated they need to be stored. Once
    1084                 again, it is very easy if you use one of the
     1123                <exceptionname>Throwable</exceptionname>:s that can be
     1124                given directly to the <code>response.setError()</code>
     1125                methods.
     1126                </para>
     1127              </important>
     1128              <para>
     1129                When the parameters have been validated they need to be stored
     1130                in the datatbase. Once again, it is very easy if you use one of the
    10851131                <methodname>AbstractPlugin.storeValue()</methodname>
    10861132                or
     
    10891135              </para>
    10901136              <para>
    1091                 The configure method works much like the
    1092                 <methodname>Plugin.run()</methodname>
    1093                 method. It must return the result in the
    1094                 <classname>Response</classname>
    1095                 object, i.e. it shouldn't trow any exceptions.
    1096               </para>
     1137                The configure method works much like the <methodname>Plugin.run()</methodname>
     1138                method. It must return the result in the <classname>Response</classname> object,
     1139                and shouldn't trow any exceptions.
     1140              </para>
     1141             
    10971142              <example id="net.sf.basedb.core.plugin.InteractivePlugin.configure">
    10981143                <title>
     
    11351180   }
    11361181}
    1137                 </programlisting>
     1182</programlisting>
    11381183              </example>
    1139               <para>
    1140                 Note that the
    1141                 <methodname>setDone()</methodname>
     1184             
     1185              <para>
     1186                Note that the call to
     1187                <methodname>response.setDone()</methodname>
    11421188                has a second parameter
    1143                 <classname>Job.ExecutionTime</classname>
    1144                 . It is an indication about how long time it will take to execute the
    1145                 plugin. This is of interest for job queue managers which probably
     1189                <constant>Job.ExecutionTime.SHORT</constant>. It is an indication
     1190                about how long time it will take to execute the
     1191                plug-in. This is of interest for job queue managers which probably
    11461192                doesn't want to start too many long-running jobs at the same time
    11471193                blocking the entire system. Please try to use this parameter wisely and
    1148                 not use the
    1149                 <constant>Job.ExecutionTime.SHORT</constant>
    1150                 value out of old habit all the time.
    1151               </para>
    1152               <para>
    1153                 The response also has a
     1194                not use <constant>Job.ExecutionTime.SHORT</constant>
     1195                out of old habit all the time.
     1196              </para>
     1197              <para>
     1198                The <classname>Response</classname> class also has a
    11541199                <methodname>setContinue()</methodname>
    1155                 method which tells the core that the plugin needs more parameters,
     1200                method which tells the core that the plug-in needs more parameters,
    11561201                i.e. the core will then call
    11571202                <methodname>getRequestInformation()</methodname>
    1158                 again with the new command, let the user enter values, and the call
     1203                again with the new command, let the user enter values, and then call
    11591204                <methodname>configure()</methodname>
    1160                 with the new values. This process is repeated until the plugin
     1205                with the new values. This process is repeated until the plug-in
    11611206                reports that it is done or an error occurs.
    11621207              </para>
    11631208              <para>
    11641209                An important note is that during this iteration it is the same instance
    1165                 of the plugin that is used. However, no parameter values are stored in
    1166                 the database until
    1167                 <methodname>setDone()</methodname>
    1168                 is called. Then, the plugin instance is usually discarded. The execution
    1169                 of the plugin happens in a new instance and maybe on a different server.
     1210                of the plug-in that is used. However, no parameter values are stored in
     1211                the database until the plugin sends a
     1212                <methodname>response.setDone()</methodname>.
     1213                After that, the plug-in instance is usually discarded, and a job is placed
     1214                in the job queue. The execution of the plug-in happens in a new instance
     1215                and maybe on a different server.
    11701216              </para>
    11711217              <tip>
    11721218                  <para>
    1173                     You don't have to store all values the plugin asked for in the
     1219                    You don't have to store all values the plug-in asked for in the
    11741220                    first place. You may even choose to store different values than
    11751221                    those that were entered. For example, you might ask for the mass
     
    11851231    </sect2>
    11861232 
    1187     <sect2 id="plugin_developer.api.parameters">
    1188       <title>Asking for parameters</title>
     1233    <sect2 id="plugin_developer.api.callsequence">
     1234      <title>What happens when...</title>
     1235     
    11891236      <para>
    1190         The webclient will ask for parameters by calling the method
    1191         <methodname>getRequestInformation</methodname> from the interface
    1192         <interfacename>InteractivePlugin</interfacename>. The
    1193         <methodname>getRequestInformation</methodname> is described in detail in this example,
    1194         <xref linkend="net.sf.basedb.core.plugin.InteractivePlugin.getRequestInformation"/>.
     1237        This section describes how the BASE core interacts with the
     1238        plug-in in a number of use cases. We will outline the
     1239        order the methods are invoked on the plug-in.
    11951240      </para>
    11961241     
    1197       <sect3 id="plugin_developer.api.parameters.jsp">
    1198         <title>Using custom JSP pages for parameters</title>
     1242      <sect3 id="plugin_developer.api.callsequence.install">
     1243        <title>Installing a plug-in</title>
     1244       
    11991245        <para>
    1200           This is an advanced option for plugins that require a different interface for
    1201           specifying plugin parameters than the default list showing each parameter at a
     1246          When a plug-in is installed the core is eager to find out
     1247          information about the plug-in. To do this it calls the
     1248          following methods in this order:
     1249        </para>
     1250       
     1251        <orderedlist>
     1252        <listitem>
     1253          <para>
     1254          A new instance of the plug-in class is created. The plug-in must
     1255          have a public no-argument constructor.
     1256          </para>
     1257        </listitem>
     1258       
     1259        <listitem>
     1260          <para>
     1261          Calls are made to <methodname>Plugin.getMainType()</methodname>,
     1262          <methodname>Plugin.supportsConfigurations()</methodname>,
     1263          <methodname>Plugin.requiresConfiguration()</methodname> and
     1264          <methodname>Plugin.getAbout()</methodname> to find out information
     1265          about the plug-in. This is the only time theese methods are called.
     1266          The information that is returned by them are copied and stored in
     1267          the database for easy access.
     1268          </para>
     1269         
     1270          <note>
     1271            <para>
     1272            The <methodname>Plugin.init()</methodname> method is
     1273            never called during plug-in installation.
     1274            </para>
     1275          </note>
     1276        </listitem>
     1277       
     1278        <listitem>
     1279          <para>
     1280          If the plug-in implements the <interfacename>InteractivePlugin</interfacename>
     1281          interface the <methodname>InteractivePlugin.getGuiContexts()</methodname>
     1282          method is called. This is the only time this method. The information it
     1283          returns are copied and stored in the database.
     1284          </para>
     1285        </listitem>
     1286       
     1287        <listitem>
     1288          <para>
     1289          If the server admin decided to use the plug-in permission system, the
     1290          <methodname>Plugin.getPermissions()</methodname> method is called.
     1291          The returned information is copied and stored in the database.
     1292          </para>
     1293        </listitem>
     1294       
     1295        </orderedlist>
     1296      </sect3>
     1297   
     1298      <sect3 id="plugin_developer.api.callsequence.configure">
     1299        <title>Configuring a plug-in</title>
     1300       
     1301        <para>
     1302          The plug-in must implement the <interfacename>InteractivePlugin</interfacename>
     1303          interface and the <methodname>Plugin.supportsConfigurations()</methodname> method
     1304          must return <constant>TRUE</constant>. The configuration is done with
     1305          a wizard-like interface (see <xref linkend="plugins.configuration.wizard" />).
     1306          The same plug-in instance is used throughout the entire configuration sequence.
     1307        </para>
     1308       
     1309        <orderedlist>
     1310        <listitem>
     1311          <para>
     1312          A new instance of the plug-in class is created. The plug-in must
     1313          have a public no-argument constructor.
     1314          </para>
     1315        </listitem>
     1316       
     1317        <listitem>
     1318          <para>
     1319          The <methodname>Plugin.init()</methodname> method is called. The
     1320          <varname>job</varname> parameter is null.
     1321          </para>
     1322        </listitem>
     1323       
     1324        <listitem id="plugin_developer.api.callsequence.configure.requestinformation">
     1325          <para>
     1326          The <methodname>InteractivePlugin.getRequestInformation()</methodname>
     1327          method is called. The <varname>context</varname> parameter is <constant>null</constant>
     1328          and the <varname>command</varname> is the value of the string
     1329          constant <constant>Request.COMMAND_CONFIGURE_PLUGIN</constant>
     1330          (_config_plugin).
     1331          </para>
     1332        </listitem>
     1333       
     1334        <listitem id="plugin_developer.api.callsequence.configure.form">
     1335          <para>
     1336          The web client process this information and displays a form for user
     1337          input. The plug-in will have to wait some time while the user enters
     1338          data.
     1339          </para>
     1340        </listitem>
     1341       
     1342        <listitem>
     1343          <para>
     1344          The <methodname>InteractivePlugin.configure()</methodname> method
     1345          is called. The <varname>context</varname> parameter is still
     1346          <constant>null</constant> and the <varname>request</varname>
     1347          parameter contains the parameter values entered by the user.
     1348          </para>
     1349        </listitem>
     1350       
     1351        <listitem>
     1352          <para>
     1353          The plug-in must validate the values and decided if they should be
     1354          stored in the database or not. We recommend that you use the
     1355          methods in the <classname>AbstractPlugin</classname> class for this.
     1356          </para>
     1357        </listitem>
     1358       
     1359        <listitem>
     1360          <para>
     1361          The plug-in has three different respones:
     1362         
     1363          <itemizedlist>
     1364          <listitem>
     1365            <para>
     1366            <methodname>Response.setDone()</methodname>: The configuration
     1367            is complete. The core will write any configuation changes to the
     1368            database, call the <methodname>Plugin.done()</methodname> method and
     1369            then discard the plug-in instance.
     1370            </para>
     1371          </listitem>
     1372         
     1373          <listitem>
     1374            <para>
     1375            <methodname>Response.setError()</methodname>: There was one or more
     1376            errors. The web client will display the error messages for the user and
     1377            allow the user to enter new values. The process continues with
     1378            step <xref linkend="plugin_developer.api.callsequence.configure.form" />.
     1379            </para>
     1380          </listitem>
     1381         
     1382          <listitem>
     1383            <para>
     1384            <methodname>Response.setContinue()</methodname>: The parameters are correct
     1385            but the plug-in wants more parameters. The process continues with
     1386            step <xref linkend="plugin_developer.api.callsequence.configure.requestinformation" />.
     1387            </para>
     1388          </listitem>
     1389          </itemizedlist>
     1390         
     1391          </para>
     1392        </listitem>
     1393        </orderedlist>
     1394
     1395      </sect3>   
     1396   
     1397      <sect3 id="plugin_developer.api.callsequence.context">
     1398        <title>Checking if a plug-in can be used in a given context</title>
     1399       
     1400        <para>
     1401          If the plug-in is an <interfacename>InteractivePlugin</interfacename>
     1402          it has specified in which contexts it can be used by the
     1403          information returned from <methodname>InteractivePlugin.getGuiContexts()</methodname>
     1404          method. The web client uses this information to decide if,
     1405          for example, an <guibutton>Run plugin</guibutton>
     1406          button should be displayed on a page or not. However this is not
     1407          always enough to know if the plug-in can be used or not.
     1408          For example, a raw data importer plug-in can't be used to
     1409          import raw data if the raw bioassay already has data.
     1410          So, when the user clicks the button, the web client will
     1411          load all plug-ins that maybe can be used in the given context
     1412          and let each one of the check if they can be used or not.
     1413        </para>
     1414       
     1415     
     1416        <orderedlist>
     1417        <listitem>
     1418          <para>
     1419          A new instance of the plug-in class is created. The plug-in must
     1420          have a public no-argument constructor.
     1421          </para>
     1422        </listitem>
     1423       
     1424        <listitem>
     1425          <para>
     1426          The <methodname>Plugin.init()</methodname> method is called.
     1427          The <varname>job</varname> parameter is <constant>null</constant>.
     1428          The <varname>configuration</varname> parameter is <constant>null</constant>
     1429          if the plug-in doesn't have any configuration parameters.
     1430          </para>
     1431        </listitem>
     1432       
     1433        <listitem>
     1434          <para>
     1435          The <methodname>InteractivePlugin.isInContext()</methodname>
     1436          is called. If the context is a list context, the <varname>item</varname>
     1437          parameter is null, otherwise the current item is passed. The plug-in
     1438          should return <constant>null</constant> if it can be used under the
     1439          current circumstances, or a message explaining why not.
     1440          </para>
     1441        </listitem>
     1442       
     1443        <listitem>
     1444          <para>
     1445            After this, the plug-in instance is discarded. If there are
     1446            several configurations for a plug-in this procedure is repeated
     1447            for each configuration.
     1448          </para>
     1449
     1450          <warning>
     1451          <para>
     1452            The <methodname>Plugin.done()</methodname> method is never
     1453            called! This is bug that has been reported to the developers
     1454            and hopefully it will be fixed shortly.
     1455          </para>
     1456          </warning>
     1457        </listitem>
     1458        </orderedlist>
     1459      </sect3>
     1460   
     1461      <sect3 id="plugin_developer.api.callsequence.job">
     1462        <title>Creating a new job</title>
     1463       
     1464        <para>
     1465          If the web client found that the plug-in could be
     1466          used in a given context and the user selected the plug-in
     1467          the job configuration sequence is started. It is a wizard-like interface
     1468          identical to the configuration wizard. In fact, the same JSP pages,
     1469          and calling sequence is used. See <xref linkend="plugin_developer.api.callsequence.configure" />.
     1470          We don't repeat everything here. There are a few differences:
     1471        </para>
     1472       
     1473        <itemizedlist>
     1474        <listitem>
     1475          <para>
     1476          The <varname>job</varname> parameter is not null, but it doesn't contain
     1477          any parameter values to start with. The plug-in should use this
     1478          object to store job-related parameter values. The
     1479          <varname>configuration</varname> parameter is <constant>null</constant>
     1480          if the plug-in is started without configuration. In any case,
     1481          the configuration values are write-protected and can't be modified.
     1482          </para>
     1483        </listitem>
     1484       
     1485        <listitem>
     1486          <para>
     1487          The first call to <methodname>InteractivePlugin.getRequestInformation()</methodname>
     1488          is done with <constant>Request.COMMAND_CONFIGURE_JOB</constant> (_configjob)
     1489          as the command. The <varname>context</varname> parameter reflects the
     1490          current context.
     1491          </para>
     1492        </listitem>
     1493       
     1494        <listitem>
     1495          <para>
     1496          When calling <methodname>Response.setDone()</methodname> the plug-in
     1497          should use the variant that takes an estimated execution time.
     1498          If the plug-in has support for immediate execution or download
     1499          (export plug-ins only) it can also respond with
     1500          <methodname>Response.setExecuteImmediately()</methodname> or
     1501          <methodname>Response.setDownloadImmediately()</methodname>.
     1502          </para>
     1503         
     1504          <para>
     1505          If the plug-in requested and was granted immediate execution or
     1506          download the same plug-in instance is used to execute the plug-in.
     1507          The may be done with the same or a new thread. Otherwise, a new
     1508          job is added to the job queue, the parameter value are saved
     1509          and the plug-in instance is discarded after calling the
     1510          <methodname>Plugin.done()</methodname> method.
     1511          </para>
     1512        </listitem>
     1513        </itemizedlist>
     1514      </sect3>
     1515   
     1516      <sect3 id="plugin_developer.api.callsequence.execute">
     1517        <title>Executing a job</title>
     1518       
     1519        <para>
     1520          Normally, the creation of a job and the execution of it are
     1521          two different events. The execution may as well be done on a
     1522          different server. See <xref linkend="installation_upgrade.jobagents" />.
     1523          This means that the execution takes place in a different instance
     1524          of the plug-in class than what was used for creating the job.
     1525          The exception is if a plug-in supports immediate execution or download.
     1526          In this case the same instance is used, and it, of course,
     1527          is always executed on the web server.
     1528        </para>
     1529       
     1530        <orderedlist>
     1531        <listitem>
     1532          <para>
     1533          A new instance of the plug-in class is created. The plug-in must
     1534          have a public no-argument constructor.
     1535          </para>
     1536        </listitem>
     1537       
     1538        <listitem>
     1539          <para>
     1540          The <methodname>Plugin.init()</methodname> method is called.
     1541          The <varname>job</varname> parameter contains the job
     1542          configuration paramters. The <varname>configuration</varname> parameter
     1543          is <constant>null</constant> if the plug-in doesn't have any
     1544          configuration parameters.
     1545          </para>
     1546        </listitem>
     1547       
     1548        <listitem>
     1549          <para>
     1550          The <methodname>Plugin.run()</methodname> method is called.
     1551          It is finally time for the plug-in to do the work it has bee
     1552          designed for. This method shouldn't throw any exceptions.
     1553          Use the <methodname>Response.setDone()</methodname>
     1554          method to report success or the <methodname>Response.setError()</methodname>
     1555          to reporter errors.
     1556          </para>
     1557        </listitem>
     1558       
     1559        <listitem>
     1560          <para>
     1561          In both cases the <methodname>Plugin.done()</methodname>
     1562          method is called and the plug-in instance is discarded.
     1563          </para>
     1564        </listitem>
     1565       
     1566        </orderedlist>
     1567      </sect3>
     1568   
     1569    </sect2>
     1570 
     1571    <sect2 id="plugin_developer.api.jspparameters">
     1572      <title>Using custom JSP pages for parameter input</title>
     1573
     1574        <para>
     1575          This is an advanced option for plug-ins that require a different interface for
     1576          specifying plug-in parameters than the default list showing each parameter at a
    12021577          time. This feature is used by setting the RequestInformation.getJspPage()
    1203           property when construction the request information object. If this property has
     1578          property when constructing the request information object. If this property has
    12041579          a non-null value, the web client will send the browser to the specified JSP page
    12051580          instead of to the generic parameter input page.
    12061581        </para>
    12071582        <para>
    1208           When setting the JSP page you should not specify any path information. The web
     1583          When setting the JSP page you should only set the file name. Don't include
     1584          any path information. The web
    12091585          client has a special location for these JSP pages, generated from the package
    1210           name of your plugin and the returned values. If the plugin is located in the
    1211           package
     1586          name of your plug-in. If the plug-in is located in the package
    12121587          <classname>org.company</classname>
    12131588          the JSP page must be located in
    1214           <filename class="directory">www-root/plugins/org/company/</filename>
    1215           . Please note that the browser still thinks that it is showing the regular page
     1589          <filename class="directory">&lt;base-dir&gt;/www/plugins/org/company/</filename>.
     1590          Please note that the browser still thinks that it is showing the regular page
    12161591          at the usual location:
    1217           <filename class="directory">www-root/common/plugin/index.jsp</filename>
    1218           , so all links in your JSP page should be relative to that directory.
     1592          <filename class="directory">&lt;base-dir&gt;/www/common/plugin/index.jsp</filename>.
     1593          All links in your JSP page should be relative to that directory.
    12191594        </para>
    12201595        <para>
    12211596          Even if you use your own JSP page we recommend that you use the built-in
    1222           facility for passing the parameters back to the plugin. For this to work you
     1597          facility for passing the parameters back to the plug-in. For this to work you
    12231598          must:
    12241599        </para>
    12251600        <itemizedlist spacing="compact">
    12261601          <listitem>
    1227             <simpara>Generate the list of <classname>PluginParameter</classname> objects as usual</simpara>
     1602            <simpara>
     1603            Generate the list of <classname>PluginParameter</classname>
     1604            objects as usual.
     1605            </simpara>
    12281606          </listitem>
    12291607          <listitem>
    12301608            <simpara>
    1231               Name all your input fields like:
     1609              Name all your input fields in the JSP like:
    12321610              <parameter>
    1233                 parameter:
    1234                 <replaceable>name-of-parameter</replaceable>
     1611                parameter:<replaceable>name-of-parameter</replaceable>
    12351612              </parameter>
    12361613            </simpara>
     
    12441621First string: &lt;input type="text" name="parameter:one"&gt;&lt;br&gt;
    12451622Second string: &lt;input type="text" name="parameter:two"&gt;
    1246             </programlisting>
     1623</programlisting>
    12471624          </listitem>
    12481625          <listitem>
     
    12501627            Send the form to
    12511628            <filename>index.jsp</filename>
    1252             with some parameters
     1629            with the <varname>ID</varname> and <varname>cmd</varname> parameters
     1630            as shown below.
    12531631          </simpara>
    12541632          <programlisting>
     
    12581636...
    12591637&lt;/form&gt;
    1260             </programlisting>
     1638</programlisting>
     1639
     1640          </listitem>
     1641          </itemizedlist>
    12611642            <para>
    12621643              In your JSP page you will probably need to access some information like the
    1263               <classname>SessionControl</classname>
    1264               and possible even the
    1265               <classname>RequestInformation</classname>
    1266               object created by your plugin.
     1644              <classname>SessionControl</classname>, <classname>Job</classname>
     1645              and possible even the <classname>RequestInformation</classname>
     1646              object created by your plug-in.
    12671647            </para>
    12681648            <programlisting>
     
    12711651final String ID = sc.getId();
    12721652
    1273 // Get information about the current request to the plugin
     1653// Get information about the current request to the plug-in
    12741654PluginConfigurationRequest pcRequest =
    12751655   (PluginConfigurationRequest)sc.getSessionSetting("plugin.configure.request");
     
    12811661   (PluginDefinition)sc.getSessionSetting("plugin.configure.job");
    12821662RequestInformation ri = pcRequest.getRequestInformation();
    1283             </programlisting>
    1284           </listitem>
    1285         </itemizedlist>
    1286       </sect3>
     1663</programlisting>
     1664
    12871665    </sect2>
    12881666  </sect1>
    12891667
    12901668  <sect1 id="plugin_developer.import">
    1291     <title>Import plugins</title>
     1669    <title>Import plug-ins</title>
    12921670    <para>
    12931671   
     
    13091687
    13101688  <sect1 id="plugin_developer.export">
    1311     <title>Export plugins</title>
     1689    <title>Export plug-ins</title>
    13121690    <para>TODO</para>
    13131691   
     
    13191697 
    13201698  <sect1 id="plugin_developer.analyse">
    1321     <title>Analysis plugins</title>
     1699    <title>Analysis plug-ins</title>
    13221700    <para>
    1323       A plugin becomes an analysis plugin simply by returning
     1701      A plug-in becomes an analysis plug-in simply by returning
    13241702      <constant>Plugin.MainType.ANALYSIS</constant> from the
    13251703      <methodname>Plugin.getMainType()</methodname> method. The information returned from
    13261704      <methodname>InteractivePlugin.getGuiContexts()</methodname>
    13271705      must include: [<constant>Item.BIOASSAYSET</constant>, <constant>Type.ITEM</constant>] since
    1328       this is the only place where the web client looks for analysis plugins.
     1706      this is the only place where the web client looks for analysis plug-ins.
    13291707    </para>
    13301708   
     
    13491727 
    13501728  <sect1 id="plugin_developer.other">
    1351     <title>Other plugins</title>
     1729    <title>Other plug-ins</title>
    13521730    <para></para>
    13531731   
    13541732    <sect2 id="plugin_developer.other.authentication">
    1355       <title>Authentication plugins</title>
     1733      <title>Authentication plug-ins</title>
    13561734      <para>
    13571735        This documentation is only available in the old format.
     
    13711749   
    13721750    <sect2 id="plugin_developer.other.unpacker">
    1373       <title>File unpacker plugins</title>
     1751      <title>File unpacker plug-ins</title>
    13741752      <para>
    13751753        TODO
     
    13791757 
    13801758  <sect1 id="plugin_developer.example">
    1381     <title>Example plugins (with download)</title>
     1759    <title>Example plug-ins (with download)</title>
    13821760    <para>
    13831761      <para>
Note: See TracChangeset for help on using the changeset viewer.