Changeset 3178


Ignore:
Timestamp:
Mar 12, 2007, 9:54:30 AM (15 years ago)
Author:
Johan Enell
Message:

added the section from the draft file

Location:
trunk/doc/src/docbook
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/src/docbook/admindoc/plugin_installation.xml

    r3176 r3178  
    100100    which can be used for all import plugins that supports automatic detection of file formats.
    101101    Read more about this in the
    102     <xref linkend="plugin_developer.import_plugins"/>
     102    <xref linkend="plugin_developer.import"/>
    103103    chapter.
    104104  </para>
  • trunk/doc/src/docbook/developerdoc/plugin_developer.xml

    r3175 r3178  
    2929<chapter id="plugin_developer">
    3030  <title>Plugin developer</title>
    31   <sect1 id="plugin_developer.interfaces">
    32     <title>The plugin interfaces</title>
     31  <sect1 id="plugin_developer.organize">
     32    <title>How to organize your plugin project</title>
     33   
     34    <sect2 id="plugin_developer.organize.ant">
     35      <title>Using Ant</title>
     36      <para>
     37        Here is a simple example of how you might organize your project using ant (
     38        <ulink url="http://ant.apache.org">http://ant.apache.org</ulink>
     39        ) as the build tool. This is just a recommendation that we have found to be working
     40        well. You may choose to do it another way.
     41      </para>
     42
     43      <sect3 id="plugin_developer.organize.ant.directories">
     44        <title>Directory layout</title>
     45        <para>
     46          <literallayout>
     47<filename class="directory"><replaceable>pluginname</replaceable>/</filename>
     48<filename class="directory"><replaceable>pluginname</replaceable>/bin/</filename>
     49<filename class="directory"><replaceable>pluginname</replaceable>/lib/</filename>
     50<filename class="directory"><replaceable>pluginname</replaceable>/src/<replaceable>org/company</replaceable>/</filename>
     51          </literallayout>
     52          The
     53          <filename class="directory">bin/</filename>
     54          directory is empty to start with. It will contain the compiled code. The
     55          <filename class="directory">lib/</filename>
     56          directory contains the JAR files your plugin uses (including the
     57          <filename>BASE2Core.jar</filename>
     58          ). The
     59          <filename class="directory">src/</filename>
     60          directory contains your source code.
     61        </para>
     62      </sect3>
     63   
     64      <sect3 id="plugin_developer.organize.ant.buildfile">
     65        <title>The build file</title>
     66        <para>
     67          In the root of your directory, create the build file:
     68          <filename>build.xml</filename>
     69          . Here is an example that will compile your plugin and put it in a JAR file.
     70        </para>
     71        <example id="plugin_developer.organize.build.file">
     72          <title>A simple build file</title>
     73          <programlisting>
     74&lt;?xml version="1.0" encoding="UTF-8"?&gt;
     75&lt;project
     76   name="MyPlugin"
     77   default="build.plugin"
     78   basedir="."
     79   &gt;
     80
     81   &lt;!-- variables used --&gt;
     82   &lt;property name="plugin.name" value="MyPlugin" /&gt;
     83   &lt;property name="src" value="src" /&gt;
     84   &lt;property name="bin" value="bin" /&gt;
     85
     86   &lt;!-- set up classpath for compiling --&gt;
     87   &lt;path id="classpath"&gt;
     88      &lt;fileset dir="lib"&gt;
     89         &lt;include name="**/*.jar"/&gt;
     90      &lt;/fileset&gt;
     91   &lt;/path&gt;
     92
     93   
     94   &lt;!-- main target --&gt;
     95   &lt;target
     96      name="build.plugin" 
     97      description="Compiles the plugin and put in jar"
     98      &gt;
     99      &lt;javac
     100         encoding="ISO-8859-1"
     101         srcdir="${src}"
     102         destdir="${bin}"
     103         classpathref="classpath"&gt;
     104      &lt;/javac&gt;
     105      &lt;jar
     106         jarfile="${plugin.name}.jar"
     107         basedir="bin"
     108         manifest="MANIFEST.MF"
     109         &gt;
     110      &lt;/jar&gt;
     111
     112    &lt;/target&gt;
     113&lt;/project&gt;
     114          </programlisting>
     115        </example>
     116        <para>
     117          If your plugin depends on other JAR files than the
     118          <filename>Base2Core.jar</filename>
     119          you should list them in the
     120          <filename>MANIFEST.MF</filename>
     121          file. Otherwise you should remove the manifest attribute of the jar tag in the build
     122          file.
     123          <programlisting>
     124Manifest-Version: 1.0
     125Class-Path: OtherJar.jar ASecondJar.jar
     126          </programlisting>
     127        </para>
     128      </sect3>
     129       
     130      <sect3 id="plugin_developer.organize.ant.build">
     131        <title>Building the plugin</title>
     132        <para>
     133          Compile the plugin simply by typing
     134          <command>ant</command>
     135          in the console window. If all went well the
     136          <filename>MyPlugin.jar</filename>
     137          will be created in the same directory.
     138        </para>
     139        <para>
     140          To install the plugin copy the JAR file to the server including the dependent JAR
     141          files (if any). Place all files together in the same directory. Then follow the
     142          instructions in chapter
     143          <xref linkend="plugin_installation" />
     144          .
     145        </para>
     146      </sect3>
     147    </sect2>
     148   
     149    <sect2 id="plugin_developer.organize.eclipse">
     150      <title>With Eclipse</title>
     151      <para></para>
     152    </sect2>
     153   
     154    <sect2 id="plugin_developer.organize.installing">
     155      <title>Packaging and installing the plugin</title>
     156      <para></para>
     157    </sect2>
     158  </sect1>
     159
     160  <sect1 id="plugin_developer.api">
     161    <title>The Plugin API</title>
    33162    <para>
    34       The Base2 core defined two interfaces that are vital for implementing plugins.
    35       <itemizedlist spacing="compact">
    36         <listitem>
    37           <simpara>net.sf.basedb.core.plugin.Plugin</simpara>
    38         </listitem>
    39         <listitem>
    40           <simpara>net.sf.basedb.core.plugin.InteractivePlugin</simpara>
    41         </listitem>
    42       </itemizedlist>
    43       It is required that the
    44       <interfacename>Plugin</interfacename>
    45       interface is implemented, but the
    46       <interfacename>InteractivePlugin</interfacename>
    47       is optional, and is only needed if you want user interaction.
    48163    </para>
    49 
    50     <sect2 id="plugin_developer.interfaces.plugin">
    51       <title>The Plugin interface</title>
    52       <para>This interface defines seven methods and must be implemented by all plugins.</para>
    53       <variablelist>
    54         <varlistentry>
    55           <term>
    56             <methodsynopsis language="java">
    57               <modifier>public</modifier>
    58               <type>About</type>
    59               <methodname>getAbout</methodname>
    60               <void />
    61             </methodsynopsis>
    62           </term>
     164   
     165    <sect2 id="plugin_developer.api.interfaces">
     166   
     167      <title>The plugin interfaces</title>
     168      <para>
     169        The Base2 core defined two interfaces that are vital for implementing plugins.
     170        <itemizedlist spacing="compact">
    63171          <listitem>
    64             <para>
    65               Return information about the plugin, i.e. the name, version, and a short
    66               description about what the plugin does. The
    67               <classname>About</classname>
    68               object also has fields for naming the author and various other contact
    69               information. The returned information is copied by the core at
    70               installation time into the database. The only required information is
    71               the name of the plugin. All other fields may have null values.
    72             </para>
    73             <example id="net.sf.basedb.core.plugin.Plugin.getAbout">
    74               <title>A typical implementation stores this information in a static field</title>
    75               <programlisting>
     172            <simpara>
     173              <interfacename>net.sf.basedb.core.plugin.Plugin</interfacename>
     174            </simpara>
     175          </listitem>
     176          <listitem>
     177            <simpara>
     178              <interfacename>net.sf.basedb.core.plugin.InteractivePlugin</interfacename>
     179            </simpara>
     180          </listitem>
     181        </itemizedlist>
     182        It is required that the
     183        <interfacename>Plugin</interfacename>
     184        interface is implemented, but the
     185        <interfacename>InteractivePlugin</interfacename>
     186        is optional, and is only needed if you want user interaction.
     187      </para>
     188 
     189      <sect3 id="plugin_developer.api.interfaces.plugin">
     190        <title>net.sf.basedb.core.plugin.Plugin</title>
     191        <para>This interface defines seven methods and must be implemented by all plugins.</para>
     192        <variablelist>
     193          <varlistentry>
     194            <term>
     195              <methodsynopsis language="java">
     196                <modifier>public</modifier>
     197                <type>About</type>
     198                <methodname>getAbout</methodname>
     199                <void />
     200              </methodsynopsis>
     201            </term>
     202            <listitem>
     203              <para>
     204                Return information about the plugin, i.e. the name, version, and a short
     205                description about what the plugin does. The
     206                <classname>About</classname>
     207                object also has fields for naming the author and various other contact
     208                information. The returned information is copied by the core at
     209                installation time into the database. The only required information is
     210                the name of the plugin. All other fields may have null values.
     211              </para>
     212              <example id="net.sf.basedb.core.plugin.Plugin.getAbout">
     213                <title>A typical implementation stores this information in a static field</title>
     214                <programlisting>
    76215private static final About about = new AboutImpl
    77216(
     
    90229   return about;
    91230}
    92               </programlisting>
    93             </example>
    94           </listitem>
    95         </varlistentry>
    96         <varlistentry>
    97           <term>
    98             <methodsynopsis language="java">
    99               <modifier>public</modifier>
    100               <type>Plugin.MainType</type>
    101               <methodname>getMainType</methodname>
    102               <void />
    103             </methodsynopsis>
    104           </term>
    105           <listitem>
    106             <para>
    107               Return information about the main type of plugin. The
    108               <classname>MainType</classname>
    109               is an enumeration which defines five possible values:
    110               <itemizedlist>
    111                 <listitem>
    112                   <para>
    113                     <constant>ANALYZE</constant>
    114                     : An analysis plugin
    115                   </para>
    116                 </listitem>
    117                 <listitem>
    118                   <para>
    119                     <constant>EXPORT</constant>
    120                     : A plugin the exports data
    121                   </para>
    122                 </listitem>
    123                 <listitem>
    124                   <para>
    125                     <constant>IMPORT</constant>
    126                     : A plugin that imports data
    127                   </para>
    128                 </listitem>
    129                 <listitem>
    130                   <para>
    131                     <constant>INTENSITY</constant>
    132                     : A plugin that calculates the original spot intensities
    133                     from raw data
    134                   </para>
    135                 </listitem>
    136                 <listitem>
    137                   <para>
    138                     <constant>OTHER</constant>
    139                     : Any other type of plugin
    140                   </para>
    141                 </listitem>
    142               </itemizedlist>
    143               The returned value is stored in the database but is otherwise not used
    144               by the core. Client applications (such as the web client) will probably
    145               use this information to group the plugins, i.e., a button labeled Export
    146               will let you select among the export plugins.
    147             </para>
    148             <example id="net.sf.basedb.core.plugin.Plugin.getMainType">
    149               <title>A typical implementation just return one of the values</title>
    150               <programlisting>
     231                </programlisting>
     232              </example>
     233            </listitem>
     234          </varlistentry>
     235          <varlistentry>
     236            <term>
     237              <methodsynopsis language="java">
     238                <modifier>public</modifier>
     239                <type>Plugin.MainType</type>
     240                <methodname>getMainType</methodname>
     241                <void />
     242              </methodsynopsis>
     243            </term>
     244            <listitem>
     245              <para>
     246                Return information about the main type of plugin. The
     247                <classname>MainType</classname>
     248                is an enumeration which defines five possible values:
     249                <itemizedlist>
     250                  <listitem>
     251                    <para>
     252                      <constant>ANALYZE</constant>
     253                      : An analysis plugin
     254                    </para>
     255                  </listitem>
     256                  <listitem>
     257                    <para>
     258                      <constant>EXPORT</constant>
     259                      : A plugin the exports data
     260                    </para>
     261                  </listitem>
     262                  <listitem>
     263                    <para>
     264                      <constant>IMPORT</constant>
     265                      : A plugin that imports data
     266                    </para>
     267                  </listitem>
     268                  <listitem>
     269                    <para>
     270                      <constant>INTENSITY</constant>
     271                      : A plugin that calculates the original spot intensities
     272                      from raw data
     273                    </para>
     274                  </listitem>
     275                  <listitem>
     276                    <para>
     277                      <constant>OTHER</constant>
     278                      : Any other type of plugin
     279                    </para>
     280                  </listitem>
     281                </itemizedlist>
     282                The returned value is stored in the database but is otherwise not used
     283                by the core. Client applications (such as the web client) will probably
     284                use this information to group the plugins, i.e., a button labeled Export
     285                will let you select among the export plugins.
     286              </para>
     287              <example id="net.sf.basedb.core.plugin.Plugin.getMainType">
     288                <title>A typical implementation just return one of the values</title>
     289                <programlisting>
    151290public Plugin.MainType getMainType()
    152291{
    153292   return Plugin.MainType.OTHER;
    154293}
    155               </programlisting>
    156             </example>
    157           </listitem>
    158         </varlistentry>
    159         <varlistentry>
    160           <term>
    161             <methodsynopsis language="java">
    162               <modifier>public</modifier>
    163               <type>boolean</type>
    164               <methodname>supportsConfigurations</methodname>
    165               <void />
    166             </methodsynopsis>
    167           </term>
    168           <listitem>
    169             <para>
    170               If this method returns true the plugin can have different
    171               configurations, (i.e.
    172               <classname>PluginConfiguration</classname>
    173               ). Note that this method may return true even if the
    174               <interfacename>InteractivePlugin</interfacename>
    175               interface isn't implemented. The
    176               <classname>AbstractPlugin</classname>
    177               returns true for this method which is the old way before the
    178               introduction of this method.
    179             </para>
    180           </listitem>
    181         </varlistentry>
    182         <varlistentry>
    183           <term>
    184             <methodsynopsis language="java">
    185               <modifier>public</modifier>
    186               <type>boolean</type>
    187               <methodname>requiresConfiguration</methodname>
    188               <void />
    189             </methodsynopsis>
    190           </term>
    191           <listitem>
    192             <para>
    193               If this method returns true a Job can't be created without a
    194               configuration. The
    195               <classname>AbstractPlugin</classname>
    196               returns false for this method which is the old way before the
    197               introduction of this method.
    198             </para>
    199           </listitem>
    200         </varlistentry>
    201         <varlistentry>
    202           <term>
    203             <methodsynopsis language="java">
    204               <modifier>public</modifier>
    205               <void />
    206               <methodname>init</methodname>
    207               <methodparam>
    208                 <type>SessionControl</type>
    209                 <parameter>sc</parameter>
    210               </methodparam>
    211               <methodparam>
    212                 <type>ParameterValues</type>
    213                 <parameter>configuration</parameter>
    214               </methodparam>
    215               <methodparam>
    216                 <type>ParameterValues</type>
    217                 <parameter>job</parameter>
    218               </methodparam>
    219             </methodsynopsis>
    220           </term>
    221           <listitem>
    222             <para>
    223               Prepare the plugin for execution (or configuration). If the plugin needs
    224               to do some initialization this is the place to do it. A typical
    225               implementation however only stores the passed parameters in instance
    226               variables for later use.
    227             </para>
    228             <para>
    229               The parameters passed to this method has vital information that is
    230               needed to execute the plugin. The
    231               <classname>SessionControl</classname>
    232               is a central core object which holds information about the logged in
    233               user and allows you to create
    234               <classname>DbControl</classname>
    235               objects which allows a plugin to connect to the database to read, add or
    236               update information. The two
    237               <classname>ParameterValues</classname>
    238               objects contains information about the parameters to the plugin. The
    239               configuration object holds all parameters stored together with a
    240               <classname>PluginConfiguration</classname>
    241               object in the database. The job object holds all parameters that are
    242               stored together with a Job object in the database.
    243             </para>
    244             <para>
    245               The difference between a plugin configuration and a job parameter is
    246               that a configuration is usually something an administrator sets up,
    247               while a job is an actual execution of a plugin. For example a
    248               configuration for an import plugin holds the regular expressions needed
    249               to parse a text file and find the headers, sections and data lines,
    250               while the job holds the file to parse.
    251             </para>
    252             <para>
    253               The
    254               <classname>AbstractPlugin</classname>
    255               contains an implementation of this method make the passed parameters
    256               available as protected instance variables. We recommend plugin
    257               developers to let their plugins extend this class since it also has some
    258               other useful methods. For example for validating parameters resulting
    259               from user interaction and to store these values in the database.
    260             </para>
    261             <example id="net.sf.basedb.core.plugin.Plugin.init">
    262               <title>The <classname>AbstractPlugin</classname> implementation of this method</title>
    263               <programlisting>
     294                </programlisting>
     295              </example>
     296            </listitem>
     297          </varlistentry>
     298          <varlistentry>
     299            <term>
     300              <methodsynopsis language="java">
     301                <modifier>public</modifier>
     302                <type>boolean</type>
     303                <methodname>supportsConfigurations</methodname>
     304                <void />
     305              </methodsynopsis>
     306            </term>
     307            <listitem>
     308              <para>
     309                If this method returns true the plugin can have different
     310                configurations, (i.e.
     311                <classname>PluginConfiguration</classname>
     312                ). Note that this method may return true even if the
     313                <interfacename>InteractivePlugin</interfacename>
     314                interface isn't implemented. The
     315                <classname>AbstractPlugin</classname>
     316                returns true for this method which is the old way before the
     317                introduction of this method.
     318              </para>
     319            </listitem>
     320          </varlistentry>
     321          <varlistentry>
     322            <term>
     323              <methodsynopsis language="java">
     324                <modifier>public</modifier>
     325                <type>boolean</type>
     326                <methodname>requiresConfiguration</methodname>
     327                <void />
     328              </methodsynopsis>
     329            </term>
     330            <listitem>
     331              <para>
     332                If this method returns true a Job can't be created without a
     333                configuration. The
     334                <classname>AbstractPlugin</classname>
     335                returns false for this method which is the old way before the
     336                introduction of this method.
     337              </para>
     338            </listitem>
     339          </varlistentry>
     340          <varlistentry>
     341            <term>
     342              <methodsynopsis language="java">
     343                <modifier>public</modifier>
     344                <void />
     345                <methodname>init</methodname>
     346                <methodparam>
     347                  <type>SessionControl</type>
     348                  <parameter>sc</parameter>
     349                </methodparam>
     350                <methodparam>
     351                  <type>ParameterValues</type>
     352                  <parameter>configuration</parameter>
     353                </methodparam>
     354                <methodparam>
     355                  <type>ParameterValues</type>
     356                  <parameter>job</parameter>
     357                </methodparam>
     358              </methodsynopsis>
     359            </term>
     360            <listitem>
     361              <para>
     362                Prepare the plugin for execution (or configuration). If the plugin needs
     363                to do some initialization this is the place to do it. A typical
     364                implementation however only stores the passed parameters in instance
     365                variables for later use.
     366              </para>
     367              <para>
     368                The parameters passed to this method has vital information that is
     369                needed to execute the plugin. The
     370                <classname>SessionControl</classname>
     371                is a central core object which holds information about the logged in
     372                user and allows you to create
     373                <classname>DbControl</classname>
     374                objects which allows a plugin to connect to the database to read, add or
     375                update information. The two
     376                <classname>ParameterValues</classname>
     377                objects contains information about the parameters to the plugin. The
     378                configuration object holds all parameters stored together with a
     379                <classname>PluginConfiguration</classname>
     380                object in the database. The job object holds all parameters that are
     381                stored together with a Job object in the database.
     382              </para>
     383              <para>
     384                The difference between a plugin configuration and a job parameter is
     385                that a configuration is usually something an administrator sets up,
     386                while a job is an actual execution of a plugin. For example a
     387                configuration for an import plugin holds the regular expressions needed
     388                to parse a text file and find the headers, sections and data lines,
     389                while the job holds the file to parse.
     390              </para>
     391              <para>
     392                The
     393                <classname>AbstractPlugin</classname>
     394                contains an implementation of this method make the passed parameters
     395                available as protected instance variables. We recommend plugin
     396                developers to let their plugins extend this class since it also has some
     397                other useful methods. For example for validating parameters resulting
     398                from user interaction and to store these values in the database.
     399              </para>
     400              <example id="net.sf.basedb.core.plugin.Plugin.init">
     401                <title>The <classname>AbstractPlugin</classname> implementation of this method</title>
     402                <programlisting>
    264403protected SessionControl sc = null;
    265404protected ParameterValues configuration = null;
     
    279418   this.job = job;
    280419}
    281               </programlisting>
    282             </example>
    283           </listitem>
    284         </varlistentry>
    285         <varlistentry>
    286           <term>
    287             <methodsynopsis language="java">
    288               <modifier>public</modifier>
    289               <void />
    290               <methodname>run</methodname>
    291               <methodparam>
    292                 <type>Request</type>
    293                 <parameter>request</parameter>
    294               </methodparam>
    295               <methodparam>
    296                 <type>Response</type>
    297                 <parameter>response</parameter>
    298               </methodparam>
    299               <methodparam>
    300                 <type>ProgressReporter</type>
    301                 <parameter>progress</parameter>
    302               </methodparam>
    303               <exceptionname>BaseException</exceptionname>
    304             </methodsynopsis>
    305           </term>
    306           <listitem>
    307             <para>
    308               Runs the plugin. The
    309               <classname>Request</classname>
    310               parameter has no useful information and can be ignored. It was
    311               originally used for passing parameters to the plugin but this is now
    312               found in the two
    313               <classname>ParameterValues</classname>
    314               objects passed to the init method.
    315             </para>
    316             <para>
    317               The
    318               <classname>ProgressReporter</classname>
    319               can be used by a plugin to report it's progress back to the core. The
    320               core will usually send the progress information to the database, which
    321               allows users to see exactly how the plugin is progressing from the web
    322               interface. This parameter can be null, but if it isn't we recommend all
    323               plugins to use it. However, it should be used sparingly, since each call
    324               to set the progress results in a database update. If the execution
    325               involves several thousands of items it is a bad idea to update the
    326               progress after processing each one of them. A good starting point is to
    327               divide the work into 100 pieces each representing 1% of the work, i.e.,
    328               if the plugin should export 100 000 items it should report progress
    329               after every 1000 items.
    330             </para>
    331             <para>
    332               The
    333               <classname>Response</classname>
    334               parameter is used to tell the core if the plugin was successful or
    335               failed. Not setting a response is considered a failure by the core. From
    336               the run method it is only allowed to use the
    337               <methodname>setDone()</methodname>
    338               or the
    339               <methodname>setError()</methodname>
    340               methods.
    341             </para>
    342             <example id="net.sf.basedb.core.plugin.Plugin.run">
    343               <title>
    344                 Here is a skeleton that we recommend each plugin to use in it's
    345                 implementation of the
    346                 <methodname>run()</methodname>
    347                 method
    348               </title>
    349               <programlisting>
     420                </programlisting>
     421              </example>
     422            </listitem>
     423          </varlistentry>
     424          <varlistentry>
     425            <term>
     426              <methodsynopsis language="java">
     427                <modifier>public</modifier>
     428                <void />
     429                <methodname>run</methodname>
     430                <methodparam>
     431                  <type>Request</type>
     432                  <parameter>request</parameter>
     433                </methodparam>
     434                <methodparam>
     435                  <type>Response</type>
     436                  <parameter>response</parameter>
     437                </methodparam>
     438                <methodparam>
     439                  <type>ProgressReporter</type>
     440                  <parameter>progress</parameter>
     441                </methodparam>
     442                <exceptionname>BaseException</exceptionname>
     443              </methodsynopsis>
     444            </term>
     445            <listitem>
     446              <para>
     447                Runs the plugin. The
     448                <classname>Request</classname>
     449                parameter has no useful information and can be ignored. It was
     450                originally used for passing parameters to the plugin but this is now
     451                found in the two
     452                <classname>ParameterValues</classname>
     453                objects passed to the init method.
     454              </para>
     455              <para>
     456                The
     457                <classname>ProgressReporter</classname>
     458                can be used by a plugin to report it's progress back to the core. The
     459                core will usually send the progress information to the database, which
     460                allows users to see exactly how the plugin is progressing from the web
     461                interface. This parameter can be null, but if it isn't we recommend all
     462                plugins to use it. However, it should be used sparingly, since each call
     463                to set the progress results in a database update. If the execution
     464                involves several thousands of items it is a bad idea to update the
     465                progress after processing each one of them. A good starting point is to
     466                divide the work into 100 pieces each representing 1% of the work, i.e.,
     467                if the plugin should export 100 000 items it should report progress
     468                after every 1000 items.
     469              </para>
     470              <para>
     471                The
     472                <classname>Response</classname>
     473                parameter is used to tell the core if the plugin was successful or
     474                failed. Not setting a response is considered a failure by the core. From
     475                the run method it is only allowed to use the
     476                <methodname>setDone()</methodname>
     477                or the
     478                <methodname>setError()</methodname>
     479                methods.
     480              </para>
     481              <example id="net.sf.basedb.core.plugin.Plugin.run">
     482                <title>
     483                  Here is a skeleton that we recommend each plugin to use in it's
     484                  implementation of the
     485                  <methodname>run()</methodname>
     486                  method
     487                </title>
     488                <programlisting>
    350489public void run(Request request, Response response, ProgressReporter progress)
    351490{
     
    373512   }
    374513}
    375               </programlisting>
    376             </example>
    377           </listitem>
    378         </varlistentry>
    379         <varlistentry>
    380           <term>
    381             <methodsynopsis language="java">
    382               <modifier>public</modifier>
    383               <void />
    384               <methodname>done</methodname>
    385               <void />
    386             </methodsynopsis>
    387           </term>
    388           <listitem>
    389             <para>
    390               Clean up all resources after executing the plugin. This method mustn't
    391               throw any exceptions.
    392             </para>
    393             <example id="net.sf.basedb.core.plugin.Plugin.done">
    394               <title>
    395                 The
    396                 <classname>AbstractPlugin</classname>
    397                 contains an implementation of this method which simply sets the
    398                 parameters passed to the
    399                 <methodname>init()</methodname>
    400                 method to null
    401               </title>
    402               <programlisting>
     514                </programlisting>
     515              </example>
     516            </listitem>
     517          </varlistentry>
     518          <varlistentry>
     519            <term>
     520              <methodsynopsis language="java">
     521                <modifier>public</modifier>
     522                <void />
     523                <methodname>done</methodname>
     524                <void />
     525              </methodsynopsis>
     526            </term>
     527            <listitem>
     528              <para>
     529                Clean up all resources after executing the plugin. This method mustn't
     530                throw any exceptions.
     531              </para>
     532              <example id="net.sf.basedb.core.plugin.Plugin.done">
     533                <title>
     534                  The
     535                  <classname>AbstractPlugin</classname>
     536                  contains an implementation of this method which simply sets the
     537                  parameters passed to the
     538                  <methodname>init()</methodname>
     539                  method to null
     540                </title>
     541                <programlisting>
    403542/**
    404543   Clears the variables set by the init method. If a subclass
     
    411550   sc = null;
    412551}
    413               </programlisting>
    414             </example>
    415           </listitem>
    416         </varlistentry>
    417       </variablelist>
    418     </sect2>
    419 
    420     <sect2 id="plugin_developer.interfaces.interactive">
    421       <title>The InteractivePlugin interface</title>
    422       <para>
    423         If you want the plugin to be able to interact with the user you must also implement
    424         this interface. This is probably the case for most plugins. Among the plugins
    425         supplied with the core of Base the
    426         <classname>SpotImageCreator</classname>
    427         is one plugin that doesn't interact with the user. Instead, the web client has
    428         special JSP pages that handles all the interaction, creates a job for it and sets
    429         the parameters. This, kind of hardcoded, approach can be used for other plugins as
    430         well, but then it usually requires modification of the client application as well.
    431       </para>
    432       <para>
    433         The
    434         <interfacename>InteractivePlugin</interfacename>
    435         has three main tasks: tell a client application where the plugin should be plugged
    436         in, ask users for parameters, and validate and store those parameters. It requires
    437         the implementation of four method.
    438       </para>
    439       <variablelist>
    440         <varlistentry>
    441           <term>
    442             <methodsynopsis language="java">
    443               <modifier>public</modifier>
    444               <type>Set&lt;GuiContext&gt;</type>
    445               <methodname>getGuiContexts</methodname>
    446               <void />
    447             </methodsynopsis>
    448           </term>
    449           <listitem>
    450             <para>
    451               Return information about where the plugin should be plugged in. Each
    452               place is identified by a
    453               <classname>GuiContext</classname>
    454               object, which is an
    455               <classname>Item</classname>
    456               and a
    457               <classname>Type</classname>
    458               . The item is one of the objects defined by the
    459               <classname>net.sf.basedb.core.Item</classname>
    460               enumeration and the type is either
    461               <constant>Type.LIST</constant>
    462               or
    463               <constant>Type.ITEM</constant>
    464               .
    465             </para>
    466             <para>
    467               For example, the
    468               <varname>GuiContext</varname>
    469               <literal>= (</literal>
    470               <constant>Item.REPORTER</constant>
    471               <literal>,</literal>
    472               <constant>Type.LIST</constant>
    473               <literal>)</literal>
    474               tells a client application that this plugin can be plugged in whenever a
    475               list of reporters is displayed. The
    476               <varname>GuiContext</varname>
    477               = (
    478               <constant>Item.REPORTER</constant>
    479               ,
    480               <constant>Type.ITEM</constant>
    481               ) tells a client application that this plugin can be plugged in whenever
    482               a single reporter is displayed. The first case may be appropriate for a
    483               plugin that imports or exports reporters. The second case may be used by
    484               a plugin that updates the reporter information from an external source
    485               (well, it may make sense to use this in the list case as well).
    486             </para>
    487             <para>
    488               The returned information is copied by the core at installation time to
    489               make it easy to ask for all plugins for a certain
    490               <classname>GuiContext</classname>
    491               .
    492             </para>
    493             <para>
    494               A typical implementation creates a static unmodifiable
    495               <classname>Set</classname>
    496               which is returned by this method. It is important that the returned set
    497               can't be modified, since it may be a security issue if a bad behaving
    498               client application does that.
    499             </para>
    500             <example id="net.sf.basedb.core.plugin.InteractivePlugin.getGuiContexts">
    501               <title>
    502                 A typical implementation of
     552                </programlisting>
     553              </example>
     554            </listitem>
     555          </varlistentry>
     556        </variablelist>
     557      </sect3>
     558 
     559      <sect3 id="plugin_developer.api.interfaces.interactive">
     560        <title>net.sf.basedb.core.plugin.InteractivePlugin</title>
     561        <para>
     562          If you want the plugin to be able to interact with the user you must also implement
     563          this interface. This is probably the case for most plugins. Among the plugins
     564          supplied with the core of Base the
     565          <classname>SpotImageCreator</classname>
     566          is one plugin that doesn't interact with the user. Instead, the web client has
     567          special JSP pages that handles all the interaction, creates a job for it and sets
     568          the parameters. This, kind of hardcoded, approach can be used for other plugins as
     569          well, but then it usually requires modification of the client application as well.
     570        </para>
     571        <para>
     572          The
     573          <interfacename>InteractivePlugin</interfacename>
     574          has three main tasks: tell a client application where the plugin should be plugged
     575          in, ask users for parameters, and validate and store those parameters. It requires
     576          the implementation of four method.
     577        </para>
     578        <variablelist>
     579          <varlistentry>
     580            <term>
     581              <methodsynopsis language="java">
     582                <modifier>public</modifier>
     583                <type>Set&lt;GuiContext&gt;</type>
    503584                <methodname>getGuiContexts</methodname>
    504               </title>
    505               <programlisting>
     585                <void />
     586              </methodsynopsis>
     587            </term>
     588            <listitem>
     589              <para>
     590                Return information about where the plugin should be plugged in. Each
     591                place is identified by a
     592                <classname>GuiContext</classname>
     593                object, which is an
     594                <classname>Item</classname>
     595                and a
     596                <classname>Type</classname>
     597                . The item is one of the objects defined by the
     598                <classname>net.sf.basedb.core.Item</classname>
     599                enumeration and the type is either
     600                <constant>Type.LIST</constant>
     601                or
     602                <constant>Type.ITEM</constant>
     603                .
     604              </para>
     605              <para>
     606                For example, the
     607                <varname>GuiContext</varname>
     608                <literal>= (</literal>
     609                <constant>Item.REPORTER</constant>
     610                <literal>,</literal>
     611                <constant>Type.LIST</constant>
     612                <literal>)</literal>
     613                tells a client application that this plugin can be plugged in whenever a
     614                list of reporters is displayed. The
     615                <varname>GuiContext</varname>
     616                = (
     617                <constant>Item.REPORTER</constant>
     618                ,
     619                <constant>Type.ITEM</constant>
     620                ) tells a client application that this plugin can be plugged in whenever
     621                a single reporter is displayed. The first case may be appropriate for a
     622                plugin that imports or exports reporters. The second case may be used by
     623                a plugin that updates the reporter information from an external source
     624                (well, it may make sense to use this in the list case as well).
     625              </para>
     626              <para>
     627                The returned information is copied by the core at installation time to
     628                make it easy to ask for all plugins for a certain
     629                <classname>GuiContext</classname>
     630                .
     631              </para>
     632              <para>
     633                A typical implementation creates a static unmodifiable
     634                <classname>Set</classname>
     635                which is returned by this method. It is important that the returned set
     636                can't be modified, since it may be a security issue if a bad behaving
     637                client application does that.
     638              </para>
     639              <example id="net.sf.basedb.core.plugin.InteractivePlugin.getGuiContexts">
     640                <title>
     641                  A typical implementation of
     642                  <methodname>getGuiContexts</methodname>
     643                </title>
     644                <programlisting>
    506645// From the net.sf.basedb.plugins.RawDataFlatFileImporter plugin
    507646private static final Set&lt;GuiContext&gt; guiContexts =
     
    512651   return <returnvalue>guiContexts</returnvalue>;
    513652}
    514               </programlisting>
    515             </example>
    516           </listitem>
    517         </varlistentry>
    518         <varlistentry>
    519           <term>
    520             <methodsynopsis language="java">
    521               <modifier>public</modifier>
    522               <type>String</type>
    523               <methodname>isInContext</methodname>
    524               <methodparam>
    525                 <type>GuiContext</type>
    526                 <parameter>context</parameter>
    527               </methodparam>
    528               <methodparam>
    529                 <type>Object</type>
    530                 <parameter>item</parameter>
    531               </methodparam>
    532             </methodsynopsis>
    533           </term>
    534           <listitem>
    535             <para>
    536               This method is called to check if a particular item is usable for the
    537               plugin, when the context type is
    538               <constant>Type.ITEM</constant>
    539               , i.e. the user has selected a specific sample and the the client
    540               application is now displaying information about that sample. Thus, our
    541               <varname>GuiContext</varname>
    542               = (
    543               <constant>Item.SAMPLE</constant>
    544               ,
    545               <constant>Type.ITEM</constant>
    546               ). Now, the client application asks for a list of plugins supporting
    547               this context and for each one in the list calls this method with the
    548               current sample as the item parameter. The plugin should answer if it can
    549               do whatever it is supposed to do by returning null or a string
    550               containing a message why it can't.
    551             </para>
    552             <para>
    553               Here is a real example from the
    554               <classname>RawDataFlatFileImporter</classname>
    555               plugin which imports raw data to a
    556               <classname>RawBioAssay</classname>
    557               . Thus,
    558               <varname>GuiContext</varname>
    559               = (
    560               <constant>Item.RAWBIOASSAY</constant>
    561               ,
    562               <constant>Type.ITEM</constant>
    563               ), but the plugin can only import data if there isn't any already, and
    564               if the raw bioassay has the same raw data type as the plugin has been
    565               configured for.
    566             </para>
    567             <example id="net.sf.basedb.core.plugin.InteractivePlugin.isInContext">
    568               <title>
    569                 A simple implementation of
     653                </programlisting>
     654              </example>
     655            </listitem>
     656          </varlistentry>
     657          <varlistentry>
     658            <term>
     659              <methodsynopsis language="java">
     660                <modifier>public</modifier>
     661                <type>String</type>
    570662                <methodname>isInContext</methodname>
    571               </title>
    572               <programlisting>
     663                <methodparam>
     664                  <type>GuiContext</type>
     665                  <parameter>context</parameter>
     666                </methodparam>
     667                <methodparam>
     668                  <type>Object</type>
     669                  <parameter>item</parameter>
     670                </methodparam>
     671              </methodsynopsis>
     672            </term>
     673            <listitem>
     674              <para>
     675                This method is called to check if a particular item is usable for the
     676                plugin, when the context type is
     677                <constant>Type.ITEM</constant>
     678                , i.e. the user has selected a specific sample and the the client
     679                application is now displaying information about that sample. Thus, our
     680                <varname>GuiContext</varname>
     681                = (
     682                <constant>Item.SAMPLE</constant>
     683                ,
     684                <constant>Type.ITEM</constant>
     685                ). Now, the client application asks for a list of plugins supporting
     686                this context and for each one in the list calls this method with the
     687                current sample as the item parameter. The plugin should answer if it can
     688                do whatever it is supposed to do by returning null or a string
     689                containing a message why it can't.
     690              </para>
     691              <para>
     692                Here is a real example from the
     693                <classname>RawDataFlatFileImporter</classname>
     694                plugin which imports raw data to a
     695                <classname>RawBioAssay</classname>
     696                . Thus,
     697                <varname>GuiContext</varname>
     698                = (
     699                <constant>Item.RAWBIOASSAY</constant>
     700                ,
     701                <constant>Type.ITEM</constant>
     702                ), but the plugin can only import data if there isn't any already, and
     703                if the raw bioassay has the same raw data type as the plugin has been
     704                configured for.
     705              </para>
     706              <example id="net.sf.basedb.core.plugin.InteractivePlugin.isInContext">
     707                <title>
     708                  A simple implementation of
     709                  <methodname>isInContext</methodname>
     710                </title>
     711                <programlisting>
    573712/**
    574713   Returns null if the item is a {@link RawBioAssay} of the correct
     
    601740   return message;   
    602741}
    603               </programlisting>
    604             </example>
    605           </listitem>
    606         </varlistentry>
    607         <varlistentry>
    608           <term>
    609             <methodsynopsis language="java">
    610               <modifier>public</modifier>
    611               <type>RequestInformation</type>
    612               <methodname>getRequestInformation</methodname>
    613               <methodparam>
    614                 <type>GuiContext</type>
    615                 <parameter>context</parameter>
    616               </methodparam>
    617               <methodparam>
    618                 <type>String</type>
    619                 <parameter>command</parameter>
    620               </methodparam>
    621               <exceptionname>BaseException</exceptionname>
    622             </methodsynopsis>
    623           </term>
    624           <listitem>
    625             <para>
    626               Ask the plugin for parameters that needs to be entered by the user. The
    627               <classname>GuiContext</classname>
    628               parameter is one of the contexts returned by the
    629               <methodname>getGuiContexts</methodname>
    630               method. The command is string telling the plugin what command was
    631               executed. There are two predefined commands but as you will see the
    632               plugin may define it's own commands. The two predefined commands are
    633               defined in the
    634               <classname>net.sf.basedb.core.plugin.Request</classname>
    635               class.
    636               <variablelist>
    637                 <varlistentry>
    638                   <term>
    639                     <constant>Request.COMMAND_CONFIGURE_PLUGIN</constant>
    640                   </term>
    641                   <listitem>
    642                     <para>
    643                       Used when an administrator is initiating a configuration
    644                       of the plugin.
    645                     </para>
    646                   </listitem>
    647                 </varlistentry>
    648                 <varlistentry>
    649                   <term>
    650                     <constant>Request.COMMAND_CONFIGURE_JOB</constant>
    651                   </term>
    652                   <listitem>
    653                     <para>
    654                       Used when a user has selected the plugin for running a
    655                       job.
    656                     </para>
    657                   </listitem>
    658                 </varlistentry>
    659               </variablelist>
    660               Given this information the plugin must return a
    661               <classname>RequestInformation</classname>
    662               object. This is simply a title, a description and a list of parameters.
    663               Usually the title will end up as the input form title and the
    664               description as a help text for the entire form. Do not put information
    665               about the individual parameters in this description, since each
    666               parameter has a description of their own.
    667             </para>
    668             <example id="net.sf.basedb.core.plugin.InteractivePlugin.getRequestInformation_1">
    669               <title>
    670                 When running an import plugin it needs to ask for the file to import
    671                 from and if existing items should be updated or not
    672               </title>
    673               <programlisting>
     742                </programlisting>
     743              </example>
     744            </listitem>
     745          </varlistentry>
     746          <varlistentry>
     747            <term>
     748              <methodsynopsis language="java">
     749                <modifier>public</modifier>
     750                <type>RequestInformation</type>
     751                <methodname>getRequestInformation</methodname>
     752                <methodparam>
     753                  <type>GuiContext</type>
     754                  <parameter>context</parameter>
     755                </methodparam>
     756                <methodparam>
     757                  <type>String</type>
     758                  <parameter>command</parameter>
     759                </methodparam>
     760                <exceptionname>BaseException</exceptionname>
     761              </methodsynopsis>
     762            </term>
     763            <listitem>
     764              <para>
     765                Ask the plugin for parameters that needs to be entered by the user. The
     766                <classname>GuiContext</classname>
     767                parameter is one of the contexts returned by the
     768                <methodname>getGuiContexts</methodname>
     769                method. The command is string telling the plugin what command was
     770                executed. There are two predefined commands but as you will see the
     771                plugin may define it's own commands. The two predefined commands are
     772                defined in the
     773                <classname>net.sf.basedb.core.plugin.Request</classname>
     774                class.
     775                <variablelist>
     776                  <varlistentry>
     777                    <term>
     778                      <constant>Request.COMMAND_CONFIGURE_PLUGIN</constant>
     779                    </term>
     780                    <listitem>
     781                      <para>
     782                        Used when an administrator is initiating a configuration
     783                        of the plugin.
     784                      </para>
     785                    </listitem>
     786                  </varlistentry>
     787                  <varlistentry>
     788                    <term>
     789                      <constant>Request.COMMAND_CONFIGURE_JOB</constant>
     790                    </term>
     791                    <listitem>
     792                      <para>
     793                        Used when a user has selected the plugin for running a
     794                        job.
     795                      </para>
     796                    </listitem>
     797                  </varlistentry>
     798                </variablelist>
     799                Given this information the plugin must return a
     800                <classname>RequestInformation</classname>
     801                object. This is simply a title, a description and a list of parameters.
     802                Usually the title will end up as the input form title and the
     803                description as a help text for the entire form. Do not put information
     804                about the individual parameters in this description, since each
     805                parameter has a description of their own.
     806              </para>
     807              <example id="net.sf.basedb.core.plugin.InteractivePlugin.getRequestInformation_1">
     808                <title>
     809                  When running an import plugin it needs to ask for the file to import
     810                  from and if existing items should be updated or not
     811                </title>
     812                <programlisting>
    674813// The complete request information
    675814private RequestInformation configure Job;
     
    734873   return configureJob;
    735874}
    736               </programlisting>
    737             </example>
    738             <para>
    739               As you can see it takes some code to put together a
    740               <classname>RequestInformation</classname>
    741               object. For each parameter needed you need one
    742               <classname>PluginParameter</classname>
    743               object and one
    744               <classname>ParameterType</classname>
    745               object. Actually, a
    746               <classname>ParameterType</classname>
    747               can be reused for more than one
    748               <classname>PluginParameter</classname>
    749               .
    750             </para>
    751            
    752             <programlisting>
     875                </programlisting>
     876              </example>
     877              <para>
     878                As you can see it takes some code to put together a
     879                <classname>RequestInformation</classname>
     880                object. For each parameter needed you need one
     881                <classname>PluginParameter</classname>
     882                object and one
     883                <classname>ParameterType</classname>
     884                object. Actually, a
     885                <classname>ParameterType</classname>
     886                can be reused for more than one
     887                <classname>PluginParameter</classname>
     888                .
     889              </para>
     890             
     891              <programlisting>
    753892StringParameterType stringPT = new StringParameterType(255, null, true);
    754893PluginParameter one = new PluginParameter("one", "One", "First string", stringPT);
    755894PluginParameter two = new PluginParameter("two", "Two", "Second string", stringPT);
    756895// ... and so on
    757             </programlisting>
    758             <para>
    759               The
    760               <classname>ParameterType</classname>
    761               is an abstract base class for several subclasses each implementing a
    762               specific type of parameter. The list of subclasses may grow in the
    763               future, but here are the most important ones currently implemented.
    764             </para>
    765             <note>
    766               <para>
    767                 Most parameter types include support for supplying a predefined list
    768                 of options to select from. In that case the list will be displayed
    769                 as a drop-down list for the user, otherwise a free input field is
    770                 used.
    771               </para>
    772             </note>
    773             <variablelist>
    774               <varlistentry>
    775                 <term>
    776                   <classname>StringParameterType</classname>
    777                 </term>
    778                 <listitem>
    779                   <para>
    780                     Asks for a string value. Includes an option for
    781                     specifying the maximum length of the string.
    782                   </para>
    783                 </listitem>
    784               </varlistentry>
    785               <varlistentry>
    786                 <term>
    787                   <classname>FloatParameterType</classname>,
    788                   <classname>DoubleParameterType</classname>,
    789                   <classname>IntegerParameterType</classname>,
    790                   <classname>LongParameterType</classname>
    791                 </term>
    792                 <listitem>
    793                   <para>
    794                     Asks for numerical values. Includes options for
    795                     specifying a range (min/max) of allowed values.
    796                   </para>
    797                 </listitem>
    798               </varlistentry>
    799               <varlistentry>
    800                 <term>
    801                   <classname>BooleanParameterType</classname>
    802                 </term>
    803                 <listitem>
    804                   <para>Asks for a boolean value.
    805                   </para>
    806                 </listitem>
    807               </varlistentry>
    808               <varlistentry>
    809                 <term>
    810                   <classname>DateParameterType</classname>
    811                 </term>
    812                 <listitem>
    813                   <para>Asks for a date.
    814                   </para>
    815                 </listitem>
    816               </varlistentry>
    817               <varlistentry>
    818                 <term>
    819                   <classname>FileParameterType</classname>
    820                 </term>
    821                 <listitem>
    822                   <para>Asks for a file item.
    823                   </para>
    824                 </listitem>
    825               </varlistentry>
    826               <varlistentry>
    827                 <term>
    828                   <classname>ItemParameterType</classname>
    829                 </term>
    830                 <listitem>
    831                   <para>
    832                     Asks for any other item. This parameter type requires
    833                     that a list of options is supplied, except when the item
    834                     type asked for matches the current GuiContext, in which
    835                     case the currently selected item is used as the
    836                     parameter value.
    837                   </para>
    838                 </listitem>
    839               </varlistentry>
    840               <varlistentry>
    841                 <term>
    842                   <classname>PathParameterType</classname>
    843                 </term>
    844                 <listitem>
    845                   <para>
    846                     Ask for a path to a file or directory. The path may be
    847                     non-existing and should be used when a plugin needs an
    848                     output destination, i.e., the file to export to, or a
    849                     directory where the output files should be placed.
    850                   </para>
    851                 </listitem>
    852               </varlistentry>
    853             </variablelist>
    854             <para>
    855               You can also create a
    856               <classname>PluginParameter</classname>
    857               with a null name and
    858               <classname>ParameterType</classname>
    859               . In that case, the core will not ask for input from the user, instead
    860               it is used as a section header, allowing you to group parameters into
    861               different sections which increase the readability of the input
    862               parameters page.
    863             </para>
    864             <programlisting>
     896              </programlisting>
     897              <para>
     898                The
     899                <classname>ParameterType</classname>
     900                is an abstract base class for several subclasses each implementing a
     901                specific type of parameter. The list of subclasses may grow in the
     902                future, but here are the most important ones currently implemented.
     903              </para>
     904              <note>
     905                <para>
     906                  Most parameter types include support for supplying a predefined list
     907                  of options to select from. In that case the list will be displayed
     908                  as a drop-down list for the user, otherwise a free input field is
     909                  used.
     910                </para>
     911              </note>
     912              <variablelist>
     913                <varlistentry>
     914                  <term>
     915                    <classname>StringParameterType</classname>
     916                  </term>
     917                  <listitem>
     918                    <para>
     919                      Asks for a string value. Includes an option for
     920                      specifying the maximum length of the string.
     921                    </para>
     922                  </listitem>
     923                </varlistentry>
     924                <varlistentry>
     925                  <term>
     926                    <classname>FloatParameterType</classname>,
     927                    <classname>DoubleParameterType</classname>,
     928                    <classname>IntegerParameterType</classname>,
     929                    <classname>LongParameterType</classname>
     930                  </term>
     931                  <listitem>
     932                    <para>
     933                      Asks for numerical values. Includes options for
     934                      specifying a range (min/max) of allowed values.
     935                    </para>
     936                  </listitem>
     937                </varlistentry>
     938                <varlistentry>
     939                  <term>
     940                    <classname>BooleanParameterType</classname>
     941                  </term>
     942                  <listitem>
     943                    <para>Asks for a boolean value.
     944                    </para>
     945                  </listitem>
     946                </varlistentry>
     947                <varlistentry>
     948                  <term>
     949                    <classname>DateParameterType</classname>
     950                  </term>
     951                  <listitem>
     952                    <para>Asks for a date.
     953                    </para>
     954                  </listitem>
     955                </varlistentry>
     956                <varlistentry>
     957                  <term>
     958                    <classname>FileParameterType</classname>
     959                  </term>
     960                  <listitem>
     961                    <para>Asks for a file item.
     962                    </para>
     963                  </listitem>
     964                </varlistentry>
     965                <varlistentry>
     966                  <term>
     967                    <classname>ItemParameterType</classname>
     968                  </term>
     969                  <listitem>
     970                    <para>
     971                      Asks for any other item. This parameter type requires
     972                      that a list of options is supplied, except when the item
     973                      type asked for matches the current GuiContext, in which
     974                      case the currently selected item is used as the
     975                      parameter value.
     976                    </para>
     977                  </listitem>
     978                </varlistentry>
     979                <varlistentry>
     980                  <term>
     981                    <classname>PathParameterType</classname>
     982                  </term>
     983                  <listitem>
     984                    <para>
     985                      Ask for a path to a file or directory. The path may be
     986                      non-existing and should be used when a plugin needs an
     987                      output destination, i.e., the file to export to, or a
     988                      directory where the output files should be placed.
     989                    </para>
     990                  </listitem>
     991                </varlistentry>
     992              </variablelist>
     993              <para>
     994                You can also create a
     995                <classname>PluginParameter</classname>
     996                with a null name and
     997                <classname>ParameterType</classname>
     998                . In that case, the core will not ask for input from the user, instead
     999                it is used as a section header, allowing you to group parameters into
     1000                different sections which increase the readability of the input
     1001                parameters page.
     1002              </para>
     1003              <programlisting>
    8651004PluginParameter firstSection = new PluginParameter(null, "First section", null, null);
    8661005PluginParameter secondSection = new PluginParameter(null, "Second section", null, null);
     
    8741013parameters.add(firstParameterInSecondSection);
    8751014parameters.add(secondParameteInSecondSection);
    876             </programlisting>
    877           </listitem>
    878         </varlistentry>
    879         <varlistentry>
    880           <term>
    881             <methodsynopsis language="java">
    882               <modifier>public</modifier>
    883               <void />
    884               <methodname>configure</methodname>
    885               <methodparam>
    886                 <type>GuiContext</type>
    887                 <parameter>context</parameter>
    888               </methodparam>
    889               <methodparam>
    890                 <type>Request</type>
    891                 <parameter>request</parameter>
    892               </methodparam>
    893               <methodparam>
    894                 <type>Response</type>
    895                 <parameter>response</parameter>
    896               </methodparam>
    897             </methodsynopsis>
    898           </term>
    899           <listitem>
    900             <para>
    901               Sends parameter values entered by the user for processing by the plugin.
    902               Typically the plugin should validate that the parameter values are
    903               correct and then store them in database.
    904             </para>
    905             <para>
    906               No validation is done by the core, except converting the input to the
    907               correct object type, i.e. if the parameter asked for a
    908               <classname>Float</classname>
    909               the input string is parsed and converted to a Float. If you have
    910               extended the
    911               <classname>AbstractPlugin</classname>
    912               class it is very easy to validate the parameters using it's
    913               <methodname>validateRequestParameters()</methodname>
    914               method. This method takes the same list of
    915               <classname>PluginParameter</classname>
    916               's used in the
    917               <classname>RequestInformation</classname>
    918               object and uses that information for validation. It returns null or a
    919               list of
    920               <exceptionname>Throwable</exceptionname>
    921               .
    922             </para>
    923             <para>
    924               When the parameters have been validated they need to be stored. Once
    925               again, it is very easy if you use one of the
    926               <methodname>AbstractPlugin.storeValue()</methodname>
    927               or
    928               <methodname>AbstractPlugin.storeValues()</methodname>
    929               methods.
    930             </para>
    931             <para>
    932               The configure method works much like the
    933               <methodname>Plugin.run()</methodname>
    934               method. It must return the result in the
    935               <classname>Response</classname>
    936               object, i.e. it shouldn't trow any exceptions.
    937             </para>
    938             <example id="net.sf.basedb.core.plugin.InteractivePlugin.configure">
    939               <title>
    940                 Configuration implementation building on the examples above
    941               </title>
    942               <programlisting>
     1015              </programlisting>
     1016            </listitem>
     1017          </varlistentry>
     1018          <varlistentry>
     1019            <term>
     1020              <methodsynopsis language="java">
     1021                <modifier>public</modifier>
     1022                <void />
     1023                <methodname>configure</methodname>
     1024                <methodparam>
     1025                  <type>GuiContext</type>
     1026                  <parameter>context</parameter>
     1027                </methodparam>
     1028                <methodparam>
     1029                  <type>Request</type>
     1030                  <parameter>request</parameter>
     1031                </methodparam>
     1032                <methodparam>
     1033                  <type>Response</type>
     1034                  <parameter>response</parameter>
     1035                </methodparam>
     1036              </methodsynopsis>
     1037            </term>
     1038            <listitem>
     1039              <para>
     1040                Sends parameter values entered by the user for processing by the plugin.
     1041                Typically the plugin should validate that the parameter values are
     1042                correct and then store them in database.
     1043              </para>
     1044              <para>
     1045                No validation is done by the core, except converting the input to the
     1046                correct object type, i.e. if the parameter asked for a
     1047                <classname>Float</classname>
     1048                the input string is parsed and converted to a Float. If you have
     1049                extended the
     1050                <classname>AbstractPlugin</classname>
     1051                class it is very easy to validate the parameters using it's
     1052                <methodname>validateRequestParameters()</methodname>
     1053                method. This method takes the same list of
     1054                <classname>PluginParameter</classname>
     1055                's used in the
     1056                <classname>RequestInformation</classname>
     1057                object and uses that information for validation. It returns null or a
     1058                list of
     1059                <exceptionname>Throwable</exceptionname>
     1060                .
     1061              </para>
     1062              <para>
     1063                When the parameters have been validated they need to be stored. Once
     1064                again, it is very easy if you use one of the
     1065                <methodname>AbstractPlugin.storeValue()</methodname>
     1066                or
     1067                <methodname>AbstractPlugin.storeValues()</methodname>
     1068                methods.
     1069              </para>
     1070              <para>
     1071                The configure method works much like the
     1072                <methodname>Plugin.run()</methodname>
     1073                method. It must return the result in the
     1074                <classname>Response</classname>
     1075                object, i.e. it shouldn't trow any exceptions.
     1076              </para>
     1077              <example id="net.sf.basedb.core.plugin.InteractivePlugin.configure">
     1078                <title>
     1079                  Configuration implementation building on the examples above
     1080                </title>
     1081                <programlisting>
    9431082public void configure(GuiContext context, Request request, Response response)
    9441083{
     
    9761115   }
    9771116}
    978               </programlisting>
    979             </example>
    980             <para>
    981               Note that the
    982               <methodname>setDone()</methodname>
    983               has a second parameter
    984               <classname>Job.ExecutionTime</classname>
    985               . It is an indication about how long time it will take to execute the
    986               plugin. This is of interest for job queue managers which probably
    987               doesn't want to start too many long-running jobs at the same time
    988               blocking the entire system. Please try to use this parameter wisely and
    989               not use the
    990               <constant>Job.ExecutionTime.SHORT</constant>
    991               value out of old habit all the time.
    992             </para>
    993             <para>
    994               The response also has a
    995               <methodname>setContinue()</methodname>
    996               method which tells the core that the plugin needs more parameters,
    997               i.e. the core will then call
    998               <methodname>getRequestInformation()</methodname>
    999               again with the new command, let the user enter values, and the call
    1000               <methodname>configure()</methodname>
    1001               with the new values. This process is repeated until the plugin
    1002               reports that it is done or an error occurs.
    1003             </para>
    1004             <para>
    1005               An important note is that during this iteration it is the same instance
    1006               of the plugin that is used. However, no parameter values are stored in
    1007               the database until
    1008               <methodname>setDone()</methodname>
    1009               is called. Then, the plugin instance is usually discarded. The execution
    1010               of the plugin happens in a new instance and maybe on a different server.
    1011             </para>
    1012             <tip>
    1013                 <para>
    1014                   You don't have to store all values the plugin asked for in the
    1015                   first place. You may even choose to store different values than
    1016                   those that were entered. For example, you might ask for the mass
    1017                   and height of a person and then only store the body mass index,
    1018                   which is calculated from those values.
    1019                 </para>
    1020             </tip>
     1117                </programlisting>
     1118              </example>
     1119              <para>
     1120                Note that the
     1121                <methodname>setDone()</methodname>
     1122                has a second parameter
     1123                <classname>Job.ExecutionTime</classname>
     1124                . It is an indication about how long time it will take to execute the
     1125                plugin. This is of interest for job queue managers which probably
     1126                doesn't want to start too many long-running jobs at the same time
     1127                blocking the entire system. Please try to use this parameter wisely and
     1128                not use the
     1129                <constant>Job.ExecutionTime.SHORT</constant>
     1130                value out of old habit all the time.
     1131              </para>
     1132              <para>
     1133                The response also has a
     1134                <methodname>setContinue()</methodname>
     1135                method which tells the core that the plugin needs more parameters,
     1136                i.e. the core will then call
     1137                <methodname>getRequestInformation()</methodname>
     1138                again with the new command, let the user enter values, and the call
     1139                <methodname>configure()</methodname>
     1140                with the new values. This process is repeated until the plugin
     1141                reports that it is done or an error occurs.
     1142              </para>
     1143              <para>
     1144                An important note is that during this iteration it is the same instance
     1145                of the plugin that is used. However, no parameter values are stored in
     1146                the database until
     1147                <methodname>setDone()</methodname>
     1148                is called. Then, the plugin instance is usually discarded. The execution
     1149                of the plugin happens in a new instance and maybe on a different server.
     1150              </para>
     1151              <tip>
     1152                  <para>
     1153                    You don't have to store all values the plugin asked for in the
     1154                    first place. You may even choose to store different values than
     1155                    those that were entered. For example, you might ask for the mass
     1156                    and height of a person and then only store the body mass index,
     1157                    which is calculated from those values.
     1158                  </para>
     1159              </tip>
     1160            </listitem>
     1161          </varlistentry>
     1162        </variablelist>
     1163      </sect3>
     1164   
     1165    </sect2>
     1166 
     1167    <sect2 id="plugin_developer.api.parameters">
     1168      <title>Asking for parameters</title>
     1169      <para></para>
     1170     
     1171      <sect3 id="plugin_developer.api.parameters.jsp">
     1172        <title>Using custom JSP pages for parameters</title>
     1173        <para>
     1174          This is an advanced option for plugins that require a different interface for
     1175          specifying plugin parameters than the default list showing each parameter at a
     1176          time. This feature is used by setting the RequestInformation.getJspPage()
     1177          property when construction the request information object. If this property has
     1178          a non-null value, the web client will send the browser to the specified JSP page
     1179          instead of to the generic parameter input page.
     1180        </para>
     1181        <para>
     1182          When setting the JSP page you should not specify any path information. The web
     1183          client has a special location for these JSP pages, generated from the package
     1184          name of your plugin and the returned values. If the plugin is located in the
     1185          package
     1186          <classname>
     1187            <replaceable>org.company</replaceable>
     1188          </classname>
     1189          the JSP page must be located in
     1190          <filename class="directory">
     1191            <replaceable>www-root</replaceable>
     1192            /plugins/
     1193            <replaceable>org/company</replaceable>
     1194            /
     1195          </filename>
     1196          . Please note that the browser still thinks that it is showing the regular page
     1197          at the usual location:
     1198          <filename class="directory">
     1199            <replaceable>www-root</replaceable>
     1200            /common/plugin/index.jsp
     1201          </filename>
     1202          , so all links in your JSP page should be relative to that directory.
     1203        </para>
     1204        <para>
     1205          Even if you use your own JSP page we recommend that you use the built-in
     1206          facility for passing the parameters back to the plugin. For this to work you
     1207          must:
     1208        </para>
     1209        <itemizedlist spacing="compact">
     1210          <listitem>
     1211            <simpara>Generate the list of <classname>PluginParameter</classname> objects as usual</simpara>
    10211212          </listitem>
    1022         </varlistentry>
    1023       </variablelist>
    1024     </sect2>
    1025 
    1026   </sect1>
    1027 
    1028   <sect1 id="plugin_developer.organize">
    1029     <title>How to organize your plugin project</title>
    1030     <para>
    1031       Here is a simple example of how you might organize your project using ant (
    1032       <ulink url="http://ant.apache.org">http://ant.apache.org</ulink>
    1033       ) as the build tool. This is just a recommendation that we have found to be working
    1034       well. You may choose to do it another way.
    1035     </para>
    1036    
    1037     <sect2 id="plugin_developer.organize.layout">
    1038       <title>Directory layout</title>
    1039       <para>
    1040         <literallayout>
    1041           <filename class="directory"><replaceable>pluginname</replaceable>/</filename>
    1042           <filename class="directory"><replaceable>pluginname</replaceable>/bin/</filename>
    1043           <filename class="directory"><replaceable>pluginname</replaceable>/lib/</filename>
    1044           <filename class="directory"><replaceable>pluginname</replaceable>/src/<replaceable>org/company</replaceable>/</filename>
    1045         </literallayout>
    1046         The
    1047         <filename class="directory">bin/</filename>
    1048         directory is empty to start with. It will contain the compiled code. The
    1049         <filename class="directory">lib/</filename>
    1050         directory contains the JAR files your plugin uses (including the
    1051         <filename>BASE2Core.jar</filename>
    1052         ). The
    1053         <filename class="directory">src/</filename>
    1054         directory contains your source code.
    1055       </para>
    1056     </sect2>
    1057    
    1058     <sect2 id="plugin_developer.organize.ant">
    1059       <title>Ant build file</title>
    1060       <para>
    1061         In the root of your directory, create the build file:
    1062         <filename>build.xml</filename>
    1063         . Here is an example that will compile your plugin and put it in a JAR file.
    1064       </para>
    1065       <example id="plugin_developer.organize.build.file">
    1066         <title>A simple build file</title>
    1067         <programlisting>
    1068 &lt;?xml version="1.0" encoding="UTF-8"?&gt;
    1069 &lt;project
    1070    name="MyPlugin"
    1071    default="build.plugin"
    1072    basedir="."
    1073    &gt;
    1074 
    1075    &lt;!-- variables used --&gt;
    1076    &lt;property name="plugin.name" value="MyPlugin" /&gt;
    1077    &lt;property name="src" value="src" /&gt;
    1078    &lt;property name="bin" value="bin" /&gt;
    1079 
    1080    &lt;!-- set up classpath for compiling --&gt;
    1081    &lt;path id="classpath"&gt;
    1082       &lt;fileset dir="lib"&gt;
    1083          &lt;include name="**/*.jar"/&gt;
    1084       &lt;/fileset&gt;
    1085    &lt;/path&gt;
    1086 
    1087    
    1088    &lt;!-- main target --&gt;
    1089    &lt;target
    1090       name="build.plugin" 
    1091       description="Compiles the plugin and put in jar"
    1092       &gt;
    1093       &lt;javac
    1094          encoding="ISO-8859-1"
    1095          srcdir="${src}"
    1096          destdir="${bin}"
    1097          classpathref="classpath"&gt;
    1098       &lt;/javac&gt;
    1099       &lt;jar
    1100          jarfile="${plugin.name}.jar"
    1101          basedir="bin"
    1102          manifest="MANIFEST.MF"
    1103          &gt;
    1104       &lt;/jar&gt;
    1105 
    1106     &lt;/target&gt;
    1107 &lt;/project&gt;
    1108         </programlisting>
    1109       </example>
    1110       <para>
    1111         If your plugin depends on other JAR files than the
    1112         <filename>Base2Core.jar</filename>
    1113         you should list them in the
    1114         <filename>MANIFEST.MF</filename>
    1115         file. Otherwise you should remove the manifest attribute of the jar tag in the build
    1116         file.
    1117       </para>
    1118         <programlisting>
    1119 Manifest-Version: 1.0
    1120 Class-Path: OtherJar.jar ASecondJar.jar
    1121         </programlisting>
    1122     </sect2>
    1123      
    1124     <sect2 id="plugin_developer.organize.build">
    1125       <title>Building the plugin</title>
    1126       <para>
    1127         Compile the plugin simply by typing
    1128         <command>ant</command>
    1129         in the console window. If all went well the
    1130         <filename>MyPlugin.jar</filename>
    1131         will be created in the same directory.
    1132       </para>
    1133       <para>
    1134         To install the plugin copy the JAR file to the server including the dependent JAR
    1135         files (if any). Place all files together in the same directory. Then follow the
    1136         instructions in chapter
    1137         <xref linkend="plugin_installation" />
    1138         .
    1139       </para>
    1140     </sect2>
    1141   </sect1>
    1142 
    1143   <sect1 id="plugin_developer.customJSP">
    1144     <title>Using a custom JSP page for parameter input</title>
    1145     <para>
    1146       This is an advanced option for plugins that require a different interface for specifying
    1147       plugin parameters than the default list showing each parameter at a time. This feature
    1148       is used by setting the RequestInformation.getJspPage() property when construction the
    1149       request information object. If this property has a non-null value, the web client will
    1150       send the browser to the specified JSP page instead of to the generic parameter input
    1151       page.
    1152     </para>
    1153     <para>
    1154       When setting the JSP page you should not specify any path information. The web client
    1155       has a special location for these JSP pages, generated from the package name of your
    1156       plugin and the returned values. If the plugin is located in the package
    1157       <classname><replaceable>org.company</replaceable></classname>
    1158       the JSP page must be located in
    1159       <filename class="directory">
    1160         <replaceable>www-root</replaceable>
    1161         /plugins/
    1162         <replaceable>org/company</replaceable>
    1163         /
    1164       </filename>
    1165       . Please note that the browser still thinks that it is showing the regular page at the
    1166       usual location:
    1167       <filename class="directory"><replaceable>www-root</replaceable>/common/plugin/index.jsp</filename>
    1168       , so all links in your JSP page should be relative to that directory.
    1169     </para>
    1170     <para>
    1171       Even if you use your own JSP page we recommend that you use the built-in facility for
    1172       passing the parameters back to the plugin. For this to work you must:
    1173     </para>
    1174       <itemizedlist spacing="compact">
    1175         <listitem>
    1176           <simpara>Generate the list of <classname>PluginParameter</classname> objects as usual</simpara>
    1177         </listitem>
    1178         <listitem>
    1179           <simpara>
    1180             Name all your input fields like:
    1181             <parameter>
    1182               parameter:
    1183               <replaceable>name-of-parameter</replaceable>
    1184             </parameter>
    1185           </simpara>
    1186           <programlisting>
     1213          <listitem>
     1214            <simpara>
     1215              Name all your input fields like:
     1216              <parameter>
     1217                parameter:
     1218                <replaceable>name-of-parameter</replaceable>
     1219              </parameter>
     1220            </simpara>
     1221            <programlisting>
    11871222// Plugin generate PluginParameter
    11881223StringParameterType stringPT = new StringParameterType(255, null, true);
     
    11931228First string: &lt;input type="text" name="parameter:one"&gt;&lt;br&gt;
    11941229Second string: &lt;input type="text" name="parameter:two"&gt;
    1195           </programlisting>
    1196         </listitem>
    1197         <listitem>
    1198         <simpara>
    1199           Send the form to
    1200           <filename>index.jsp</filename>
    1201           with some parameters
    1202         </simpara>
    1203         <programlisting>
     1230            </programlisting>
     1231          </listitem>
     1232          <listitem>
     1233          <simpara>
     1234            Send the form to
     1235            <filename>index.jsp</filename>
     1236            with some parameters
     1237          </simpara>
     1238          <programlisting>
    12041239&lt;form action="index.jsp" method="post"&gt;
    12051240&lt;input type="hidden" name="ID" value="&lt;%=ID%&gt;"&gt;
     
    12071242...
    12081243&lt;/form&gt;
    1209           </programlisting>
    1210         <para>
    1211           In your JSP page you will probably need to access some information like the
    1212           <classname>SessionControl</classname>
    1213           and possible even the
    1214           <classname>RequestInformation</classname>
    1215           object created by your plugin.
    1216         </para>
    1217         <programlisting>
     1244            </programlisting>
     1245            <para>
     1246              In your JSP page you will probably need to access some information like the
     1247              <classname>SessionControl</classname>
     1248              and possible even the
     1249              <classname>RequestInformation</classname>
     1250              object created by your plugin.
     1251            </para>
     1252            <programlisting>
    12181253// Get session control and it's ID (required to post to index.jsp)
    12191254final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
     
    12301265   (PluginDefinition)sc.getSessionSetting("plugin.configure.job");
    12311266RequestInformation ri = pcRequest.getRequestInformation();
    1232         </programlisting>
    1233         </listitem>
    1234       </itemizedlist>
     1267            </programlisting>
     1268          </listitem>
     1269        </itemizedlist>
     1270      </sect3>
     1271    </sect2>
    12351272  </sect1>
    12361273
    1237   <sect1 id="plugin_developer.import_plugins">
    1238     <title id="plugin_developer.import_plugins.title">Plugins for importing data</title>
     1274  <sect1 id="plugin_developer.import">
     1275    <title>Import plugins</title>
     1276    <para></para>
     1277   
     1278    <sect2 id="plugin_developer.import.autodetect">
     1279      <title>Autodetecting importer</title>
     1280      <para></para>
     1281    </sect2>
     1282   
     1283    <sect2 id="plugin_developer.import.abstractflatfileimporter">
     1284      <title>The AbstractFlatFileImporter superclass</title>
     1285      <para></para>
     1286    </sect2>
     1287  </sect1>
     1288
     1289  <sect1 id="plugin_developer.export">
     1290    <title>Export plugins</title>
     1291    <para></para>
     1292   
     1293    <sect2 id="plugin_developer.export.download">
     1294      <title>Immediate download of exported data</title>
     1295      <para></para>
     1296    </sect2>
     1297  </sect1>
     1298 
     1299  <sect1 id="plugin_developer.analyse">
     1300    <title>Analysis plugins</title>
    12391301    <para></para>
    12401302  </sect1>
    1241 
     1303 
     1304  <sect1 id="plugin_developer.other">
     1305    <title>Other plugins</title>
     1306    <para></para>
     1307   
     1308    <sect2 id="plugin_developer.other.authentication">
     1309      <title>Authentication plugins</title>
     1310      <para></para>
     1311    </sect2>
     1312   
     1313    <sect2 id="plugin_developer.other.secondary">
     1314      <title>Secondary file storage plugins</title>
     1315      <para></para>
     1316    </sect2>
     1317   
     1318    <sect2 id="plugin_developer.other.unpacker">
     1319      <title>File unpacker plugins</title>
     1320      <para></para>
     1321    </sect2>
     1322  </sect1>
     1323 
     1324  <sect1 id="plugin_developer.example">
     1325    <title>Example plugins (with download)</title>
     1326    <para></para>
     1327  </sect1>
    12421328</chapter>
Note: See TracChangeset for help on using the changeset viewer.