From 7cf3aeed0e6f82d7bd69303dc54018959e400315 Mon Sep 17 00:00:00 2001
From: Martin Goik <goik@hdm-stuttgart.de>
Date: Fri, 12 Dec 2014 19:02:06 +0100
Subject: [PATCH] Better Junit userr hints in case of non-wellformed XML
 documents

---
 .../mi/sda1/saxhtml/v1/Driver.java            |  2 +-
 .../mi/sda1/saxhtml/v1/Memo2Html.java         |  9 +-
 .../mi/sda1/saxhtml/v1/Memo2HtmlHandler.java  | 16 +++-
 .../mi/sda1/saxhtml/v2/Driver.java            |  4 +-
 .../mi/sda1/saxhtml/v2/Memo2Html.java         |  7 +-
 .../mi/sda1/saxhtml/v2/Memo2HtmlHandler.java  | 15 +++-
 .../src/main/resources/memo.xml.1.html        | 23 +++--
 ...nTest.java => TestSimpleSaxTransform.java} | 35 ++------
 .../sda1/saxhtml/v2/test/ConversionTest.java  | 73 ---------------
 .../v2/test/TestComplexSaxTransform.java}     | 31 ++-----
 .../de/testing/dom/ConversionTest.java        | 75 ++++++++++++++++
 ...nTest.java => TestSimpleSaxTransform.java} | 34 ++-----
 .../v2/test/TestComplexSaxTransform.java      | 56 ++++++++++++
 .../de/testing/dom/ConversionTest.java        | 80 +++++++++++++++++
 Sda1/Etest/SaxMemo2Html/exercise1.xhtml       | 22 ++---
 Sda1/Etest/SaxMemo2Html/exercise2.xhtml       | 90 -------------------
 16 files changed, 295 insertions(+), 277 deletions(-)
 rename Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/{ConversionTest.java => TestSimpleSaxTransform.java} (59%)
 delete mode 100644 Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java
 rename Sda1/Etest/SaxMemo2Html/{Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java => SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java} (74%)
 create mode 100644 Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
 rename Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/{ConversionTest.java => TestSimpleSaxTransform.java} (59%)
 create mode 100644 Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
 create mode 100644 Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
 delete mode 100644 Sda1/Etest/SaxMemo2Html/exercise2.xhtml

diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Driver.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Driver.java
index 78c63536f..1a3cd8f29 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Driver.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Driver.java
@@ -5,7 +5,7 @@ public class Driver {
   /** @param argv unused */
   public static void main(String argv[]) {
     try{
-    Memo2Html memo2html = new Memo2Html(System.out);
+    Memo2Html memo2html = new Memo2Html(new Memo2HtmlHandler());
     memo2html.parse("src/main/resources/memo.xml");
 
     } catch (Exception e){
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2Html.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2Html.java
index 1e0d749a6..399857954 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2Html.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2Html.java
@@ -7,14 +7,14 @@ import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
+import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 
 /** Parser, content- and error handler assembly */
-public class Memo2Html {
+public class Memo2Html  {
 
 	private final XMLReader xmlReader;
-	private final Memo2HtmlHandler eventHandler;
 	private final MyErrorHandler errorHandler = new MyErrorHandler();
 
 	/**
@@ -24,14 +24,13 @@ public class Memo2Html {
 	 * @throws ParserConfigurationException
 	 *             Unable to instantiate parser.
 	 */
-	public Memo2Html(final PrintStream out) throws SAXException,
+	public Memo2Html(final ContentHandler handler) throws SAXException,
 			ParserConfigurationException {
 		final SAXParserFactory saxPf = SAXParserFactory.newInstance();
 		final SAXParser saxParser = saxPf.newSAXParser();
 		xmlReader = saxParser.getXMLReader();
 
-		eventHandler = new Memo2HtmlHandler(out);
-		xmlReader.setContentHandler(eventHandler);
+		xmlReader.setContentHandler(handler);
 		xmlReader.setErrorHandler(errorHandler);
 	}
 
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java
index 69226b80b..580fcfbc5 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v1/Memo2HtmlHandler.java
@@ -6,19 +6,21 @@ import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import de.hdm_stuttgart.mi.sda1.saxhtml.tools.ContentRedirect;
+
 /**
  * Turning &lt;memo&gt; documents to HTML
  *
  */
-public class Memo2HtmlHandler extends DefaultHandler {
+public class Memo2HtmlHandler extends DefaultHandler implements ContentRedirect {
 
-	private final PrintStream out;
+	private PrintStream out;
 
 	/**
 	 * @param out
 	 */
-	public Memo2HtmlHandler(final PrintStream out) {
-		this.out = out;
+	public Memo2HtmlHandler() {
+		out = System.out;
 	}
 
 	boolean printCharacters = false;
@@ -94,4 +96,10 @@ public class Memo2HtmlHandler extends DefaultHandler {
 		out.println("\n  </body>" + "\n</html>");
 		out.flush();
 	}
+
+   @Override
+   public void setOutputStream(final PrintStream out) {
+      this.out = out;
+      
+   }
 }
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Driver.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Driver.java
index c36643969..99616e0b9 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Driver.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Driver.java
@@ -1,11 +1,13 @@
 package de.hdm_stuttgart.mi.sda1.saxhtml.v2;
 
+import de.hdm_stuttgart.mi.sda1.saxhtml.v1.Memo2HtmlHandler;
+
 /** Driver */
 public class Driver {
   /** @param argv unused */
   public static void main(String argv[]) {
     try{
-    Memo2Html memo2html = new Memo2Html(System.out);
+    Memo2Html memo2html = new Memo2Html(new Memo2HtmlHandler());
     memo2html.parse("src/main/resources/memo.xml");
 
     } catch (Exception e){
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2Html.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2Html.java
index 5d0dcf1ba..5b98ba9ca 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2Html.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2Html.java
@@ -7,6 +7,7 @@ import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
 
+import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 
@@ -16,7 +17,6 @@ import de.hdm_stuttgart.mi.sda1.saxhtml.v1.MyErrorHandler;
 public class Memo2Html {
 
 	private final XMLReader xmlReader;
-	private final Memo2HtmlHandler eventHandler;
 	private final MyErrorHandler errorHandler = new MyErrorHandler();
 
 	/**
@@ -26,14 +26,13 @@ public class Memo2Html {
 	 * @throws ParserConfigurationException
 	 *             Unable to instantiate parser.
 	 */
-	public Memo2Html(final PrintStream out) throws SAXException,
+	public Memo2Html(final ContentHandler handler) throws SAXException,
 			ParserConfigurationException {
 		final SAXParserFactory saxPf = SAXParserFactory.newInstance();
 		final SAXParser saxParser = saxPf.newSAXParser();
 		xmlReader = saxParser.getXMLReader();
 
-		eventHandler = new Memo2HtmlHandler(out);
-		xmlReader.setContentHandler(eventHandler);
+		xmlReader.setContentHandler(handler);
 		xmlReader.setErrorHandler(errorHandler);
 	}
 
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java
index d71670297..dcdf36a95 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/java/de/hdm_stuttgart/mi/sda1/saxhtml/v2/Memo2HtmlHandler.java
@@ -8,20 +8,22 @@ import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import de.hdm_stuttgart.mi.sda1.saxhtml.tools.ContentRedirect;
+
 /**
  * Turning &lt;memo&gt; documents to HTML
  *
  */
-public class Memo2HtmlHandler extends DefaultHandler {
+public class Memo2HtmlHandler extends DefaultHandler implements ContentRedirect {
 
-	private final PrintStream out;
+	private PrintStream out;
 
 	/**
 	 * @param out
 	 *            Write output to stream
 	 */
-	public Memo2HtmlHandler(final PrintStream out) {
-		this.out = out;
+	public Memo2HtmlHandler() {
+		out = System.out;
 	}
 
 	String from, subject, content;
@@ -94,4 +96,9 @@ public class Memo2HtmlHandler extends DefaultHandler {
 				+ from + "</strong></p>\n" + "  </body>\n" + "</html>\n");
 		out.flush();
 	}
+
+   @Override
+   public void setOutputStream(PrintStream out) {
+      this.out = out;
+   }
 }
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml.1.html b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml.1.html
index 9157fb5aa..85659d988 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml.1.html
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/main/resources/memo.xml.1.html
@@ -1,15 +1,20 @@
 <html>
-  <head>
-    <title>Memo message</title>
-  </head>
+  <head><title>Memo from M. Goik</title></head>
   <body>
-    <h2>Message from <strong>M. Goik</strong></h2>
-    <h2>Recipients:</h2>
-    <ul>
-      <li>B. King</li>
-      <li>A. June</li>
-    </ul>
+    <h2>Subject:Best wishes</h2>
+    <dl>
+      <dt>Sender:</dt>
+      <dd>M. Goik</dd>
+      <dt>Recipients:</dt>
+      <dd>
+        <ul>
+          <li>B. King</li>
+          <li>A. June</li>
+        </ul>
+      </dd>
+    </dl>
     <h2>Subject: Best wishes</h2>
     <p>Hi all, congratulations to your splendid party</p>
+    <p>End of message from <strong>M. Goik</strong></p>
   </body>
 </html>
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
similarity index 59%
rename from Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java
rename to Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
index c4b3c305d..f8bbf56bc 100644
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
@@ -1,41 +1,24 @@
 package de.hdm_stuttgart.de.sda1.saxhtml.v1.test;
 
-import java.io.IOException;
-import java.io.PrintStream;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-import org.junit.BeforeClass;
+import org.junit.Assert;
 import org.junit.Test;
-import org.xml.sax.SAXException;
 
+import de.hdm_stuttgart.de.testing.dom.ConversionTest;
 import de.hdm_stuttgart.de.testing.dom.DomAssert;
-import de.hdm_stuttgart.mi.sda1.saxhtml.v1.Memo2Html;
+import de.hdm_stuttgart.mi.sda1.saxhtml.v1.Memo2HtmlHandler;
 
 /**
  * Unit testing XML to HTML output
  */
 @SuppressWarnings("javadoc")
-public class ConversionTest {
+public class TestSimpleSaxTransform extends ConversionTest {
    
-   final static String
-      xmlInputFileName = "src/main/resources/memo.xml",
-      htmlOutputFileName = xmlInputFileName + ".1.html";
-   
-   static Element htmlRootElement; 
+   public TestSimpleSaxTransform() {
+      super("src/main/resources/memo.xml", new Memo2HtmlHandler(), ".1.html");
+   }
    
-   @BeforeClass public static void init()
-         throws JDOMException, SAXException, ParserConfigurationException, IOException {
-      
-         final PrintStream out = new PrintStream(htmlOutputFileName);
-         final Memo2Html memo2html = new Memo2Html(out);
-         memo2html.parse(xmlInputFileName);
-         final SAXBuilder parser = new SAXBuilder();
-         htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
-         out.close();
+   @Test public void checkWellFormedness() {
+      Assert.assertNull("Unable to parse generated file:" + errorInitString, errorInitString);
    }
    
    @Test public void testSenderInHeader() {
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java
deleted file mode 100644
index 4c0467f29..000000000
--- a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.hdm_stuttgart.de.sda1.saxhtml.v2.test;
-
-import java.io.IOException;
-import java.io.PrintStream;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.xml.sax.SAXException;
-
-import de.hdm_stuttgart.de.testing.dom.DomAssert;
-import de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2Html;
-
-/**
- * Unit testing XML to HTML output
- */
-@SuppressWarnings("javadoc")
-public class ConversionTest {
-   
-   final static String
-      xmlInputFileName = "src/main/resources/memo.xml",
-      htmlOutputFileName = xmlInputFileName + ".2.html";
-   
-   static Element htmlRootElement; 
-   
-   /**
- * @throws JDOMException
- * @throws SAXException
- * @throws ParserConfigurationException
- * @throws IOException
- */
-@BeforeClass public static void init()
-         throws JDOMException, SAXException, ParserConfigurationException, IOException {
-      
-         final PrintStream out = new PrintStream(htmlOutputFileName);
-         final Memo2Html memo2html = new Memo2Html(out);
-         memo2html.parse(xmlInputFileName);
-         final SAXBuilder parser = new SAXBuilder();
-         htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
-         out.close();
-   }
-   
-@Test public void testSenderInHeader() {
-      DomAssert.assertSingleNodeContent("<title>Memo from M. Goik</title> must be child of <head>", htmlRootElement, "head/title", "Memo from M. Goik");
-   }
-   @Test public void testNumberfRecipients() {
-      DomAssert.assertNumberOfNodes("There should be two <li> elements matching two recipients", htmlRootElement, "body/dl/dd/ul/li", 2);
-   }
-   @Test public void testH1MemoSubjectMessage() {
-      DomAssert.assertSingleNodeContent("<h2>Subject:Best wishes</h2> must appear as first child of <body>",
-            htmlRootElement, "body/*[1]", "h2", "Subject:Best wishes");
-   }
-   @Test public void testSenderBeforeRecipientList() {
-      DomAssert.assertSingleNodeContent("<dd>M. Goik</dd> must appear as second child  of the list of recipients",
-            htmlRootElement, "body/dl/*[2]", "dd", "M. Goik");
-   }
-   @Test public void testMemoContent() {
-      DomAssert.assertSingleNodeContent("content must appear as second <p> child after recipient list in <body>",
-            htmlRootElement, "body/dl/following-sibling::*[2]", "p", "Hi all, congratulations to your splendid party");
-   }
-   @Test public void testLastParagraph() {
-      DomAssert.assertNumberOfNodes("Expecting two <p> children of <body>",
-            htmlRootElement, "body/*[name(.)='p']", 2);
-   }
-   @Test public void testSenderAtFoot() {
-      DomAssert.assertSingleNodeContent("<strong>M. Goik</strong> must appear inside a <p> immediately following the list of recipients",
-            htmlRootElement, "body/dl/following-sibling::*[1]", "h2", "Subject: Best wishes");
-   }
-}
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
similarity index 74%
rename from Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java
rename to Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
index b7ed83106..adda24bb8 100644
--- a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/ConversionTest.java
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
@@ -12,38 +12,21 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.xml.sax.SAXException;
 
+import de.hdm_stuttgart.de.testing.dom.ConversionTest;
 import de.hdm_stuttgart.de.testing.dom.DomAssert;
 import de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2Html;
+import de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2HtmlHandler;
 
 /**
  * Turning &lt;memo&gt; documents to HTML as being shown in sample document memo.xml.2.sample.html 
 
  */
 @SuppressWarnings("javadoc")
-public class ConversionTest {
-
-	final static String
-	xmlInputFileName = "src/main/resources/memo.xml",
-	htmlOutputFileName = xmlInputFileName + ".2.html";
-
-	static Element htmlRootElement; 
-
-	/**
-	 * @throws JDOMException
-	 * @throws SAXException
-	 * @throws ParserConfigurationException
-	 * @throws IOException
-	 */
-	@BeforeClass public static void init()
-			throws JDOMException, SAXException, ParserConfigurationException, IOException {
-
-		final PrintStream out = new PrintStream(htmlOutputFileName);
-		final Memo2Html memo2html = new Memo2Html(out);
-		memo2html.parse(xmlInputFileName);
-		final SAXBuilder parser = new SAXBuilder();
-		htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
-		out.close();
-	}
+public class TestComplexSaxTransform extends ConversionTest {
+   
+   public TestComplexSaxTransform() {
+      super("src/main/resources/memo.xml", new Memo2HtmlHandler(), ".2.html");
+   }
 
 	@Test public void testSenderInHeader() {
 		DomAssert.assertSingleNodeContent("<title>Memo from M. Goik</title> must be child of <head>", htmlRootElement, "head/title", "Memo from M. Goik");
diff --git a/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
new file mode 100644
index 000000000..d26e81018
--- /dev/null
+++ b/Sda1/Etest/SaxMemo2Html/SaxMemo2Hhtml_solution/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
@@ -0,0 +1,75 @@
+package de.hdm_stuttgart.de.testing.dom;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import de.hdm_stuttgart.de.testing.dom.DomAssert;
+import de.hdm_stuttgart.mi.sda1.saxhtml.tools.ContentRedirect;
+import de.hdm_stuttgart.mi.sda1.saxhtml.v1.Memo2Html;
+
+/**
+ * Turning &lt;memo&gt; documents to HTML as being shown in sample document memo.xml.2.sample.html 
+
+ */
+@SuppressWarnings("javadoc")
+public abstract class ConversionTest {
+   
+   public final String xmlInputFileName, htmlOutputFileName; 
+   final ContentRedirect saxHandler;
+   protected String errorInitString = null;
+
+   protected Element htmlRootElement; 
+
+   protected ConversionTest(final String xmlInputFileName, final ContentRedirect saxHandler, final String outputExtension) {
+      
+      this.saxHandler = saxHandler;
+      
+      this.xmlInputFileName = xmlInputFileName;
+      this.htmlOutputFileName = xmlInputFileName + outputExtension;
+      
+      final PrintStream out;
+
+      try {
+         out = new PrintStream(htmlOutputFileName);
+      } catch (FileNotFoundException e1) {
+         errorInitString = "Unable to open file '" + htmlOutputFileName + "' for writing";
+         return;
+      }
+      saxHandler.setOutputStream(out);
+      final Memo2Html memo2html;
+      try {
+         memo2html = new Memo2Html(saxHandler);
+      } catch (SAXException | ParserConfigurationException e2) {
+         e2.printStackTrace();
+         return;
+      }
+      try {
+         memo2html.parse(xmlInputFileName);
+      } catch (IOException e1) {
+         errorInitString = "Unable parse file '" + xmlInputFileName + "'";
+         return;
+      } catch (SAXException e) {
+         e.printStackTrace();
+      }
+      final SAXBuilder parser = new SAXBuilder();
+      
+      try {
+         htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
+      } catch (JDOMException | IOException e1) {
+         errorInitString = "Unable to parse file '" + htmlOutputFileName + "', see stack trace for further information";
+         e1.printStackTrace();
+      }
+      out.close();
+   }
+}
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
similarity index 59%
rename from Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java
rename to Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
index c4b3c305d..939fa29a1 100644
--- a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/ConversionTest.java
+++ b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v1/test/TestSimpleSaxTransform.java
@@ -1,41 +1,23 @@
 package de.hdm_stuttgart.de.sda1.saxhtml.v1.test;
 
-import java.io.IOException;
-import java.io.PrintStream;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-import org.junit.BeforeClass;
+import org.junit.Assert;
 import org.junit.Test;
-import org.xml.sax.SAXException;
 
+import de.hdm_stuttgart.de.testing.dom.ConversionTest;
 import de.hdm_stuttgart.de.testing.dom.DomAssert;
-import de.hdm_stuttgart.mi.sda1.saxhtml.v1.Memo2Html;
 
 /**
  * Unit testing XML to HTML output
  */
 @SuppressWarnings("javadoc")
-public class ConversionTest {
+public class TestSimpleSaxTransform extends ConversionTest {
    
-   final static String
-      xmlInputFileName = "src/main/resources/memo.xml",
-      htmlOutputFileName = xmlInputFileName + ".1.html";
-   
-   static Element htmlRootElement; 
+   public TestSimpleSaxTransform() {
+      super("src/main/resources/memo.xml", ".1.html");
+   }
    
-   @BeforeClass public static void init()
-         throws JDOMException, SAXException, ParserConfigurationException, IOException {
-      
-         final PrintStream out = new PrintStream(htmlOutputFileName);
-         final Memo2Html memo2html = new Memo2Html(out);
-         memo2html.parse(xmlInputFileName);
-         final SAXBuilder parser = new SAXBuilder();
-         htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
-         out.close();
+   @Test public void checkWellFormedness() {
+      Assert.assertNull("Unable to parse generated file:" + errorInitString, errorInitString);
    }
    
    @Test public void testSenderInHeader() {
diff --git a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
new file mode 100644
index 000000000..d6f7e525a
--- /dev/null
+++ b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/sda1/saxhtml/v2/test/TestComplexSaxTransform.java
@@ -0,0 +1,56 @@
+package de.hdm_stuttgart.de.sda1.saxhtml.v2.test;
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+import de.hdm_stuttgart.de.testing.dom.ConversionTest;
+import de.hdm_stuttgart.de.testing.dom.DomAssert;
+import de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2Html;
+
+/**
+ * Turning &lt;memo&gt; documents to HTML as being shown in sample document memo.xml.2.sample.html 
+
+ */
+@SuppressWarnings("javadoc")
+public class TestComplexSaxTransform extends ConversionTest {
+   
+   public TestComplexSaxTransform() {
+      super("src/main/resources/memo.xml", ".2.html");
+   }
+
+	@Test public void testSenderInHeader() {
+		DomAssert.assertSingleNodeContent("<title>Memo from M. Goik</title> must be child of <head>", htmlRootElement, "head/title", "Memo from M. Goik");
+	}
+	@Test public void testNumberfRecipients() {
+		DomAssert.assertNumberOfNodes("There should be two <li> elements matching two recipients", htmlRootElement, "body/dl/dd/ul/li", 2);
+	}
+	@Test public void testH1MemoSubjectMessage() {
+		DomAssert.assertSingleNodeContent("<h2>Subject:Best wishes</h2> must appear as first child of <body>",
+				htmlRootElement, "body/*[1]", "h2", "Subject:Best wishes");
+	}
+	@Test public void testSenderBeforeRecipientList() {
+		DomAssert.assertSingleNodeContent("<dd>M. Goik</dd> must appear as second child  of the list of recipients",
+				htmlRootElement, "body/dl/*[2]", "dd", "M. Goik");
+	}
+	@Test public void testMemoContent() {
+		DomAssert.assertSingleNodeContent("content must appear as second <p> child after recipient list in <body>",
+				htmlRootElement, "body/dl/following-sibling::*[2]", "p", "Hi all, congratulations to your splendid party");
+	}
+	@Test public void testLastParagraph() {
+		DomAssert.assertNumberOfNodes("Expecting two <p> children of <body>",
+				htmlRootElement, "body/*[name(.)='p']", 2);
+	}
+	@Test public void testSenderAtFoot() {
+		DomAssert.assertSingleNodeContent("<strong>M. Goik</strong> must appear inside a <p> immediately following the list of recipients",
+				htmlRootElement, "body/dl/following-sibling::*[1]", "h2", "Subject: Best wishes");
+	}
+}
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
new file mode 100644
index 000000000..4886a72e7
--- /dev/null
+++ b/Sda1/Etest/SaxMemo2Html/Saxmemo2html/src/test/java/de/hdm_stuttgart/de/testing/dom/ConversionTest.java
@@ -0,0 +1,80 @@
+package de.hdm_stuttgart.de.testing.dom;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+import de.hdm_stuttgart.de.testing.dom.DomAssert;
+import de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2Html;
+
+/**
+ * Turning &lt;memo&gt; documents to HTML as being shown in sample document memo.xml.2.sample.html 
+
+ */
+@SuppressWarnings("javadoc")
+public abstract class ConversionTest {
+   
+   protected ConversionTest(final String xmlInputFileName, final String extension) {
+      this.xmlInputFileName = xmlInputFileName;
+      this.htmlOutputFileName = xmlInputFileName + extension;
+   }
+
+	public final String xmlInputFileName, htmlOutputFileName; // To be statically initialized in derived class
+	protected String errorInitString = null;
+
+	protected Element htmlRootElement; 
+
+	/**
+	 * @throws JDOMException
+	 * @throws SAXException
+	 * @throws ParserConfigurationException
+	 * @throws IOException
+	 */
+	public void init() {
+      
+         PrintStream out;
+
+         try {
+            System.err.println("of=" + htmlOutputFileName);
+            out = new PrintStream(htmlOutputFileName);
+         } catch (FileNotFoundException e1) {
+            errorInitString = "Unable to open file '" + htmlOutputFileName + "' for writing";
+            return;
+         }
+         Memo2Html memo2html;
+         try {
+            memo2html = new Memo2Html(out);
+         } catch (SAXException | ParserConfigurationException e2) {
+            // TODO Auto-generated catch block
+            e2.printStackTrace();
+            return;
+         }
+         try {
+            memo2html.parse(xmlInputFileName);
+         } catch (IOException e1) {
+            errorInitString = "Unable parse file '" + xmlInputFileName + "'";
+            return;
+         } catch (SAXException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+         }
+         final SAXBuilder parser = new SAXBuilder();
+         
+         try {
+            htmlRootElement = parser.build(htmlOutputFileName).getRootElement();
+         } catch (JDOMException | IOException e1) {
+            errorInitString = "Unable to parse file '" + htmlOutputFileName + "', see stack trace for further information";
+            e1.printStackTrace();
+         }
+         out.close();
+   }
+}
\ No newline at end of file
diff --git a/Sda1/Etest/SaxMemo2Html/exercise1.xhtml b/Sda1/Etest/SaxMemo2Html/exercise1.xhtml
index 0bb111955..2f98a36e1 100644
--- a/Sda1/Etest/SaxMemo2Html/exercise1.xhtml
+++ b/Sda1/Etest/SaxMemo2Html/exercise1.xhtml
@@ -33,7 +33,7 @@
           <li><p><strong>src/main/resources/memo.xml.1.sample.html</strong></p><p>The
           intended output corresponding to be generated from </p></li>
 
-          <li><p><strong>de.hdm_stuttgart.de.sda1.saxhtml.v1.test.ConversionTest</strong></p><p>This
+          <li><p><strong>de.hdm_stuttgart.de.sda1.saxhtml.v1.test.TestSimpleSaxTransform</strong></p><p>This
           Junit class executes your handler and writes the corresponding
           output to src/main/resources/memo.xml.1.html. The latter file then
           becomes subject to a series of XPath expression tests checking for
@@ -63,9 +63,10 @@
     &lt;h2&gt;Subject: Best wishes&lt;/h2&gt;
     &lt;p&gt;Hi all, congratulations to your splendid party&lt;/p&gt;
   &lt;/body&gt;
-&lt;/html&gt;</pre><p> Watch your output being generated by executing
-  <code>de.hdm_stuttgart.mi.sda1.saxhtml.v1.Driver</code>. When you are
-  satisfied with your result execute the Junit test
+&lt;/html&gt;</pre><p>Your SAX handler shall allow for processing of multiple
+  XML input documents in sequence. </p><p>Watch your output being generated by
+  executing <code>de.hdm_stuttgart.mi.sda1.saxhtml.v1.Driver</code>. When you
+  are satisfied with your result execute the Junit test
   <code>de.hdm_stuttgart.de.sda1.saxhtml.v1.test.ConversionTest</code>. When
   you are finished export your Maven project as a compressed .zip archive and
   upload it.</p><h2>ToDo, Part 2</h2><p>This second exercise deals with Java
@@ -73,8 +74,8 @@
   names. So you might want to close <strong>all</strong> file tabs in your
   current Eclipse project to avoid confusing yourself with files from the
   first part of this exercise.</p><p>Your project contains a second set of
-  files intended to create more sophisticated output as being contained in
-  <code>memo.xml.2.sample.html</code>:</p><pre>&lt;html&gt;
+  files intended to create more sophisticated output. A sample result is being
+  contained in <code>memo.xml.2.sample.html</code>:</p><pre>&lt;html&gt;
   &lt;head&gt;&lt;title&gt;Memo from M. Goik&lt;/title&gt;&lt;/head&gt;
   &lt;body&gt;
     &lt;h2&gt;Subject:Best wishes&lt;/h2&gt;
@@ -95,13 +96,14 @@
   &lt;/body&gt;
 &lt;/html&gt;</pre><p>Complete the implementation of
   <code>de.hdm_stuttgart.mi.sda1.saxhtml.v2.Memo2HtmlHandler</code>.
-  Corresponding Driver and Junit classes are being supplied by
+  Corresponding Driver and Junit classes are being supplied as
   <code>de.hdm_stuttgart.mi.sda1.saxhtml.v2.Driver</code> and
-  <code>de.hdm_stuttgart.de.sda1.saxhtml.v2.test.ConversionTest</code>.</p><p>When
+  <code>de.hdm_stuttgart.de.sda1.saxhtml.v2.test.TestComplexSaxTransform</code>.</p><p>When
   you are finished zip your project again and upload it. Only the last .zip
   file will become subject to marking.</p><h3>Hint:</h3><p>In this second part
-  the order of content from your XML input is not being preserved. Furthermore
-  some input (sender's name) has to be duplicated. To deal with these
+  the order of content from your XML input is not being preserved. The subject
+  for example is to be shown before both sender and recipients. Furthermore
+  some input (sender's name) has to be shown multiple times. To tackle these
   challenges you may first collect all relevant input during the SAX parsing
   process and completely defer HTML output generation to the <a
   href="http://docs.oracle.com/javase/8/docs/api/org/xml/sax/ContentHandler.html#endDocument--">endDocument()</a>
diff --git a/Sda1/Etest/SaxMemo2Html/exercise2.xhtml b/Sda1/Etest/SaxMemo2Html/exercise2.xhtml
deleted file mode 100644
index 392b6ec3b..000000000
--- a/Sda1/Etest/SaxMemo2Html/exercise2.xhtml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>Exercise 2</title>
-  </head>
-
-  <body><h2>Objective</h2><p>Extension of the <code>Book1/book2html.xsl</code>
-  stylesheet from the previous exercise to accomplish additional
-  features.</p><h2>Preparations</h2><p>Reuse your current project from the
-  previous exercise. It contains a second sub folder<code> Book2</code>
-  offering similar files as before. Configure a second transformation scenario
-  named book2ToHtml accordingly.</p><h2>Description</h2><p>The current
-  <code><code>Book2/work.xml</code></code> and <code>Book2/book.xsd</code>
-  files differ from the previous exercise by:</p><ul>
-      <li>Allowing <strong>optional</strong> <code>id</code> attributes of
-      type <code>xs:ID</code> for <code>&lt;book&gt;</code>,
-      <code>&lt;chapter&gt;</code> and <code>&lt;para&gt;</code> elements</li>
-
-      <li><p>Allowing para elements to be composed of mixed content involving
-      two new elements:</p><ol>
-          <li>&lt;emphasis&gt; elements to indicate important text
-          sections.</li>
-
-          <li><code>&lt;link linkend="xyz"&gt;</code> elements allowing for
-          document internal links being implemented by <code>xs:ID</code> /
-          <code>xs:IDREF</code> pairs.</li>
-        </ol></li>
-    </ul><pre style="font-family:monospace;">&lt;book ... xsi:noNamespaceSchemaLocation="book.xsd"&gt;
-    &lt;title&gt;Beginning XSL&lt;/title&gt;
-    &lt;chapter id="firstChapter"&gt;
-        &lt;title&gt;Basic structure&lt;/title&gt;
-        &lt;para&gt;An XSLT consists of a stylesheet declaration and a set of templates.&lt;/para&gt;
-        &lt;para&gt;Do &lt;emphasis&gt;not forget&lt;/emphasis&gt;: template elements must not be nested!&lt;/para&gt;
-    &lt;/chapter&gt;
-    &lt;chapter&gt;
-        &lt;title&gt;Important elements&lt;/title&gt;
-        &lt;para id="someText"&gt;Some more text.&lt;/para&gt;
-        &lt;para&gt;The &lt;link linkend="firstChapter"&gt;first chapter&lt;/link&gt; explains basic structures.&lt;/para&gt;
-    &lt;/chapter&gt;
-&lt;/book&gt;</pre><p>We want to transform instances like the above into HTML
-  by means of <code>Book2/book2html.xsl</code>. The intended result is being
-  shown in file <code>Book2/work.reference.html</code>:</p><pre
-  style="font-family:monospace;">&lt;html&gt;
-   &lt;head&gt;
-      &lt;title&gt;Beginning XSL&lt;/title&gt;
-   &lt;/head&gt;
-   &lt;body id="top"&gt;
-      &lt;h1&gt;Beginning XSL&lt;/h1&gt;
-      &lt;h2 id="firstChapter"&gt;Basic structure&lt;/h2&gt;
-      &lt;p&gt;An XSLT consists of a stylesheet declaration and a set of templates.&lt;/p&gt;
-      &lt;p&gt;Do &lt;em&gt;not forget&lt;/em&gt;: template elements must not be nested!&lt;/p&gt;
-      &lt;h2&gt;Important elements&lt;/h2&gt;
-      &lt;p id="someText"&gt;Some more text.&lt;/p&gt;
-      &lt;p&gt;The &lt;a href="#firstChapter"&gt;first chapter&lt;/a&gt; explains basic structures.&lt;/p&gt;
-   &lt;/body&gt;
-&lt;/html&gt;</pre><p>The following conditions shall be met:</p><ul>
-      <li><p>Implementing <code>id</code> attributes:</p><ul>
-          <li><code>&lt;book id='xyz'&gt;</code> becomes <code>&lt;body
-          id='xyz'&gt;</code></li>
-
-          <li><code>&lt;chapter id='xyz'&gt;</code> becomes <code>&lt;h2
-          id='xyz'&gt;</code></li>
-
-          <li><code>&lt;para id='xyz'&gt;</code> becomes <code>&lt;p
-          id='xyz'&gt;</code></li>
-        </ul></li>
-
-      <li><p><code>xs:IDREF</code> attributes shall be represented by local
-      HTML references as shown above in <code>&lt;a
-      href="#firstChapter"&gt;</code>.</p></li>
-    </ul><h2>ToDo</h2><p>Complete the implementation of
-  <code>Book2/book2html.xsl</code>. You may want to start from your XSL result
-  of the previous exercise by copying relevant content from
-  <code>Book1/book2html.xsl</code>.</p><p>Open the unit test file
-  <code>Book2/bookLinkMixedTest.xspec</code> (which imports all tests from the
-  previous exercise file <code>Book1/bookBasicTest.xspec</code> as well) and
-  hit <code>Apply transformation scenario(s) Xspec for XSLT</code> in the
-  Eclipse tool bar. This allows to continuously check your progress and
-  reminds you about possible errors. When you are finished upload your final
-  <code>Book2/book2html.xsl</code> result.</p><h2>Hints:</h2><ul>
-      <li>Use <code>&lt;xsl:attributes&gt;</code> to supply <code>id</code>
-      values.</li>
-
-      <li>Optional <code>id</code> values may be handled either by
-      <code>&lt;xsl:if&gt;</code> statements or by &lt;xsl:apply-templates
-      select='...|@id'&gt; having a corresponding <code>&lt;xsl:template
-      match='@id'&gt;</code> counterpart.</li>
-    </ul></body>
-</html>
-- 
GitLab