Skip to content

Commit

Permalink
Fix RDF issues testing 4.1.0 RC 1 #412
Browse files Browse the repository at this point in the history
This commit adds a test for ill formed XML literals, which are expected
to fail to serialize.
The issue is that ill formed literals would create ontologies that
cannot be parsed back.
  • Loading branch information
ignazio1977 committed Jun 1, 2015
1 parent 703a506 commit 522f505
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,7 @@
import org.semanticweb.owlapi.api.test.baseclasses.TestBase;
import org.semanticweb.owlapi.formats.FunctionalSyntaxDocumentFormat;
import org.semanticweb.owlapi.io.StringDocumentSource;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.vocab.OWL2Datatype;

@SuppressWarnings({ "javadoc", "null" })
Expand All @@ -38,68 +32,68 @@ public void shouldroundTripLiteral() {
int count = 17;
while (count-- > 0) {
sb.append("200 \u00B5Liters + character above U+0FFFF = ");
sb.appendCodePoint(0x10192); // happens to be "ROMAN SEMUNCIA SIGN"
sb.appendCodePoint(0x10192); // happens to be "ROMAN SEMUNCIA SIGN"
sb.append('\n');
}
testString = sb.toString();
OWLLiteral literal = Literal(testString);
assertEquals("Out = in ? false", literal.getLiteral(), testString);
}

@Test
public void shouldRoundTripXMLLiteral() throws OWLOntologyCreationException, OWLOntologyStorageException {
String literal="<div xmlns='http://www.w3.org/1999/xhtml'><h3>[unknown]</h3><p>(describe NameGroup \"[unknown]\")</p></div>";
OWLOntology o=m.createOntology();
OWLDataProperty p=df.getOWLDataProperty(IRI.create("urn:test#p"));
OWLLiteral l=df.getOWLLiteral(literal, OWL2Datatype.RDF_XML_LITERAL);
OWLNamedIndividual i=df.getOWLNamedIndividual(IRI.create("urn:test#i"));
String literal = "<div xmlns='http://www.w3.org/1999/xhtml'><h3>[unknown]</h3><p>(describe NameGroup \"[unknown]\")</p></div>";
OWLOntology o = m.createOntology();
OWLDataProperty p = df.getOWLDataProperty(IRI.create("urn:test#p"));
OWLLiteral l = df.getOWLLiteral(literal, OWL2Datatype.RDF_XML_LITERAL);
OWLNamedIndividual i = df.getOWLNamedIndividual(IRI.create("urn:test#i"));
m.addAxiom(o, df.getOWLDataPropertyAssertionAxiom(p, i, l));
String string = saveOntology(o).toString();
assertTrue(string.contains(literal));
}


