diff --git a/pom.xml b/pom.xml index 4075b2217770a89795034aaf9057525c65d6c8a6..620a4aef70eb3afedb542364750f1809f95eab61 100644 --- a/pom.xml +++ b/pom.xml @@ -176,6 +176,30 @@ <version>11</version> </dependency> + <dependency> + <groupId>org.apache.any23</groupId> + <artifactId>apache-any23-core</artifactId> + <version>2.0</version> + </dependency> + + <dependency> + <groupId>org.openrdf.sesame</groupId> + <artifactId>sesame-rio-api</artifactId> + <version>4.0.2</version> + </dependency> + + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>4.2.2</version> + </dependency> + + <dependency> + <groupId>com.opencsv</groupId> + <artifactId>opencsv</artifactId> + <version>4.1</version> + </dependency> + </dependencies> <build> diff --git a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_3_Checker.java b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_3_Checker.java index 037f6e73aa1fe84656b159cd3fea4ce225e56717..c40d9ef2cf5e15b00cd4e8961159c514f4584b82 100644 --- a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_3_Checker.java +++ b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_3_Checker.java @@ -32,8 +32,11 @@ import java.nio.file.Path; import java.util.Optional; import java.util.stream.Collectors; +import org.apache.commons.io.FileUtils; + import fr.emse.gitlab.saref.SAREF; import fr.emse.gitlab.saref.SAREFPipelineException; +import fr.emse.gitlab.saref.managers.GenerateRDFaManager; import fr.emse.gitlab.saref.managers.RepositoryManager; /** @@ -61,6 +64,7 @@ public class Clause_9_3_Checker extends AbstractClauseChecker { try { checkExists(dir.toPath()); checkFirstLine(dir.toPath()); + requirementsRDFaGenerator(); } catch (IOException ex) { logError(getMessage(MESSAGE.ioexception), ex); } @@ -117,4 +121,15 @@ public class Clause_9_3_Checker extends AbstractClauseChecker { }); } + private void requirementsRDFaGenerator() throws SAREFPipelineException, IOException{ + String categoryChanger = ""; + String repoName = project.getName(); + String href = project.getNamespace(); + File reqCSV = new File(repository.getDirectory(), "/requirements/requirements.csv"); + File versionSite = new File(siteManager.siteDir, version.getVersionPath()); + FileUtils.forceMkdir(versionSite); + File reqHTML = new File(versionSite, "requirements.html"); + GenerateRDFaManager.GenerateRDFa(categoryChanger, repoName, href, reqCSV, reqHTML, "requirements"); + } + } diff --git a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_4_5_Checker.java b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_4_5_Checker.java index 40af9b409f6fedbac2582ae08f520707ece647b0..4b95f82ca956b1301df275d1c14c7c942bc61bc7 100644 --- a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_4_5_Checker.java +++ b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_4_5_Checker.java @@ -25,9 +25,14 @@ */ package fr.emse.gitlab.saref.checkers; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import org.apache.jena.rdf.model.Model; import org.semanticweb.owl.explanation.api.Explanation; import org.semanticweb.owl.explanation.api.ExplanationGenerator; import org.semanticweb.owlapi.model.OWLAxiom; @@ -37,7 +42,13 @@ import org.semanticweb.owlapi.profiles.OWLProfileReport; import fr.emse.gitlab.saref.SAREFPipelineException; import fr.emse.gitlab.saref.managers.OntologyManager; +import fr.emse.gitlab.saref.managers.OopsManager; import fr.emse.gitlab.saref.managers.RepositoryManager; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; /** * Checks TS 103 673 Clause 9.4.5: OWL Profile, Consistency, and Satisfiability @@ -47,7 +58,7 @@ import fr.emse.gitlab.saref.managers.RepositoryManager; public class Clause_9_4_5_Checker extends AbstractClauseChecker { private static enum MESSAGE { - profile, consistent, satisfiable; + profile, consistent, satisfiable, oops, oopsError; } /** @@ -64,12 +75,12 @@ public class Clause_9_4_5_Checker extends AbstractClauseChecker { } final OWLProfileReport report = new OWL2DLProfile().checkOntology(ontology); - if(!report.getViolations().isEmpty()) { + if (!report.getViolations().isEmpty()) { String violations = report.getViolations().stream().map(Object::toString) .collect(Collectors.joining("\n- ", "\n\n- ", "\n\n")); logError(getMessage(MESSAGE.profile, violations)); } - + OntologyManager ontologyManager = pipeline.getOntologyManager(); Set<Explanation<OWLAxiom>> incExplanation = ontologyManager.getInconsistenceExplanations(ontology, errorLogger); @@ -80,7 +91,7 @@ public class Clause_9_4_5_Checker extends AbstractClauseChecker { } else { ExplanationGenerator<OWLAxiom> generator = ontologyManager.getExplanationGenerator(ontology); ontology.classesInSignature().forEach(c -> { - if(c.isOWLNothing()) { + if (c.isOWLNothing()) { return; } Set<Explanation<OWLAxiom>> incExplanation2 = ontologyManager.getIncoherenceExplanations(generator, c); @@ -88,10 +99,78 @@ public class Clause_9_4_5_Checker extends AbstractClauseChecker { String explanation = incExplanation2.stream().map(e -> e.getAxioms().toString()) .collect(Collectors.joining("\n- ", "\n\n- ", "\n\n")); logError(getMessage(MESSAGE.satisfiable, c, explanation)); - + } }); } + checkOops(); + } + + public void checkOops() throws SAREFPipelineException { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + String onto = ""; + + Model model = version.getModel(); + model.write(out, "RDF/XML"); // write in string and then replace + onto = out.toString().replaceAll("]]", "] ]"); + + String xmlRequest = "<?xml version='1.0' encoding='UTF-8'?>" + "<OOPSRequest>" + "<OntologyURI></OntologyURI>" + + "<OntologyContent><![CDATA[" + onto + "]]></OntologyContent>" + "<Pitfalls>10</Pitfalls>" + + "<OutputFormat>RDF/XML</OutputFormat>" + "</OOPSRequest>"; + + Object[] arrayData = new Object[0]; + + try { + + OkHttpClient httpClient = new OkHttpClient().newBuilder().build(); + + MediaType mediaType = MediaType.parse("application/xml"); + + RequestBody body = RequestBody.create(xmlRequest, mediaType); + + Request request = new Request.Builder().url("http://oops.linkeddata.es/rest").method("POST", body) + .addHeader("Content-Type", "application/xml").build(); + + Response response = httpClient.newCall(request).execute(); + + String result = response.body().string(); + + String[] results = result.split("\\n"); + List<String> pureData = new ArrayList<String>(); + for (int i = 0; i < results.length; i++) { + if (results[i].startsWith("<")) { + for (int j = i; j < results.length; j++) { + pureData.add(results[j]); + } + } + } + + arrayData = pureData.toArray(); // response into array + + } catch (IOException e) { + logWarning(getMessage(MESSAGE.oopsError)); + } + + int count = OopsManager.counter(arrayData); + + ArrayList<ArrayList<String>> result = OopsManager.getData(arrayData); + + int s = 0; + + ArrayList<String> results = new ArrayList<String>(); + + while (s < count) { + String data = result.get(0).get(s) + result.get(1).get(s) + result.get(2).get(s); + results.add(data); + s++; + } + + String printData = results.stream().map(e -> e.toString()) + .collect(Collectors.joining("\n- ", "\n\n- ", "\n\n")); + if (count != 0) { + logWarning(getMessage(MESSAGE.oops, printData)); + } } } diff --git a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_5_Checker.java b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_5_Checker.java index 495b95962e4df8b08e44da36e787ecc020f99347..a06800b0f723a9b7d64ff197093ac34b0be54354 100644 --- a/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_5_Checker.java +++ b/src/main/java/fr/emse/gitlab/saref/checkers/Clause_9_5_Checker.java @@ -25,17 +25,42 @@ */ package fr.emse.gitlab.saref.checkers; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.PathMatcher; +import java.util.ArrayList; import java.util.Optional; import java.util.stream.Collectors; +import org.apache.any23.Any23; +import org.apache.any23.extractor.ExtractionException; +import org.apache.any23.source.DocumentSource; +import org.apache.any23.source.FileDocumentSource; +import org.apache.any23.writer.RDFXMLWriter; +import org.apache.any23.writer.TripleHandler; +import org.apache.any23.writer.TripleHandlerException; +import org.apache.commons.io.FileUtils; +import org.apache.jena.rdf.model.Model; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + import fr.emse.gitlab.saref.SAREFPipelineException; +import fr.emse.gitlab.saref.entities.SAREFRepository; +import fr.emse.gitlab.saref.entities.SAREFVersion; +import fr.emse.gitlab.saref.managers.DatasetManager; +import fr.emse.gitlab.saref.managers.GenerateRDFaManager; import fr.emse.gitlab.saref.managers.RepositoryManager; +import fr.emse.gitlab.saref.managers.ThemisManager; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; /** * Checks TS 103 673 Clause 9.5: Ontology tests @@ -47,7 +72,7 @@ public class Clause_9_5_Checker extends AbstractClauseChecker { private static final String FIRST_LINE = "Id;Requirement;Category;Test"; private static enum MESSAGE { - directories, csv, missing, ioexception, line; + directories, csv, missing, ioexception, line, themis, themisError; } /** @@ -67,6 +92,8 @@ public class Clause_9_5_Checker extends AbstractClauseChecker { try { checkExists(dir.toPath()); checkFirstLine(dir.toPath()); + testsRDFaGenerator(); + checkThemis(); } catch (IOException ex) { logError(getMessage(MESSAGE.ioexception)); } @@ -76,11 +103,11 @@ public class Clause_9_5_Checker extends AbstractClauseChecker { String directories = Files.walk(path).filter(p -> { try { return p.toFile().isDirectory() && !Files.isSameFile(path, p); - } catch(IOException ex) { + } catch (IOException ex) { return false; } }).map(p -> p.toString()).collect(Collectors.joining(", ")); - if(directories.length()>0) { + if (directories.length() > 0) { logWarning(getMessage(MESSAGE.directories, directories)); } @@ -91,10 +118,10 @@ public class Clause_9_5_Checker extends AbstractClauseChecker { return false; } }).map(p -> p.getFileName().toString()).collect(Collectors.joining(", ")); - if(nonCsv.length()>0) { + if (nonCsv.length() > 0) { logError(getMessage(MESSAGE.csv, nonCsv)); } - + boolean containsFile = Files.walk(path, 1).anyMatch(p -> { return csvMatcher.matches(p); }); @@ -123,4 +150,99 @@ public class Clause_9_5_Checker extends AbstractClauseChecker { }); } + public void checkThemis() throws SAREFPipelineException { + File versionSite = new File(siteManager.siteDir, version.getVersionPath()); + File tHTML = new File(versionSite, "tests.html"); + DocumentSource source = new FileDocumentSource(tHTML); + Any23 runner = new Any23(); + try(ByteArrayOutputStream out = new ByteArrayOutputStream(); TripleHandler handler = new RDFXMLWriter(out);) { + runner.extract(source, handler); + + String xmlData = out.toString(); + + ArrayList<String[]> res = makeCall(xmlData, repository, datasetManager, version); + + ArrayList<String> result = new ArrayList<String>(); + + for (int i = 0; i < res.size(); i++) { + String response = res.get(i)[0] + ", " + res.get(i)[1] + ", " + res.get(i)[2]; + result.add(response); + } + + if (!res.isEmpty()) { + String data = result.stream().map(e -> e.toString()).collect(Collectors.joining("\n- ", "\n\n- ", "\n\n")); + logWarning(getMessage(MESSAGE.themis, data)); + } + + } catch (ExtractionException | IOException | TripleHandlerException e) { + logWarning(getMessage(MESSAGE.themisError)); + } + } + + public ArrayList<String[]> makeCall(String xmlData, SAREFRepository repository, DatasetManager datasetManager, + SAREFVersion version) throws SAREFPipelineException { + + ArrayList<String[]> res = new ArrayList<String[]>(); + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + String onto = ""; + + Model model = version.getModel(); + model.write(out, "RDF/XML"); + onto = out.toString(); + + OkHttpClient httpClient = new OkHttpClient().newBuilder().build(); + + MediaType mediaType = MediaType.parse("application/json"); + + String jsonRequest = "{\"ontologiesCode\":[\"" + + onto.replaceAll("\\\"", "\\\\\"").replaceAll("\"", "\\\"").replaceAll("\t", " ") + "\"]," + + "\"testfile\":[\"" + xmlData.replaceAll("\\\"", "\\\\\"").replaceAll("\"", "\\\"").replaceAll("\t", " ") + + "\"]," + "\"format\":\"junit\"}"; + + RequestBody body = RequestBody.create(jsonRequest, mediaType); + + Request request = new Request.Builder().url("http://themis.linkeddata.es/rest/api/results") + .method("POST", body).addHeader("accept", "application/json") + .addHeader("Content-Type", "application/json").build(); + + Response response = httpClient.newCall(request).execute(); + + String result = response.body().string(); + + Document doc = ThemisManager.convertStringToXMLDocument(result); + + NodeList nodeList = doc.getElementsByTagName("testcase"); + for (int temp = 0; temp < nodeList.getLength(); temp++) { + org.w3c.dom.Node node = nodeList.item(temp); + String[] part = new String[3]; + if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) { + Element element = (Element) node; + part[0] = "" + element.getAttributeNode("id"); + part[1] = "" + element.getAttributeNode("name"); + part[2] = "" + ((Element) node).getElementsByTagName("error").item(0).getAttributes() + .getNamedItem("message"); + + res.add(part); + } + } + } catch (IOException e) { + logWarning(getMessage(MESSAGE.themisError)); + } + return res; + } + + private void testsRDFaGenerator() throws SAREFPipelineException, IOException { + if(pipeline.ignoreSite) { + return; + } + String categoryChanger = ""; + String repoName = project.getName(); + String href = project.getNamespace(); + File testCSV = new File(repository.getDirectory(), "/tests/tests.csv"); + File versionSite = new File(siteManager.siteDir, version.getVersionPath()); + FileUtils.forceMkdir(versionSite); + File testHTML = new File(versionSite, "tests.html"); + GenerateRDFaManager.GenerateRDFa(categoryChanger, repoName, href, testCSV, testHTML, "tests"); + } + } diff --git a/src/main/java/fr/emse/gitlab/saref/entities/SAREFNamedGraph.java b/src/main/java/fr/emse/gitlab/saref/entities/SAREFNamedGraph.java index 05645491c5883eb9684e58923d52f7bada7f0702..7e2440508c93e721e89fccb8409a1cdb1302fba8 100644 --- a/src/main/java/fr/emse/gitlab/saref/entities/SAREFNamedGraph.java +++ b/src/main/java/fr/emse/gitlab/saref/entities/SAREFNamedGraph.java @@ -45,7 +45,7 @@ public class SAREFNamedGraph { return false; if (getClass() != obj.getClass()) return false; - SAREFTerm other = (SAREFTerm) obj; + SAREFNamedGraph other = (SAREFNamedGraph) obj; if (iri == null) { if (other.iri != null) return false; diff --git a/src/main/java/fr/emse/gitlab/saref/managers/GenerateRDFaManager.java b/src/main/java/fr/emse/gitlab/saref/managers/GenerateRDFaManager.java new file mode 100644 index 0000000000000000000000000000000000000000..1d34584e229c030a979d544c38990a9f529388ad --- /dev/null +++ b/src/main/java/fr/emse/gitlab/saref/managers/GenerateRDFaManager.java @@ -0,0 +1,195 @@ +/* + * Copyright 2020 ETSI + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package fr.emse.gitlab.saref.managers; + +import com.opencsv.CSVParser; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import fr.emse.gitlab.saref.Main; +import org.apache.commons.io.IOUtils; +import org.eclipse.jgit.util.StringUtils; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class GenerateRDFaManager { + + public static void GenerateRDFa(String categoryChanger, String repoName, String href, File CSV, File HTML, + String identifier) { + String row = ""; + + try (FileWriter htmlWriter = new FileWriter(HTML); + BufferedReader csvReader = new BufferedReader(new FileReader(CSV));) { + String header = IOUtils.toString(Main.class.getClassLoader().getResourceAsStream("themis/header.html"), + StandardCharsets.UTF_8); + String body = IOUtils.toString(Main.class.getClassLoader().getResourceAsStream("themis/body.html"), + StandardCharsets.UTF_8); + String footer = IOUtils.toString(Main.class.getClassLoader().getResourceAsStream("themis/footer.html"), + StandardCharsets.UTF_8); + + header = header.replaceAll("@ontologyName", repoName).replaceAll("@href", href + "/" + identifier + "/"); + + body = body.replaceAll("@docType", StringUtils.capitalize(identifier)).replaceAll("@ontologyName", + repoName); + + htmlWriter.write(header); + htmlWriter.write(body); + + List<String[]> allData = readDataFromCustomSeperator(CSV); + + if (identifier.equals("requirements")) { + for (String[] data : allData) { + if (data[1].equals("Category")) { + continue; + } else { + if (categoryChanger.equals("") || categoryChanger.equals(data[1]) + || !data[1].equals("Category")) { + if (!categoryChanger.equals(data[1]) && !categoryChanger.equals("Category")) { + if (categoryChanger.equals("")) { + categoryChanger = data[1]; + } else { + categoryChanger = data[1]; + String endTableData = "</table> \n" + "\n" + "<p>\n" + "</p>\n" + "\n"; + htmlWriter.write(endTableData); + } + categoryChanger = data[1]; + String entrytoTable2 = "<table align=\"center\" border=\"1\" prefix=\"vtc: https://w3id.org/def/vtc#\">\n"; + htmlWriter.write(entrytoTable2); + String category = "<caption>Requirements for the \"" + categoryChanger + + "\" category</caption>\n"; + htmlWriter.write(category); + + String entry = "<tr>\n" + " <th>Id</th>\n" + " <th>Requirement</th>\n" + + " </tr>\n" + "\n" + "<tr id=\"" + data[0] + "\" resource=\"requirement/" + + data[0] + "\" typeof=\"vtc:Requirement\" property=\"vtc:category\" content=\"" + + data[1] + "\">\n" + " <td property=\"vtc:requirementId\">" + data[0] + + "</td>\n" + " <td property=\"dc:description\">" + data[2] + "</td>\n" + + " </tr>\n" + "\n"; + htmlWriter.write(entry); + } else { + categoryChanger = data[1]; + + String entry = "<tr id=\"" + data[0] + "\" resource=\"requirement/" + data[0] + + "\" typeof=\"vtc:Requirement\" property=\"vtc:category\" content=\"" + data[1] + + "\">\n" + " <td property=\"vtc:requirementId\">" + data[0] + "</td>\n" + + " <td property=\"dc:description\">" + data[2] + "</td>\n" + " </tr>\n" + + "\n"; + htmlWriter.write(entry); + } + } + + } + } + + } else { + for (String[] data : allData) { + if (data[2].equals("Category")) { + continue; + } else { + if (categoryChanger.equals("") || categoryChanger.equals(data[2]) + || !data[2].equals("Category")) { + + if (!categoryChanger.equals(data[2]) && !categoryChanger.equals("Category")) { + if (categoryChanger.equals("")) { + categoryChanger = data[2]; + } else { + categoryChanger = data[2]; + String endTableData2 = "</table> \n" + "\n" + "<p>\n" + "</p>\n" + "\n"; + htmlWriter.write(endTableData2); + } + + categoryChanger = data[2]; + String entrytoTable2 = "<table align=\"center\" border=\"1\" prefix=\"vtc: https://w3id.org/def/vtc#\">\n"; + htmlWriter.write(entrytoTable2); + String category = "<caption>Tests for the \"" + categoryChanger + + "\" category</caption>\n"; + htmlWriter.write(category); + if (!data[1].isEmpty()) { + String entry = "<tr>\n" + " <th>Id</th>\n" + " <th>Requirement</th>\n" + + " <th>Test</th>\n" + " </tr>\n" + "\n" + "<tr id=\"" + data[1] + + "\" resource=\"testCaseDesign/" + data[0] + + "\" typeof=\"vtc:TestCaseDesign\">\n" + " <td property=\"vtc:testId\">" + + data[0] + "</td>\n" + + " <td><span property=\"vtc:comesFromRequirement\" href=\"requirement/" + + data[1] + "\"><a href=\"requirements.html#" + data[1] + "\">" + + data[1] + "</a></span></td>\n" + + " <td property=\"vtc:desiredBehaviour\">" + data[3] + "</td>\n" + + " </tr>\n" + "\n"; + htmlWriter.write(entry); + } else { + String entry = "<tr>\n" + " <th>Id</th>\n" + " <th>Test</th>\n" + " </tr>\n" + + "\n" + "<tr resource=\"testCaseDesign/" + data[0] + + "\" typeof=\"vtc:TestCaseDesign\">\n" + " <td property=\"vtc:testId\">" + + data[0] + "</td>\n" + " <td property=\"vtc:desiredBehaviour\">" + + data[3] + "</td>\n" + " </tr>\n" + "\n"; + htmlWriter.write(entry); + } + } else { + categoryChanger = data[2]; + + String entry = "<tr resource=\"testCaseDesign/" + data[0] + + "\" typeof=\"vtc:TestCaseDesign\">\n" + " <td property=\"vtc:testId\">" + + data[0] + "</td>\n" + + " <td><span property=\"vtc:comesFromRequirement\" href=\"requirement/" + + data[1] + "\"><a href=\"requirements.html#" + data[1] + "\">" + + data[1] + "</a></span></td>\n" + " <td property=\"vtc:desiredBehaviour\">" + + data[3] + "</td>\n" + " </tr>\n" + "\n"; + htmlWriter.write(entry); + } + } + + } + } + } + + String endTableData = "</table> \n" + "\n" + "<p>\n" + "</p>\n" + "\n"; + htmlWriter.write(endTableData); + + htmlWriter.write(footer); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static List<String[]> readDataFromCustomSeperator(File file) { + CSVParser parser = new CSVParserBuilder().withSeparator(';').withQuoteChar('"').build(); + + try (FileReader filereader = new FileReader(file); + CSVReader csvReader = new CSVReaderBuilder(filereader).withCSVParser(parser).build();) { + + // Read all data at once + List<String[]> allData = csvReader.readAll(); + return allData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/fr/emse/gitlab/saref/managers/OopsManager.java b/src/main/java/fr/emse/gitlab/saref/managers/OopsManager.java new file mode 100644 index 0000000000000000000000000000000000000000..fcc76667bdc4c204e3aa2c2c87505a96b3de2eb6 --- /dev/null +++ b/src/main/java/fr/emse/gitlab/saref/managers/OopsManager.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 ETSI + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package fr.emse.gitlab.saref.managers; + +import java.util.ArrayList; + +public class OopsManager { + + public static ArrayList<ArrayList<String>> getData(Object[] data) { + ArrayList<String> getID = new ArrayList<String>(); + ArrayList<String> getName = new ArrayList<String>(); + ArrayList<String> getInfo = new ArrayList<String>(); + ArrayList<ArrayList<String>> elements = new ArrayList<ArrayList<String>>(); + elements.add(getID); + elements.add(getName); + elements.add(getInfo); + + for (int i = 0; i < data.length; i++) { + String data2 = data[i].toString().replaceAll(" ", ""); + if (data2.startsWith("<oops:hasCode")) { + String[] data3 = data2.split("(<|>)"); + getID.add(data3[2]); + elements.set(0, getID); + } else if (data2.startsWith("<oops:hasName")) { + String[] data3 = data2.split("(<|>)"); + getName.add(data3[2]); + elements.set(1, getName); + } else if (data2.startsWith("<oops:hasDescription")) { + String[] data3 = data2.split("(<|>)"); + getInfo.add(data3[2]); + elements.set(2, getInfo); + } + } + + return elements; + } + + public static int counter(Object[] data) { + int counter = 0; + for (int i = 0; i < data.length; i++) { + String data2 = data[i].toString().replaceAll(" ", ""); + if (data2.startsWith("<oops:hasCode")) { + counter++; + } + } + return counter; + } + +} diff --git a/src/main/java/fr/emse/gitlab/saref/managers/RepositoryManager.java b/src/main/java/fr/emse/gitlab/saref/managers/RepositoryManager.java index fd4837882a154dfca2ab137ca6232c964c1573df..50712b638e50d64b31248daa12c8228a33b5a5db 100644 --- a/src/main/java/fr/emse/gitlab/saref/managers/RepositoryManager.java +++ b/src/main/java/fr/emse/gitlab/saref/managers/RepositoryManager.java @@ -26,20 +26,14 @@ package fr.emse.gitlab.saref.managers; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.Charset; -import java.nio.charset.MalformedInputException; import java.nio.file.Files; import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.jena.atlas.RuntimeIOException; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Resource; -import org.apache.jena.riot.Lang; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Ref; @@ -51,7 +45,6 @@ import fr.emse.gitlab.saref.SAREFPipeline; import fr.emse.gitlab.saref.SAREFPipeline.Mode; import fr.emse.gitlab.saref.SAREFPipelineException; import fr.emse.gitlab.saref.entities.SAREFExample; -import fr.emse.gitlab.saref.entities.SAREFNamedGraph; import fr.emse.gitlab.saref.entities.SAREFProject; import fr.emse.gitlab.saref.entities.SAREFRepository; import fr.emse.gitlab.saref.entities.SAREFTerm; diff --git a/src/main/java/fr/emse/gitlab/saref/managers/SiteManager.java b/src/main/java/fr/emse/gitlab/saref/managers/SiteManager.java index 6223683c132dc2c520274db63abdab5bbe327a27..2f053aa77dc3bbccbbbe7514115d9a6d1b6eb49c 100644 --- a/src/main/java/fr/emse/gitlab/saref/managers/SiteManager.java +++ b/src/main/java/fr/emse/gitlab/saref/managers/SiteManager.java @@ -76,7 +76,7 @@ public class SiteManager extends SAREFErrorLogger { private static final String NAME_REPORT_HTML = "report.html"; private static final SPARQLExtStreamManager STREAM_MANAGER_BASE = StreamManagerFactory.get(); - private final File siteDir; + public final File siteDir; private final File reportFileHTML; private final RootPlan planForTerm; private final RootPlan planForOntologyVersion; diff --git a/src/main/java/fr/emse/gitlab/saref/managers/TermSiteManager.java b/src/main/java/fr/emse/gitlab/saref/managers/TermSiteManager.java index 3de5bacb1f348adc71ba8d3505a5c42403e1a589..aa7c9fc7a9deef5b5fa89755c3ba0d95cc7b8d42 100644 --- a/src/main/java/fr/emse/gitlab/saref/managers/TermSiteManager.java +++ b/src/main/java/fr/emse/gitlab/saref/managers/TermSiteManager.java @@ -103,6 +103,9 @@ public class TermSiteManager extends SAREFRepositoryErrorLogger { model.add(term.getResource(), EX.isUsedBy, v.getResource()); }); SAREFVersion lastVersion = getLastVersion(term); + if(lastVersion == null) { + return; + } model.add(QueryExecutionFactory.create(String.format("DESCRIBE <%s>", term.getIRI()), lastVersion.getModel()).execDescribe()); } diff --git a/src/main/java/fr/emse/gitlab/saref/managers/ThemisManager.java b/src/main/java/fr/emse/gitlab/saref/managers/ThemisManager.java new file mode 100644 index 0000000000000000000000000000000000000000..01c25cf352364f5764f14f3e40a92c894e865852 --- /dev/null +++ b/src/main/java/fr/emse/gitlab/saref/managers/ThemisManager.java @@ -0,0 +1,55 @@ +/* + * Copyright 2020 ETSI + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package fr.emse.gitlab.saref.managers; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; + +public class ThemisManager { + + public static Document convertStringToXMLDocument(String xmlString) { + // Parser that produces DOM object trees from XML content + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + // API to obtain DOM Document instance + try { + // Create DocumentBuilder with default configuration + DocumentBuilder builder = factory.newDocumentBuilder(); + + // Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(xmlString))); + + return doc; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/src/main/resources/messages/Clause_9_4_5_Checker.properties b/src/main/resources/messages/Clause_9_4_5_Checker.properties index ba47030a725c186976c6365cb8c9965acd504923..012453f34c5b0fcdb290ce563ba883c04b88b870 100644 --- a/src/main/resources/messages/Clause_9_4_5_Checker.properties +++ b/src/main/resources/messages/Clause_9_4_5_Checker.properties @@ -1,3 +1,5 @@ profile=The ontology in the ontology document shall satisfy the OWL2 DL profile. Violations are: %s consistent=The ontology in the ontology document shall be Consistent. Violations are: %s satisfiable=OWL Class %s declared in the ontology document should be satisfiable. Violations are: %s +oops=OOPS found some problems. Violations are: %s +oopsError=OOPS error. The service may be under maintenance. \ No newline at end of file diff --git a/src/main/resources/messages/Clause_9_5_Checker.properties b/src/main/resources/messages/Clause_9_5_Checker.properties index b27ffe58c4b7f41f8220446681999320f0cf182d..a53ae8e3f58854365a0bfa8d9ba2c5a9e7f2e164 100644 --- a/src/main/resources/messages/Clause_9_5_Checker.properties +++ b/src/main/resources/messages/Clause_9_5_Checker.properties @@ -3,3 +3,5 @@ line=The `tests` specification shall be a CSV (Comma-Separated Values) file enco ioexception=Error while checking the `tests` directory directories=There should not be directories in the `tests` directory. Their content will be ignored. csv=Every test document shall have the extension `.csv`. The following documents violate this clause: %s +themis=OOPS found some problems. Violations are: %s +themisError=Themis error. The service may be under maintenance. \ No newline at end of file diff --git a/src/main/resources/themis/body.html b/src/main/resources/themis/body.html new file mode 100644 index 0000000000000000000000000000000000000000..4b203adf2a855d52c37d90b534f67b08f88fb2e2 --- /dev/null +++ b/src/main/resources/themis/body.html @@ -0,0 +1,86 @@ +<body class="gantry g-helium-style site com_content view-article no-layout no-task dir-ltr itemid-217 outline-19 g-offcanvas-left g-default g-style-preset1"> +<div id="g-offcanvas" data-g-offcanvas-swipe="1" data-g-offcanvas-css3="1"> + <div class="g-grid"> + <div class="g-block size-100"> + <div class="g-content g-particle"> + <div id="g-mobilemenu-container" data-g-menu-breakpoint="48rem"></div> + </div> + </div> + </div> +</div> +<div id="g-page-surround"> + <div class="g-offcanvas-hide g-offcanvas-toggle" data-offcanvas-toggle-aria-controls="g-offcanvas" aria-expanded="false"><i class="fa fa-fw fa-bars"></i></div> + <section id="g-navigation"> + <div class="g-container"> + <div class="g-grid"> + <div class="g-block size-17"> + <div class="g-content g-particle"> + <a href="" title="" rel="home" class="g-logo g-logo-helium"> + <img src="../../static/images/logo-l.png" alt="" /> + </a> + </div> + </div> + <div class="g-block size-50"> + <div class="g-content g-particle"> + <nav class="g-main-nav" role="navigation" data-g-hover-expand="true"> + <ul class="g-toplevel"> + <li class="g-menu-item g-menu-item-type-component g-menu-item-217 active g-standard"> + <a class="g-menu-item-container" href="index.html"><span class="g-menu-item-content"><span class="g-menu-item-title">Home</span></span></a> + </li> + <li class="g-menu-item g-menu-item-type-component g-menu-item-242 g-standard"> + <a class="g-menu-item-container" href="core/"><span class="g-menu-item-content"><span class="g-menu-item-title">SAREF core</span></span></a> + </li> + <li class="g-menu-item g-menu-item-type-component g-menu-item-242 g-standard"> + <a class="g-menu-item-container" href="resources.html"><span class="g-menu-item-content"><span class="g-menu-item-title">Resources</span></span></a> + </li> + <li class="g-menu-item g-menu-item-type-component g-menu-item-242 g-standard"> + <a class="g-menu-item-container" href="https://forge.etsi.org/gitlab/SAREF/"><span class="g-menu-item-content"><span class="g-menu-item-title">Participate</span></span></a> + </li> + <li class="g-menu-item g-menu-item-type-component g-menu-item-242 g-standard"> + <a class="g-menu-item-container" href=""><span class="g-menu-item-content"><span class="g-menu-item-title">About us</span></span></a> + </li> + <li class="g-menu-item g-menu-item-type-component g-menu-item-242 g-standard"> + <a class="g-menu-item-container" href="https://www.etsi.org/committee/smartm2m"><span class="g-menu-item-content"><span class="g-menu-item-title">SmartM2M</span></span></a> + </li> + </ul> + </nav> + </div> + </div> + <div class="g-block g-social-header size-33"> + <div class="g-content g-particle"> + <div class="g-social"> + <a target="_blank" href="https://twitter.com/ETSI_STANDARDS" title="" aria-label=""> + <span class="fa fa-twitter fa-fw"></span> + <span class="g-social-text"></span> + </a> + <a target="_blank" href="https://www.facebook.com/etsi.standards" title="" aria-label=""> + <span class="fa fa-facebook-official"></span> + <span class="g-social-text"></span> + </a> + <a target="_blank" href="https://www.linkedin.com/company/etsi?trk=biz-companies-cym" title="" aria-label=""> + <span class="fa fa-linkedin-square"></span> + <span class="g-social-text"></span> + </a> + <a target="_blank" href="https://www.youtube.com/user/ETSIstandards" title="" aria-label=""> + <span class="fa fa-youtube-play"></span> + <span class="g-social-text"></span> + </a> + </div> + </div> + </div> + </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>SAREF Pipeline @docType</h1> + </div> + </div> + </div> + </header> + + <h1 align="center">@ontologyName</h1> \ No newline at end of file diff --git a/src/main/resources/themis/footer.html b/src/main/resources/themis/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..f8cf47d768014b7e3c04eb2b4ad90eb537c1a49e --- /dev/null +++ b/src/main/resources/themis/footer.html @@ -0,0 +1,50 @@ +</div> +<footer id="g-footer"> + <div class="g-container"> + <div class="g-grid"> + <div class="g-block size-15"> + <div class="g-content g-particle"> + <a href="https://www.etsi.org/" title="" class="g-logo g-logo-helium"> + <img src="https://forge.etsi.org/files/ETSI-Logo_BW_S_Office1.png" alt="" /> + </a> + </div> + </div> + <div class="g-block size-20"> + <div class="g-content g-particle">© ETSI 2020<br /><a style="font-size:10pt; color:white" href="https://www.etsi.org/">Visit ETSI website for more information on Terms & Conditions.</a></div> + </div> + <div class="g-block g-horizontalmenu size-40"> + <div class="g-content g-particle"> + <nav class="g-main-nav" role="navigation" data-g-hover-expand="true"> + <ul class="g-toplevel"> + <li class="g-menu-item g-menu-item-type-component g-menu-item-245 g-standard "> + <a class="g-menu-item-container" href="index.php/legal-matters"> + <span class="g-menu-item-content"> + <span class="g-menu-item-title">Legal matters</span> + </span> + </a> + </li> + <li class="g-menu-item g-menu-item-type-url g-menu-item-247 g-standard "> + <a class="g-menu-item-container" href="mailto:cti_support@etsi.org?subject=[SAREF]"> + <span class="g-menu-item-content"> + <span class="g-menu-item-title">Contact & Support</span> + </span> + </a> + </li> + </ul> + </nav> + </div> + </div> + <div class="g-block size-25"> + <div class="g-content g-particle"> + <div class=""> + <div class="g-totop"> + <a href="#" id="g-totop" rel="nofollow">Back to top <i class="fa fa-chevron-up fa-fw"></i></a> + </div> + </div> + </div> + </div> + </div> + </div> +</footer> +</body> +</html> \ No newline at end of file diff --git a/src/main/resources/themis/header.html b/src/main/resources/themis/header.html new file mode 100644 index 0000000000000000000000000000000000000000..78312de21b28153caac9c18d1229be6f662280a6 --- /dev/null +++ b/src/main/resources/themis/header.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta charset="utf-8" /> + <meta name="generator" content="SPARQL-Generate" /> + <title>SAREF pipeline report</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" /> + <link href="../../static/templates/g5_helium/custom/css-compiled/helium_19.css" rel="stylesheet" /> + <link href="../../static/media/gantry5/assets/css/bootstrap-gantry.css" rel="stylesheet" /> + <link href="../../static/media/gantry5/engines/nucleus/css-compiled/joomla.css" rel="stylesheet" /> + <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 href="../../static/jqtree/jqtree.css" rel="stylesheet"/> + <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> + <script src="../../static/media/system/js/caption.js?06eedc97766b70aa1fa0e80231495faa"></script> + <script src="../../static/media/jui/js/bootstrap.min.js?06eedc97766b70aa1fa0e80231495faa"></script> + <script src="../../static/templates/g5_helium/js/juitabs.js"></script> + <script> + jQuery(window).on('load', function() { + new JCaption('img.caption'); + }); + </script> + <title>@ontologyName</title> + <base href="@href" /> +</head> \ No newline at end of file