From 9bc6d9093906e6249411ad4a4e511cc5a3a92f7c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Maxime=20Lefran=C3=A7ois?= <maxime.lefrancois.86@gmail.com>
Date: Tue, 10 Mar 2020 12:21:14 +0100
Subject: [PATCH] updated report output management, HTTP POST

---
 .gitignore                                    |   1 +
 pom.xml                                       |   5 +
 report_output.xml                             |  42 +++++++
 .../server/outputformatter/TestCase.java      | 112 ++++++++++++------
 .../server/outputformatter/TestSuite.java     |  26 +++-
 .../etsi/saref/server/resources/Report.java   |  44 +++----
 src/main/resources/templates/footer.mustache  |   5 +
 src/main/resources/templates/header.mustache  |  19 +--
 src/main/resources/templates/report.mustache  |  74 ++++--------
 9 files changed, 198 insertions(+), 130 deletions(-)
 create mode 100644 report_output.xml

diff --git a/.gitignore b/.gitignore
index c90b8db..02b05b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
 nbactions.xml
 .classpath
 .settings
+bin/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index fc6c9d0..31e53e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,6 +88,11 @@
         
         
         
+        <dependency>
+            <groupId>com.atlassian.commonmark</groupId>
+            <artifactId>commonmark</artifactId>
+            <version>0.14.0</version>
+        </dependency>
             
     </dependencies>
     