@Test
public void shouldRoundtripPaddedLiterals()
throws OWLOntologyCreationException, OWLOntologyStorageException {
String in = "Prefix(:=<urn:test#>)\n"
+ "Prefix(a:=<urn:test#>)\n"
+ "Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)\n"
+ "Prefix(owl2xml:=<http://www.w3.org/2006/12/owl2-xml#>)\n"
+ "Prefix(test:=<urn:test#>)\n"
+ "Prefix(owl:=<http://www.w3.org/2002/07/owl#>)\n"
+ "Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)\n"
+ "Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)\n"
+ "Ontology(<urn:test>\n"
+ "DataPropertyAssertion(:dp :c \"1\"^^xsd:integer) "
+ "DataPropertyAssertion(:dp :c \"01\"^^xsd:integer) "
+ "DataPropertyAssertion(:dp :c \"1\"^^xsd:short))";
OWLOntology o = loadOntologyFromString(new StringDocumentSource(in,
IRI.create("urn:test"), new FunctionalSyntaxDocumentFormat(),
null));
public void shouldFailOnMalformedXMLLiteral() throws OWLOntologyCreationException, OWLOntologyStorageException {
String literal = "<ncicp:ComplexDefinition><ncicp:def-definition>A form of cancer that begins in melanocytes (cells that make the pigment melanin). It may begin in a mole (skin melanoma), but can also begin in other pigmented tissues, such as in the eye or in the intestines.</ncicp:def-definition><ncicp:def-source>NCI-GLOSS</ncicp:def-source></ncicp:ComplexDefinition>";
OWLOntology o = m.createOntology();
OWLDataProperty p = df.getOWLDataProperty(IRI.create("urn:test#p"));
OWLLiteral l = df.getOWLLiteral(literal, OWL2Datatype.RDF_XML_LITERAL);
OWLNamedIndividual i = df.getOWLNamedIndividual(IRI.create("urn:test#i"));
m.addAxiom(o, df.getOWLDataPropertyAssertionAxiom(p, i, l));
expectedException.expect(OWLOntologyStorageException.class);
expectedException.expectMessage(literal);
expectedException.expectMessage("XML literal is not self contained");
saveOntology(o).toString();
}

@Test
public void shouldRoundtripPaddedLiterals() throws OWLOntologyCreationException, OWLOntologyStorageException {
String in = "Prefix(:=<urn:test#>)\n" + "Prefix(a:=<urn:test#>)\n"
+ "Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)\n"
+ "Prefix(owl2xml:=<http://www.w3.org/2006/12/owl2-xml#>)\n" + "Prefix(test:=<urn:test#>)\n"
+ "Prefix(owl:=<http://www.w3.org/2002/07/owl#>)\n" + "Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)\n"
+ "Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)\n" + "Ontology(<urn:test>\n"
+ "DataPropertyAssertion(:dp :c \"1\"^^xsd:integer) " + "DataPropertyAssertion(:dp :c \"01\"^^xsd:integer) "
+ "DataPropertyAssertion(:dp :c \"1\"^^xsd:short))";
OWLOntology o = loadOntologyFromString(new StringDocumentSource(in, IRI.create("urn:test"),
new FunctionalSyntaxDocumentFormat(), null));
OWLOntology o2 = roundTrip(o, new FunctionalSyntaxDocumentFormat());
equal(o, o2);
OWLDataProperty p = df.getOWLDataProperty(IRI.create("urn:test#dp"));
OWLNamedIndividual i = df.getOWLNamedIndividual(IRI
.create("urn:test#c"));
assertTrue(o.getAxioms().contains(
df.getOWLDataPropertyAssertionAxiom(p, i,
df.getOWLLiteral("01", df.getIntegerOWLDatatype()))));
assertTrue(o.getAxioms().contains(
df.getOWLDataPropertyAssertionAxiom(p, i,
df.getOWLLiteral("1", df.getIntegerOWLDatatype()))));
assertTrue(o.getAxioms().contains(
df.getOWLDataPropertyAssertionAxiom(
p,
i,
df.getOWLLiteral("1",
OWL2Datatype.XSD_SHORT.getDatatype(df)))));
OWLNamedIndividual i = df.getOWLNamedIndividual(IRI.create("urn:test#c"));
assertTrue(o.getAxioms().contains(df.getOWLDataPropertyAssertionAxiom(p, i, df.getOWLLiteral("01", df
.getIntegerOWLDatatype()))));
assertTrue(o.getAxioms().contains(df.getOWLDataPropertyAssertionAxiom(p, i, df.getOWLLiteral("1", df
.getIntegerOWLDatatype()))));
assertTrue(o.getAxioms().contains(df.getOWLDataPropertyAssertionAxiom(p, i, df.getOWLLiteral("1",
OWL2Datatype.XSD_SHORT.getDatatype(df)))));
}

@Test
public void shouldNotFindPaddedLiteralsEqualToNonPadded() {
assertNotEquals(df.getOWLLiteral("01", df.getIntegerOWLDatatype()),
df.getOWLLiteral("1", df.getIntegerOWLDatatype()));
assertNotEquals(df.getOWLLiteral("1", df.getIntegerOWLDatatype()),
df.getOWLLiteral("01", df.getIntegerOWLDatatype()));
assertNotEquals(df.getOWLLiteral("01", df.getIntegerOWLDatatype()), df.getOWLLiteral("1", df
.getIntegerOWLDatatype()));
assertNotEquals(df.getOWLLiteral("1", df.getIntegerOWLDatatype()), df.getOWLLiteral("01", df
.getIntegerOWLDatatype()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import static org.semanticweb.owlapi.util.OWLAPIPreconditions.*;

import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import java.util.*;

Expand All @@ -23,7 +24,11 @@

import org.semanticweb.owlapi.io.XMLUtils;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.util.SAXParsers;
import org.semanticweb.owlapi.util.StringLengthComparator;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.google.common.collect.Lists;

Expand Down Expand Up @@ -61,15 +66,13 @@ public class XMLWriterImpl implements XMLWriter {
* @param preferences
* xml writer preferences instance
*/
public XMLWriterImpl(@Nonnull Writer writer,
@Nonnull XMLWriterNamespaceManager xmlWriterNamespaceManager,
public XMLWriterImpl(@Nonnull Writer writer, @Nonnull XMLWriterNamespaceManager xmlWriterNamespaceManager,
@Nonnull String xmlBase, @Nonnull XMLWriterPreferences preferences) {
this.writer = checkNotNull(writer, "writer cannot be null");
this.xmlWriterNamespaceManager = checkNotNull(xmlWriterNamespaceManager,
"xmlWriterNamespaceManager cannot be null");
this.xmlBase = checkNotNull(xmlBase, "xmlBase cannot be null");
xmlPreferences = checkNotNull(preferences,
"preferences cannot be null");
xmlPreferences = checkNotNull(preferences, "preferences cannot be null");
// no need to set it to UTF-8: it's supposed to be the default encoding
// for XML.
// Must be set correctly for the Writer anyway, or bugs will ensue.
Expand All @@ -79,19 +82,16 @@ public XMLWriterImpl(@Nonnull Writer writer,
}

private void setupEntities() {
List<String> namespaces = Lists.newArrayList(xmlWriterNamespaceManager
.getNamespaces());
List<String> namespaces = Lists.newArrayList(xmlWriterNamespaceManager.getNamespaces());
Collections.sort(namespaces, new StringLengthComparator());
entities = new LinkedHashMap<>();
for (String curNamespace : namespaces) {
assert curNamespace != null;
String curPrefix = "";
if (xmlWriterNamespaceManager.getDefaultNamespace().equals(
curNamespace)) {
if (xmlWriterNamespaceManager.getDefaultNamespace().equals(curNamespace)) {
curPrefix = xmlWriterNamespaceManager.getDefaultPrefix();
} else {
curPrefix = xmlWriterNamespaceManager.getPrefixForNamespace(
curNamespace);
curPrefix = xmlWriterNamespaceManager.getPrefixForNamespace(curNamespace);
}
assert curPrefix != null;
if (!curPrefix.isEmpty()) {
Expand Down Expand Up @@ -197,8 +197,7 @@ public void writeTextContent(String text) {
@Override
public void writeComment(String commentText) throws IOException {
XMLElement element = new XMLElement(null, elementStack.size());
element.setText("<!-- " + commentText.replace("--", "&#45;&#45;")
+ " -->");
element.setText("<!-- " + commentText.replace("--", "&#45;&#45;") + " -->");
if (!elementStack.isEmpty()) {
XMLElement topElement = elementStack.peek();
if (topElement != null) {
Expand All @@ -215,8 +214,7 @@ public void writeComment(String commentText) throws IOException {
private void writeEntities(@Nonnull IRI rootName) throws IOException {
String qName = xmlWriterNamespaceManager.getQName(rootName);
if (qName == null) {
throw new IOException("Cannot create valid XML: qname for "
+ rootName + " is null");
throw new IOException("Cannot create valid XML: qname for " + rootName + " is null");
}
writer.write("\n\n<!DOCTYPE " + qName + " [\n");
for (String entityVal : entities.keySet()) {
Expand Down Expand Up @@ -249,16 +247,14 @@ public void startDocument(@Nonnull IRI rootElement) throws IOException {
}
writeStartElement(rootElement);
setWrapAttributes(true);
writeAttribute("xmlns", xmlWriterNamespaceManager
.getDefaultNamespace());
writeAttribute("xmlns", xmlWriterNamespaceManager.getDefaultNamespace());
if (!xmlBase.isEmpty()) {
writeAttribute("xml:base", xmlBase);
}
for (String curPrefix : xmlWriterNamespaceManager.getPrefixes()) {
if (!curPrefix.isEmpty()) {
writeAttribute("xmlns:" + curPrefix, verifyNotNull(
xmlWriterNamespaceManager.getNamespaceForPrefix(
curPrefix)));
writeAttribute("xmlns:" + curPrefix, verifyNotNull(xmlWriterNamespaceManager.getNamespaceForPrefix(
curPrefix)));
}
}
}
Expand Down Expand Up @@ -339,8 +335,7 @@ public void writeElementStart(boolean close) throws IOException {
writeAttributes();
if (textContent != null) {
@SuppressWarnings("null")
boolean wrap = textContent
.length() > TEXT_CONTENT_WRAP_LIMIT;
boolean wrap = textContent.length() > TEXT_CONTENT_WRAP_LIMIT;
if (wrap) {
writeNewLine();
indentation++;
Expand Down Expand Up @@ -369,8 +364,7 @@ public void writeElementStart(boolean close) throws IOException {
// Name is null so by convension this is a comment
if (textContent != null) {
writer.write("\n\n\n");
StringTokenizer tokenizer = new StringTokenizer(
textContent, "\n", true);
StringTokenizer tokenizer = new StringTokenizer(textContent, "\n", true);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (!token.equals("\n")) {
Expand Down Expand Up @@ -406,8 +400,7 @@ public void writeElementEnd() throws IOException {
}
}

private void writeAttribute(String attr, String val)
throws IOException {
private void writeAttribute(String attr, String val) throws IOException {
writer.write(attr);
writer.write('=');
writer.write('"');
Expand All @@ -420,8 +413,7 @@ private void writeAttribute(String attr, String val)
}

private void writeAttributes() throws IOException {
for (Iterator<String> it = attributes.keySet().iterator(); it
.hasNext();) {
for (Iterator<String> it = attributes.keySet().iterator(); it.hasNext();) {
String attr = it.next();
String val = attributes.get(attr);
writer.write(' ');
Expand All @@ -438,19 +430,27 @@ private void writeAttributes() throws IOException {
private void writeTextContent() throws IOException {
if (textContent != null) {
// only escape the data if this is not an XML literal
if ("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
.equals(attributes.get("rdf:datatype"))) {
if ("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral".equals(attributes.get("rdf:datatype"))) {
checkProperXMLLiteral(textContent);
writer.write(textContent);
} else {
writer.write(XMLUtils.escapeXML(textContent));
}
}
}

private void checkProperXMLLiteral(String text) throws IOException {
try {
SAXParsers.initParserWithOWLAPIStandards(null).parse(new InputSource(new StringReader(text)),
new DefaultHandler());
} catch (SAXException e) {
throw new IOException("XML literal is not self contained: \"" + text + "\"", e);
}
}

private void insertIndentation() throws IOException {
if (xmlPreferences.isIndenting()) {
for (int i = 0; i < indentation * xmlPreferences
.getIndentSize(); i++) {
for (int i = 0; i < indentation * xmlPreferences.getIndentSize(); i++) {
writer.write(' ');
}
}
Expand Down

0 comments on commit 522f505

Please sign in to comment.