<?xml version="1.0" encoding="UTF-8"?>
<appendix annotations="slide" version="5.1" xml:id="sd1_appendix"
          xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
          xmlns:xi="http://www.w3.org/2001/XInclude"
          xmlns:svg="http://www.w3.org/2000/svg"
          xmlns:ns="http://docbook.org/ns/transclusion"
          xmlns:m="http://www.w3.org/1998/Math/MathML"
          xmlns:html="http://www.w3.org/1999/xhtml"
          xmlns:db="http://docbook.org/ns/docbook">
  <title xml:id="sd1Appendix">Appendix</title>

  <section xml:id="sd1_sect_exercisingPastExaminations">
    <title>Exercising past examinations</title>

    <para>Lecture notes exercise solutions are being provided as <xref
    linkend="glo_Maven"/> projects below <link
    xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/P/Sd1">P/Sd1</link>
    by the <link xlink:href="https://gitlab.mi.hdm-stuttgart.de">MI
    Gitlab</link> repository. Comparing these solutions to your own solution
    may be easily accomplished by importing them into your <xref
    linkend="glo_IDE"/>.</para>

    <para>Moreover the final examination and some exercises require importing
    <xref linkend="glo_Maven"/> skeleton projects to start from. The general
    procedure during an examination with respect to programming components is
    being described subsequently.</para>

    <figure xml:id="sd1_fig_examRemoteGuacamole">
      <title>Exam training by Guacamole</title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Fig/guacamoleExam.multi.svg"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_examRemoteGuacamoleHints">
      <title>Environment hints:</title>

      <para>The following installations allow for exercises with respect to
      the final examination:</para>

      <itemizedlist>
        <listitem>
          <para>E-Exam 113105 <foreignphrase
          xml:lang="de">Softwareentwicklung</foreignphrase> 1 Test / Network
          blocked:</para>

          <para>The examination environment with firewall rules restricting
          Internet access to a small number of allowed sites.</para>
        </listitem>

        <listitem>
          <para>E-Exam 113105 <foreignphrase
          xml:lang="de">Softwareentwicklung</foreignphrase> 1 Test /
          <productname>Teamviewer</productname>:</para>

          <para>No Internet blocking. <link
          xlink:href="https://www.teamviewer.com/en/products/teamviewer"><productname>Teamviewer</productname></link>
          allows for getting external help.</para>
        </listitem>
      </itemizedlist>
    </figure>

    <section xml:id="sd1_sect_exam_prepare">
      <title>Starting an exam</title>

      <figure xml:id="sd1_fig_examPrepare">
        <title>Preparing an examination</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/prepare.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>
    </section>

    <section xml:id="sd1_sect_exam_workUnitTest">
      <title>Implementing the project skeleton</title>

      <figure xml:id="sd1_fig_examGenJavadoc">
        <title>Generating <xref linkend="glo_Javadoc"/>.</title>

        <itemizedlist>
          <listitem>
            <para>HTML is difficult to read:</para>

            <programlisting language="java">   *     &lt;td&gt;&lt;code&gt;a = -3&lt;/code&gt;, &lt;code&gt;b = 4&lt;/code&gt;, &lt;code&gt;c = 3&lt;/code&gt;&lt;/td&gt;
   *     &lt;td&gt;4 - (-3) = 7&lt;/td&gt;
   *   &lt;/tr&gt;
   * &lt;/table&gt;
   ...
   */
  static public int getMaxAbsoluteDiff(int a, int b, int c) {
    return 42;  // TODO: Implement me correctly</programlisting>
          </listitem>

          <listitem>
            <para>⇒ Generate <xref linkend="glo_Javadoc"/> by <acronym
            linkend="sd1_fig_mavenJavadoc">CLI</acronym> or <link
            linkend="sd1_fig_mavenIdeaExecuteJavadocGoal">Idea</link>.</para>
          </listitem>
        </itemizedlist>
      </figure>

      <figure xml:id="sd1_fig_examProgrammingHints">
        <title>Programming hints</title>

        <itemizedlist>
          <listitem>
            <para>The debugger is your friend ...</para>
          </listitem>

          <listitem>
            <para>... but only if acquiring prior proficiency.</para>
          </listitem>

          <listitem>
            <para>Train <link linkend="sd1_fig_primeDebugError">prime or
            related example</link>.</para>
          </listitem>
        </itemizedlist>
      </figure>

      <figure xml:id="sd1_fig_examImplementTestCycle">
        <title>The implement - test - implement cycle</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/implement.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>
    </section>

    <section xml:id="sd1_sect_examFinish">
      <title>Finish the exam</title>

      <figure xml:id="sd1_fig_examFinish">
        <title>Finishing the exam</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/finish.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>
    </section>
  </section>

  <section xml:id="sd1ExaminationHints">
    <title>Examination hints</title>

    <figure xml:id="sd1_fig_examCheatSheet">
      <title>Personal examination cheat sheets</title>

      <itemizedlist>
        <listitem>
          <para>Username based Zip archive of <emphasis role="red">10 MB
          max</emphasis> e.g. <filename>xy123.zip</filename>.</para>

          <caution>
            <para>Use standard formats e.g. <acronym>png</acronym>,
            <acronym>gif</acronym>, <acronym>pdf</acronym>. Proprietary stuff
            like <acronym>.doc</acronym>, <acronym>.docx</acronym>,
            <acronym>.rtf</acronym> possibly lack tool support by exam
            environment.</para>
          </caution>
        </listitem>

        <listitem>
          <para>Link for <link
          xlink:href="https://freedocs.mi.hdm-stuttgart.de/uploadCheat">cheat
          sheet uploads</link>.</para>
        </listitem>

        <listitem>
          <para>Freeze during exam periods.</para>
        </listitem>

        <listitem>
          <para>Cheat sheets available at <uri
          xlink:href="https://freedocs.mi.hdm-stuttgart.de/cheat/">https://freedocs.mi.hdm-stuttgart.de/cheat/</uri>
          until end of exam period.</para>
        </listitem>

        <listitem>
          <para><emphasis role="red">Check your archive's content in the exam
          environment!</emphasis></para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_examByJunit">
      <title>Unit tests in examinations</title>

      <itemizedlist>
        <listitem>
          <para>Task definitions by <xref linkend="glo_Javadoc"/>.</para>
        </listitem>

        <listitem>
          <para>Corresponding Unit tests.</para>
        </listitem>

        <listitem>
          <para>Automated evaluation scoring your achievements.</para>
        </listitem>

        <listitem>
          <para>Individual weights reflecting a test's significance.</para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_interfaceDefExample">
      <title>Example interface definition</title>

      <programlisting language="java">/**
* Finde das n-te ungerade Element einer Wertefolge.
* 
* &lt;p&gt;Beispiel: Im Array {3, 2, 0, 1, 4} ist der Wert «1» an der Index-
*   position «3» das zweite ungerade Element.&lt;/p&gt;
* 
* @param werte Die zu durchsuchenden Werte.
* @param n Die gewünschte Position, Start bei 1.
* 
* @return Den Index des n-ten ungeraden Wertes falls es mindestens n
* ungerade Werte gibt, ...
*/
static public int getNtesUngeradesElement(final int[] werte, final int n){     
    return 12345; // TODO: Implementiere mich korrekt!
}</programlisting>
    </figure>

    <figure xml:id="sd1_fig_testExample">
      <title>Corresponding test</title>

      <programlisting language="java">@Test
@Marking(points=1) /* 1 point if test passes */
public void test_400() {
  Assert.assertEquals(
    2, /* Expected result */
    Helper.getNtesUngeradesElement(new int[]{-4,  6,  1, -2,   8}, 1));
}</programlisting>
    </figure>

    <figure xml:id="sd1_fig_testDontCheat">
      <title>Don't cheat!</title>

      <informaltable border="1">
        <tr>
          <th>Unit Tests</th>

          <th>Your solution</th>
        </tr>

        <tr>
          <td valign="top"><programlisting language="none">assertFalse(isPrime(1));
assertTrue (isPrime(<emphasis role="red">2</emphasis>));
assertTrue (isPrime(<emphasis role="red">3</emphasis>));
assertFalse(isPrime(4));
assertTrue (isPrime(<emphasis role="red">5</emphasis>));
assertFalse(isPrime(6));
assertTrue (isPrime(<emphasis role="red">7</emphasis>));
assertFalse(isPrime(8));
assertFalse(isPrime(9));
assertFalse(isPrime(10));</programlisting></td>

          <td valign="top"><programlisting language="none">... boolean isPrime(final int p) {
  switch (p) {
    case <emphasis role="red">2</emphasis>:
    case <emphasis role="red">3</emphasis>:
    case <emphasis role="red">5</emphasis>:
    case <emphasis role="red">7</emphasis>:
      return true;
    default:
      return false;    }</programlisting></td>
        </tr>
      </informaltable>

      <para>Will be treated as an <emphasis role="red">attempt at
      deception</emphasis> / <foreignphrase xml:lang="de"><emphasis
      role="red">Täuschungsversuch</emphasis></foreignphrase>.</para>
    </figure>

    <figure xml:id="sd1_fig_unitTestsStrategy">
      <title>Unit tests strategy in examinations</title>

      <itemizedlist>
        <listitem>
          <para>Unit testing is relentless: You are no longer at high school
          where a result having <quote>just</quote> a wrong sign used to
          matter next to nothing.</para>
        </listitem>

        <listitem>
          <para>Focus on completing units of work rather than
          <quote>nearly</quote> finishing a large number of tasks.</para>
        </listitem>

        <listitem>
          <para>Watching a test fail just happens. Learn to
          <emphasis>systematically</emphasis> fix bugs:</para>

          <orderedlist>
            <listitem>
              <para>Use your <xref linkend="glo_IDE"/>'s debugger. Practise
              debugging <xref linkend="glo_Junit"/> tests individually
              addressing failures one by one.</para>
            </listitem>

            <listitem>
              <para>Insert log statements using <productname
              xlink:href="https://logging.apache.org/log4j/2.x/">log4j</productname>.</para>
            </listitem>
          </orderedlist>
        </listitem>
      </itemizedlist>
    </figure>
  </section>

  <section xml:id="sd1SectExamAmendingProjects">
    <title>Examination bonus point projects</title>

    <figure xml:id="sd1_fig_collaborativeEfforts">
      <title>Collaborative efforts</title>

      <informaltable border="1">
        <tr>
          <td><mediaobject>
              <imageobject>
                <imagedata fileref="Fig/soDumm2.png"/>
              </imageobject>
            </mediaobject></td>

          <td><para>Is this your <emphasis
          role="red">TEAM</emphasis>?</para><para><emphasis
          role="red">T</emphasis>oll</para><para><emphasis
          role="red">E</emphasis>in</para><para><emphasis
          role="red">A</emphasis>nderer</para><para><emphasis
          role="red">M</emphasis>achts</para></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_projectRules">
      <title>Project rules</title>

      <orderedlist>
        <listitem>
          <para>You are expected to work as a <emphasis role="bold">team of
          three partners</emphasis>.</para>
        </listitem>

        <listitem>
          <para>Using the <link
          xlink:href="https://gitlab.mi.hdm-stuttgart.de/">MI Gitlab
          SCM</link> is a plus with respect to project evaluation. See table
          below.</para>
        </listitem>

        <listitem>
          <para>Your team is expected to supply a Maven project based on the
          MI <quote>Maven archetype quickstart</quote> available from <uri
          xlink:href="https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven/archetype-catalog.xml">https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven/archetype-catalog.xml</uri>.</para>
        </listitem>

        <listitem>
          <para>You are expected to provide good internal code documentation
          with respect both to method signatures (<xref
          linkend="glo_Javadoc"/>) and method implementation.</para>
        </listitem>
      </orderedlist>
    </figure>

    <figure xml:id="sd1_fig_projectCodeDoc">
      <title>Internal code documentation</title>

      <para>You are expected to provide good internal code documentation with
      respect both to method signatures (<xref linkend="glo_Javadoc"/>) and
      method implementation. Possible problems involve:</para>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Fig/bonusJavadocCompileTimeProblems.png"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_projectCodeDocHint">
      <title>Internal code documentation hints</title>

      <glosslist>
        <glossentry>
          <glossterm>Compile time warnings</glossterm>

          <glossdef>
            <para>Activate most compiler warnings at
            <guimenuitem>Editor</guimenuitem> --&gt;
            <guimenuitem>Inspections</guimenuitem>. This will show potential
            compile time problems like dead / unnecessary / unreachable code,
            unused variable values, shadowing conflicts and so on.</para>
          </glossdef>
        </glossentry>
      </glosslist>
    </figure>

    <figure xml:id="sd1_fig_projectJavadoc">
      <title><xref linkend="glo_Javadoc"/> mismatches</title>

      <para>Your method's formal parameters, their type and a method's return
      type must match your documentation.</para>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Fig/bonusJavadocMismatch.png"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_projectUnitTests">
      <title>(Automated) tests</title>

      <para>You are expected to provide meaningful unit tests:</para>

      <itemizedlist>
        <listitem>
          <para>Try to cover all your implementation code and not just
          isolated modules / methods.</para>
        </listitem>

        <listitem>
          <para>If methods allow for null values write suitable tests.</para>
        </listitem>

        <listitem>
          <para>Test special cases: If a method expects <abbrev>i.e.</abbrev>
          an array of strings it may be allowed having zero length.</para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_projectDeployRun">
      <title>Deployment and execution</title>

      <para>Your resulting project should be easily installable and
      runnable.</para>

      <itemizedlist>
        <listitem>
          <para>Maven is a good starting point with respect both to testing
          and cross platform (Unix / Windows / Apple) portability.</para>
        </listitem>

        <listitem>
          <para>Avoid dependencies to local file system resources like
          <filename>c:\users\xyz\testdata.txt</filename>.</para>
        </listitem>
      </itemizedlist>

      <tip>
        <para>Test your application's deployability by installing it on an
        untouched target platform (possibly of a different hard/software
        architecture) and execute <command>mvn</command> <option>test</option>
        (provided you do have written meaningful unit tests).</para>
      </tip>
    </figure>

    <figure xml:id="sd1_fig_projectEvalCriteria">
      <title>Marking criteria</title>

      <informaltable border="1">
        <colgroup width="62%"/>

        <colgroup width="38%"/>

        <tr>
          <th>Criterion</th>

          <th>Percentage</th>
        </tr>

        <tr>
          <td valign="top">Overall code quality</td>

          <td valign="top">20%</td>
        </tr>

        <tr>
          <td valign="top">Code documentation</td>

          <td valign="top">20%</td>
        </tr>

        <tr>
          <td valign="top">Unit tests</td>

          <td valign="top">10%</td>
        </tr>

        <tr>
          <td valign="top">Deployment</td>

          <td valign="top">5%</td>
        </tr>

        <tr>
          <td valign="top">SCM usage</td>

          <td valign="top">5%</td>
        </tr>

        <tr>
          <td valign="top">Software functionality</td>

          <td valign="top">40%</td>
        </tr>
      </informaltable>
    </figure>

    <para>Some of these terms require further explanations:</para>

    <glosslist>
      <glossentry>
        <glossterm>Overall code quality</glossterm>

        <glossdef>
          <para>Subject to personal preferences unfortunately.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Code documentation</glossterm>

        <glossdef>
          <para>This involves writing <xref linkend="glo_Javadoc"/> describing
          your classes. Furthermore you may want to add a project /
          architecture description. A <filename>Readme.md</filename> in your
          project's root is a good starting point.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Unit tests</glossterm>

        <glossdef>
          <para>Ideally your whole code could be covered by sensible unit
          tests. Albeit guaranteeing absence of errors it may help minimizing
          them.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Deployment</glossterm>

        <glossdef>
          <para>How difficult is your software's deployment? Sample:</para>

          <screen>git clone git@gitlab.mi.hdm-stuttgart.de:.../yourProject.git

cd yourProject
mvn package
# possible configuration according to documentation
java -jar target/yourArchive.jar
</screen>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>SCM usage</glossterm>

        <glossdef>
          <para>Using <abbrev>e.g.</abbrev> git supports team oriented project
          development. It also allows for tracing the participants individual
          contributions. For this reason your tutor is required to have read
          access to your project.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm>Software functionality</glossterm>

        <glossdef>
          <itemizedlist>
            <listitem>
              <para>Project specification met?</para>
            </listitem>

            <listitem>
              <para>(User input) Error handling?</para>
            </listitem>

            <listitem>
              <para>Stability</para>
            </listitem>
          </itemizedlist>
        </glossdef>
      </glossentry>
    </glosslist>

    <para>The following sections contain both current and archived project
    propositions.</para>

    <section xml:id="sd1_sect_projectWeatherForecast">
      <title>Weather forecast</title>

      <warning>
        <para>This project aims at using third party software components. It
        may not be appropriate if you fancy <quote>bottom up</quote> coding
        yourself.</para>
      </warning>

      <para>In this project you'll implement a terminal based weather forecast
      application. Consider the following invocation:</para>

      <figure xml:id="sd1_weather_fig_invocationVideo">
        <title>Sample forecast session</title>

        <mediaobject>
          <videoobject>
            <videodata fileref="Fig/weather.webm"/>
          </videoobject>
        </mediaobject>
      </figure>

      <figure xml:id="sd1_weather_fig_invocationExample">
        <title>Sample forecast invocation</title>

        <screen>goik@goiki target&gt; java -jar weather-1.0.jar <emphasis
            role="red">Stuttgart</emphasis> <co
            linkends="sd1_weather_fig_invocationExample-1.2"
            xml:id="sd1_weather_fig_invocationExample-1.2-co"/>
1 = Stadtkreis Stuttgart         <co
            linkends="sd1_weather_fig_invocationExample-2.2"
            xml:id="sd1_weather_fig_invocationExample-2.2-co"/>
<emphasis role="red">2 = Regierungsbezirk Stuttgart</emphasis> 
3 = Stuttgart
4 = Stuttgart Feuerbach
5 = Stuttgart Muehlhausen

Bitte gültige Auswahl 1 bis 5 treffen:<emphasis role="red">2</emphasis> <co
            linkends="sd1_weather_fig_invocationExample-3"
            xml:id="sd1_weather_fig_invocationExample-3-co"/>
Vorhersage für <emphasis role="red">Regierungsbezirk Stuttgart</emphasis> <co
            linkends="sd1_weather_fig_invocationExample-4"
            xml:id="sd1_weather_fig_invocationExample-4-co"/>
Dienstag, 15.05
    23:00:  11°C, Leichter Regen
Mittwoch, 16.05
    02:00:  10°C, Leichter Regen
    05:00:  10°C, Leichter Regen
    08:00:  11°C, Leichter Regen
 ...</screen>
      </figure>

      <calloutlist>
        <callout arearefs="sd1_weather_fig_invocationExample-1.2-co"
                 xml:id="sd1_weather_fig_invocationExample-1.2">
          <para>Command line argument <emphasis
          role="red">Stuttgart</emphasis> acting as a search filter.</para>
        </callout>

        <callout arearefs="sd1_weather_fig_invocationExample-2.2-co"
                 xml:id="sd1_weather_fig_invocationExample-2.2">
          <para>The filter <emphasis role="red">Stuttgart</emphasis> yields
          five matching towns / regions.</para>
        </callout>

        <callout arearefs="sd1_weather_fig_invocationExample-3-co"
                 xml:id="sd1_weather_fig_invocationExample-3">
          <para>User choosing second match.</para>
        </callout>

        <callout arearefs="sd1_weather_fig_invocationExample-4-co"
                 xml:id="sd1_weather_fig_invocationExample-4">
          <para>Forecast corresponding to <emphasis
          role="red">Regierungsbezirk Stuttgart</emphasis>.</para>
        </callout>
      </calloutlist>

      <para>The actual weather data is being provided by a web service:</para>

      <figure xml:id="sd1_weather_fig_underlyingData">
        <title>Underlying data provider</title>

        <screen>https://api.openweathermap.org/data/2.5/forecast?lang=de&amp; <co
            linkends="sd1_weather_fig_underlyingData-1"
            xml:id="sd1_weather_fig_underlyingData-1-co"/>
APPID=7cufdhdcgdhsgdhgfcgsdss67b3&amp;units=metric&amp;<emphasis role="red">id=3214105</emphasis>


{"cod":"200","message":0.0042,"cnt":40,"list":[            <co
            linkends="sd1_weather_fig_underlyingData-2"
            xml:id="sd1_weather_fig_underlyingData-2-co"/>
 {"dt":1526428800,"main":{"temp":10.29,"temp_min":10.29,
"temp_max":12.45,"pressure":985.75,"sea_level":1027.48,
"grnd_level":985.75,"humidity":80,"temp_kf":-2.16},
"weather":[{"id":500,"main":"Rain",
"description":"Leichter Regen","icon":"10n"}],"clouds":
{"all":88},"wind":{"speed":1.59,"deg":313.503},"rain":
{"3h":0.315},"sys":{"pod":"n"},"dt_txt":"2018-05-16 00:00:00"},           
{"dt":1526439600,"main": ...</screen>

        <calloutlist>
          <callout arearefs="sd1_weather_fig_underlyingData-1-co"
                   xml:id="sd1_weather_fig_underlyingData-1">
            <para>An <xref linkend="glo_URL"/> containing an id value
            corresponding to a uniquely defined town or region. We identify
            the following components:</para>

            <glosslist>
              <glossentry>
                <glossterm><code>lang=de</code></glossterm>

                <glossdef>
                  <para>Provide German localization e.g. «<foreignphrase
                  xml:lang="de">Leichter Regen</foreignphrase>» in favour of
                  «light rain».</para>
                </glossdef>
              </glossentry>

              <glossentry>
                <glossterm><abbrev>APPID</abbrev>=7cufdhdcgdhsgdhgfcgsdss67b3</glossterm>

                <glossdef>
                  <para>This parameter allows for accessing the service:
                  «7cufdhdcgdhsgdhgfcgsdss67b3» is actually a fake value. Your
                  project requires <link
                  xlink:href="https://openweathermap.org/appid">obtaining an
                  APPID token</link>.</para>
                </glossdef>
              </glossentry>

              <glossentry>
                <glossterm>units=metric</glossterm>

                <glossdef>
                  <para>Favour metric over imperial units.</para>
                </glossdef>
              </glossentry>

              <glossentry>
                <glossterm>id=3214105</glossterm>

                <glossdef>
                  <para>«3214105» identifies «<foreignphrase
                  xml:lang="de">Regierungsbezirk Stuttgart</foreignphrase>»,
                  see line 262703 in <filename
                  xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/resources/cities.list.json">cities.list.json</filename>:</para>

                  <programlisting language="json">"id": 3214105,
"name": "Regierungsbezirk Stuttgart",
"country": "DE",
"coord": {
  "lon": 9.66667,
  "lat": 49.083328
}</programlisting>
                </glossdef>
              </glossentry>
            </glosslist>
          </callout>

          <callout arearefs="sd1_weather_fig_underlyingData-2-co"
                   xml:id="sd1_weather_fig_underlyingData-2">
            <para><uri
            xlink:href="https://openweathermap.org/api">https://openweathermap.org/api</uri>'s
            reply providing <abbrev>JSON</abbrev> based weather data.</para>
          </callout>
        </calloutlist>
      </figure>

      <figure xml:id="sd1_weather_fig_citiesFile">
        <title><filename
        xlink:href="http://bulk.openweathermap.org/sample/city.list.json.gz">cities.list.json.gz</filename>
        providing cities</title>

        <programlisting language="json">[
  {
    "id": 2886241,
    "name": "Regierungsbezirk Köln",
    "country": "DE",
    "coord": {
      "lon": 7.16667,
      "lat": 50.833328
    }
  },
  {
    "id": 3247452,
    "name": "Kreis Euskirchen",
...
]</programlisting>
      </figure>

      <figure xml:id="sd1_weather_fig_urlToFileHelper">
        <title>ma/Copy URL result to file</title>

        <programlisting language="java">FileUtils.<link
            xlink:href="https://commons.apache.org/proper/commons-io/javadocs/api-2.6/org/apache/commons/io/FileUtils.html#copyURLToFile(java.net.URL,java.io.File)">copyURLToFile</link>(
  "https://api.openweathermap.org/data/2.5/forecast...",
  new File("weatherData.json"));</programlisting>

        <programlisting language="xml">&lt;dependency&gt;
  &lt;groupId&gt;commons-io&lt;/groupId&gt;
  &lt;artifactId&gt;commons-io&lt;/artifactId&gt;
  &lt;version&gt;2.6&lt;/version&gt;
&lt;/dependency&gt;</programlisting>
      </figure>

      <figure xml:id="sd1_weather_fig_parseCityData">
        <title>Parse city data</title>

        <programlisting language="java"><link
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/cities/Cities.java">public class Cities</link> {
  static public final City[] cities;
   ...
}</programlisting>

        <programlisting language="java">@Test <link
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/test/java/de/hdm_stuttgart/mi/sd1/weather/CityParserTest.java">public void testParsedCityCount()</link> {
  Assert.assertEquals(209579, Cities.cities.length);
}</programlisting>
      </figure>

      <figure xml:id="sd1_weather_fig_parseWeatherData">
        <title>Parse weather data</title>

        <programlisting language="java"><link
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/WeatherDataParser.java">public class WeatherDataParser</link> {

  static public final <link
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/java/de/hdm_stuttgart/mi/sd1/weather/model/Weather.java">Weather</link> parse(final String jsonWeatherDataFilename)
     throws IOException {
    return ...;
  }
}</programlisting>

        <programlisting language="java">@Test <link
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/test/java/de/hdm_stuttgart/mi/sd1/weather/WeatherDataParseTest.java">public void testParseWeatherData()</link> {
...
  Weather weather = WeatherDataParser.parse(
    "src/main/resources/stuttgart.weather.json");
...</programlisting>
      </figure>

      <figure xml:id="sd1_weather_fig_weatherRequirements">
        <title>Requirements</title>

        <orderedlist>
          <listitem>
            <para>The application shall accept a command line parameter like
            e.g. «Stuttgart» to filter matching cities from <filename
            xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/blob/master/Doc/Sd1/Ref/Projects/WeatherSkeleton/src/main/resources/cities.list.json">cities.list.json</filename>.</para>
          </listitem>

          <listitem>
            <para>If a given filter matches multiple locations the user shall
            have an option for choosing the desired one.</para>
          </listitem>

          <listitem>
            <para>The most recent city id value shall be cached in a file.
            Subsequent invocations without command line parameter shall
            provide a current forecast corresponding to this value.</para>
          </listitem>

          <listitem>
            <para>Weather data belonging to a given id value shall be cached
            locally for 10 minutes. Subsequent weather queries within this
            period shall be read from cache rather than by accessing
            <uri>https://api.openweathermap.org/...</uri> .</para>

            <para>Provide logging to a file rather than to the console to
            avoid cluttering the user interface. Log cache handling.</para>
          </listitem>
        </orderedlist>
      </figure>

      <figure xml:id="sd1_weather_fig_weatherLogging">
        <title>Logging</title>

        <itemizedlist>
          <listitem>
            <para>Provide logging to a file rather than to the console to
            avoid cluttering the user interface.</para>
          </listitem>

          <listitem>
            <para>Log cache handling.</para>
          </listitem>
        </itemizedlist>

        <screen>main INFO  weather.Forecast - Re-using cache file
 '/ma/goik/Forecast/6930414.json' from 196 seconds ago</screen>
      </figure>

      <tip>
        <para>See the related <link
        xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/-/tree/master/Doc/Sd1/Ref/Projects/WeatherSkeleton">skeleton
        project</link>.</para>
      </tip>
    </section>

    <section xml:id="sd1_sect_projectRpnCalculator">
      <title>Reverse Polish notation (<abbrev><abbrev
      xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev></abbrev>)
      calculator</title>

      <para>In a nutshell <abbrev
      xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
      allows for compact arithmetic expressions requiring no parentheses to
      express operator priorities. The introductory article <link
      xlink:href="http://www.calculator.org/rpn.aspx">What is Reverse Polish
      Notation?</link> explains the underlying idea.</para>

      <para>This project's comprises two different goals:</para>

      <orderedlist>
        <listitem>
          <para>Parse and evaluate <abbrev
          xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
          expressions:</para>

          <informaltable border="1">
            <colgroup width="24%"/>

            <colgroup width="28%"/>

            <colgroup width="14%"/>

            <colgroup width="34%"/>

            <tr>
              <th><abbrev
              xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
              expression</th>

              <th>Conventional expression</th>

              <th>Result</th>

              <th>Comment</th>
            </tr>

            <tr>
              <td>1 2 +</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mrow>
                      <m:mi>1</m:mi>

                      <m:mo>+</m:mo>

                      <m:mi>2</m:mi>
                    </m:mrow>
                  </m:math>
                </inlineequation></td>

              <td>3</td>

              <td/>
            </tr>

            <tr>
              <td>1 2 3 4 + - +</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mrow>
                      <m:mi>1</m:mi>

                      <m:mo>+</m:mo>

                      <m:mrow>
                        <m:mo>(</m:mo>

                        <m:mrow>
                          <m:mi>2</m:mi>

                          <m:mo>-</m:mo>

                          <m:mrow>
                            <m:mo>(</m:mo>

                            <m:mrow>
                              <m:mi>3</m:mi>

                              <m:mo>+</m:mo>

                              <m:mi>4</m:mi>
                            </m:mrow>

                            <m:mo>)</m:mo>
                          </m:mrow>
                        </m:mrow>

                        <m:mo>)</m:mo>
                      </m:mrow>
                    </m:mrow>
                  </m:math>
                </inlineequation></td>

              <td>-4</td>

              <td/>
            </tr>

            <tr>
              <td>1 2 + 4 *</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mrow>
                      <m:mrow>
                        <m:mo>(</m:mo>

                        <m:mrow>
                          <m:mi>1</m:mi>

                          <m:mo>+</m:mo>

                          <m:mi>2</m:mi>
                        </m:mrow>

                        <m:mo>)</m:mo>
                      </m:mrow>

                      <m:mo>×</m:mo>

                      <m:mi>4</m:mi>
                    </m:mrow>
                  </m:math>
                </inlineequation></td>

              <td>12</td>

              <td>No parentheses required</td>
            </tr>

            <tr>
              <td>pi</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mi>π</m:mi>
                  </m:math>
                </inlineequation></td>

              <td>3.1415926...</td>

              <td>symbolic constant pi</td>
            </tr>

            <tr>
              <td>pi sin</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mrow>
                      <m:mi>sin</m:mi>

                      <m:mo>⁡</m:mo>

                      <m:mrow>
                        <m:mo>(</m:mo>

                        <m:mi>π</m:mi>

                        <m:mo>)</m:mo>
                      </m:mrow>
                    </m:mrow>
                  </m:math>
                </inlineequation></td>

              <td>0</td>

              <td/>
            </tr>

            <tr>
              <td>4 sqrt ~</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mrow>
                      <m:mo>-</m:mo>

                      <m:msqrt>
                        <m:mi>4</m:mi>
                      </m:msqrt>
                    </m:mrow>
                  </m:math>
                </inlineequation></td>

              <td>-2</td>

              <td>«~» is Unary minus</td>
            </tr>

            <tr>
              <td>0x1a 0b1101 +</td>

              <td><inlineequation>
                  <m:math display="inline">
                    <m:mn>0</m:mn>
                  </m:math>
                </inlineequation></td>

              <td>3</td>

              <td>Binary and Hexadecimal literals</td>
            </tr>
          </informaltable>
        </listitem>

        <listitem>
          <para>Providing a user interface. Your are expected to write a
          terminal based application. This leaves different choices:</para>

          <glosslist>
            <glossentry>
              <glossterm>The easy way</glossterm>

              <glossdef>
                <para>Ask the user for line by line input as you already did
                in e.g. <xref linkend="sd1QandaAtTheBar"/>. This is
                straightforward but offers little responsiveness.</para>
              </glossdef>
            </glossentry>

            <glossentry>
              <glossterm>The hard way</glossterm>

              <glossdef>
                <para>Use a library for creating text-based GUIs like
                <productname
                xlink:href="https://github.com/mabe02/lanterna">Lanterna</productname>.
                This requires some time diving into the API.</para>
              </glossdef>
            </glossentry>

            <glossentry>
              <glossterm>The really hard way</glossterm>

              <glossdef>
                <para>Depending on your <xref linkend="glo_Java"/> skills you
                may favour a <xref linkend="glo_GUI"/> application over the
                proposed terminal based approach. However do not forget to
                implement the calculator's logic when fiddling with the user
                interface and be aware to reserve (possibly a lot of) extra
                time for the project.</para>
              </glossdef>
            </glossentry>
          </glosslist>
        </listitem>
      </orderedlist>

      <para>A prototype is available at <link
      xlink:href="/Sd1/Ref/Src/rpncalculator-0.1.jar">rpncalculator-0.1.jar</link>.
      Executing <command>java</command> <option>-jar</option>
      <option>rpncalculator-0.1.jar</option> allows for evaluating <abbrev
      xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
      expressions in a terminal:</para>

      <mediaobject>
        <videoobject>
          <videodata fileref="Fig/rpnCalculator.webm" format="video/webm"/>
        </videoobject>
      </mediaobject>

      <section xml:id="sd1_sect_projectRpnCalculatorFunctionality">
        <title>Desired functionality</title>

        <para>Implement the following elements:</para>

        <glosslist>
          <glossentry>
            <glossterm>Literals</glossterm>

            <glossdef>
              <informaltable border="1">
                <colgroup width="24%"/>

                <colgroup width="76%"/>

                <tr>
                  <th>Example</th>

                  <th>Description</th>
                </tr>

                <tr>
                  <td>2, 3.0, -1.82 1.3E-23</td>

                  <td><link
                  xlink:href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">IEEE
                  754 Double-precision</link></td>
                </tr>

                <tr>
                  <td>0b100, -0B101</td>

                  <td>Integer Binary representation</td>
                </tr>

                <tr>
                  <td>0xa7, -0xB2FF</td>

                  <td>Integer Hexadecimal representation</td>
                </tr>

                <tr>
                  <td>pi</td>

                  <td>Math <link
                  xlink:href="https://en.wikipedia.org/wiki/Pi"><inlineequation>
                      <m:math display="inline">
                        <m:mi>π</m:mi>
                      </m:math>
                    </inlineequation> 3.1415926...</link></td>
                </tr>

                <tr>
                  <td>e</td>

                  <td><link
                  xlink:href="https://en.wikipedia.org/wiki/E_(mathematical_constant)">Euler's
                  number</link> 2.71828...</td>
                </tr>
              </informaltable>
            </glossdef>
          </glossentry>

          <glossentry>
            <glossterm>Unary operators / functions</glossterm>

            <glossdef>
              <informaltable border="1">
                <colgroup width="18%"/>

                <colgroup width="82%"/>

                <tr>
                  <th>Example</th>

                  <th>Description</th>
                </tr>

                <tr>
                  <td>~</td>

                  <td>Unary minus</td>
                </tr>

                <tr>
                  <td>sin, cos, tan</td>

                  <td>Trigonometric functions</td>
                </tr>

                <tr>
                  <td>exp</td>

                  <td>Exponential to <link
                  xlink:href="https://en.wikipedia.org/wiki/E_(mathematical_constant)">base
                  e</link></td>
                </tr>

                <tr>
                  <td>ln</td>

                  <td>Natural logarithm (<link
                  xlink:href="https://en.wikipedia.org/wiki/E_(mathematical_constant)">base
                  e</link>)</td>
                </tr>

                <tr>
                  <td>sqrt</td>

                  <td>Square root</td>
                </tr>
              </informaltable>
            </glossdef>
          </glossentry>

          <glossentry>
            <glossterm>Binary operators / functions</glossterm>

            <glossdef>
              <informaltable border="1">
                <colgroup width="25%"/>

                <colgroup width="75%"/>

                <tr>
                  <th>Example</th>

                  <th>Description</th>
                </tr>

                <tr>
                  <td>+</td>

                  <td>Binary plus</td>
                </tr>

                <tr>
                  <td>-</td>

                  <td>Binary minus</td>
                </tr>

                <tr>
                  <td>*</td>

                  <td>Binary multiply</td>
                </tr>

                <tr>
                  <td>/</td>

                  <td>Binary divide</td>
                </tr>

                <tr>
                  <td>pow</td>

                  <td>Power function</td>
                </tr>
              </informaltable>
            </glossdef>
          </glossentry>
        </glosslist>
      </section>

      <section xml:id="sd1_sect_rpnImplementationHints">
        <title>Implementation hints</title>

        <para>Every <abbrev
        xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">RPN</abbrev>
        expression may be viewed as a sequence of tokens each having both a
        type and a content. Consider the following expression <code>-1.34 0.34
        + sqrt</code> consisting of four tokens:</para>

        <screen>Type: Double | Type: Double| Type: Binary plus | Type: square Function
             |             |       operator    |       root
Value: -1.34 | Value: 0.34 | Value: +          | value: sqrt</screen>

        <para>The following scanner application utilizes <link
        xlink:href="http://www.vogella.com/tutorials/JavaRegularExpressions/article.html">pattern
        matching</link> for decomposing expressions like <code>-1.34 0.34 +
        sqrt</code> into a token sequence:</para>

        <figure xml:id="sd1_fig_minimalTokenScanner">
          <title>Minimalist token scanner</title>

          <programlisting language="java">final String[] patterns = new String[] {
  "sqrt",
  "[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?",// Matches e.g. -1.5E-33
  "\\+"};// Escape required avoiding regular expression syntax clash.
final String expression = "2.1 -3.4 sqrt";
try (final Scanner scanner = new Scanner(expression)) {
  while (scanner.hasNext()) {
    for (final String p: patterns) {
      if (scanner.hasNext(p)) {
        System.out.println("Token '" + scanner.next(p) +
            "' matched by '" + p + "'");
        break;
      }
    }
  }
}</programlisting>
        </figure>

        <para>The current example expression <code>-1.34 0.34 + sqrt</code>
        results in:</para>

        <figure xml:id="sd1_fig_simpleScannerOutput">
          <title>Scanner output <code>-1.34 0.34 + sqrt</code></title>

          <screen>Token '2.1' matched by '[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?'
Token '-3.4' matched by '[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?'
Token 'sqrt' matched by 'sqrt'</screen>
        </figure>

        <para>We provide error handling capabilities dealing with erroneous
        input <coref linkend="sd1_fig_errorHandlingBogusInput"/>:</para>

        <figure xml:id="sd1_fig_scannerErrorHandling">
          <title>Adding error detection</title>

          <programlisting language="none">...
final String[] patterns = new String[] {
  "sqrt",
  "[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?",// Matches e.g. -1.5E-33
  "\\+"};// Escape required avoiding regular expression syntax clash.
try (final Scanner scanner = new Scanner("2.1 -3.4 <emphasis role="red">pbck</emphasis>") <co
              xml:id="sd1_fig_errorHandlingBogusInput"/>) {
  while (scanner.hasNext()) {
    boolean foundToken = false;
    for (final String p: patterns) {
      if (scanner.hasNext(p)) {
        foundToken = true;
        System.out.println("Token '" + scanner.next(p) +
          "' matched by '" + p + "'");
        break;
      }
    }
    if (!foundToken) {
      System.out.println("Parsing error at '" + scanner.nextLine() + "'");
      System.exit(1);
    } ...</programlisting>
        </figure>

        <para>Bogus input like <code>2.1 -3.4 <emphasis
        role="red">pbck</emphasis></code> will now be detected as such:</para>

        <figure xml:id="sd1_fig_scannerErrorResult">
          <title>Error message</title>

          <screen>Token '2.1' matched by '[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?'
Token '-3.4' matched by '[-]?([0-9]+[.]?[0-9]*|[.][0-9]+)(E[-]?[0-9]+)?'
<emphasis role="red">Parsing error at 'pbck'</emphasis></screen>
        </figure>

        <para>A token sequence may then be evaluated using the <link
        xlink:href="https://en.wikipedia.org/wiki/Reverse_Polish_notation#Postfix_evaluation_algorithm">postfix
        evaluation algorithm</link> (Read it!).</para>
      </section>
    </section>

    <section xml:id="sd1BonusCurrency">
      <title>Currency converter, Summer 2017</title>

      <para>A set of predefined currencies shall be mutually converted. The
      user will be able to choose both a <quote>buy</quote> and a
      <quote>sell</quote> currency. The desired <quote>buy</quote> amount
      shall than be converted into the corresponding <quote>sell</quote>
      currency amount. The following video illustrates its intended
      usage:</para>

      <figure xml:id="sd1FigCurrencyConverterVideo">
        <title>Running the currency converter terminal application.</title>

        <mediaobject>
          <videoobject>
            <videodata fileref="Fig/currencyConverter.webm"/>
          </videoobject>
        </mediaobject>
      </figure>

      <para>You may follow the subsequent steps:</para>

      <orderedlist>
        <listitem>
          <para>Choose a suitable representation which allows for defining
          currencies among with their corresponding conversion rates. A good
          starting point is being provided by <link
          xlink:href="https://en.wikipedia.org/wiki/Special_drawing_rights">IMF
          SDR currency units</link> leading to <link
          xlink:href="https://www.imf.org/external/np/fin/data/rms_mth.aspx?SelectDate=2017-03-31&amp;reportType=CVSDR">flat
          currency table structures</link>. These allow for a simple text file
          representation e.g. <filename>currencies.txt</filename>:</para>

          <screen>Chinese Yuan:	9.348070
Euro:	1.264280
Japanese Yen:	153.778000
U.K. Pound Sterling:	1.102940
U.S. Dollar:	1.356070
Algerian Dinar:	148.618000
...</screen>

          <para>The rates being provided here allow for converting each
          currency to its <link
          xlink:href="https://en.wikipedia.org/wiki/Special_drawing_rights">SDR</link>
          value. Thus converting e.g. Euro to U.S. Dollar requires a
          conversion to its <link
          xlink:href="https://en.wikipedia.org/wiki/Special_drawing_rights">SDR</link>
          value followed by a second conversion to U.S. Dollar.</para>

          <para>This way we only have to store a single rate for each currency
          in question.</para>
        </listitem>

        <listitem>
          <para>Write a class reading the above table and storing all
          currencies among with their rates into a suitable array. <link
          xlink:href="https://www.javatpoint.com/how-to-open-a-file-in-java">How
          to Open a File in Java</link> provides different methods reading and
          scanning file input.</para>
        </listitem>

        <listitem>
          <para>Create user interface dialogs providing the »glue« to access
          currency information.</para>
        </listitem>
      </orderedlist>
    </section>

    <section xml:id="sd1SectProjectAddressDatabase">
      <title>An address database, Winter 2016</title>

      <para>Consider executing <command>java</command> <option>-jar <link
      xlink:href="/Sd1/Ref/Src/address.zip">address.zip</link></option>:</para>

      <screen>Current person records:

0: Frank Bone, email: bone@re.org, phone: 885-11-87
1: Julius Caesar, email: -, phone: -
2: Clive Freemantle, email: freemantle@spam.org, phone: 112-22 33 12
3: Eve Gardener, email: -, phone: 32-44-2234
--------------------------------------
Main options:

0: Browse person entries <co linkends="sd1CalloutAddressDbProject-1"
          xml:id="sd1CalloutAddressDbProject-1-co"/>
1: Toggle filtering person entries <co linkends="sd1CalloutAddressDbProject-2"
          xml:id="sd1CalloutAddressDbProject-2-co"/>
2: Create new person entry <co linkends="sd1CalloutAddressDbProject-3"
          xml:id="sd1CalloutAddressDbProject-3-co"/>
3: Delete person entry <co linkends="sd1CalloutAddressDbProject-4"
          xml:id="sd1CalloutAddressDbProject-4-co"/>
4: Exit
Your choice: 2</screen>

      <calloutlist>
        <callout arearefs="sd1CalloutAddressDbProject-1-co"
                 xml:id="sd1CalloutAddressDbProject-1">
          <para>List all person records within your database. In presence of a
          filter (See <coref linkend="sd1CalloutAddressDbProject-2-co"/>) only
          a subset of entries will be displayed.</para>
        </callout>

        <callout arearefs="sd1CalloutAddressDbProject-2-co"
                 xml:id="sd1CalloutAddressDbProject-2">
          <para>For large person databases listing all entries becomes
          cumbersome. You may want to define filters limiting your visible
          result output by examining the last name attribute.</para>

          <para><xref linkend="glo_Java"/> allows for matching strings by
          <link
          xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html">regular
          expressions</link> to be used with e.g. <link
          xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#matches(java.lang.String)">String.matches(...)</link>.
          Examples:</para>

          <glosslist>
            <glossentry>
              <glossterm>^A.*</glossterm>

              <glossdef>
                <para>Strings starting (^) with capital A followed by an
                arbitrary number of arbitrary characters.</para>
              </glossdef>
            </glossentry>

            <glossentry>
              <glossterm>^[G-J].*</glossterm>

              <glossdef>
                <para>Strings starting with a capital letters G,H,I or J
                followed by an arbitrary number of arbitrary
                characters.</para>
              </glossdef>
            </glossentry>

            <glossentry>
              <glossterm>.*s$</glossterm>

              <glossdef>
                <para>Strings ending with character s.</para>
              </glossdef>
            </glossentry>
          </glosslist>
        </callout>

        <callout arearefs="sd1CalloutAddressDbProject-3-co"
                 xml:id="sd1CalloutAddressDbProject-3">
          <para>Creating a new person record</para>
        </callout>

        <callout arearefs="sd1CalloutAddressDbProject-4-co"
                 xml:id="sd1CalloutAddressDbProject-4">
          <para>Deleting a person record from your database</para>
        </callout>
      </calloutlist>

      <para>In order for entries to survive program termination we need a
      <link
      xlink:href="https://en.wikipedia.org/wiki/Persistence_(computer_science)">persistence</link>
      mechanism. The example application will create a new file
      <filename>address.txt</filename> on first invocation when adding at
      least one person:</para>

      <screen>Frank,Bone, ,885-11-87
Julius,Caesar, , 
Ee,Ff,hh,45
A,B, ,24
Eve,Gardener, ,32-44-2234</screen>

      <para>Each person record is being represented by four values being
      separated by three commas. Empty attribute values require a single
      space. The method <link
      xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#split(java.lang.String)">String.split(...)</link>
      is your friend when reading this file on program startup using
      <quote>,</quote> as separator split token.</para>

      <para>The following resources may help you getting started with <xref
      linkend="glo_Java"/> file input/output:</para>

      <itemizedlist>
        <listitem>
          <para><link
          xlink:href="https://www.tutorialspoint.com/java/java_files_io.htm">TutorialsPoint
          Java - Files and I/O</link></para>
        </listitem>

        <listitem>
          <para><link
          xlink:href="https://docs.oracle.com/javase/tutorial/essential/io/">Oracle
          The Java™ Tutorials Lesson: Basic I/O</link></para>
        </listitem>

        <listitem>
          <para><link
          xlink:href="http://tutorials.jenkov.com/java-io/index.html">jenkov.com
          Java IO Tutorial</link></para>
        </listitem>
      </itemizedlist>
    </section>

    <section xml:id="sd1SectProjectGrep">
      <title>Poor man's <xref linkend="glo_UNIX"/> <command
      xlink:href="https://linux.die.net/man/1/grep">grep</command>, Summer
      2016</title>

      <para>The <xref linkend="glo_UNIX"/> operating system provides a command
      <command xlink:href="https://linux.die.net/man/1/grep">grep</command>
      which allows for retrieving occurrences of a given string in text files.
      We consider an example text file <filename>input.txt</filename>
      containing four lines:</para>

      <literallayout linenumbering="numbered">Roses are nice flowers.
Red wine is tasty
The red cross acts worldwide
Mayflower used to be a ship.</literallayout>

      <para>We search this file <filename>input.txt</filename> for the
      occurrence of the string <quote>flower</quote> being contained in lines
      1 and 4:</para>

      <screen>&gt; grep <emphasis role="bold">flower</emphasis> input.txt 
Roses are nice <emphasis role="bold">flower</emphasis>s.
May<emphasis role="bold">flower</emphasis> used to be a ship.</screen>

      <para>Thus the <command
      xlink:href="https://linux.die.net/man/1/grep">grep</command> command
      echoes all lines containing the search string in question to standard
      output. Adding the command line option <option>-i</option> allows for
      case insensitive searches:</para>

      <screen linenumbering="unnumbered">&gt; grep <option>-i</option> <emphasis
          role="bold">red</emphasis> input.txt
<emphasis role="bold">Red</emphasis> wine is tasty
The <emphasis role="bold">red</emphasis> cross acts worldwide</screen>

      <para>This time all possible variants like <quote>Red</quote>,
      <quote>red</quote>, <quote>RED</quote> and so on will match.</para>

      <para><command
      xlink:href="https://linux.die.net/man/1/grep">grep</command> also allows
      for searching multiple files. Consider a second file
      <filename>inputSecond.txt</filename>:</para>

      <screen linenumbering="numbered">Errors will show up in red.
Let's start bug fixing</screen>

      <para>We may search for case insensitive (<option>-i</option> again)
      appearances of <quote>red</quote> within both files:</para>

      <screen linenumbering="unnumbered">&gt; grep -i <emphasis role="bold">red</emphasis> input.txt  inputSecond.txt 
input.txt:<emphasis role="bold">Red</emphasis> wine is tasty
input.txt:The <emphasis role="bold">red</emphasis> cross acts worldwide
inputSecond.txt:Errors will show up in <emphasis role="bold">red</emphasis>.</screen>

      <para>Finally the <option>-l</option> option will filter individual
      appearances just showing filenames containing matches:</para>

      <screen>&gt; grep -l Red input.txt  inputSecond.txt 
input.txt</screen>

      <para>In contrast a case insensitive search combining both
      <option>-i</option> and <option>-l</option> options yields:</para>

      <screen>&gt; grep -i -l Red input.txt  inputSecond.txt 
input.txt
inputSecond.txt</screen>

      <para>The <command
      xlink:href="https://linux.die.net/man/1/grep">grep</command> command may
      read its input from standard input allowing for <link
      xlink:href="https://en.wikipedia.org/wiki/Pipeline_(Unix)">pipes</link>.
      This way another command's output feeds into a subsequently executed
      command. As an example consider a recursive search for HTML files using
      the <link xlink:href="https://linux.die.net/man/1/find">find</link>
      command:</para>

      <screen>&gt; find . -name \*.html
./Sd1/Wc/wc/Testdata/input.html
./Sda1/rdbmsXml2Html/TestData/climbingprice.html
./Sda1/NoCast/src/main/resources/gallery.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExampleNew.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExample.html
./Sda1/VerifyImgAccess/fileextref.html</screen>

      <para>We want to restrict the above list to pathnames containing the
      string <quote>Example</quote>. This may be achieved by <link
      xlink:href="https://en.wikipedia.org/wiki/Pipeline_(Unix)">piping</link>
      the <link xlink:href="https://linux.die.net/man/1/find">find</link>
      command's output as input to <command
      xlink:href="https://linux.die.net/man/1/grep">grep</command> searching
      for the occurrence of the string <quote>Example</quote>. Technically
      both processes get connected by means of the pipe symbol
      <quote>|</quote>:</para>

      <screen>&gt; find . -name \*.html|grep Example
./Sda1/Jdom/Html2Html/src/main/resources/imageExampleNew.html
./Sda1/Jdom/Html2Html/src/main/resources/imageExample.html</screen>

      <tip>
        <orderedlist>
          <listitem>
            <para>Read about reading from files by using instances of
            <classname
            xlink:href="http://www.tutorialspoint.com/java/io/bufferedreader_readline.htm">java.io.BufferedReader</classname>.</para>
          </listitem>

          <listitem>
            <para>Reading from standard input may be achieved by:</para>

            <programlisting language="java">final BufferedReader source = new BufferedReader(new InputStreamReader(System.in));
...</programlisting>
          </listitem>

          <listitem>
            <para>You may create an executable jar archive using Maven.
            Starting from the <code>mi-mavem-archetype-quickstart</code> your
            <filename>pom.xml</filename> already contains a blueprint. Just
            insert your class containing the entry
            <methodname>main(...)</methodname> method (i.e.
            <classname>de.hdm_stuttgart.mi.sd1.grep.Grep</classname> in the
            current example) accordingly:</para>

            <programlisting language="xml">&lt;plugin&gt;
  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
  &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
  &lt;version&gt;2.4.1&lt;/version&gt;
  &lt;configuration&gt;
    &lt;transformers&gt;
      &lt;transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"&gt;
        &lt;manifestEntries&gt;
          &lt;Main-Class&gt;<emphasis role="bold">de.hdm_stuttgart.mi.sd1.grep.Grep</emphasis>&lt;/Main-Class&gt;
        &lt;/manifestEntries&gt;
      &lt;/transformer&gt;
    &lt;/transformers&gt;
  &lt;/configuration&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;phase&gt;package&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;shade&lt;/goal&gt;
        &lt;/goals&gt;
     &lt;/execution&gt;
  &lt;/executions&gt;
&lt;/plugin&gt;</programlisting>

            <para>Running <command>mvn</command> <option>install</option> will
            create an executable jar file like e.g.
            <filename>~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar</filename>
            with <quote>~</quote> denoting your home directory:</para>

            <screen>&gt; mvn install
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building grep 0.9
[INFO] ------------------------------------------------------------------------

...
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running de.hdm_stuttgart.mi.sd1.grep.CommandLineTest
Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.757 sec

Results :

Tests run: 5, Failures: 0, Errors: 0, Skipped: 0

...
[INFO] Installing /home/goik/workspace/sd-project-summer/grep/target/grep-0.9.jar to 
     /home/goik/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
...
</screen>

            <para>Due to our
            <code>&lt;Main-Class&gt;de.hdm_stuttgart.mi.sd1.grep.Grep&lt;/Main-Class&gt;</code>
            declaration in <filename>pom.xml</filename> this jar file is
            executable:</para>

            <screen>&gt; java -jar ~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</screen>

            <para>There are further simplification steps:</para>

            <orderedlist>
              <listitem>
                <para>Making the jar file executable using <command
                xlink:href="https://linux.die.net/man/1/chmod">chmod</command>
                allows for omitting the <command>java</command>
                command:</para>

                <screen>&gt; <command>chmod</command> <option>+x</option> <filename>~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar</filename>
&gt; <filename>~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar</filename>
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</screen>

                <para>Notice <quote>~</quote> representing a user's home
                directory.</para>
              </listitem>

              <listitem>
                <para>We may copy the jar archive to a standard location
                containing executable commands:</para>

                <screen>&gt; <command>mkdir</command> <filename>~/bin</filename>
&gt; 
&gt; <command>cp</command> <filename>~/.m2/repository/de/hdm-stuttgart/mi/sd1/grep/0.9/grep-0.9.jar</filename> <filename>~/bin/jgrep</filename>
&gt; 
&gt; <command>~/bin/jgrep</command> 
No search string given
Usage: grep [-i] [-l] searchString [file 1] [file 2] ...</screen>
              </listitem>

              <listitem>
                <para>We may add this directory to the set of directories
                being searched by the operating system's command line
                interpreter for executable commands. This is being achieved by
                either creating or modifying a file
                <filename>~/.profile</filename> in the user's home directory
                using a text editor. <filename>~/.profile</filename> should
                contain:</para>

                <screen>PATH="$HOME/bin:$PATH"</screen>

                <para>After logging out and on again your PATH environment
                variable should contain your <filename>~/bin</filename>
                component:</para>

                <screen>&gt; <command>echo</command> <envar>$PATH</envar>
<emphasis role="bold">/home/goik/bin</emphasis>:/usr/local/sbin:/usr/local/bin:/usr/...</screen>

                <para>You should now be able to call <command>jgrep</command>
                from arbitrary filesystem locations:</para>

                <screen>&gt; cd Desktop/
&gt; cat Testdata/input.txt | ./bin/mygrep red
The red cross acts worldwide</screen>
              </listitem>
            </orderedlist>
          </listitem>

          <listitem xml:id="sd1ProjectGrepUnitTestingHint">
            <para>Testing requires capturing of output being generated by e.g.
            <methodname
            xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#out">System.out</methodname><code>.</code><methodname
            xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/PrintStream.html#println(java.lang.String)">println(...)</methodname>
            calls. Consider the following code writing the string <quote>Hello
            World!</quote> to standard output:</para>

            <programlisting language="java">public class App {
    /**
     * @param args Unused
     */
    public static void main( String[] args ) {
        System.out.print( "Hello World!" );
    }
}</programlisting>

            <para>We want to set up a <productname>Junit</productname> test
            which captures the output to compare it with the expected string
            value <code language="java">"Hello World!"</code>. Following <uri
            xlink:href="https://stackoverflow.com/questions/1119385/junit-test-for-system-out-println">http://stackoverflow.com/questions/1119385/junit-test-for-system-out-println</uri>
            we redefine the standard output stream by a private instance of
            <classname
            xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/ByteArrayOutputStream.html">java.io.ByteArrayOutputStream</classname>.
            Due to <productname>Junit</productname>'s <classname
            xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Before.html">@Before</classname>
            and <classname
            xlink:href="http://junit.sourceforge.net/javadoc/org/junit/After.html">@After</classname>
            annotations this instance replaces <classname
            xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#out">System.out</classname>
            during our tests:</para>

            <programlisting language="java">import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit test for simple App.
 */
public class AppTest {
   private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

   <classname xlink:href="http://junit.sourceforge.net/javadoc/org/junit/Before.html">@Before</classname>
   public void setUpStreams() {
       System.setOut(new PrintStream(outContent));
   }

   <classname xlink:href="http://junit.sourceforge.net/javadoc/org/junit/After.html">@After</classname>
   public void cleanUpStreams() {
       System.setOut(null);
       outContent.reset();
   }
   
    /**
     * Test method accessing output generated by System.out.println(...) calls.
     */
    @Test
    public void testApp() {
       App.main(new String[]{}); // Calling main() method printing "Hello World!"
       Assert.assertEquals("Hello World!", outContent.toString());
    }
}</programlisting>
          </listitem>
        </orderedlist>
      </tip>
    </section>

    <section xml:id="sd1ProjectSieveErathostenes">
      <title>Project <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler's
      sieve</link>, Winter 2015</title>

      <para>The project's goal is about:</para>

      <itemizedlist>
        <listitem>
          <para>Generating all prime numbers of type <code
          language="java">int</code>.</para>
        </listitem>

        <listitem>
          <para>Using this set of prime numbers for decomposing arbitrary
          <code language="java">int</code> values into prime factors
          e.g.:</para>

          <para>1050 = 2 * 3 * 5 * 5 * 7</para>
        </listitem>
      </itemizedlist>

      <para>We start with the first task by implementing the <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
      sieve algorithm</link>. We may use a boolean array representing e.g. the
      first 100 primes:</para>

      <programlisting language="java">boolean[] nonPrimes = new boolean[100];</programlisting>

      <para>This array will initially be filled with 100 <code
      language="java">false</code> values. The idea is using the <link
      xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
      sieve algorithm</link> to turn all non-prime value to <code>true
      (t)</code> and leaving al prime index values at <code>false
      (f)</code>:</para>

      <screen>Index | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14 ...
------+--+--+--+--+--+--+--+--+--+--+---+---+---+---+--- ...
value | t| t| f| f| t| f| t| f| t| t|  t|  f|  t|  f|  t ...</screen>

      <para>Since we intend to deal with a large number <code
      xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE</code>
      of values (rather than just 100 ) we only consider odd values since even
      numbers are never prime except for the value 2. Thus 0 will represent 1,
      1 will represent 3 and n will represent 2 * n + 1:</para>

      <screen>Index      | 0| 1| 2| 3| 4|  5|  6|  7| ...
-----------+--+--+--+--+--+---+---+---+ ...
represents | 1| 3| 5| 7| 9| 11| 13| 15| ... 
-----------+--+--+--+--+--+---+---+---+ ...
value      | t| f| f| f| t|  f|  f|  t| ...</screen>

      <para>This requires a boolean array of just <code
      xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE
      / 2</code>. Start from the following skeleton:</para>

      <programlisting language="java">public class Sieve {

   final boolean[] nonPrimes;
   final int numPrimesFound;

   /**
    * Creating a prime number Euler variant sieve 
    * 
    * @param limit The last value to be considered. May or may not be prime.
    * 
    */
   public Sieve(final int limit) {
      ...// initialize nonPrimes and numPrimesFound.
   }
  ...

   /**
    * Test if a given value is prime or not
    * 
    * @param candidate The value in question.
    * 
    * @return True if value is prime, false otherwise.
    */
   public boolean isPrime(final int candidate) {
     // Based on nonPrimes array
     ...
   }
}</programlisting>

      <tip>
        <para>Decompose the <link
        xlink:href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Euler.27s_Sieve">Euler
        sieve algorithm</link> into smaller tasks and write appropriate tests.
        Start with small <code language="java">limit</code> values (like 20)
        and extend to <code
        xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html#MAX_VALUE">Integer.MAX_VALUE</code>
        step by step.</para>
      </tip>

      <para>Once you've finished implementing the sieve continue by
      implementing the second task of prime decomposition. We recall the
      initial example:</para>

      <para>1050 = 2 * 3 * 5 * 5 * 7</para>

      <para>So the primes 2, 3 and 7 appear with frequency 1 whereas 5 appears
      with frequency 2. For meaningful operations we introduce a new class
      combining a prime number and its corresponding frequency of appearance
      to represent prime factor decompositions appropriately:</para>

      <programlisting language="java">/**
 * Representing a single prime factor among with its
 * frequency.
 *
 */
public class PrimeFrequency {
   
   /**
    * The prime's immutable value.
    */
   public final int prime;
   
   /**
    * The prime's frequency of appearance. 
    */
   int frequency;
   
   /**
    * @param prime {@link #prime} 
    * @param frequency The prime's frequency of appearance.
    */
   public PrimeFrequency(final int prime, final int frequency) {
      this.prime = prime;
      this.frequency = frequency;
   }

   /**
    * @return The prime factor's frequency of appearance.
    */
   public int getFrequency() {
      return frequency;
   }
   
   /**
    * change the given frequency value.
    * @param frequency change by this value.
    */
   public void addFrequency(@SuppressWarnings("hiding") final int frequency) {
      this.frequency += frequency;
   }

   @Override
   public boolean equals(final Object obj) {
      ...
   }   
}</programlisting>

      <para>Now 2 * 3 * 5 * 5 * 7 may be represented by three (not four!)
      instances of <code language="java">PrimeFrequency</code>. In order to
      represent the whole product implement a second container:</para>

      <programlisting language="java">/**
 * Representing integer values by an ordered set of prime factors among with
 * their frequencies of appearance.
 *
 */
public class PrimeFrequencySet {

   private final static int initialCapacity = 16;
   
   private PrimeFrequency[] store = new PrimeFrequency[initialCapacity]; // May grow due to new factors.

   /**
    * Searching for the existence of a {@link PrimeFrequency} with a matching
    * prime value (frequency may be different!).
    * 
    * Example: If the set contains the prime values {3, 7, 11} (we ignore
    * frequencies) then searching for:
    * &lt;ul&gt;
    *   &lt;li&gt;3 return index 0&lt;/li&gt;
    *   &lt;li&gt;11 returns index 2&lt;/li&gt;
    *   &lt;li&gt;5 return -2&lt;/li&gt;
    *   &lt;li&gt;13 returns -3&lt;/li&gt;
    *   &lt;li&gt;2 returns -1&lt;/li&gt;
    * &lt;/ul&gt;
    * 
    * @param primeFrequency The candidate to be looked up.
    * 
    * @return If a prime value match exists return its index. If no match
    * exists return the negative value of the first index belonging to a set
    * value having a larger prime value than the candidate (the "natural"
    * insertion point) minus 1 (see example).
    */
   public int find(final PrimeFrequency primeFrequency) {
     ...
   }
   
   /**
    * Either add a new prime or just add a prime's frequency to an existing one.
    * 
    * @param primeFrequency If the prime is already in the current set, add its
    * frequency. Otherwise insert the new element preserving the order of prime
    * values.
    */
   public void add(final PrimeFrequency primeFrequency) {
     ...
   }
   
   /**
    * @return The count of all prime factors.
    */
   public int getLength() {
      ...
   }

   /**
    * The prime factor corresponding to a given index.
    * @param index .
    * @return .
    */
   public PrimeFrequency get(int index) {
      ...
   }
   
   /**
    * @return All prime factors among with their respective frequencies.
    */
   public PrimeFrequency[] get() {
     ...
   }
}</programlisting>

      <para>This allows for decomposing arbitrary <code
      language="java">int</code> values into their prime factors. We show a
      unit test example:</para>

      <programlisting language="java">/**
 * Prime factor decomposition.
 */
public class FactorTest {

   final Sieve sieve = new Sieve(100000);

   @Test
   public void test2 () {
      PrimeFrequencySet pfs = sieve.getPrimeFactors(12); <co
          linkends="sd1ListingTestPrimeFactorDecompose-1"
          xml:id="sd1ListingTestPrimeFactorDecompose-1-co"/>
      Assert.assertEquals(2, pfs.getLength()); <co
          linkends="sd1ListingTestPrimeFactorDecompose-2"
          xml:id="sd1ListingTestPrimeFactorDecompose-2-co"/>
      Assert.assertEquals(new PrimeFrequency(2, 2), pfs.get(0)); <co
          linkends="sd1ListingTestPrimeFactorDecompose-3"
          xml:id="sd1ListingTestPrimeFactorDecompose-3-co"/>
      Assert.assertEquals(new PrimeFrequency(3, 1), pfs.get(1)); <co
          linkends="sd1ListingTestPrimeFactorDecompose-4"
          xml:id="sd1ListingTestPrimeFactorDecompose-4-co"/>
   }
}</programlisting>

      <calloutlist>
        <callout arearefs="sd1ListingTestPrimeFactorDecompose-1-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-1">
          <para>Decomposing 12 into 2 * 2 * 3.</para>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-2-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-2">
          <para>We expect two factors:</para>

          <orderedlist>
            <listitem>
              <para>Prime factor 2 having frequency 2.</para>
            </listitem>

            <listitem>
              <para>Prime factor 3 having frequency 1.</para>
            </listitem>
          </orderedlist>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-3-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-3">
          <para>Check for first prime factor 2 of frequency 2.</para>
        </callout>

        <callout arearefs="sd1ListingTestPrimeFactorDecompose-4-co"
                 xml:id="sd1ListingTestPrimeFactorDecompose-4">
          <para>Check for second prime factor 3 of frequency 1.</para>
        </callout>
      </calloutlist>

      <para>For better illustration we provide the following example:</para>

      <programlisting language="java">public class Driver {

   /**
    * @param args Unused
    */
   public static void main( String[] args ) {
      
      final Sieve sieve = new Sieve(Integer.MAX_VALUE);

      
      int value = Integer.MAX_VALUE;
      System.out.println("Value " + value + " is " + 
        (sieve.isPrime(value)? "" : "not") + " prime.");

      value--; // Even Value
      
      System.out.println("Value " + value + " is " + 
            (sieve.isPrime(value)? "" : "not") + " prime.");

      value --; // Non-prime as well.
      System.out.println("Value " + value + " is " + 
            (sieve.isPrime(value)? "" : "not") + " prime.");


      value = Integer.MAX_VALUE - 1;
      final PrimeFrequencySet pfs = sieve.getPrimeFactors(value);
      
      System.out.print(value + " = ");
      String separator = "";
      for (PrimeFrequency pf : pfs.get()) {
         for (int i = 0; i &lt; pf.getFrequency(); i++) {
            System.out.print(separator + pf.prime);
            separator = " * ";
         }
      }
      System.out.println();
   }
}</programlisting>

      <para>This yields the following output:</para>

      <screen>Value 2147483647 is  prime.
Value 2147483646 is not prime.
Value 2147483645 is not prime.
2147483646 = 2 * 3 * 3 * 7 * 11 * 31 * 151 * 331</screen>

      <para>Depending on your implementation you may encounter the following
      heap memory related error:</para>

      <screen>Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at de.hdm_stuttgart.mi.prim.sieve.Sieve.initSieve(Sieve.java:75)
	at de.hdm_stuttgart.mi.prim.sieve.Sieve.&lt;init&gt;(Sieve.java:60)
	at de.hdm_stuttgart.mi.prim.Driver.main(Driver.java:19)</screen>

      <para>The <xref linkend="glo_Java"/> virtual machine by default may not
      provide enough heap space. You may enlarge the default allocation by
      setting the <option>-Xmx</option>. Eclipse provides a convenient way by
      means of a run time configuration (Menu Run --&gt; Run
      Configurations):</para>

      <informalfigure>
        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/primDriverRunConfigOverview.bmp"/>
          </imageobject>
        </mediaobject>
      </informalfigure>

      <para>Clicking the <quote>Arguments</quote> tab allows for setting the
      respective VM heap setting:</para>

      <informalfigure>
        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/primDriverRunConfigVmOptions.bmp"/>
          </imageobject>
        </mediaobject>
      </informalfigure>

      <para>This allows for running your application with a maximum of 4
      gigabytes of heap space.</para>

      <para>With respect to automated unit testing (<command>mvn</command>
      <option>test</option>)you may want to set the same value in you
      <filename>pom.xml</filename> file</para>

      <programlisting language="xml">&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
    &lt;version&gt;2.19&lt;/version&gt;
    &lt;configuration&gt;
      <emphasis role="bold">&lt;argLine&gt;-Xmx4G&lt;/argLine&gt;</emphasis>
  &lt;/configuration&gt;
&lt;/plugin&gt;</programlisting>
    </section>
  </section>

  <section xml:id="sd1_exams">
    <title>Past Software Development 1 examinations</title>

    <para>Solutions to implementation tasks are being provided below <link
    xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/-/tree/master/Klausuren/Sd1">https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/-/tree/master/Klausuren/Sd1</link>.
    Each sub folder contains:</para>

    <orderedlist>
      <listitem>
        <para>An <filename>Exam</filename> Folder containing the original
        implementation tasks.</para>
      </listitem>

      <listitem>
        <para>A <filename>Solve</filename> folder containing a proposed
        solution.</para>
      </listitem>
    </orderedlist>

    <xi:include href="Exam/2023/Summer/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2022/Winter/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2021/Winter/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2021/Summer/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2020/Winter_1/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2020/Winter_2/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2020/Summer/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2019/Winter/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2019/Summer/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2018/Winter/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>

    <xi:include href="Exam/2018/Summer/exam.xml" xpointer="element(/1)"
                ns:idfixup="auto"/>
  </section>

  <section xml:id="sect_Git">
    <title>Working with git</title>

    <para><uri
    xlink:href="https://gitlab.mi.hdm-stuttgart.de">https://gitlab.mi.hdm-stuttgart.de</uri>
    provides an interface creating a new <xref linkend="glo_Soft_Git"/>
    project. This involves:</para>

    <figure xml:id="sd1_fig_media_gitlabCreateProjectSteps">
      <title>Steps creating a new project</title>

      <orderedlist>
        <listitem>
          <para>Creating an empty new project itself.</para>
        </listitem>

        <listitem>
          <para>Adding fellow project users for participation.</para>
        </listitem>
      </orderedlist>
    </figure>

    <figure xml:id="sd1_fig_media_gitlabCreateProject">
      <title>Creating a project at MI
      <productname>gitlab</productname></title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Fig/gitlabNewProject.multi.svg"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_media_gitClone">
      <title>Cloning a git project</title>

      <screen>&gt;git clone git@gitlab.mi.hdm-stuttgart.de:goik/vcintro.git
Cloning into 'vcintro'...
warning: <emphasis role="red">You appear to have cloned an empty repository</emphasis>.</screen>
    </figure>

    <figure xml:id="sd1_fig_media_gitCdIntoProject">
      <title>Enter project folder, add <filename>Readme.md</filename></title>

      <informaltable border="0">
        <tr>
          <td valign="top"><screen>&gt;cd vcintro/
&gt;vim Readme.md
&gt;git add Readme.md</screen></td>

          <td valign="top"><screen># Initial project description.

Will be extended when adding more assets.</screen></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_media_gitCommitChangeset">
      <title>Committing change set</title>

      <informaltable border="0">
        <tr>
          <td valign="top"><screen>EDITOR=vim git commit Readme.md </screen></td>
        </tr>

        <tr>
          <td valign="top"><screen><emphasis role="red">Adding Readme file in Markdown format</emphasis>
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
#
# Initial commit
#
# Changes to be committed:
#       new file:   Readme.md</screen></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_media_gitPush">
      <title>Push to upstream repository</title>

      <screen>&gt;git push
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 306 bytes | 306.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
<emphasis role="red">To gitlab.mi.hdm-stuttgart.de:goik/vcintro.git</emphasis>
 * [new branch]      master -&gt; master</screen>
    </figure>

    <figure xml:id="sd1_fig_gitCreateMaven">
      <title>Inserting a Maven project</title>

      <screen>&gt;mvn --batch-mode -e archetype:generate -Dversion=0.9 \
&gt; -DgroupId=de.hdm_stuttgart.mi.sd1 \
&gt; -DartifactId=first -DarchetypeGroupId=de.hdm_stuttgart.mi \
&gt; -DarchetypeArtifactId=mi-maven-archetype-quickstart -DarchetypeVersion=1.2.1
</screen>

      <screen>&gt;find first/ -type f
first/.gitignore
first/src/test/java/de/hdm_stuttgart/mi/sd1/AppTest.java
first/src/main/java/de/hdm_stuttgart/mi/sd1/App.java
first/src/main/resources/log4j2.xml
first/pom.xml</screen>
    </figure>

    <figure xml:id="sd1_fig_gitInsertMavenStatus_1">
      <title>git status 1</title>

      <screen>&gt; git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "<emphasis role="red">git add &lt;file&gt;</emphasis>..." to include in what will be committed)

	<emphasis role="red">first/</emphasis>

nothing added to commit <emphasis role="red">but untracked files present</emphasis> (use "git add" to track)</screen>
    </figure>

    <figure xml:id="sd1_fig_gitAddMavenFiles">
      <title>Adding Maven files to repository</title>

      <screen>&gt;<emphasis role="red">git add `find first/ -type f`</emphasis>
&gt;git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD &lt;file&gt;..." to unstage)

	new file:   first/.gitignore
	new file:   first/pom.xml
	new file:   first/src/main/java/de/hdm_stuttgart/mi/sd1/App.java
	new file:   first/src/main/resources/log4j2.xml
	new file:   first/src/test/java/de/hdm_stuttgart/mi/sd1/AppTest.java</screen>
    </figure>

    <figure xml:id="sd1_fig_gitInsertMavenStatus_2">
      <title>git status 2</title>

      <screen>&gt;git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD &lt;file&gt;..." to unstage)

	new file:   first/.gitignore
	new file:   first/pom.xml
	new file:   first/src/main/java/de/hdm_stuttgart/mi/sd1/App.java
	new file:   first/src/main/resources/log4j2.xml
	new file:   first/src/test/java/de/hdm_stuttgart/mi/sd1/AppTest.java</screen>
    </figure>

    <figure xml:id="sd1_fig_media_gitCommitMavenProjectFiles">
      <title>Commit Maven project files</title>

      <informaltable border="0">
        <tr>
          <td valign="top"><screen>EDITOR=vim git commit -a</screen></td>
        </tr>

        <tr>
          <td valign="top"><screen><emphasis role="red">Adding a Maven project.</emphasis>
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Your branch is up to date with 'origin/master'.
#
# Changes to be committed:
#       new file:   first/.gitignore
#       new file:   first/pom.xml
#       new file:   first/src/main/java/de/hdm_stuttgart/mi/sd1/App.java
#       new file:   first/src/main/resources/log4j2.xml
#       new file:   first/src/test/java/de/hdm_stuttgart/mi/sd1/AppTest.java
</screen></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_gitInsertMavenStatus_3">
      <title>git status 3</title>

      <screen>&gt;git status
On branch master
<emphasis role="red">Your branch is ahead of 'origin/master' by 1 commit.</emphasis>
  (use "git push" to publish your local commits)

nothing to commit, working tree clean</screen>
    </figure>

    <figure xml:id="sd1_fig_media_gitPushMaven">
      <title>Push to upstream again</title>

      <screen>&gt;git push
Counting objects: 22, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (22/22), 3.31 KiB | 1.10 MiB/s, done.
Total 22 (delta 0), reused 0 (delta 0)
<emphasis role="red">To gitlab.mi.hdm-stuttgart.de:goik/vcintro.git</emphasis>
   32da2ff..4e19142  master -&gt; master</screen>
    </figure>

    <figure xml:id="sd1_fig_media_gitUndoChanges">
      <title>Reverting changes</title>

      <screen>&gt;git status
...
Changes not staged for commit:
  (use "git add &lt;file&gt;..." to update what will be committed)
  (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)

	modified:   Readme.md
</screen>

      <screen>git checkout -- Readme.md</screen>

      <screen>&gt;git status
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean</screen>
    </figure>

    <figure xml:id="sd1_fig_media_gitPull">
      <title>Pull changes from upstream</title>

      <screen>&gt;git pull
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From gitlab.mi.hdm-stuttgart.de:goik/vcintro
   3751344..83bd7b9  master     -&gt; origin/master
Updating 3751344..83bd7b9
Fast-forward
 Readme.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)</screen>
    </figure>
  </section>

  <section xml:id="sd1_sect_Maven">
    <title>Apache Maven</title>

    <figure xml:id="sd1_fig_mavenReading">
      <title>Maven: Recommended reading</title>

      <itemizedlist>
        <listitem>
          <para><xref linkend="bib_MavenRef2010"/></para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_whatIsMaven">
      <title>What is Maven anyway?</title>

      <itemizedlist>
        <listitem>
          <para>Build tool</para>
        </listitem>

        <listitem>
          <para>Project management tool</para>

          <itemizedlist>
            <listitem>
              <para>Create reports</para>
            </listitem>

            <listitem>
              <para>Continuous integration support</para>
            </listitem>
          </itemizedlist>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_factsAndBenefits">
      <title>Maven: Facts and benefits</title>

      <itemizedlist>
        <listitem>
          <para>Build tool</para>
        </listitem>

        <listitem>
          <para>Dependency management</para>
        </listitem>

        <listitem>
          <para>Repository system</para>
        </listitem>

        <listitem>
          <para>Plugin framework</para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_maven_fig_conventionOverConfiguration">
      <title>Convention Over Configuration</title>

      <itemizedlist>
        <listitem>
          <para>Sensible default values:</para>

          <itemizedlist>
            <listitem>
              <para>Source below <code>${basedir}/src/main/java</code></para>
            </listitem>

            <listitem>
              <para>Tests below <code>${basedir}/src/test</code></para>
            </listitem>

            <listitem>
              <para>Bytecode, jar/war archives below
              <code>${basedir}/target</code></para>
            </listitem>

            <listitem>
              <para>...</para>
            </listitem>
          </itemizedlist>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_fig_maven_ProjectLayout">
      <title>Maven project layout</title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Fig/projectLayout.multi.svg"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_maven_pomFile">
      <title>The project object model file</title>

      <programlisting language="xml">&lt;project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
    <uri xlink:href="http://maven.apache.org/xsd/maven-4.0.0.xsd">http://maven.apache.org/xsd/maven-4.0.0.xsd</uri>"&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
...

&lt;/project&gt;</programlisting>
    </figure>

    <figure xml:id="sd1_maven_fig_pomFeatures">
      <title>pom.xml characteristics</title>

      <itemizedlist>
        <listitem>
          <para>Declarative project description</para>

          <itemizedlist>
            <listitem>
              <para>Dependencies</para>
            </listitem>

            <listitem>
              <para>Builds</para>
            </listitem>

            <listitem>
              <para>Artifacts</para>
            </listitem>
          </itemizedlist>
        </listitem>

        <listitem>
          <para>No explicit instructions</para>
        </listitem>
      </itemizedlist>
    </figure>

    <figure xml:id="sd1_maven_fig_pomVsMake">
      <title>pom.xml vs. Makefile</title>

      <informaltable border="0">
        <tr>
          <td valign="top"><programlisting language="xml">&lt;plugin&gt;
  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
  &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
  &lt;configuration&gt;
    &lt;Main-Class&gt;org.devel.App&lt;/Main-Class&gt;
...
      &lt;execution&gt;
        &lt;phase&gt;package&lt;/phase&gt;
        &lt;goals&gt;
          &lt;goal&gt;shade&lt;/goal&gt;
        &lt;/goals&gt;
...</programlisting></td>

          <td valign="top"><programlisting language="xml">module.o: module.c
	gcc -c -g module.c</programlisting></td>
        </tr>
      </informaltable>
    </figure>

    <section xml:id="sd1_maven_sect_pomBasiss">
      <title>The project object model <filename>pom.xml</filename></title>

      <figure xml:id="sd1_fig_maven_helloWorldPom">
        <title>«Hello, world» pom.xml</title>

        <programlisting language="xml">&lt;project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
              http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;

  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;de.hdm_stuttgart.mi&lt;/groupId&gt;
  &lt;artifactId&gt;first&lt;/artifactId&gt;
  &lt;version&gt;0.9&lt;/version&gt;

&lt;/project&gt;</programlisting>
      </figure>

      <figure xml:id="sd1_fig_maven_helloWorldPomExec">
        <title>Executing «compile» phase</title>

        <screen>mkdir -p src/main/java <co
            linkends="sd1_fig_maven_helloWorldPomExec-1"
            xml:id="sd1_fig_maven_helloWorldPomExec-1-co"/>

vim src/main/java/Hello.java <co linkends="sd1_fig_maven_helloWorldPomExec-2"
            xml:id="sd1_fig_maven_helloWorldPomExec-2-co"/>

first&gt; mvn compile ...
[WARNING] <emphasis role="red">File encoding has not been set, using platform encoding UTF-8</emphasis>, <co
            linkends="sd1_fig_maven_helloWorldPomExec-3"
            xml:id="sd1_fig_maven_helloWorldPomExec-3-co"/>
    i.e. build is platform dependent! ...
[ERROR] error: <emphasis role="red">Source option 5 is no longer supported</emphasis>. <co
            linkends="sd1_fig_maven_helloWorldPomExec-4"
            xml:id="sd1_fig_maven_helloWorldPomExec-4-co"/> Use 6 or later.
[ERROR] error: <emphasis role="red">Target option 1.5 is no longer supported</emphasis>. <co
            linkends="sd1_fig_maven_helloWorldPomExec-5"
            xml:id="sd1_fig_maven_helloWorldPomExec-5-co"/> Use 1.6 or later.
</screen>

        <calloutlist role="slideExclude">
          <callout arearefs="sd1_fig_maven_helloWorldPomExec-1-co"
                   xml:id="sd1_fig_maven_helloWorldPomExec-1">
            <para>Create an empty folder designated for hosting <xref
            linkend="glo_Java"/> sources. See <xref
            linkend="sd1_fig_maven_ProjectLayout"/> for reference.</para>
          </callout>

          <callout arearefs="sd1_fig_maven_helloWorldPomExec-2-co"
                   xml:id="sd1_fig_maven_helloWorldPomExec-2">
            <para>Create an executable «Hello,world ...» class:</para>

            <programlisting language="java">public class Hello {

   public static void main(String[] args) {
      System.out.println("Hello!");
}</programlisting>
          </callout>

          <callout arearefs="sd1_fig_maven_helloWorldPomExec-3-co"
                   xml:id="sd1_fig_maven_helloWorldPomExec-3">
            <para>Ask <xref linkend="glo_Maven"/> for execution of the
            «compile» phase.</para>
          </callout>

          <callout arearefs="sd1_fig_maven_helloWorldPomExec-4-co"
                   xml:id="sd1_fig_maven_helloWorldPomExec-4">
            <para>We have not yet specified an encoding on project level. Thus
            two platforms using different encoding may provide different
            artifact outcomes.</para>
          </callout>

          <callout arearefs="sd1_fig_maven_helloWorldPomExec-5-co"
                   xml:id="sd1_fig_maven_helloWorldPomExec-5">
            <para>The world has moved: <xref linkend="glo_Java"/> 1.5
            compilers are outdated.</para>
          </callout>
        </calloutlist>
      </figure>

      <figure xml:id="sd1_fig_maven_simplePomJavaVersionPromlem">
        <title>Examining the <xref linkend="glo_Java"/> version
        culprit</title>

        <screen>&gt;mvn <emphasis role="red">help:effective-pom</emphasis>

&lt;project ...&gt;
   ...
  &lt;plugin&gt;
    &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt; ...

&gt; find ~/.m2/repository/ -name maven-compiler-plugin\* ...
       
&gt;jar -xf ~/.m2/repository/org/apache/maven/plugins/maven-compiler-plugin/3.7.0/maven-compiler-plugin-3.7.0.jar
&gt;cat <emphasis role="red">META-INF/maven/plugin.xml</emphasis></screen>

        <programlisting language="xml">&lt;encoding implementation="java.lang.String" default-value="${<emphasis
            role="red">project.build.sourceEncoding</emphasis>}"&gt;${encoding}&lt;/encoding&gt;
&lt;source implementation="java.lang.String" default-value="1.5"&gt;${<emphasis
            role="red">maven.compiler.source</emphasis>}&lt;/source&gt;
&lt;target implementation="java.lang.String" default-value="1.5"&gt;${<emphasis
            role="red">maven.compiler.target</emphasis>}&lt;/target&gt;</programlisting>
      </figure>

      <figure xml:id="sd1_fig_maven_simplePom">
        <title>Resolving encoding / <xref linkend="glo_Java"/> version
        issues</title>

        <programlisting language="none">&lt;project ... xsd/maven-4.0.0.xsd"&gt;
...
  &lt;properties&gt;
    &lt;project.build.sourceEncoding&gt;<emphasis role="red">UTF-8</emphasis>&lt;/project.build.sourceEncoding&gt;

    &lt;maven.compiler.source&gt;<emphasis role="red">1.8</emphasis>&lt;/maven.compiler.source&gt;
    &lt;maven.compiler.target&gt;<emphasis role="red">1.8</emphasis>&lt;/maven.compiler.target&gt;
  &lt;/properties&gt; ...</programlisting>

        <screen>rm -rf ~/.m2/repository/
mvn compile;     find ~/.m2/repository/ -type f|wc -l
<emphasis role="red">220</emphasis></screen>
      </figure>

      <figure xml:id="sd1_maven_fig_superPomInherit">
        <title>POM inheritance</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/superPomInherit.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>

      <figure xml:id="sd1_maven_fig_superPom">
        <title>The Super POM</title>

        <programlisting language="bash">jar -tf /usr/share/apache-maven-3.0.5/lib/<emphasis
            role="red">maven-model-builder-3.0.5.jar</emphasis>

...
org/apache/maven/model/plugin/ReportingConverter.class
org/apache/maven/model/<emphasis role="red">pom-4.0.0.xml</emphasis>
org/apache/maven/model/profile/activation/FileProfileActivator$1.class
...</programlisting>
      </figure>

      <figure xml:id="sd1_maven_fig_superPomContent">
        <title>pom-4.0.0.xml content</title>

        <programlisting language="xml">...                          <emphasis
            role="red">&lt;!-- Does this ring a (security related?) bell? --&gt;</emphasis>
&lt;repositories&gt;
  &lt;repository&gt;
    &lt;id&gt;central&lt;/id&gt;
    &lt;name&gt;Central Repository&lt;/name&gt;
    &lt;url&gt;<emphasis role="red">http://repo.maven.apache.org/maven2</emphasis>&lt;/url&gt;
...
  &lt;pluginRepositories&gt;
    &lt;pluginRepository&gt;
      &lt;id&gt;central&lt;/id&gt;
      &lt;name&gt;Central Repository&lt;/name&gt;
      &lt;url&gt;<emphasis role="red">http://repo.maven.apache.org/maven2</emphasis>&lt;/url&gt;
...</programlisting>
      </figure>

      <figure xml:id="sd1_maven_fig_favourHttps">
        <title>Favour <abbrev>https</abbrev> in
        <filename>~/.m2/settings.xml</filename></title>

        <programlisting language="xml">&lt;settings ... settings-1.0.0.xsd"&gt;

  &lt;mirrors&gt;
    &lt;mirror&gt;
      &lt;id&gt;central-secure&lt;/id&gt;
      &lt;mirrorOf&gt;central&lt;/mirrorOf&gt;
      &lt;name&gt;Maven Central: Favour https over http.&lt;/name&gt;
      &lt;url&gt;<emphasis role="red">https</emphasis>://repo.maven.apache.org/maven2&lt;/url&gt;
    &lt;/mirror&gt;
  &lt;/mirrors&gt;
  ...</programlisting>
      </figure>

      <figure xml:id="sd1_fig_maven_getEffectivePom">
        <title>Resolving to effective pom.xml</title>

        <screen>first&gt; <emphasis role="red">mvn help:effective-pom</emphasis>
... Effective POMs, after inheritance, interpolation, and profiles are applied:

&lt;project xmlns="http://maven.apache.org/POM/4.0.0" ...&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
...
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.3.2&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;id&gt;default-jar&lt;/id&gt;
...</screen>
      </figure>
    </section>

    <section xml:id="sd1_maven_sect_plugins">
      <title>Plugins</title>

      <figure xml:id="sd1_fig_maven_pluginArchitecture">
        <title>Plugin architecture</title>

        <itemizedlist>
          <listitem>
            <para>Tiny core</para>
          </listitem>

          <listitem>
            <para>Plugin extensible</para>
          </listitem>
        </itemizedlist>

        <para>Hint: <command>mvn</command> <option>help:effective-pom</option>
        lists included plugins.</para>
      </figure>

      <figure xml:id="sd1_fig_maven_pluginSamples">
        <title>Sample plugins</title>

        <itemizedlist>
          <listitem>
            <para>Testing: <code>maven-surefire-plugin</code></para>
          </listitem>

          <listitem>
            <para>Library dependencies:
            <code>maven-dependency-plugin</code></para>
          </listitem>

          <listitem>
            <para>Packaging: <code>maven-jar-plugin</code></para>
          </listitem>

          <listitem>
            <para>Documentation: <code>maven-javadoc-plugin</code></para>
          </listitem>
        </itemizedlist>
      </figure>

      <figure xml:id="sd1_fig_maven_javadocPlugin">
        <title>Example: The <code>maven-javadoc-plugin</code></title>

        <screen>first&gt; <emphasis role="red">jar -tf ~/.m2/repository/org/apache/maven/plugins/\
        maven-javadoc-plugin/3.0.0/maven-javadoc-plugin-3.0.0.jar</emphasis>
...
META-INF/LICENSE
META-INF/maven/org.apache.maven.plugins/maven-javadoc-plugin/plugin-help.xml
javadoc-report.properties
META-INF/maven/plugin.xml
log4j.properties
META-INF/NOTICE
org/apache/maven/plugins/javadoc/AbstractFixJavadocMojo$JavaEntityTags.class
org/apache/maven/plugins/javadoc/AggregatorTestJavadocReport.class
...</screen>
      </figure>
    </section>

    <section xml:id="sd1_maven_sect_dependencies">
      <title>Dependencies</title>

      <figure xml:id="sd1_fig_maven_addingTestCapabilities">
        <title>Adding test capabilities</title>

        <informaltable border="0">
          <tr>
            <td valign="top"><programlisting language="none">&lt;project ... maven-4.0.0.xsd"&gt; ...
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;<emphasis role="red">junit</emphasis>&lt;/groupId&gt;
      &lt;artifactId&gt;<emphasis role="red">junit</emphasis>&lt;/artifactId&gt;
      &lt;version&gt;<emphasis role="red">4.12</emphasis>&lt;/version&gt;
      <emphasis role="red">&lt;scope&gt;test&lt;/scope&gt;</emphasis>
    &lt;/dependency&gt;...</programlisting></td>

            <td valign="top"><programlisting language="none">import <emphasis
                  role="red">org.junit.Test</emphasis>;
import <emphasis role="red">org.junit.Assert</emphasis>;

public class AppTest {
  <emphasis role="red">@Test</emphasis>
  public void doTest() {
    <emphasis role="red">Assert</emphasis>.assertEquals(1, 1);
  }</programlisting></td>
          </tr>

          <tr>
            <td colspan="2"><screen>first&gt; mvn test
[INFO] Scanning for projects...
Running de.hdm_stuttgart.mi.sd1.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.053 sec</screen></td>
          </tr>
        </informaltable>
      </figure>

      <figure xml:id="sd1_fig_maven_testListDeps">
        <title>Dependency listing</title>

        <screen>first&gt; <emphasis role="red">mvn dependency:tree</emphasis>
        ...
[INFO] de.hdm_stuttgart.mi.sd1:first:jar:0.9
[INFO] \- <emphasis role="red">junit</emphasis>:<emphasis role="red">junit</emphasis>:<emphasis
            role="red">jar</emphasis>:<emphasis role="red">4.12</emphasis>:test
[INFO]    \- <emphasis role="red">org.hamcrest</emphasis>:<emphasis role="red">hamcrest-core</emphasis>:<emphasis
            role="red">jar</emphasis>:<emphasis role="red">1.3</emphasis>:test</screen>

        <itemizedlist>
          <listitem>
            <para><filename>~/.m2/repository/<emphasis
            role="red">junit</emphasis>/<emphasis
            role="red">junit</emphasis>/<emphasis
            role="red">4.12</emphasis>/<emphasis
            role="red">junit</emphasis>-<emphasis
            role="red">4.12</emphasis>.<emphasis
            role="red">jar</emphasis></filename></para>
          </listitem>

          <listitem>
            <para><filename>~/.m2/repository/<emphasis
            role="red">org/hamcrest</emphasis>/<emphasis
            role="red">hamcrest-core</emphasis>/<emphasis
            role="red">1.3</emphasis>/<emphasis
            role="red">hamcrest-core</emphasis>-<emphasis
            role="red">1.3</emphasis>.<emphasis
            role="red">jar</emphasis></filename></para>
          </listitem>
        </itemizedlist>
      </figure>

      <figure xml:id="sd1_fig_maven_whyHamcrestAbsence">
        <title>Absence of <productname>hamcrest</productname> in
        <filename>pom.xml</filename></title>

        <programlisting language="xml">&lt;project ... maven-4.0.0.xsd"&gt; 
      ...
<emphasis role="red">&lt;!-- no such entry --&gt;</emphasis>
  &lt;dependency&gt;
    &lt;groupId&gt;org.hamcrest&lt;/groupId&gt;
    &lt;artifactId&gt;hamcrest-core&lt;/artifactId&gt;
    &lt;version&gt;1.3&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
      ...</programlisting>
      </figure>

      <figure xml:id="sd1_fig_maven_depJunitToHamcrest">
        <title><filename>~/.m2/repository/junit/junit/4.12/junit-4.12.pom</filename></title>

        <programlisting language="xml">&lt;dependency&gt;
  &lt;groupId&gt;org.hamcrest&lt;/groupId&gt;
  &lt;artifactId&gt;hamcrest-core&lt;/artifactId&gt;
  &lt;version&gt;1.3&lt;/version&gt;
  &lt;/dependency&gt;
&lt;/dependencies&gt;</programlisting>
      </figure>

      <figure xml:id="sd1_fig_maven_hamcrestTransitiveDep">
        <title>Transitive dependencies</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/transitiveDep.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>

      <figure xml:id="sd1_fig_maven_switchTestNg">
        <title>Oblivious to test implementation: TestNG</title>

        <informaltable border="0">
          <tr>
            <td valign="top"><programlisting language="none">&lt;project ... maven-4.0.0.xsd"&gt; ...
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;<emphasis role="red">org.testng</emphasis>&lt;/groupId&gt;
      &lt;artifactId&gt;<emphasis role="red">testng</emphasis>&lt;/artifactId&gt;
      &lt;version&gt;<emphasis role="red">6.14.3</emphasis>&lt;/version&gt;
      <emphasis role="red">&lt;scope&gt;test&lt;/scope&gt;</emphasis>
    &lt;/dependency&gt;...</programlisting></td>

            <td valign="top"><programlisting language="none">import <emphasis
                  role="red">org.testng.annotations.Test</emphasis>;
import <emphasis role="red">org.testng.Assert</emphasis>;

public class AppTest {
  <emphasis role="red">@Test</emphasis>
  public void doTest() {
    <emphasis role="red">Assert</emphasis>.assertEquals(1, 1);
  }</programlisting></td>
          </tr>

          <tr>
            <td colspan="2"><screen>testng&gt; <emphasis role="red">mvn test</emphasis>
Running de.hdm_stuttgart.mi.sd1.AppTest
Configuring TestNG with: org.apache.maven.surefire...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 sec</screen></td>
          </tr>
        </informaltable>
      </figure>
    </section>

    <section xml:id="sd1_maven_sect_PhasesAndGoals">
      <title>Lifecycle, phases and goals</title>

      <figure xml:id="sd1_fig_maven_prjPhases">
        <title>Phases</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="Fig/phases.multi.svg"/>
          </imageobject>
        </mediaobject>
      </figure>

      <figure xml:id="sd1_fig_maven_lifeCycle">
        <title>Maven lifecyles and phases</title>

        <glosslist>
          <glossentry>
            <glossterm>Phases:</glossterm>

            <glossdef>
              <para>clean, compile, test, package, deploy, ...</para>
            </glossdef>
          </glossentry>

          <glossentry>
            <glossterm>Lifecycle</glossterm>

            <glossdef>
              <para>Sequence of <link
              xlink:href="http://maven.apache.org/ref/current/maven-core/lifecycles.html">named
              phases</link></para>
            </glossdef>
          </glossentry>

          <glossentry>
            <glossterm>Example: <command>mvn</command> <option>clean</option>
            (Lifecycle)</glossterm>

            <glossdef>
              <itemizedlist>
                <listitem>
                  <para><code>pre-clean</code></para>
                </listitem>

                <listitem>
                  <para><code>clean</code> (Phase)</para>
                </listitem>

                <listitem>
                  <para><code>post-clean</code></para>
                </listitem>
              </itemizedlist>
            </glossdef>
          </glossentry>
        </glosslist>

        <para>See <link
        xlink:href="https://books.sonatype.com/mvnref-book/reference/lifecycle-sect-structure.html#lifecycle-sect-default">Default
        Lifecycle</link>.</para>
      </figure>

      <figure xml:id="sd1_fig_maven_pluginHook">
        <title>hooking into phase</title>

        <programlisting language="none">&lt;plugin&gt;
  &lt;groupId&gt;com.mysema.maven&lt;/groupId&gt;
  &lt;artifactId&gt;apt-maven-plugin&lt;/artifactId&gt;
  &lt;version&gt;1.1.3&lt;/version&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;id&gt;process&lt;/id&gt;
      &lt;goals&gt;
        &lt;goal&gt;process&lt;/goal&gt;
      &lt;/goals&gt;
      <emphasis role="red">&lt;phase&gt;generate-sources&lt;/phase&gt;</emphasis>
      &lt;configuration&gt;
        &lt;outputDirectory&gt;${project.build.directory}/metamodel&lt;/outputDirectory&gt;
        &lt;processor&gt;com.mysema.query.apt.jpa.JPAAnnotationProcessor&lt;/processor&gt;
      &lt;/configuration&gt;
      ...</programlisting>
      </figure>
    </section>
  </section>
</appendix>