diff --git a/report_output.xml b/report_output.xml
new file mode 100644
index 0000000..485d8de
--- /dev/null
+++ b/report_output.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<testsuite name="Report for commit af93d289 of SAREF4EHAW">
+    <testcase name="The directory structure is conformant to TS 103 673 Clause x" status="success">
+    </testcase>
+    <testcase name="The syntax of `ontology/saref4ehaw.ttl` is correct" status="success">
+    </testcase>
+    <testcase name="The ontology lack the dcterms:abstract metadata. The documentation will be incomplete" status="warning">
+        <info>See http://saref.etsi.org/guidelines.html#dcterms:abstract for guidelines.</info>
+    </testcase>
+    <testcase name="The term `s4ehaw:BAN` does not have a label and a comment. The documentation will be incomplete" status="warning">
+        <info>See [http://saref.etsi.org/guidelines.html#terms](http://saref.etsi.org/guidelines.html#terms) for guidelines.</info>
+    </testcase>
+    <testcase name="The term `s4ehaw:faultTolerence` does not have a label and a comment. The documentation will be incomplete" status="warning">
+        <info>See http://saref.etsi.org/guidelines.html#terms for guidelines.</info>
+    </testcase>
+    <testcase name="Ontology pitfall #P06: Including cycles in a class hierarchy" status="danger">
+        <info>See [http://oops.linkeddata.es/catalogue.jsp](http://oops.linkeddata.es/catalogue.jsp)</info>
+    </testcase>
+    <testcase name="The syntax of `example/myFakeExample.ttl` is incorrect" status="danger">
+        <info>Line 4 column 35, Prefix `:` is not defined</info>
+    </testcase>
+    <testcase name="In `example/myFakeExample2.ttl` is incorrect" status="warning">
+        <info>Term `saref:Sansor` does not exist in the SAREF ontology</info>
+    </testcase>
+    <testcase name="Errors while generating the documentation" status="danger">
+        <info>Query https://saref.etsi.org/documentation/function/processLines.rqg could not be found</info>
+        <systemErr>25:16,361 main TRACE fr.emse.ci.sparqlext.SPARQLExt:141 - initializing SPARQLGenerate
+25:16,550 main DEBUG Jena:212 - Jena initialization
+25:17,413 main INFO  fr.emse.ci.sparqlext.engine.RootPlan:386 - Starting execution
+25:17,428 main INFO  fr.emse.ci.sparqlext.engine.QueryExecutor:86 - Loading https://saref.etsi.org/documentation/ontology/main.rqg
+25:17,916 main INFO  fr.emse.ci.sparqlext.engine.QueryExecutor:86 - Loading https://saref.etsi.org/documentation/header.rqg
+25:18,009 main INFO  fr.emse.ci.sparqlext.function.SPARQLExtFunctionRegistry:121 - attempting load https://saref.etsi.org/documentation/function/href.rqg
+25:18,070 main INFO  fr.emse.ci.sparqlext.engine.QueryExecutor:86 - Loading https://saref.etsi.org/documentation/function/formatText.rqg
+25:18,105 main INFO  fr.emse.ci.sparqlext.function.SPARQLExtFunctionRegistry:121 - attempting load https://saref.etsi.org/documentation/function/processLines.rqg
+25:18,115 main ERROR  fr.emse.ci.sparqlext.function.SPARQLExtFunctionRegistry:121 - Query https://saref.etsi.org/documentation/function/processLines.rqg could not be found</systemErr>
+    </testcase>
+    <testcase name="Fake test" status="soldnfbslpegb">
+        <info>Fake test</info>
+    </testcase>
+
+
+</testsuite>
diff --git a/src/main/java/org/etsi/saref/server/outputformatter/TestCase.java b/src/main/java/org/etsi/saref/server/outputformatter/TestCase.java
index 97b00ac..cc0e948 100644
--- a/src/main/java/org/etsi/saref/server/outputformatter/TestCase.java
+++ b/src/main/java/org/etsi/saref/server/outputformatter/TestCase.java
@@ -7,26 +7,33 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.jena.sparql.expr.nodevalue.NodeValueString;
+import org.commonmark.node.Node;
+import org.commonmark.parser.Parser;
+import org.commonmark.renderer.html.HtmlRenderer;
+
 /**
  * @author Omar Qawasmeh
  *
  *
  */
 
-
 @XmlRootElement(name = "testcase")
-@XmlType(propOrder = { "systemErr", "systemOut", "info"})
+@XmlType(propOrder = { "systemErr", "systemOut", "info" })
 public class TestCase {
 
+	public enum Status {
+		SUCCESS, WARNING, DANGER, UNKNOWN;
+	}
 
 	private String name;
 	private String className;
 	private String systemErr;
 	private String systemOut;
-	private String status; //either pass or failure
+	private String status; // either pass or failure
 	private String info;
-	private boolean statusFlag;
-	
+	private Status statusObj;
+
 	/**
 	 * @return the status
 	 */
@@ -34,49 +41,74 @@ public class TestCase {
 	public String getStatus() {
 		return status;
 	}
-	
+
 	/**
-	 * @param status the status to set
+	 * @param status
+	 *            the status to set
 	 */
 	public void setStatus(String status) {
 		this.status = status;
 	}
-	
-	
-	public boolean getStatusFlag() {
-		return statusFlag;
+
+	public boolean isSuccess() {
+		return statusObj == Status.SUCCESS;
 	}
-	
+
+	public boolean isDanger() {
+		return statusObj == Status.DANGER;
+	}
+
+	public boolean isWarning() {
+		return statusObj == Status.WARNING;
+	}
+
+
+	public boolean isUnknown() {
+		return statusObj == Status.UNKNOWN;
+	}
+
 	/**
-	 * @param status the status to set
+	 * @param status
+	 *            the status to set
 	 */
 	public void setStatusFlag(String status) {
-		if(status.equals("fail"))
-			this.statusFlag = false;
-		else if(status.equals("pass"))
-			this.statusFlag = true;
-		
-		
+		switch (status) {
+		case "danger":
+			this.statusObj = Status.DANGER;
+			break;
+		case "success":
+			this.statusObj = Status.SUCCESS;
+			break;
+		case "warning":
+			this.statusObj = Status.WARNING;
+			break;
+		default:
+			this.statusObj = Status.UNKNOWN;
+		}
 	}
-	
-	
 
 	@XmlAttribute
 	public String getClassName() {
 		return className;
 	}
-	
+
 	/**
-	 * @param className the className to set
+	 * @param className
+	 *            the className to set
 	 */
 	public void setClassName(String className) {
 		this.className = className;
 	}
-	
-	
+
 	@XmlAttribute
 	public String getName() {
-		return name;
+		if(name != null) {
+	        Parser parser = Parser.builder().build();
+	        Node document = parser.parse(name);
+	        HtmlRenderer renderer = HtmlRenderer.builder().build();
+	        return renderer.render(document);
+		}
+		return null;
 	}
 
 	/**
@@ -87,30 +119,31 @@ public class TestCase {
 		this.name = name;
 	}
 
-	
 	/**
 	 * @return the systemErr
 	 */
 	public String getSystemErr() {
 		return systemErr;
 	}
-	
+
 	/**
-	 * @param systemErr the systemErr to set
+	 * @param systemErr
+	 *            the systemErr to set
 	 */
 	public void setSystemErr(String systemErr) {
 		this.systemErr = systemErr;
 	}
-	
+
 	/**
 	 * @return the systemOut
 	 */
 	public String getSystemOut() {
 		return systemOut;
 	}
-	
+
 	/**
-	 * @param systemOut the systemOut to set
+	 * @param systemOut
+	 *            the systemOut to set
 	 */
 	public void setSystemOut(String systemOut) {
 		this.systemOut = systemOut;
@@ -120,14 +153,21 @@ public class TestCase {
 	 * @return the info
 	 */
 	public String getInfo() {
-		return info;
+		if(info != null) {
+	        Parser parser = Parser.builder().build();
+	        Node document = parser.parse(info);
+	        HtmlRenderer renderer = HtmlRenderer.builder().build();
+	        return renderer.render(document);
+		}
+		return null;
 	}
-	
+
 	/**
-	 * @param info the info to set
+	 * @param info
+	 *            the info to set
 	 */
 	public void setInfo(String info) {
 		this.info = info;
 	}
-	
+
 }
diff --git a/src/main/java/org/etsi/saref/server/outputformatter/TestSuite.java b/src/main/java/org/etsi/saref/server/outputformatter/TestSuite.java
index e7ec82c..a5854b1 100644
--- a/src/main/java/org/etsi/saref/server/outputformatter/TestSuite.java
+++ b/src/main/java/org/etsi/saref/server/outputformatter/TestSuite.java
@@ -44,6 +44,7 @@ public class TestSuite implements Serializable {
 	private float time;
 	private String name;
 	private TestCase[] testCase;
+	private int nbWarning=-1, nbDanger=-1;
 	
 	
 	public TestCase[] getTestcase() {
@@ -62,7 +63,30 @@ public class TestSuite implements Serializable {
 	public void setTests(int tests) {
 
 		this.tests = tests;
-
+	}
+	
+	public int getNbDanger() {
+		if(nbDanger == -1) {
+			nbDanger = 0;
+			for (int i = 0; i < testCase.length; i++) {
+				if(testCase[i].isDanger()) {
+						nbDanger++;
+				};
+			}
+		} 
+		return nbDanger;
+	}
+	
+	public int getNbWarning() {
+		if(nbWarning == -1) {
+			nbWarning = 0;
+			for (int i = 0; i < testCase.length; i++) {
+				if(testCase[i].isWarning()) {
+					nbWarning++;
+				};
+			}
+		} 
+		return nbWarning;
 	}
 
 	@XmlAttribute
diff --git a/src/main/java/org/etsi/saref/server/resources/Report.java b/src/main/java/org/etsi/saref/server/resources/Report.java
index cc18e2f..9e26c78 100644
--- a/src/main/java/org/etsi/saref/server/resources/Report.java
+++ b/src/main/java/org/etsi/saref/server/resources/Report.java
@@ -7,12 +7,16 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
+import javax.ws.rs.ServerErrorException;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
@@ -32,10 +36,8 @@ public class Report {
 	@GET
 	@Produces(MediaType.TEXT_HTML)
 	@Template(name = "/report")
-
 	public TestSuite fillReportPage(@QueryParam("q") String url)
 			throws WebApplicationException, JAXBException, IOException {
-
 		// url=getRedirectedLink(url).replaceAll("https://gitlab.emse.fr/saref/",
 		// "http://saref.gitlab.emse.fr/-/");
 		// url=url.replaceAll("/file/", "/");
@@ -46,37 +48,29 @@ public class Report {
 		// To access the xml file directly
 		// https://gitlab.emse.fr/saref/saref4abcd/-/jobs/artifacts/master/file/report_output.xml?job=checkshacl
 		JAXBContext jaxbContext;
-
 		jaxbContext = JAXBContext.newInstance(TestSuite.class);
-
 		Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
-
 		TestSuite tstSuite = (TestSuite) jaxbUnmarshaller.unmarshal(new URL(url));
-		// .unmarshal(new
-		// URL("http://saref.gitlab.emse.fr/-/saref4abcd/-/jobs/5654/artifacts/report_output.xml"));
-		System.out.println(tstSuite.getDisabled());
-		System.out.println(tstSuite.getTime());
-
-		// System.out.println(tstSuite.getTestcase());
 		TestCase[] tstCase = tstSuite.getTestcase();
-
 		for (int i = 0; i < tstCase.length; i++) {
-
-			System.out.println(tstCase[i].getStatus());
-
 			tstCase[i].setStatusFlag(tstCase[i].getStatus());
-
-			System.out.println("Status Flag\t\t" + tstCase[i].getStatusFlag());
-
-			// System.out.println("Status\t" + tstCase[i].getStatus());
-			// System.out.println("Name\t" + tstCase[i].getName());
-			// System.out.println("System Error\t" + tstCase[i].getSystemErr());
-			// System.out.println("System Error\t" + tstCase[i].getSystemOut());
 		}
+		return tstSuite;
+	}
 
-		// ReportResults reportResults= new ReportResults();
-
-		// reportResults.report="asdqwe123";
+	@POST
+	@Produces(MediaType.TEXT_HTML)
+	@Consumes(MediaType.APPLICATION_XML)
+	@Template(name = "/report")
+	public TestSuite fillReportPageForPost(TestSuite tstSuite)
+			throws WebApplicationException, JAXBException, IOException {
+		if(tstSuite == null) {
+			throw new ServerErrorException(Status.BAD_REQUEST);
+		}
+		TestCase[] tstCase = tstSuite.getTestcase();
+		for (int i = 0; i < tstCase.length; i++) {
+			tstCase[i].setStatusFlag(tstCase[i].getStatus());
+		}
 		return tstSuite;
 	}
 
diff --git a/src/main/resources/templates/footer.mustache b/src/main/resources/templates/footer.mustache
index 05c8644..62ec760 100644
--- a/src/main/resources/templates/footer.mustache
+++ b/src/main/resources/templates/footer.mustache
@@ -46,6 +46,11 @@
   </div>
 </footer>
 </div>
+
+<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
+
 </body>
 
 </html>
diff --git a/src/main/resources/templates/header.mustache b/src/main/resources/templates/header.mustache
index a9bda4d..54c5f0b 100644
--- a/src/main/resources/templates/header.mustache
+++ b/src/main/resources/templates/header.mustache
@@ -9,6 +9,7 @@
   <meta name="generator" content="Ontogit" />
   <title>SAREF - portal</title>
   
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
   <link href="static/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
   <link href="static/media/gantry5/assets/css/font-awesome.min.css" rel="stylesheet" />
   <link href="static/media/gantry5/engines/nucleus/css-compiled/nucleus.css" rel="stylesheet" />
@@ -18,10 +19,6 @@
   <link href="static/media/jui/css/icomoon.css" rel="stylesheet" />
   <link href="static/templates/g5_helium/custom/css-compiled/helium-joomla_19.css" rel="stylesheet" />
   <link href="static/templates/g5_helium/custom/css-compiled/custom_19.css" rel="stylesheet" />
-  <!--     <link rel="stylesheet" href="lode/primer.css" media="screen" /> -->
-  <link rel="stylesheet" href="lode/rec.css" media="screen" />
-  <!--     <link rel="stylesheet" href="lode/extra.css" media="screen" /> -->
-  <!--     <link rel="stylesheet" href="lode/owl.css" media="screen" /> -->
   <script src="static/templates/g5_helium/js/jui/jquery.min.js?06eedc97766b70aa1fa0e80231495faa"></script>
   <script src="static/media/jui/js/jquery-noconflict.js?06eedc97766b70aa1fa0e80231495faa"></script>
   <script src="static/media/jui/js/jquery-migrate.min.js?06eedc97766b70aa1fa0e80231495faa"></script>
@@ -140,17 +137,3 @@
         </div>
       </div>
     </section>
-    <header id="g-header">
-      <div class="g-container">
-        <div class="g-block size-100">
-          <div class="g-content g-particle">
-            <h1>
-              <a id="user-content-smart-applications-reference-ontology-and-extensions" class="anchor" href="#smart-applications-reference-ontology-and-extensions" aria-hidden="true"><span aria-hidden="true"
-                  class="octicon octicon-link"></span></a>Smart Applications REFerence Ontology, and extensions</h1>
-            <p><strong>Official ETSI portal for SAREF</strong><br>This page contains pointers to the SAREF ontologies and SAREF-related work items</p>
-            <p><em><strong>Note:</strong> This portal is under construction. It was drafted in the context of <a href="https://portal.etsi.org//STF/STFs/STFHomePages/STF556" rel="nofollow">ETSI Specialist Task Force 556</a>. More effort is required
-                to automatize the portal content generation and deployment workflow.</em></p>
-          </div>
-        </div>
-      </div>
-    </header>
diff --git a/src/main/resources/templates/report.mustache b/src/main/resources/templates/report.mustache
index 0e2bd86..05725d3 100644
--- a/src/main/resources/templates/report.mustache
+++ b/src/main/resources/templates/report.mustache
@@ -1,64 +1,38 @@
 {{> header}}
 
-<section id="introduction" class="g-wrapper">
-
-  <section id="introduction" class="g-wrapper">
-    <div class="g-container">
-      <div class="alert alert-warning" role="alert">
-		<h4><strong>This page is generated automatically as an output of the pipeline's report (report.xml)</strong></h4>
+<header id="g-header">
+      <div class="g-container">
+        <div class="g-block size-100">
+          <div class="g-content g-particle">
+            <h1>
+              <a id="user-content-smart-applications-reference-ontology-and-extensions" class="anchor" href="#smart-applications-reference-ontology-and-extensions" aria-hidden="true"><span aria-hidden="true"
+                  class="octicon octicon-link"></span></a>{{name}}</h1>
+          </div>
+        </div>
       </div>
-    </div>
-
-
-
+    </header>
+    
+<section id="introduction" class="g-wrapper">
 
 <div class="g-container">
-	  <h3>
-        In the pipeline {{tests}} tests were applied on your ontology:
-      </h3>
+	  <p>There are {{nbDanger}} errors and {{nbWarning}} warnings</p>
       
-<table class="table">
-  <thead>
-    <tr>
-      <th scope="col">Test name</th>
-      <th scope="col">Status</th>
-      <th scope="col">Error</th>
-      <th scope="col">More information</th>
-    </tr>
-  </thead>
-  <tbody>
-    
-
 
       {{#testcase}}
-
-            {{#statusFlag}}
-                    <tr>
-                    <td>{{name}}</td>
-                    <td>{{status}}</td>
-                    <td>--</td>
-                    <td>All is passed</td>
-                   </tr>
-            {{/statusFlag}}
-
-
-            {{^statusFlag}}
-					<tr class="warning">
-                    <td>{{name}}</td>
-                    <td>{{status}}</td>
-                    <td>{{systemErr}}</td>
-                    <td>{{info}}</td>
-                   </tr>
-            {{/statusFlag}}
-
-
-          </div>
+      	<div class="alert {{#success}}alert-success{{/success}}{{#danger}}alert-danger{{/danger}}{{#warning}}alert-warning{{/warning}}{{#unknown}}alert-dark{{/unknown}}">
+            <p>{{{name}}}</p>
+            {{#info}}
+	            {{#systemErr}}
+	            	<details><summary>{{{info}}}</summary><pre>{{systemErr}}</pre></details>
+	            {{/systemErr}}
+	            {{^systemErr}}
+	            	<p>{{{info}}}</p>
+	            {{/systemErr}}
+            {{/info}}
         </div>
       {{/testcase}}
 
-</tbody>
-</table>
     </div>
-
+</section>
 
     {{> footer}}
\ No newline at end of file
-- 
GitLab