From 77a0649b7fd517a4f5e419c613f7bf42291e7b76 Mon Sep 17 00:00:00 2001
From: Martin Goik <goik@hdm-stuttgart.de>
Date: Thu, 15 Jan 2015 11:59:16 +0100
Subject: [PATCH] Additional sub sections for exercises

---
 Sda1/sda1.xml | 836 +++++++++++++++++++++++++-------------------------
 1 file changed, 424 insertions(+), 412 deletions(-)

diff --git a/Sda1/sda1.xml b/Sda1/sda1.xml
index 0941356b0..dcaf0057a 100644
--- a/Sda1/sda1.xml
+++ b/Sda1/sda1.xml
@@ -11415,292 +11415,304 @@ public class SimpleRead {
           </callout>
         </calloutlist>
 
-        <qandaset defaultlabel="qanda" xml:id="quandaentry_JdbcTypeConversion">
+        <para>We now present a series of exercises thereby exploring important
+        aspects of <xref linkend="glo_JDBC"/> read access.</para>
+
+        <section xml:id="sectGetterTypeConversion">
           <title>Getter methods and type conversion</title>
 
-          <qandadiv>
-            <qandaentry>
-              <question>
-                <para>Apart from type mappings the <trademark
-                xlink:href="http://electronics.zibb.com/trademark/jdbc/29545026">JDBC</trademark>
-                access methods like <link
-                xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(int)">getString()</link>
-                may also be used for type conversion. Modify <xref
-                linkend="listingJdbcRead"/> by:</para>
+          <qandaset defaultlabel="qanda"
+                    xml:id="quandaentry_JdbcTypeConversion">
+            <qandadiv>
+              <qandaentry>
+                <question>
+                  <para>Apart from type mappings the <xref
+                  linkend="glo_JDBC"/> access methods like <link
+                  xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(int)">getString()</link>
+                  may also be used for type conversion. Modify <xref
+                  linkend="listingJdbcRead"/> by:</para>
 
-                <itemizedlist>
-                  <listitem>
-                    <para>Read the database attribute <code>id</code> by <link
-                    xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(java.lang.String)">getString(String)</link>.</para>
-                  </listitem>
+                  <itemizedlist>
+                    <listitem>
+                      <para>Read the database attribute <code>id</code> by
+                      <link
+                      xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(java.lang.String)">getString(String)</link>.</para>
+                    </listitem>
 
-                  <listitem>
-                    <para>Read the database attribute nickname by <link
-                    xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getInt(java.lang.String)">getInt(String)</link>.</para>
-                  </listitem>
-                </itemizedlist>
+                    <listitem>
+                      <para>Read the database attribute nickname by <link
+                      xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getInt(java.lang.String)">getInt(String)</link>.</para>
+                    </listitem>
+                  </itemizedlist>
 
-                <para>What do you observe?</para>
-              </question>
+                  <para>What do you observe?</para>
+                </question>
 
-              <answer>
-                <para>Modifying our iteration loop:</para>
+                <answer>
+                  <para>Modifying our iteration loop:</para>
 
-                <programlisting language="none">// Step 4: Dataset iteration
+                  <programlisting language="none">// Step 4: Dataset iteration
 while (data.next()) {
     System.out.println(data.<emphasis role="bold">getString</emphasis>("id") <co
-                    linkends="jdbcReadWrongType-1"
-                    xml:id="jdbcReadWrongType-1-co"/>
+                      linkends="jdbcReadWrongType-1"
+                      xml:id="jdbcReadWrongType-1-co"/>
            + ", " + data.<emphasis role="bold">getInt</emphasis>("nickname") <co
-                    linkends="jdbcReadWrongType-2"
-                    xml:id="jdbcReadWrongType-2-co"/>
+                      linkends="jdbcReadWrongType-2"
+                      xml:id="jdbcReadWrongType-2-co"/>
            + ", " + data.getString("birthdate"));
 }</programlisting>
 
-                <para>We observe:</para>
+                  <para>We observe:</para>
 
-                <calloutlist>
-                  <callout arearefs="jdbcReadWrongType-1-co"
-                           xml:id="jdbcReadWrongType-1">
-                    <para>Calling <link
-                    xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(int)">getString()</link>
-                    for a database attribute of type INTEGER does not cause
-                    any trouble: The value gets silently converted to a string
-                    value.</para>
-                  </callout>
+                  <calloutlist>
+                    <callout arearefs="jdbcReadWrongType-1-co"
+                             xml:id="jdbcReadWrongType-1">
+                      <para>Calling <link
+                      xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getString(int)">getString()</link>
+                      for a database attribute of type INTEGER does not cause
+                      any trouble: The value gets silently converted to a
+                      string value.</para>
+                    </callout>
 
-                  <callout arearefs="jdbcReadWrongType-2-co"
-                           xml:id="jdbcReadWrongType-2">
-                    <para>Calling <link
-                    xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getInt(java.lang.String)">getInt(String)</link>
-                    for the database field of type CHAR yields an (expected)
-                    Exception:</para>
-                  </callout>
-                </calloutlist>
+                    <callout arearefs="jdbcReadWrongType-2-co"
+                             xml:id="jdbcReadWrongType-2">
+                      <para>Calling <link
+                      xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#getInt(java.lang.String)">getInt(String)</link>
+                      for the database field of type CHAR yields an (expected)
+                      Exception:</para>
+                    </callout>
+                  </calloutlist>
 
-                <programlisting language="none">Exception in thread "main" java.sql.SQLException: Invalid value for getInt() - 'Jim'
+                  <programlisting language="none">Exception in thread "main" java.sql.SQLException: Invalid value for getInt() - 'Jim'
   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
 ...</programlisting>
 
-                <para>We may however provide <quote>compatible</quote> data
-                records:</para>
+                  <para>We may however provide <quote>compatible</quote> data
+                  records:</para>
 
-                <programlisting language="none">DELETE FROM Friends;
+                  <programlisting language="none">DELETE FROM Friends;
 INSERT INTO Friends VALUES (1, <emphasis role="bold">'31'</emphasis>, '1991-10-10');</programlisting>
 
-                <para>This time our application executes perfectly
-                well:</para>
+                  <para>This time our application executes perfectly
+                  well:</para>
 
-                <programlisting language="none">1, 31, 1991-10-10</programlisting>
+                  <programlisting language="none">1, 31, 1991-10-10</programlisting>
 
-                <para>Conclusion: The <trademark
-                xlink:href="http://electronics.zibb.com/trademark/jdbc/29545026">JDBC</trademark>
-                driver performs a conversion from a string type to an integer
-                similar like the <link
-                xlink:href="http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String)">parseInt(String)</link>
-                method.</para>
-
-                <para>The next series of exercises aims on a more powerful
-                implementation of our person data insertion application in
-                <xref linkend="exerciseInsertLoginCredentials"/>.</para>
-              </answer>
-            </qandaentry>
-          </qandadiv>
-        </qandaset>
+                  <para>Conclusion: The <xref linkend="glo_JDBC"/> driver
+                  performs a conversion from a string type to an integer
+                  similar like the <link
+                  xlink:href="http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String)">parseInt(String)</link>
+                  method.</para>
+
+                  <para>The next series of exercises aims on a more powerful
+                  implementation of our person data insertion application in
+                  <xref linkend="exerciseInsertLoginCredentials"/>.</para>
+                </answer>
+              </qandaentry>
+            </qandadiv>
+          </qandaset>
+        </section>
 
-        <qandaset defaultlabel="qanda" xml:id="quandaentry_HandlingNull">
+        <section xml:id="sectHandlingNullValues">
           <title>Handling NULL values.</title>
 
-          <qandadiv>
-            <qandaentry>
-              <question>
-                <para>The attribute <code>birthday</code> in our database
-                table Friends allows <code>NULL</code> values:</para>
+          <qandaset defaultlabel="qanda" xml:id="quandaentry_HandlingNull">
+            <qandadiv>
+              <qandaentry>
+                <question>
+                  <para>The attribute <code>birthday</code> in our database
+                  table Friends allows <code>NULL</code> values:</para>
 
-                <programlisting language="none">INSERT INTO Friends VALUES
+                  <programlisting language="none">INSERT INTO Friends VALUES
    (1, 'Jim', '1991-10-10')
   ,(2, <emphasis role="bold"> NULL</emphasis>, '2003-5-24')
   ,(3, 'Mick', '2001-12-30');</programlisting>
 
-                <para>Starting our current application yields:</para>
+                  <para>Starting our current application yields:</para>
 
-                <programlisting language="none">1, Jim, 1991-10-10
+                  <programlisting language="none">1, Jim, 1991-10-10
 2, null, 2003-05-24
 3, Mick, 2001-12-30</programlisting>
 
-                <para>This might be confuses with a person having the nickname
-                <quote>null</quote>. Instead we would like to have:</para>
+                  <para>This might be confuses with a person having the
+                  nickname <quote>null</quote>. Instead we would like to
+                  have:</para>
 
-                <programlisting language="none">1, Jim, 1991-10-10
+                  <programlisting language="none">1, Jim, 1991-10-10
 2, -Name unknown- , 2003-05-24
 3, Mick, 2001-12-30</programlisting>
 
-                <para>Extend the current code of
-                <classname>sda.jdbc.intro.SimpleRead</classname> to produce
-                the above result in case of nickname <code>NULL</code>
-                values.</para>
+                  <para>Extend the current code of
+                  <classname>sda.jdbc.intro.SimpleRead</classname> to produce
+                  the above result in case of nickname <code>NULL</code>
+                  values.</para>
 
-                <para>Hint: Read the documentation of <link
-                xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#wasNull()">wasNull()</link>.</para>
-              </question>
+                  <para>Hint: Read the documentation of <link
+                  xlink:href="http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#wasNull()">wasNull()</link>.</para>
+                </question>
 
-              <answer>
-                <para>A possible implementation is being given in
-                <classname>sda.jdbc.intro.v1.SimpleRead</classname>.</para>
-              </answer>
-            </qandaentry>
-          </qandadiv>
-        </qandaset>
+                <answer>
+                  <para>A possible implementation is being given in
+                  <classname>sda.jdbc.intro.v1.SimpleRead</classname>.</para>
+                </answer>
+              </qandaentry>
+            </qandadiv>
+          </qandaset>
+        </section>
 
-        <qandaset defaultlabel="qanda" xml:id="exerciseInsecureAuth">
+        <section xml:id="sectUserAuthStrategy">
           <title>A user authentication <quote>strategy</quote></title>
 
-          <qandadiv>
-            <qandaentry>
-              <question>
-                <para>Our current application for entering <code>Person</code>
-                records lacks authentication: A user simply connects to the
-                database using credentials being hard coded in a properties
-                file. A programmer suggests to implement authentication based
-                on the following extension of the <code>Person</code>
-                table:</para>
-
-                <programlisting language="none">CREATE TABLE Person (
+          <qandaset defaultlabel="qanda" xml:id="exerciseInsecureAuth">
+            <qandadiv>
+              <qandaentry>
+                <question>
+                  <para>Our current application for entering
+                  <code>Person</code> records lacks authentication: A user
+                  simply connects to the database using credentials being hard
+                  coded in a properties file. A programmer suggests to
+                  implement authentication based on the following extension of
+                  the <code>Person</code> table:</para>
+
+                  <programlisting language="none">CREATE TABLE Person (
    name char(80) NOT NULL
   ,email CHAR(20) NOT NULL UNIQUE
   ,login CHAR(10)  UNIQUE -- login names must be unique --
   ,password CHAR(20)    
 );</programlisting>
 
-                <para>On clicking <quote>Connect</quote> a user may enter his
-                login name and password, <quote>fred</quote> and
-                <quote>12345678</quote> in the following example:</para>
+                  <para>On clicking <quote>Connect</quote> a user may enter
+                  his login name and password, <quote>fred</quote> and
+                  <quote>12345678</quote> in the following example:</para>
 
-                <figure xml:id="figLogin">
-                  <title>Login credentials for database connection</title>
+                  <figure xml:id="figLogin">
+                    <title>Login credentials for database connection</title>
 
-                  <mediaobject>
-                    <imageobject>
-                      <imagedata fileref="Ref/Screen/login.screen.png"
-                                 scale="90"/>
-                    </imageobject>
-                  </mediaobject>
-                </figure>
+                    <mediaobject>
+                      <imageobject>
+                        <imagedata fileref="Ref/Screen/login.screen.png"
+                                   scale="90"/>
+                      </imageobject>
+                    </mediaobject>
+                  </figure>
 
-                <para>Based on these input values the following SQL query is
-                being executed by a <classname>java.sql.Statement</classname>
-                object:</para>
+                  <para>Based on these input values the following SQL query is
+                  being executed by a
+                  <classname>java.sql.Statement</classname> object:</para>
 
-                <programlisting language="none">SELECT * FROM Person WHERE login='<emphasis
-                    role="bold">fred</emphasis>' and password = '<emphasis
-                    role="bold">12345678</emphasis>'</programlisting>
+                  <programlisting language="none">SELECT * FROM Person WHERE login='<emphasis
+                      role="bold">fred</emphasis>' and password = '<emphasis
+                      role="bold">12345678</emphasis>'</programlisting>
 
-                <para>Since the login attribute is UNIQUE we are sure to
-                receive either 0 or 1 dataset. Our programmer proposes to
-                grant login if the query returns at least one dataset.</para>
+                  <para>Since the login attribute is UNIQUE we are sure to
+                  receive either 0 or 1 dataset. Our programmer proposes to
+                  grant login if the query returns at least one
+                  dataset.</para>
 
-                <para>Discuss this implementation sketch with a colleague. Do
-                you think this is a sensible approach? <emphasis
-                role="bold">Write down</emphasis> your results.</para>
-              </question>
+                  <para>Discuss this implementation sketch with a colleague.
+                  Do you think this is a sensible approach? <emphasis
+                  role="bold">Write down</emphasis> your results.</para>
+                </question>
 
-              <answer>
-                <para>The approach is essentially unusable due to severe
-                security implications. Since it is based on
-                <classname>java.sql.Statement</classname> rater than on
-                <classname>java.sql.PreparedStatement</classname> objects it
-                is vulnerable to SQL injection attacks. A user my enter the
-                following password value in the GUI:</para>
-
-                <programlisting language="none">sd' OR '1' = '1</programlisting>
-
-                <para>Based on the login name <quote>fred</quote> the
-                following SQL string is being crafted:</para>
-
-                <programlisting language="none">SELECT * FROM Person WHERE login='fred' and password = 'sd' OR <emphasis
-                    role="bold">'1' = '1'</emphasis>;</programlisting>
-
-                <para>Since the WHERE clause's last component always evaluates
-                to true, all objects from the <code>Person</code> relation are
-                returned thus permitting login.</para>
-
-                <para>The implementation approach suffers from a second
-                deficiency: The passwords are stored in clear text. If an
-                attacker gains access to the <code>Person</code> table he'll
-                immediately retrieve the passwords of all users. This problem
-                can be solved by storing hash values of passwords rather than
-                the clear text values themselves.</para>
-              </answer>
-            </qandaentry>
-          </qandadiv>
-        </qandaset>
+                <answer>
+                  <para>The approach is essentially unusable due to severe
+                  security implications. Since it is based on
+                  <classname>java.sql.Statement</classname> rater than on
+                  <classname>java.sql.PreparedStatement</classname> objects it
+                  is vulnerable to SQL injection attacks. A user my enter the
+                  following password value in the GUI:</para>
+
+                  <programlisting language="none">sd' OR '1' = '1</programlisting>
+
+                  <para>Based on the login name <quote>fred</quote> the
+                  following SQL string is being crafted:</para>
+
+                  <programlisting language="none">SELECT * FROM Person WHERE login='fred' and password = 'sd' OR <emphasis
+                      role="bold">'1' = '1'</emphasis>;</programlisting>
+
+                  <para>Since the WHERE clause's last component always
+                  evaluates to true, all objects from the <code>Person</code>
+                  relation are returned thus permitting login.</para>
+
+                  <para>The implementation approach suffers from a second
+                  deficiency: The passwords are stored in clear text. If an
+                  attacker gains access to the <code>Person</code> table he'll
+                  immediately retrieve the passwords of all users. This
+                  problem can be solved by storing hash values of passwords
+                  rather than the clear text values themselves.</para>
+                </answer>
+              </qandaentry>
+            </qandadiv>
+          </qandaset>
+        </section>
 
-        <qandaset defaultlabel="qanda" xml:id="exerciseHashTraining">
+        <section xml:id="sectPasswordsHashed">
           <title>Passwords and hash values</title>
 
-          <qandadiv>
-            <qandaentry>
-              <question>
-                <para>In exercise <xref linkend="exerciseInsecureAuth"/> we
-                discarded the idea of clear text passwords in favour of
-                password hashes. In order to avoid Rainbow cracking so called
-                salted hashes are superior. You should read <uri
-                xlink:href="https://www.heckrothindustries.co.uk/articles/an-introduction-to-password-hashes">https://www.heckrothindustries.co.uk/articles/an-introduction-to-password-hashes</uri>
-                for overview purposes. The article contains further references
-                on the bottom of the page.</para>
-
-                <para>With respect to an implementation <uri
-                xlink:href="http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java#11038230">http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java</uri>
-                provides a simple example for:</para>
+          <qandaset defaultlabel="qanda" xml:id="exerciseHashTraining">
+            <qandadiv>
+              <qandaentry>
+                <question>
+                  <para>In exercise <xref linkend="exerciseInsecureAuth"/> we
+                  discarded the idea of clear text passwords in favour of
+                  password hashes. In order to avoid Rainbow cracking so
+                  called salted hashes are superior. You should read <uri
+                  xlink:href="https://www.heckrothindustries.co.uk/articles/an-introduction-to-password-hashes">https://www.heckrothindustries.co.uk/articles/an-introduction-to-password-hashes</uri>
+                  for overview purposes. The article contains further
+                  references on the bottom of the page.</para>
+
+                  <para>With respect to an implementation <uri
+                  xlink:href="http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java#11038230">http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java</uri>
+                  provides a simple example for:</para>
 
-                <itemizedlist>
-                  <listitem>
-                    <para>Creating a salted hash from a given password
-                    string.</para>
-                  </listitem>
+                  <itemizedlist>
+                    <listitem>
+                      <para>Creating a salted hash from a given password
+                      string.</para>
+                    </listitem>
 
-                  <listitem>
-                    <para>Verify if a hash string matches a given clear text
-                    password.</para>
-                  </listitem>
-                </itemizedlist>
+                    <listitem>
+                      <para>Verify if a hash string matches a given clear text
+                      password.</para>
+                    </listitem>
+                  </itemizedlist>
 
-                <para>The example uses an external library. On <productname
-                xlink:href="http://www.ubuntu.com">Ubuntu</productname> Linux
-                this may be installed by issuing <command>aptitude</command>
-                <option>install</option>
-                <option>libcommons-codec-java</option>. On successful install
-                the file
-                <filename>/usr/share/java/commons-codec-1.5.jar</filename> may
-                be appended to your <envar>CLASSPATH</envar>.</para>
-
-                <para>You may as well use <uri
-                xlink:href="http://crackstation.net/hashing-security.htm#javasourcecode">http://crackstation.net/hashing-security.htm#javasourcecode</uri>
-                as a starting point. This example works standalone without
-                needing an external library. Note: Tis example produces
-                different (incompatible) hash values.</para>
-
-                <para>Create a simple main() method to experiment with the two
-                class methods.</para>
-              </question>
+                  <para>The example uses an external library. On <productname
+                  xlink:href="http://www.ubuntu.com">Ubuntu</productname>
+                  Linux this may be installed by issuing
+                  <command>aptitude</command> <option>install</option>
+                  <option>libcommons-codec-java</option>. On successful
+                  install the file
+                  <filename>/usr/share/java/commons-codec-1.5.jar</filename>
+                  may be appended to your <envar>CLASSPATH</envar>.</para>
+
+                  <para>You may as well use <uri
+                  xlink:href="http://crackstation.net/hashing-security.htm#javasourcecode">http://crackstation.net/hashing-security.htm#javasourcecode</uri>
+                  as a starting point. This example works standalone without
+                  needing an external library. Note: Tis example produces
+                  different (incompatible) hash values.</para>
+
+                  <para>Create a simple main() method to experiment with the
+                  two class methods.</para>
+                </question>
 
-              <answer>
-                <para>Starting from <uri
-                xlink:href="http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java#11038230">http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java</uri>
-                we create a slightly modified class
-                <classname>sda.jdbc.intro.auth.HashProvider</classname>
-                offering both hash providing <coref
-                linkend="hashProviderMethod"/> and verifying <coref
-                linkend="hashVerifyMethod"/> methods:</para>
-
-                <programlisting language="none">package sda.jdbc.intro.auth;
+                <answer>
+                  <para>Starting from <uri
+                  xlink:href="http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java#11038230">http://stackoverflow.com/questions/2860943/suggestions-for-library-to-hash-passwords-in-java</uri>
+                  we create a slightly modified class
+                  <classname>sda.jdbc.intro.auth.HashProvider</classname>
+                  offering both hash providing <coref
+                  linkend="hashProviderMethod"/> and verifying <coref
+                  linkend="hashVerifyMethod"/> methods:</para>
+
+                  <programlisting language="none">package sda.jdbc.intro.auth;
 ...
 public class HashProvider {
 ...
     /** Computes a salted PBKDF2 hash of given plaintext password
         suitable for storing in a database. */
     public static <emphasis role="bold">String getSaltedHash</emphasis> <co
-                    xml:id="hashProviderMethod"/>(char [] password) {
+                      xml:id="hashProviderMethod"/>(char [] password) {
         byte[] salt;
       try {
          salt = SecureRandom.getInstance("SHA1PRNG").generateSeed(saltLen);
@@ -11716,7 +11728,7 @@ public class HashProvider {
     /** Checks whether given plaintext password corresponds 
         to a stored salted hash of the password. */
     public static <emphasis role="bold">boolean check</emphasis> <co
-                    xml:id="hashVerifyMethod"/>(char[] password, String stored){
+                      xml:id="hashVerifyMethod"/>(char[] password, String stored){
         String[] saltAndPass = stored.split("\\$");
         if (saltAndPass.length != 2)
             return false;
@@ -11725,15 +11737,15 @@ public class HashProvider {
     }
 ...}</programlisting>
 
-                <para>We may test the two class methods
-                <methodname>sda.jdbc.intro.auth.HashProvider.getSaltedHash(char[])</methodname>(...)
-                and
-                <methodname>sda.jdbc.intro.auth.HashProvider.check(char[],String)</methodname>
-                by a separate driver class. Notice the <quote>$</quote> sign
-                <coref linkend="saltPwhashSeparator"/> separating salt and
-                password hash:</para>
+                  <para>We may test the two class methods
+                  <methodname>sda.jdbc.intro.auth.HashProvider.getSaltedHash(char[])</methodname>(...)
+                  and
+                  <methodname>sda.jdbc.intro.auth.HashProvider.check(char[],String)</methodname>
+                  by a separate driver class. Notice the <quote>$</quote> sign
+                  <coref linkend="saltPwhashSeparator"/> separating salt and
+                  password hash:</para>
 
-                <programlisting language="none">package sda.jdbc.intro.auth;
+                  <programlisting language="none">package sda.jdbc.intro.auth;
 
 public class TestHashProvider {
 
@@ -11742,109 +11754,112 @@ public class TestHashProvider {
       final String hash = <emphasis role="bold">HashProvider.getSaltedHash(clearText)</emphasis>;
       System.out.println("Hash:" + hash);
       if (HashProvider.check(clearText,                 <co
-                    xml:id="saltPwhashSeparator"/>
+                      xml:id="saltPwhashSeparator"/>
             "<emphasis role="bold">HwX2DkuYiwp7xogm3AGndza8DKRVvCMntxRvCrCGFPw=</emphasis>$<emphasis
-                    role="bold">6Ix11yHNB4uPZuF2IQYxVV/MYragJwTDE33OIFR9a24=</emphasis>")) {
+                      role="bold">6Ix11yHNB4uPZuF2IQYxVV/MYragJwTDE33OIFR9a24=</emphasis>")) {
          System.out.println("hash matches");
       } else {
          System.out.println("hash does not match"); ...</programlisting>
-              </answer>
-            </qandaentry>
-          </qandadiv>
-        </qandaset>
+                </answer>
+              </qandaentry>
+            </qandadiv>
+          </qandaset>
+        </section>
 
-        <qandaset defaultlabel="qanda" xml:id="exerciseInsertLoginCredentials">
+        <section xml:id="guiAuthenticateTheRealMcCoy">
           <title>Gui authentication: The real McCoy</title>
 
-          <qandadiv>
-            <qandaentry>
-              <question>
-                <para>We now implement a refined version to enter
-                <code>Person</code> records based on the solutions of two
-                related exercises:</para>
+          <qandaset defaultlabel="qanda"
+                    xml:id="exerciseInsertLoginCredentials">
+            <qandadiv>
+              <qandaentry>
+                <question>
+                  <para>We now implement a refined version to enter
+                  <code>Person</code> records based on the solutions of two
+                  related exercises:</para>
 
-                <glosslist>
-                  <glossentry>
-                    <glossterm><xref
-                    linkend="exercisefilterUserInput"/></glossterm>
+                  <glosslist>
+                    <glossentry>
+                      <glossterm><xref
+                      linkend="exercisefilterUserInput"/></glossterm>
 
-                    <glossdef>
-                      <para>Avoiding SQL injection by sanitizing user
-                      input</para>
-                    </glossdef>
-                  </glossentry>
+                      <glossdef>
+                        <para>Avoiding SQL injection by sanitizing user
+                        input</para>
+                      </glossdef>
+                    </glossentry>
 
-                  <glossentry>
-                    <glossterm><xref
-                    linkend="exerciseSqlInjectPrepare"/></glossterm>
+                    <glossentry>
+                      <glossterm><xref
+                      linkend="exerciseSqlInjectPrepare"/></glossterm>
 
-                    <glossdef>
-                      <para>Avoiding SQL injection by using
-                      <classname>java.sql.PreparedStatement</classname>
-                      objects.</para>
-                    </glossdef>
-                  </glossentry>
-                </glosslist>
+                      <glossdef>
+                        <para>Avoiding SQL injection by using
+                        <classname>java.sql.PreparedStatement</classname>
+                        objects.</para>
+                      </glossdef>
+                    </glossentry>
+                  </glosslist>
 
-                <para>A better solution should combine both techniques.
-                Non-vulnerability a basic requirement. Checking an E-Mail for
-                minimal conformance is an added value.</para>
+                  <para>A better solution should combine both techniques.
+                  Non-vulnerability a basic requirement. Checking an E-Mail
+                  for minimal conformance is an added value.</para>
 
-                <para>In order to address authentication the relation Person
-                has to be extended appropriately. The GUI needs two additional
-                fields for login name and password as well. The following
-                video demonstrates the intended behaviour:</para>
+                  <para>In order to address authentication the relation Person
+                  has to be extended appropriately. The GUI needs two
+                  additional fields for login name and password as well. The
+                  following video demonstrates the intended behaviour:</para>
 
-                <figure xml:id="videoConnectAuth">
-                  <title>Intended usage behaviour for insertion of data
-                  records.</title>
+                  <figure xml:id="videoConnectAuth">
+                    <title>Intended usage behaviour for insertion of data
+                    records.</title>
 
-                  <mediaobject>
-                    <videoobject>
-                      <videodata fileref="Ref/Video/connectauth.mp4"/>
-                    </videoobject>
-                  </mediaobject>
-                </figure>
+                    <mediaobject>
+                      <videoobject>
+                        <videodata fileref="Ref/Video/connectauth.mp4"/>
+                      </videoobject>
+                    </mediaobject>
+                  </figure>
 
-                <para>Don't forget to use password hashes like those from
-                <xref linkend="exerciseHashTraining"/>. Due to their length
-                you may want to consider the data type
-                <code>TEXT</code>.</para>
-              </question>
+                  <para>Don't forget to use password hashes like those from
+                  <xref linkend="exerciseHashTraining"/>. Due to their length
+                  you may want to consider the data type
+                  <code>TEXT</code>.</para>
+                </question>
 
-              <answer>
-                <para>In comparison to earlier versions it does make sense to
-                add some internal container structures. First we note, that
-                each GUI input field requires:</para>
+                <answer>
+                  <para>In comparison to earlier versions it does make sense
+                  to add some internal container structures. First we note,
+                  that each GUI input field requires:</para>
 
-                <itemizedlist>
-                  <listitem>
-                    <para>A label like <quote>Enter password</quote>.</para>
-                  </listitem>
+                  <itemizedlist>
+                    <listitem>
+                      <para>A label like <quote>Enter password</quote>.</para>
+                    </listitem>
 
-                  <listitem>
-                    <para>A corresponding field object to hold user entered
-                    input.</para>
-                  </listitem>
+                    <listitem>
+                      <para>A corresponding field object to hold user entered
+                      input.</para>
+                    </listitem>
 
-                  <listitem>
-                    <para>A validator checking for correctness of entered
-                    data.</para>
-                  </listitem>
+                    <listitem>
+                      <para>A validator checking for correctness of entered
+                      data.</para>
+                    </listitem>
 
-                  <listitem>
-                    <para>A label or text field for warning messages in case
-                    of invalid user input.</para>
-                  </listitem>
-                </itemizedlist>
+                    <listitem>
+                      <para>A label or text field for warning messages in case
+                      of invalid user input.</para>
+                    </listitem>
+                  </itemizedlist>
 
-                <para>First we start by grouping label <coref
-                linkend="uiuLabel"/>, input field's verifier <coref
-                linkend="uiuVerifier"/> and the error message label <coref
-                linkend="uiuErrmsg"/> in
-                <classname>sda.jdbc.intro.auth.UserInputUnit</classname>:</para>
+                  <para>First we start by grouping label <coref
+                  linkend="uiuLabel"/>, input field's verifier <coref
+                  linkend="uiuVerifier"/> and the error message label <coref
+                  linkend="uiuErrmsg"/> in
+                  <classname>sda.jdbc.intro.auth.UserInputUnit</classname>:</para>
 
-                <programlisting language="none">package sda.jdbc.intro.auth;
+                  <programlisting language="none">package sda.jdbc.intro.auth;
 ...
 public class UserInputUnit {
    
@@ -11858,11 +11873,11 @@ public class UserInputUnit {
       errorMessage = new JLabel();
    } ...</programlisting>
 
-                <para>The actual GUI text field is being defined <coref
-                linkend="verfierGuiField"/> in class
-                <classname>sda.jdbc.intro.auth.InputVerifierNotify</classname>:</para>
+                  <para>The actual GUI text field is being defined <coref
+                  linkend="verfierGuiField"/> in class
+                  <classname>sda.jdbc.intro.auth.InputVerifierNotify</classname>:</para>
 
-                <programlisting language="none">package sda.jdbc.intro.auth;
+                  <programlisting language="none">package sda.jdbc.intro.auth;
 ...
 public abstract class InputVerifierNotify extends InputVerifier {
 
@@ -11872,40 +11887,41 @@ public abstract class InputVerifierNotify extends InputVerifier {
    
    public InputVerifierNotify(final JTextField field, final String errorMessage) { ...</programlisting>
 
-                <para>We need two field verifier classes being derived from
-                <classname>sda.jdbc.intro.auth.InputVerifierNotify</classname>:</para>
+                  <para>We need two field verifier classes being derived from
+                  <classname>sda.jdbc.intro.auth.InputVerifierNotify</classname>:</para>
 
-                <glosslist>
-                  <glossentry>
-                    <glossterm><classname>sda.jdbc.intro.auth.RegexpVerifier</classname></glossterm>
+                  <glosslist>
+                    <glossentry>
+                      <glossterm><classname>sda.jdbc.intro.auth.RegexpVerifier</classname></glossterm>
 
-                    <glossdef>
-                      <para>This one is well known from earlier versions and
-                      is used to validate text input fields by regular
-                      expressions.</para>
-                    </glossdef>
-                  </glossentry>
+                      <glossdef>
+                        <para>This one is well known from earlier versions and
+                        is used to validate text input fields by regular
+                        expressions.</para>
+                      </glossdef>
+                    </glossentry>
 
-                  <glossentry>
-                    <glossterm><classname>sda.jdbc.intro.auth.InputVerifierNotify</classname></glossterm>
+                    <glossentry>
+                      <glossterm><classname>sda.jdbc.intro.auth.InputVerifierNotify</classname></glossterm>
 
-                    <glossdef>
-                      <para>This verifier class is responsible for comparing
-                      our two password fields to have identical values.</para>
-                    </glossdef>
-                  </glossentry>
-                </glosslist>
+                      <glossdef>
+                        <para>This verifier class is responsible for comparing
+                        our two password fields to have identical
+                        values.</para>
+                      </glossdef>
+                    </glossentry>
+                  </glosslist>
 
-                <para>All these components get assembled in
-                <classname>sda.jdbc.intro.auth.InsertPerson</classname>. We
-                remark some important points:</para>
+                  <para>All these components get assembled in
+                  <classname>sda.jdbc.intro.auth.InsertPerson</classname>. We
+                  remark some important points:</para>
 
-                <programlisting language="none">package sda.jdbc.intro.auth;
+                  <programlisting language="none">package sda.jdbc.intro.auth;
 ...
 public class InsertPerson extends JFrame {
 ... // GUI attributes for user input
    final UserInputUnit name = <co linkends="listingInsertUserAuth-1"
-                    xml:id="listingInsertUserAuth-1-co"/>
+                      xml:id="listingInsertUserAuth-1-co"/>
          new UserInputUnit(
                "Name",
                new RegexpVerifier(new JTextField(15), "^[^;'\"]+$", "No special characters allowed"));
@@ -11913,8 +11929,8 @@ public class InsertPerson extends JFrame {
    // We need a reference to the password field to avoid
    // casting from JTextField later.
    private final JPasswordField passwordField = new JPasswordField(10); <co
-                    linkends="listingInsertUserAuth-2"
-                    xml:id="listingInsertUserAuth-2-co"/>
+                      linkends="listingInsertUserAuth-2"
+                      xml:id="listingInsertUserAuth-2-co"/>
    private final UserInputUnit password =
          new UserInputUnit(
                "Password",
@@ -11924,11 +11940,11 @@ public class InsertPerson extends JFrame {
          new UserInputUnit(
                "repeat pass.",
                new EqualValueVerifier <co linkends="listingInsertUserAuth-3"
-                    xml:id="listingInsertUserAuth-3-co"/> (new JPasswordField(10), passwordField, "Passwords do not match"));
+                      xml:id="listingInsertUserAuth-3-co"/> (new JPasswordField(10), passwordField, "Passwords do not match"));
    
    private final UserInputUnit [] userInputUnits = <co
-                    linkends="listingInsertUserAuth-4"
-                    xml:id="listingInsertUserAuth-4-co"/>
+                      linkends="listingInsertUserAuth-4"
+                      xml:id="listingInsertUserAuth-4-co"/>
       {name, email, login, password, passwordRepeat};
 ...   
    private void userLoginDialog() {...}
@@ -11939,8 +11955,8 @@ public class InsertPerson extends JFrame {
       add(databaseFieldPanel);
 
       for (UserInputUnit unit: userInputUnits) { <co
-                    linkends="listingInsertUserAuth-5"
-                    xml:id="listingInsertUserAuth-5-co"/>
+                      linkends="listingInsertUserAuth-5"
+                      xml:id="listingInsertUserAuth-5-co"/>
          databaseFieldPanel.add(unit.label);
          databaseFieldPanel.add(unit.verifier.field);
          databaseFieldPanel.add(unit.verifier.validationLabel);
@@ -11949,8 +11965,8 @@ public class InsertPerson extends JFrame {
          @Override public void actionPerformed(ActionEvent e) {
             if (inputValuesAllValid()) {
                if (persistenceHandler.add( <co
-                    linkends="listingInsertUserAuth-6"
-                    xml:id="listingInsertUserAuth-6-co"/>
+                      linkends="listingInsertUserAuth-6"
+                      xml:id="listingInsertUserAuth-6-co"/>
                      name.getText(),
                      email.getText(),
                      login.getText(),
@@ -11958,15 +11974,15 @@ public class InsertPerson extends JFrame {
                   clearMask();
 ...}
    private void clearMask() {  <co linkends="listingInsertUserAuth-7"
-                    xml:id="listingInsertUserAuth-7-co"/>
+                      xml:id="listingInsertUserAuth-7-co"/>
       for (UserInputUnit unit: userInputUnits) {
          unit.verifier.field.setText("");
          unit.verifier.clear();
       }
    }
    private boolean inputValuesAllValid() {<co
-                    linkends="listingInsertUserAuth-8"
-                    xml:id="listingInsertUserAuth-8-co"/>
+                      linkends="listingInsertUserAuth-8"
+                      xml:id="listingInsertUserAuth-8-co"/>
       for (UserInputUnit unit: userInputUnits) {
          if (!unit.verifier.verify(unit.verifier.field)){
             return false;
@@ -11976,68 +11992,70 @@ public class InsertPerson extends JFrame {
    }   
 }</programlisting>
 
-                <calloutlist>
-                  <callout arearefs="listingInsertUserAuth-1-co"
-                           xml:id="listingInsertUserAuth-1">
-                    <para>All GUI related stuff for entering a user's
-                    name</para>
-                  </callout>
+                  <calloutlist>
+                    <callout arearefs="listingInsertUserAuth-1-co"
+                             xml:id="listingInsertUserAuth-1">
+                      <para>All GUI related stuff for entering a user's
+                      name</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-2-co"
-                           xml:id="listingInsertUserAuth-2">
-                    <para>Password fields need special treatment:
-                    <code>getText()</code> is superseded by
-                    <code>getPassword()</code>. In order to avoid casts from
-                    <classname>javax.swing.JTextField</classname> to
-                    <classname>javax.swing.JPasswordField</classname> we
-                    simply keep an extra reference.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-2-co"
+                             xml:id="listingInsertUserAuth-2">
+                      <para>Password fields need special treatment:
+                      <code>getText()</code> is superseded by
+                      <code>getPassword()</code>. In order to avoid casts from
+                      <classname>javax.swing.JTextField</classname> to
+                      <classname>javax.swing.JPasswordField</classname> we
+                      simply keep an extra reference.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-3-co"
-                           xml:id="listingInsertUserAuth-3">
-                    <para>In order to check both password fields for identical
-                    values we need a different validator
-                    <classname>sda.jdbc.intro.auth.EqualValueVerifier</classname>
-                    expecting both password fields in its constructor.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-3-co"
+                             xml:id="listingInsertUserAuth-3">
+                      <para>In order to check both password fields for
+                      identical values we need a different validator
+                      <classname>sda.jdbc.intro.auth.EqualValueVerifier</classname>
+                      expecting both password fields in its
+                      constructor.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-4-co"
-                           xml:id="listingInsertUserAuth-4">
-                    <para>All 5 user input elements get grouped by an array.
-                    This allows for iterations like in <coref
-                    linkend="listingInsertUserAuth-7-co"/> or <coref
-                    linkend="listingInsertUserAuth-8-co"/>.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-4-co"
+                             xml:id="listingInsertUserAuth-4">
+                      <para>All 5 user input elements get grouped by an array.
+                      This allows for iterations like in <coref
+                      linkend="listingInsertUserAuth-7-co"/> or <coref
+                      linkend="listingInsertUserAuth-8-co"/>.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-5-co"
-                           xml:id="listingInsertUserAuth-5">
-                    <para>Adding all GUI elements to the base pane in a
-                    loop.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-5-co"
+                             xml:id="listingInsertUserAuth-5">
+                      <para>Adding all GUI elements to the base pane in a
+                      loop.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-6-co"
-                           xml:id="listingInsertUserAuth-6">
-                    <para>Providing user entered values to the persistence
-                    provider.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-6-co"
+                             xml:id="listingInsertUserAuth-6">
+                      <para>Providing user entered values to the persistence
+                      provider.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-7-co"
-                           xml:id="listingInsertUserAuth-7">
-                    <para>Whenever a dataset has been successfully sent to the
-                    database we have to clean our GUI to possibly enter
-                    another record.</para>
-                  </callout>
+                    <callout arearefs="listingInsertUserAuth-7-co"
+                             xml:id="listingInsertUserAuth-7">
+                      <para>Whenever a dataset has been successfully sent to
+                      the database we have to clean our GUI to possibly enter
+                      another record.</para>
+                    </callout>
 
-                  <callout arearefs="listingInsertUserAuth-8-co"
-                           xml:id="listingInsertUserAuth-8">
-                    <para>Thanks to our grouping aggregation of individual
-                    input GUI field validation states becomes easy.</para>
-                  </callout>
-                </calloutlist>
-              </answer>
-            </qandaentry>
-          </qandadiv>
-        </qandaset>
+                    <callout arearefs="listingInsertUserAuth-8-co"
+                             xml:id="listingInsertUserAuth-8">
+                      <para>Thanks to our grouping aggregation of individual
+                      input GUI field validation states becomes easy.</para>
+                    </callout>
+                  </calloutlist>
+                </answer>
+              </qandaentry>
+            </qandadiv>
+          </qandaset>
+        </section>
 
         <section xml:id="sectArchitectSecurityConsiderations">
           <title>Architectural security considerations</title>
@@ -12094,20 +12112,17 @@ PersistenceHandler.password=<emphasis role="bold">XYZ</emphasis> <co
         </section>
 
         <section xml:id="sectRelationadatal2Xml">
-          <title>Converting relational data to XML</title>
+          <title>Reversing <xref linkend="glo_XML"/> to Rdbms</title>
 
           <qandaset defaultlabel="qanda" xml:base="qandaRelationaldata2Xml"
                     xml:id="qandaRelationaldata2Xml">
-            <title>Reversing Xml to Rdbms exercise</title>
-
             <qandadiv>
               <qandaentry>
                 <question>
-                  <label>Exporting RDBMS data to XML.</label>
-
                   <para>Reverse exercise <xref
                   linkend="qandaXmldata2relational"/> to read Rdbms data via
-                  JDBC and export corresponding XML data using Jdom.</para>
+                  <xref linkend="glo_JDBC"/> and export corresponding XML data
+                  using Jdom.</para>
                 </question>
 
                 <answer>
@@ -12119,22 +12134,19 @@ PersistenceHandler.password=<emphasis role="bold">XYZ</emphasis> <co
         </section>
 
         <section xml:id="sda1SaxRdbms">
-          <title>SAX and RDBMS</title>
+          <title>Generating HTML from XML and Rdbms data using SAX and <xref
+          linkend="glo_JDBC"/>.</title>
 
           <qandaset defaultlabel="qanda" xml:id="exercise_saxAttrib">
-            <title>Reading XML attributes</title>
-
             <qandadiv>
               <qandaentry xml:id="saxRdbms">
                 <question>
-                  <label>SAX processing with RDBMS access.</label>
-
                   <para>Implement the example given in <xref
                   linkend="saxRdbmsAccessPrinciple"/> to produce the output
                   sketched in <xref linkend="saxPriceOut"/>. You may start by
                   implementing <emphasis>and testing</emphasis> the following
-                  methods of a RDBMS interfacing class using <trademark
-                  xlink:href="http://electronics.zibb.com/trademark/jdbc/29545026">JDBC</trademark>:</para>
+                  methods of a RDBMS interfacing class using <xref
+                  linkend="glo_JDBC"/>:</para>
 
                   <programlisting language="none">package sax.rdbms;
         
-- 
GitLab