<!--
	Licensed to the Apache Software Foundation (ASF) under one
	or more contributor license agreements. See the NOTICE file
	distributed with this work for additional information
	regarding copyright ownership. The ASF licenses this file
	to you under the Apache License, Version 2.0 (the
	"License"); you may not use this file except in compliance
	with the License. You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing,
	software distributed under the License is distributed on an
	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
	KIND, either express or implied. See the License for the
	specific language governing permissions and limitations
	under the License.
-->
<chapter id="ugr.tools.uimafit.gettingstarted">
  <title>Getting Started</title>

  <para>This quick start tutorial demonstrates how to use uimaFIT to define and set a configuration
    parameter in an analysis engine, run it, and generate a descriptor file for it. The complete
    code for this example can be found in the <emphasis>uimaFIT-examples</emphasis> module.</para>
  <section>
    <title>Adding uimaFIT to your project</title>
    <para>The following instructions describe how to add uimaFIT to your project's classpath.</para>
    <section>
      <title>Maven users</title>
      <para>If you use Maven, then uimaFIT can be added to your project by simply adding uimaFIT as
        a project dependency by adding the following snippet of XML to your pom.xml file:</para>
      <programlisting>&lt;dependency>
  &lt;groupId>org.apache.uima&lt;/groupId>
  &lt;artifactId>uimafit-core&lt;/artifactId>
  &lt;version><?eval ${project.version}?>&lt;/version>
&lt;/dependency></programlisting>
      <para>uimaFIT distributions are hosted by Maven Central and so no repository needs to be added
        to your pom.xml file. </para>
    </section>
    <section>
      <title>Non-Maven users</title>
      <para>If you do not build with Maven, then download uimaFIT from the <ulink
          url="http://uima.apache.org/downloads.cgi">Apache UIMA downloads page</ulink>. The file
        name should be uimafit-<?eval ${project.version}?>-bin.zip. Download and unpack this file.
        The contents of the resulting upacked directory will contain a directory called
          <filename>lib</filename>. Add all of the files in this directory to your classpath.</para>
    </section>
  </section>

  <section>
    <title>A simple analysis engine implementation</title>
    <para> Here is the complete analysis engine implementation for this example.</para>

    <programlisting format="linespecific">public class GetStartedQuickAE 
    extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
  
  public static final String PARAM_STRING = "stringParam";
  @ConfigurationParameter(name = PARAM_STRING)
  private String stringParam;
  
  @Override
  public void process(JCas jCas) throws AnalysisEngineProcessException {
    System.out.println("Hello world!  Say 'hi' to " + stringParam);
  }
}</programlisting>
    <para>The first thing to note is that the member variable <varname>stringParam</varname> is
      annotated with <classname>@ConfigurationParameter</classname> which tells uimaFIT that this is
      an analysis engine configuration parameter. It is best practice to create a public constant
      for the parameter name, here <code>PARAM_STRING</code> The second thing to note is that we
      extend uimaFIT's version of the <classname>JCasAnnotator_ImplBase</classname>. The initialize
      method of this super class calls:</para>
    <programlisting format="linespecific">ConfigurationParameterInitializer.initializeConfigurationParameters(
  Object, UimaContext) </programlisting>
    <para>which populates the configuration parameters with the appropriate contents of the
        <interfacename>UimaContext</interfacename>. If you do not want to extend uimaFIT's
        <classname>JCasAnnotator_ImplBase</classname>, then you can call this method directly in the
        <methodname>initialize</methodname> method of your analysis engine or any class that
      implements <interfacename>Initializable</interfacename>. You can call this method for an
      instance of any class that has configuration parameters.</para>
  </section>

  <section>
    <title>Running the analysis engine</title>
    <para>The following lines of code demonstrate how to instantiate and run the analysis engine
      from a main method:</para>
    <programlisting>JCas jCas = JCasFactory.createJCas();
  
AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
  GetStartedQuickAE.class,
  GetStartedQuickAE.PARAM_STRING, "uimaFIT");
  
analysisEngine.process(jCas);  </programlisting>

    <para>In a more involved example, we would probably instantiate a collection reader and run this
      analysis engine over a collection of documents. Here, it suffices to simply create a
        <interfacename>JCas</interfacename>. Line 3 instantiates the analysis engine using
        <classname>AnalysisEngineFactory</classname> and sets the string parameter named
        <parameter>stringParam</parameter> to the value <literal>uimaFIT</literal>. Running this
      simple program sends the following output to the console: </para>

    <programlisting>Hello world!  Say 'hi' to uimaFIT  </programlisting>

    <para>Normally you would be using a type system with your analysis components. When using
      uimaFIT, it is easiest to keep your type system descriptors in your source folders and make
      them known to uimaFIT. To do so, create a file
        <filename>META-INF/org.apache.uima.fit/types.txt</filename> in a source folder and add references to
      all your type descriptors to the file, one per line. You can also use wildcards. For example: </para>

    <programlisting>classpath*:org/apache/uima/fit/examples/type/Token.xml
classpath*:org/apache/uima/fit/examples/type/Sentence.xml
classpath*:org/apache/uima/fit/examples/tutorial/type/*.xml </programlisting>
  </section>

  <section>
    <title>Generate a descriptor file</title>

    <para>The following lines of code demonstrate how a descriptor file can be generated using the
      class definition:</para>

    <programlisting>AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
  GetStartedQuickAE.class,
  GetStartedQuickAE.PARAM_STRING, "uimaFIT");

analysisEngineDescription.toXML(
  new FileOutputStream("GetStartedQuickAE.xml"));</programlisting>

    <para>If you open the resulting descriptor file you will see that the configuration parameter
        <parameter>stringParam</parameter> is defined with the value set to
        <literal>uimaFIT</literal>. We could now instantiate an analysis engine using this
      descriptor file with a line of code like this:</para>

    <programlisting>AnalysisEngineFactory.createEngine("GetStartedQuickAE");</programlisting>

    <para>But, of course, we really wouldn't want to do that now that we can instantiate analysis
      engines using the class definition as was done above!</para>

    <para>This chapter, of course, did not demonstrate every feature of uimaFIT which provides
      support for annotating external resources, creating aggregate engines, running pipelines,
      testing components, among others.</para>
  </section>
</chapter>
