Newer
Older
*
* 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
*
* 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
Salva5297
committed
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.SocketTimeoutException;
Salva5297
committed
import java.util.ArrayList;
import java.util.Set;
import java.util.stream.Collectors;
Salva5297
committed
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;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.profiles.OWL2DLProfile;
import org.semanticweb.owlapi.profiles.OWLProfileReport;
import org.semanticweb.owlapi.profiles.violations.UseOfDefinedDatatypeInDatatypeRestriction;
import org.semanticweb.owlapi.profiles.violations.UseOfDefinedDatatypeInLiteral;
import org.semanticweb.owlapi.profiles.violations.UseOfUndeclaredDatatype;
import org.semanticweb.owlapi.profiles.violations.UseOfUnknownDatatype;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import fr.mines_stetienne.ci.saref.SAREF;
import fr.mines_stetienne.ci.saref.SAREFPipelineException;
import fr.mines_stetienne.ci.saref.managers.OntologyManager;
import fr.mines_stetienne.ci.saref.managers.RepositoryManager;
import fr.mines_stetienne.ci.saref.managers.ThemisManager;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
Salva5297
committed
/**
* Checks TS 103 673 Clause 9.4.5: OWL Profile, Consistency, and Satisfiability
* of Classes
*/
public class Clause_9_4_5_Checker extends AbstractClauseChecker {
private static enum MESSAGE {
Salva5297
committed
profile, consistent, satisfiable, oops, oopsError;
}
/**
*/
public Clause_9_4_5_Checker(RepositoryManager repositoryManager) {
super(repositoryManager, Clause_9_4_5_Checker.class);
}
@Override
public void checkClause() throws SAREFPipelineException {
final OWLOntology ontology = pipeline.getOntologyManager().loadOntology(version, errorLogger);
if (ontology == null) {
return;
}
final OWLProfileReport report = new OWL2DLProfile().checkOntology(ontology);
report.getViolations().removeIf(v -> {
if (v instanceof UseOfDefinedDatatypeInDatatypeRestriction || v instanceof UseOfDefinedDatatypeInLiteral
|| v instanceof UseOfUndeclaredDatatype || v instanceof UseOfUnknownDatatype) {
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);
if (incExplanation != null && !incExplanation.isEmpty()) {
String explanation = incExplanation.stream().map(e -> e.getAxioms().toString())
.collect(Collectors.joining("\n- ", "\n\n- ", "\n\n"));
logError(getMessage(MESSAGE.consistent, explanation));
} else {
ExplanationGenerator<OWLAxiom> generator = ontologyManager.getExplanationGenerator(ontology);
ontology.classesInSignature().forEach(c -> {
return;
}
Set<Explanation<OWLAxiom>> incExplanation2 = ontologyManager.getIncoherenceExplanations(generator, c);
if (!incExplanation2.isEmpty()) {
String explanation = incExplanation2.stream().map(e -> e.getAxioms().toString())
.collect(Collectors.joining("\n- ", "\n\n- ", "\n\n"));
logError(getMessage(MESSAGE.satisfiable, c, explanation));
try {
checkOops();
} catch (Exception ex) {
logWarning(getMessage(MESSAGE.oopsError), ex);
Salva5297
committed
}
public void checkOops() throws Exception {
Salva5297
committed
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("]]", "] ]");
Salva5297
committed
String xmlRequest = "<?xml version='1.0' encoding='UTF-8'?>" + "<OOPSRequest>" + "<OntologyURI></OntologyURI>"
+ "<OntologyContent><![CDATA[" + onto + "]]></OntologyContent>" + "<Pitfalls></Pitfalls>"
+ "<OutputFormat>RDF/XML</OutputFormat>" + "</OOPSRequest>";
Salva5297
committed
Object[] arrayData = new Object[0];
Salva5297
committed
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();
Salva5297
committed
try (Response response = httpClient.newCall(request).execute();) {
if (response.code() != 200) {
throw new SAREFPipelineException("response", "Unexpected response code " + response.code());
Salva5297
committed
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
String result = response.body().string();
Document doc = ThemisManager.convertStringToXMLDocument(result);
NodeList nodeList = doc.getElementsByTagName("rdf:Description");
ArrayList<String> oopsErrors = new ArrayList<String>();
for (int temp = 0; temp < nodeList.getLength(); temp++) {
org.w3c.dom.Node node = nodeList.item(temp);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
Element element = (Element) node;
if (((Element) node).getElementsByTagName("oops:hasCode").item(0) != null) {
if (((Element) node).getElementsByTagName("oops:hasName").item(0) != null) {
String code = element.getElementsByTagName("oops:hasCode").item(0).getTextContent();
String name = element.getElementsByTagName("oops:hasName").item(0).getTextContent();
String description = element.getElementsByTagName("oops:hasDescription").item(0)
.getTextContent();
String affected = "";
NodeList affectedElements = element.getElementsByTagName("oops:hasAffectedElement");
if (affectedElements != null) {
for (int k = 0; k < affectedElements.getLength(); k++) {
if (k == 0) {
affected += "\"" + affectedElements.item(k).getTextContent() + "\"";
} else {
affected += " ; \"" + affectedElements.item(k).getTextContent() + "\"";
}
}
}
String oopsError = String.format(
"Code: %s, Name: %s, Description: %s, Affected Elements: %s", code, name,
description, affected);
oopsErrors.add(oopsError);
} else {
String code = element.getElementsByTagName("oops:hasCode").item(0).getTextContent();
String description = element.getElementsByTagName("oops:hasDescription").item(0)
.getTextContent();
String affected = "";
NodeList affectedElements = element.getElementsByTagName("oops:hasAffectedElement");
if (affectedElements != null) {
for (int k = 0; k < affectedElements.getLength(); k++) {
if (k == 0) {
affected += "\"" + affectedElements.item(k).getTextContent() + "\"";
} else {
affected += " ; \"" + affectedElements.item(k).getTextContent() + "\"";
}
}
}
String oopsError = String.format("Code: %s, Description: %s, Affected Elements: %s",
code, description, affected);
oopsErrors.add(oopsError);
}
Salva5297
committed
if (!oopsErrors.isEmpty()) {
String data = oopsErrors.stream().map(e -> e.toString())
.collect(Collectors.joining("\n- ", "\n\n- ", "\n\n"));
logWarning(getMessage(MESSAGE.oops, data));
}
} catch (SocketTimeoutException e) {
logWarning(getMessage(MESSAGE.oopsError), e);
}
} catch (IOException | SAREFPipelineException e) {
logWarning(getMessage(MESSAGE.oopsError), e);
Salva5297
committed
}