diff --git a/pom.xml b/pom.xml
index 4213539..b79f043 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.edmcouncil
rdf-toolkit
- 1.14.1
+ 1.14.2
UTF-8
diff --git a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedJsonLdWriter.java b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedJsonLdWriter.java
index 163550d..449a8a7 100644
--- a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedJsonLdWriter.java
+++ b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedJsonLdWriter.java
@@ -66,6 +66,11 @@ public class SortedJsonLdWriter extends SortedRdfWriter {
// Turtle allows "values" in RDF collections
private static final Class collectionClass = Value.class;
+ /**
+ * RDF Types that are preferred to be used first.
+ */
+ private final List preferredRdfTypes = new ArrayList<>(PREFERRED_RDF_TYPES);
+
/**
* Output stream for this JSON-LD writer.
*/
@@ -147,6 +152,10 @@ public void startRDF() throws RDFHandlerException {
*/
@Override
public void endRDF() throws RDFHandlerException {
+ if (suppressNamedIndividuals) {
+ preferredRdfTypes.remove(Constants.owlNamedIndividual);
+ }
+
try {
// Sort triples, etc.
sortedOntologies = unsortedOntologies.toSorted(collectionClass, comparisonContext);
@@ -297,11 +306,14 @@ protected void writeSubjectTriples(Writer out, Resource subject) throws Exceptio
List valuesList = new ArrayList<>();
if (!values.isEmpty()) {
if (predicate == Constants.RDF_TYPE) {
- for (IRI preferredType : PREFERRED_RDF_TYPES) {
+ for (IRI preferredType : preferredRdfTypes) {
if (values.contains(preferredType)) {
valuesList.add(preferredType);
values.remove(preferredType);
}
+ if (suppressNamedIndividuals) {
+ values.remove(Constants.owlNamedIndividual);
+ }
}
}
diff --git a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedRdfXmlWriter.java b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedRdfXmlWriter.java
index 480d74f..8c02305 100644
--- a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedRdfXmlWriter.java
+++ b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedRdfXmlWriter.java
@@ -38,16 +38,6 @@
import static org.edmcouncil.rdf_toolkit.util.Constants.rdfParseType;
import static org.edmcouncil.rdf_toolkit.util.Constants.xsString;
-import org.eclipse.rdf4j.model.BNode;
-import org.eclipse.rdf4j.model.IRI;
-import org.eclipse.rdf4j.model.Literal;
-import org.eclipse.rdf4j.model.Resource;
-import org.eclipse.rdf4j.model.Value;
-import org.eclipse.rdf4j.rio.RDFHandlerException;
-import org.edmcouncil.rdf_toolkit.model.SortedTurtleObjectList;
-import org.edmcouncil.rdf_toolkit.model.SortedTurtlePredicateObjectMap;
-import org.edmcouncil.rdf_toolkit.util.Constants;
-import org.edmcouncil.rdf_toolkit.util.StringDataTypeOptions;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
@@ -58,451 +48,496 @@
import java.util.Set;
import java.util.TreeSet;
import javax.xml.namespace.QName;
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.edmcouncil.rdf_toolkit.model.SortedTurtleObjectList;
+import org.edmcouncil.rdf_toolkit.model.SortedTurtlePredicateObjectMap;
+import org.edmcouncil.rdf_toolkit.util.Constants;
+import org.edmcouncil.rdf_toolkit.util.StringDataTypeOptions;
/**
- * Equivalent to Sesame's built-in RDF/XML writer, but the triples are sorted into a consistent order.
- * In order to do the sorting, it must be possible to load all of the RDF statements into memory.
- * NOTE: comments are suppressed, as there isn't a clear way to sort them along with triples.
+ * Equivalent to Sesame's built-in RDF/XML writer, but the triples are sorted into a consistent order. In order to do
+ * the sorting, it must be possible to load all of the RDF statements into memory. NOTE: comments are suppressed, as
+ * there isn't a clear way to sort them along with triples.
*/
public class SortedRdfXmlWriter extends SortedRdfWriter {
- // TODO: the 'out' parameter in 'write...' methods is not used, and should be refactored out of the code. Perhaps. One day.
-
- // need to use namespace prefixes generated by the serializer in order to be able to convert all predicates to
- // a QName, as required for RDF/XML.
- private static final boolean USE_GENERATED_PREFIXES = true;
-
- // RDF/XML only allows "resources" in RDF collections
- private static final Class COLLECTION_CLASS = Resource.class;
-
- /**
- * RDF Types that are preferred to be used first.
- */
- private final List preferredRdfTypes = new ArrayList<>(PREFERRED_RDF_TYPES);
-
- /** Output stream for this RDF/XML writer. */
- // Note: this is an internal Java class, not part of the published API. But easier than writing our own indenter
- // here.
- private IndentingXMLStreamWriter output = null;
-
- /** Namespace prefix for the RDF namespace. */
- private String rdfPrefix = "rdf";
-
-
- /**
- * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied output stream.
- *
- * @param out The OutputStream to write the RDF/XML to.
- */
- public SortedRdfXmlWriter(OutputStream out) {
- super(out);
- this.output = new IndentingXMLStreamWriter(out, DEFAULT_LINE_END);
- }
-
- /**
- * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied writer.
- *
- * @param writer The Writer to write the RDF/XML to.
- */
- public SortedRdfXmlWriter(Writer writer) {
- super(writer);
- this.output = new IndentingXMLStreamWriter(writer, DEFAULT_LINE_END);
+ // TODO: the 'out' parameter in 'write...' methods is not used, and should be refactored out of the code. Perhaps. One day.
+
+ // need to use namespace prefixes generated by the serializer in order to be able to convert all predicates to
+ // a QName, as required for RDF/XML.
+ private static final boolean USE_GENERATED_PREFIXES = true;
+
+ // RDF/XML only allows "resources" in RDF collections
+ private static final Class COLLECTION_CLASS = Resource.class;
+
+ /**
+ * RDF Types that are preferred to be used first.
+ */
+ private final List preferredRdfTypes = new ArrayList<>(PREFERRED_RDF_TYPES);
+
+ /**
+ * Output stream for this RDF/XML writer.
+ */
+ // Note: this is an internal Java class, not part of the published API. But easier than writing our own indenter
+ // here.
+ private IndentingXMLStreamWriter output = null;
+
+ /**
+ * Namespace prefix for the RDF namespace.
+ */
+ private String rdfPrefix = "rdf";
+
+
+ /**
+ * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied output stream.
+ *
+ * @param out The OutputStream to write the RDF/XML to.
+ */
+ public SortedRdfXmlWriter(OutputStream out) {
+ super(out);
+ this.output = new IndentingXMLStreamWriter(out, DEFAULT_LINE_END);
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied writer.
+ *
+ * @param writer The Writer to write the RDF/XML to.
+ */
+ public SortedRdfXmlWriter(Writer writer) {
+ super(writer);
+ this.output = new IndentingXMLStreamWriter(writer, DEFAULT_LINE_END);
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied output stream.
+ *
+ * @param out The OutputStream to write the RDF/XML to.
+ * @param options options for the RDF/XML writer.
+ */
+ public SortedRdfXmlWriter(OutputStream out, Map options) {
+ super(out, options);
+ String indent = options.containsKey(INDENT) ? ((String) options.get(INDENT)) : null;
+ String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
+ this.output = new IndentingXMLStreamWriter(out, StandardCharsets.UTF_8.name(), indent, true, lineEnd);
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied writer.
+ *
+ * @param writer The Writer to write the RDF/XML to.
+ * @param options options for the RDF/XML writer.
+ */
+ public SortedRdfXmlWriter(Writer writer, Map options) {
+ super(writer, options);
+ String indent = options.containsKey(INDENT) ? ((String) options.get(INDENT)) : null;
+ String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
+ this.output = new IndentingXMLStreamWriter(writer, indent, true, lineEnd);
+ }
+
+ /**
+ * Signals the end of the RDF data. This method is called when all data has been reported.
+ *
+ * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
+ */
+ @Override
+ public void endRDF() throws RDFHandlerException {
+ if (suppressNamedIndividuals) {
+ preferredRdfTypes.remove(Constants.owlNamedIndividual);
}
- /**
- * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied output stream.
- *
- * @param out The OutputStream to write the RDF/XML to.
- * @param options options for the RDF/XML writer.
- */
- public SortedRdfXmlWriter(OutputStream out, Map options) {
- super(out, options);
- String indent = options.containsKey(INDENT) ? ((String) options.get(INDENT)) : null;
- String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
- this.output = new IndentingXMLStreamWriter(out, StandardCharsets.UTF_8.name(), indent, true, lineEnd);
+ try {
+ // Sort triples, etc.
+ sortedOntologies = unsortedOntologies.toSorted(COLLECTION_CLASS, comparisonContext);
+ if (sortedOntologies.size() != unsortedOntologies.size()) {
+ System.err.printf("**** ontologies unexpectedly lost or gained during sorting: %d != %d%n",
+ sortedOntologies.size(),
+ unsortedOntologies.size());
+ System.err.flush();
+ }
+
+ sortedTripleMap = unsortedTripleMap.toSorted(COLLECTION_CLASS, comparisonContext);
+ compareSortedToUnsortedTripleMap(sortedTripleMap, unsortedTripleMap, "RDF/XML"); // TODO
+
+ sortedBlankNodes = unsortedBlankNodes.toSorted(COLLECTION_CLASS, comparisonContext);
+ if (sortedBlankNodes.size() != unsortedBlankNodes.size()) {
+ System.err.printf("**** blank nodes unexpectedly lost or gained during sorting: %d != %d%n",
+ sortedBlankNodes.size(),
+ unsortedBlankNodes.size());
+ System.err.flush();
+ }
+
+ super.endRDF();
+ } catch (Exception ex) {
+ throw new RDFHandlerException("unable to generate/write RDF output", ex);
}
-
- /**
- * Creates an RDFWriter instance that will write sorted RDF/XML to the supplied writer.
- *
- * @param writer The Writer to write the RDF/XML to.
- * @param options options for the RDF/XML writer.
- */
- public SortedRdfXmlWriter(Writer writer, Map options) {
- super(writer, options);
- String indent = options.containsKey(INDENT) ? ((String) options.get(INDENT)) : null;
- String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
- this.output = new IndentingXMLStreamWriter(writer, indent, true, lineEnd);
+ }
+
+ private void writeSpecialComments(Writer out, String[] comments) throws Exception {
+ if ((comments != null) && (comments.length >= 1)) {
+ List escapedComments = new ArrayList<>();
+ for (String comment : comments) {
+ escapedComments.add(escapeCommentText(comment));
+ }
+ final String indent = output.getIndentationString();
+ final String surroundString = "\n" + indent + "####";
+ final String joinString = "\n" + indent + "## ";
+ output.writeEOL(); // add extra EOL before comments
+ output.writeComment(
+ surroundString + joinString + String.join(joinString, escapedComments) + surroundString + "\n" + indent);
+ output.writeEOL(); // add extra EOL after comments
}
-
- /**
- * Signals the end of the RDF data. This method is called when all data has
- * been reported.
- *
- * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
- */
- @Override
- public void endRDF() throws RDFHandlerException {
- if (suppressNamedIndividuals) {
- preferredRdfTypes.remove(Constants.owlNamedIndividual);
- }
-
- try {
- // Sort triples, etc.
- sortedOntologies = unsortedOntologies.toSorted(COLLECTION_CLASS, comparisonContext);
- if (sortedOntologies.size() != unsortedOntologies.size()) {
- System.err.printf("**** ontologies unexpectedly lost or gained during sorting: %d != %d%n",
- sortedOntologies.size(),
- unsortedOntologies.size());
- System.err.flush();
- }
-
- sortedTripleMap = unsortedTripleMap.toSorted(COLLECTION_CLASS, comparisonContext);
- compareSortedToUnsortedTripleMap(sortedTripleMap, unsortedTripleMap, "RDF/XML"); // TODO
-
- sortedBlankNodes = unsortedBlankNodes.toSorted(COLLECTION_CLASS, comparisonContext);
- if (sortedBlankNodes.size() != unsortedBlankNodes.size()) {
- System.err.printf("**** blank nodes unexpectedly lost or gained during sorting: %d != %d%n",
- sortedBlankNodes.size(),
- unsortedBlankNodes.size());
- System.err.flush();
+ }
+
+ protected void writeHeader(Writer out, SortedTurtleObjectList importList, String[] leadingComments)
+ throws Exception {
+ // Get prefixes used for the XML
+ rdfPrefix = reverseNamespaceTable.get(RDF_NS_URI);
+
+ // Create a sorted list of namespace prefix mappings.
+ Set prefixes = new TreeSet<>(namespaceTable.keySet());
+
+ // Write the XML prologue
+ output.writeStartDocument(output.getXmlEncoding(), "1.0");
+ output.writeEOL();
+
+ // Write the DTD subset, if required
+ if (useDtdSubset) {
+ output.startDTD("rdf:RDF");
+ if (namespaceTable.size() > 0) {
+ for (String prefix : prefixes) {
+ if (USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) {
+ if (prefix.length() >= 1) {
+ output.writeDtdEntity(prefix, namespaceTable.get(prefix));
}
-
- super.endRDF();
- } catch (Exception ex) {
- throw new RDFHandlerException("unable to generate/write RDF output", ex);
+ }
}
+ }
+ output.endDTD();
}
- private void writeSpecialComments(Writer out, String[] comments) throws Exception {
- if ((comments != null) && (comments.length >= 1)) {
- List escapedComments = new ArrayList<>();
- for (String comment : comments) {
- escapedComments.add(escapeCommentText(comment));
- }
- final String indent = output.getIndentationString();
- final String surroundString = "\n" + indent + "####";
- final String joinString = "\n" + indent + "## ";
- output.writeEOL(); // add extra EOL before comments
- output.writeComment(surroundString + joinString + String.join(joinString, escapedComments) + surroundString + "\n" + indent);
- output.writeEOL(); // add extra EOL after comments
- }
+ // Open the root element.
+ output.writeStartElement(rdfPrefix, "RDF", RDF_NS_URI); //
+
+ // Write the base IRI, if any.
+ if (baseIri != null) {
+ output.writeAttribute("xml", XML_NS_URI, "base", baseIri.stringValue());
}
- protected void writeHeader(Writer out, SortedTurtleObjectList importList, String[] leadingComments)
- throws Exception {
- // Get prefixes used for the XML
- rdfPrefix = reverseNamespaceTable.get(RDF_NS_URI);
-
- // Create a sorted list of namespace prefix mappings.
- Set prefixes = new TreeSet<>(namespaceTable.keySet());
-
- // Write the XML prologue
- output.writeStartDocument(output.getXmlEncoding(), "1.0");
- output.writeEOL();
-
- // Write the DTD subset, if required
- if (useDtdSubset) {
- output.startDTD("rdf:RDF");
- if (namespaceTable.size() > 0) {
- for (String prefix : prefixes) {
- if (USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) {
- if (prefix.length() >= 1) {
- output.writeDtdEntity(prefix, namespaceTable.get(prefix));
- }
- }
- }
- }
- output.endDTD();
+ // Write the namespace declarations into the root element.
+ if (namespaceTable.size() > 0) {
+ for (String prefix : prefixes) {
+ if (prefix.equals("") && omitXmlnsNamespace) {
+ continue;
}
-
- // Open the root element.
- output.writeStartElement(rdfPrefix, "RDF", RDF_NS_URI); //
-
- // Write the base IRI, if any.
- if (baseIri != null) {
- output.writeAttribute("xml", XML_NS_URI, "base", baseIri.stringValue());
+ if ((USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) && !"xml".equals(prefix)) {
+ if (prefix.length() >= 1) {
+ output.writeNamespace(prefix, namespaceTable.get(prefix));
+ } else {
+ output.writeDefaultNamespace(namespaceTable.get(prefix));
+ }
}
+ }
+ } else { // create RDF namespace at a minimum
+ output.writeNamespace(rdfPrefix, RDF_NS_URI);
+ }
- // Write the namespace declarations into the root element.
- if (namespaceTable.size() > 0) {
- for (String prefix : prefixes) {
- if (prefix.equals("") && omitXmlnsNamespace) {
- continue;
- }
- if ((USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) && !"xml".equals(prefix)) {
- if (prefix.length() >= 1) {
- output.writeNamespace(prefix, namespaceTable.get(prefix));
- } else {
- output.writeDefaultNamespace(namespaceTable.get(prefix));
- }
- }
- }
- } else { // create RDF namespace at a minimum
- output.writeNamespace(rdfPrefix, RDF_NS_URI);
- }
+ // RDF/XML sometimes uses the 'xml' prefix, e.g. xml:lang. This prefix is never declared explicitly.
+ addDefaultNamespacePrefixIfMissing(XML_NS_URI, "xml");
+ reverseNamespaceTable.put(XML_NS_URI, "xml"); // need to update reverse namespace table manually
- // RDF/XML sometimes uses the 'xml' prefix, e.g. xml:lang. This prefix is never declared explicitly.
- addDefaultNamespacePrefixIfMissing(XML_NS_URI, "xml");
- reverseNamespaceTable.put(XML_NS_URI, "xml"); // need to update reverse namespace table manually
+ // NOTE: have decided I don't need to preserve whitespace in attributes as I don't produce whitespace-sensitive
+ // attributes in RDF/XML. Also, apparently some less-than-conformant XML applications have problems with it.
+ // make sure whitespace is preserved, for consistency of formatting
+ // output.writeAttribute("xml", XML_NS_URI, "space", "preserve");
- // NOTE: have decided I don't need to preserve whitespace in attributes as I don't produce whitespace-sensitive
- // attributes in RDF/XML. Also, apparently some less-than-conformant XML applications have problems with it.
- // make sure whitespace is preserved, for consistency of formatting
- // output.writeAttribute("xml", XML_NS_URI, "space", "preserve");
+ output.writeCharacters(""); // force writing of closing angle bracket in root element open tag
+ output.writeEOL(); // add extra EOL after root element
- output.writeCharacters(""); // force writing of closing angle bracket in root element open tag
- output.writeEOL(); // add extra EOL after root element
+ writeSpecialComments(out, leadingComments);
+ }
- writeSpecialComments(out, leadingComments);
- }
+ protected void writeSubjectSeparator(Writer out) {
+ // nothing to do here for RDF/XML
+ }
- protected void writeSubjectSeparator(Writer out) {
- // nothing to do here for RDF/XML
+ protected void writeSubjectTriples(Writer out, Resource subject) throws Exception {
+ SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(subject);
+ if (poMap == null) {
+ poMap = new SortedTurtlePredicateObjectMap();
}
- protected void writeSubjectTriples(Writer out, Resource subject) throws Exception {
- SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(subject);
- if (poMap == null) {
- poMap = new SortedTurtlePredicateObjectMap();
+ // Try to determine whether to use or an element based on rdf:type value.
+ // Needed to determine if a type can be used as the XML element name:
+ SortedTurtleObjectList subjectRdfTypes = poMap.get(RDF_TYPE);
+ if (subjectRdfTypes != null) { // make a copy so we can remove values safely
+ subjectRdfTypes = (SortedTurtleObjectList) subjectRdfTypes.clone();
+ }
+ // ignore owl:Thing for the purposes of determining what type to use an element name in RDF/XML
+ if ((subjectRdfTypes != null) && (subjectRdfTypes.size() >= 2)) {
+ subjectRdfTypes.remove(owlThing);
+ }
+ IRI enclosingElementIRI = rdfDescription; // default value
+ QName enclosingElementQName = convertIriToQName(enclosingElementIRI, USE_GENERATED_PREFIXES);
+ for (IRI preferredType : preferredRdfTypes) { // use a preferred rdf:type for the XML element tag name, if possible
+ // If suppressNamedIndividuals is not set, prioritise owl:NamedIndividual as the preferred RDF/XML element
+ // name; otherwise, use rdf:Description.
+ if ((subjectRdfTypes != null) && subjectRdfTypes.contains(preferredType)) {
+ QName subjectRdfTypeQName = convertIriToQName(preferredType, USE_GENERATED_PREFIXES);
+ if (subjectRdfTypeQName != null) {
+ enclosingElementIRI = preferredType;
+ enclosingElementQName = subjectRdfTypeQName;
+ break;
}
+ }
+ }
- // Try to determine whether to use or an element based on rdf:type value.
- // Needed to determine if a type can be used as the XML element name:
- SortedTurtleObjectList subjectRdfTypes = poMap.get(RDF_TYPE);
- if (subjectRdfTypes != null) { // make a copy so we can remove values safely
- subjectRdfTypes = (SortedTurtleObjectList) subjectRdfTypes.clone();
- }
- // ignore owl:Thing for the purposes of determining what type to use an element name in RDF/XML
- if ((subjectRdfTypes != null) && (subjectRdfTypes.size() >= 2)) {
- subjectRdfTypes.remove(owlThing);
- }
- IRI enclosingElementIRI = rdfDescription; // default value
- QName enclosingElementQName = convertIriToQName(enclosingElementIRI, USE_GENERATED_PREFIXES);
- for (IRI preferredType : preferredRdfTypes) { // use a preferred rdf:type for the XML element tag name, if possible
- if ((subjectRdfTypes != null) && subjectRdfTypes.contains(preferredType)) { // prioritise owl:NamedIndividual as the preferred RDF/XML element name
- QName subjectRdfTypeQName = convertIriToQName(preferredType, USE_GENERATED_PREFIXES);
- if (subjectRdfTypeQName != null) {
- enclosingElementIRI = preferredType;
- enclosingElementQName = subjectRdfTypeQName;
- break;
- }
- }
+ // If no preferred type, use the type for the XML element tag, if there is only a single rdf:type
+ if ((rdfDescription.equals(enclosingElementIRI)) && (subjectRdfTypes != null) && (subjectRdfTypes.size() == 1)) {
+ Value subjectRdfTypeValue = subjectRdfTypes.first();
+ if (subjectRdfTypeValue instanceof IRI) {
+ QName subjectRdfTypeQName = convertIriToQName((IRI) subjectRdfTypeValue, USE_GENERATED_PREFIXES);
+ if (subjectRdfTypeQName != null) {
+ enclosingElementIRI = (IRI) subjectRdfTypeValue;
+ enclosingElementQName = subjectRdfTypeQName;
}
+ }
+ }
- // If no preferred type, use the type for the XML element tag, if there is only a single rdf:type
- if ((rdfDescription.equals(enclosingElementIRI)) && (subjectRdfTypes != null) && (subjectRdfTypes.size() == 1)) {
- Value subjectRdfTypeValue = subjectRdfTypes.first();
- if (subjectRdfTypeValue instanceof IRI) {
- QName subjectRdfTypeQName = convertIriToQName((IRI) subjectRdfTypeValue, USE_GENERATED_PREFIXES);
- if (subjectRdfTypeQName != null) {
- enclosingElementIRI = (IRI) subjectRdfTypeValue;
- enclosingElementQName = subjectRdfTypeQName;
- }
- }
- }
+ // Write enclosing element.
+ // The variation used for "rdf:about", or "rdf:nodeID", depends on settings and also whether the subject is a blank node or not.
+ output.writeStartElement(enclosingElementQName.getPrefix(), enclosingElementQName.getLocalPart(),
+ enclosingElementQName.getNamespaceURI());
+ if (subject instanceof BNode) {
+ if (!inlineBlankNodes) {
+ output.writeAttribute(reverseNamespaceTable.get(RDF_NS_URI), RDF_NS_URI, "nodeID",
+ blankNodeNameMap.get(subject));
+ }
+ } else if (subject instanceof IRI) {
+ output.writeStartAttribute(reverseNamespaceTable.get(RDF_NS_URI), RDF_NS_URI, "about");
+ QName subjectQName = convertIriToQName((IRI) subject, USE_GENERATED_PREFIXES);
+ if ((subjectQName != null) && (subjectQName.getPrefix() != null) && (subjectQName.getPrefix().length()
+ >= 1)) { // if a prefix is defined, write out the subject QName using an entity reference
+ output.writeAttributeEntityRef(subjectQName.getPrefix());
+ output.writeAttributeCharacters(((IRI) subject).getLocalName());
+ } else { // just write the whole subject IRI
+ output.writeAttributeCharacters(subject.toString());
+ }
+ output.endAttribute();
+ } else {
+ // this shouldn't occur, but ...
+ output.writeAttribute(
+ reverseNamespaceTable.get(RDF_NS_URI),
+ RDF_NS_URI,
+ "about",
+ subject.stringValue());
+ }
- // Write enclosing element.
- // The variation used for "rdf:about", or "rdf:nodeID", depends on settings and also whether the subject is a blank node or not.
- output.writeStartElement(enclosingElementQName.getPrefix(), enclosingElementQName.getLocalPart(), enclosingElementQName.getNamespaceURI());
- if (subject instanceof BNode) {
- if (!inlineBlankNodes) {
- output.writeAttribute(reverseNamespaceTable.get(RDF_NS_URI), RDF_NS_URI, "nodeID", blankNodeNameMap.get(subject));
- }
- } else if (subject instanceof IRI) {
- output.writeStartAttribute(reverseNamespaceTable.get(RDF_NS_URI), RDF_NS_URI, "about");
- QName subjectQName = convertIriToQName((IRI)subject, USE_GENERATED_PREFIXES);
- if ((subjectQName != null) && (subjectQName.getPrefix() != null) && (subjectQName.getPrefix().length() >= 1)) { // if a prefix is defined, write out the subject QName using an entity reference
- output.writeAttributeEntityRef(subjectQName.getPrefix());
- output.writeAttributeCharacters(((IRI) subject).getLocalName());
- } else { // just write the whole subject IRI
- output.writeAttributeCharacters(subject.toString());
- }
- output.endAttribute();
- } else {
- // this shouldn't occur, but ...
- output.writeAttribute(
- reverseNamespaceTable.get(RDF_NS_URI),
- RDF_NS_URI,
- "about",
- subject.stringValue());
+ // Write predicate/object pairs rendered first.
+ for (IRI predicate : firstPredicates) {
+ if (poMap.containsKey(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ if (values != null) { // make a copy, so we don't delete anything from the original
+ values = (SortedTurtleObjectList) values.clone();
}
-
- // Write predicate/object pairs rendered first.
- for (IRI predicate : firstPredicates) {
- if (poMap.containsKey(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- if (values != null) { // make a copy, so we don't delete anything from the original
- values = (SortedTurtleObjectList) values.clone();
- }
- ArrayList valuesList = new ArrayList<>();
- if (predicate == RDF_TYPE && values != null) { // assumes that rdfType is one of the firstPredicates
- // no need to state type explicitly if it has been used as an enclosing element name
- values.remove(enclosingElementIRI);
- }
- if (values != null && !values.isEmpty()) {
- if (predicate == RDF_TYPE) {
- for (IRI preferredType : preferredRdfTypes) {
- if (values.contains(preferredType)) {
- valuesList.add(preferredType);
- values.remove(preferredType);
- }
- }
- }
- if (!values.isEmpty()) {
- valuesList.addAll(values);
- }
- }
- if (!valuesList.isEmpty()) {
- writePredicateAndObjectValues(out, predicate, valuesList);
- }
- }
+ ArrayList valuesList = new ArrayList<>();
+ if (predicate == RDF_TYPE && values != null) { // assumes that rdfType is one of the firstPredicates
+ // no need to state type explicitly if it has been used as an enclosing element name
+ values.remove(enclosingElementIRI);
}
-
- // Write other predicate/object pairs.
- for (IRI predicate : poMap.sortedKeys()) {
- if (!firstPredicates.contains(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- writePredicateAndObjectValues(out, predicate, values);
+ if (values != null && !values.isEmpty()) {
+ if (predicate == RDF_TYPE) {
+ for (IRI preferredType : preferredRdfTypes) {
+ if (values.contains(preferredType)) {
+ valuesList.add(preferredType);
+ values.remove(preferredType);
+ }
+ if (suppressNamedIndividuals) {
+ values.remove(Constants.owlNamedIndividual);
+ }
}
+ }
+ if (!values.isEmpty()) {
+ valuesList.addAll(values);
+ }
}
-
- // Close enclosing element.
- output.writeEndElement();
- if (!inlineBlankNodes || !(subject instanceof BNode)) {
- output.writeEOL();
+ if (!valuesList.isEmpty()) {
+ writePredicateAndObjectValues(out, predicate, valuesList);
}
+ }
}
- protected void writePredicateAndObjectValues(Writer out, IRI predicate, Collection values) throws Exception {
- // Get prefixes used for the XML
- rdfPrefix = reverseNamespaceTable.get(RDF_NS_URI);
- String xmlPrefix = reverseNamespaceTable.get(XML_NS_URI);
-
- QName predicateQName = convertIriToQName(predicate, USE_GENERATED_PREFIXES);
- for (Value value : values) {
- if (inlineBlankNodes && (value instanceof BNode)) {
- BNode bnode = (BNode) value;
- if (isCollection(comparisonContext, bnode, COLLECTION_CLASS)) {
- List members = getCollectionMembers(unsortedTripleMap, bnode, COLLECTION_CLASS, comparisonContext);
- output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(), predicateQName.getNamespaceURI());
- QName rdfParseTypeQName = convertIriToQName(rdfParseType, USE_GENERATED_PREFIXES);
- output.writeAttribute(rdfParseTypeQName.getPrefix(), rdfParseTypeQName.getNamespaceURI(), rdfParseTypeQName.getLocalPart(), "Collection");
- for (Value member : members) {
- if (member instanceof BNode) {
- writeSubjectTriples(out, (Resource) member);
- } else if (member instanceof IRI) {
- QName rdfDescriptionQName = convertIriToQName(rdfDescription, USE_GENERATED_PREFIXES);
- QName rdfAboutQName = convertIriToQName(rdfAbout, USE_GENERATED_PREFIXES);
- output.writeStartElement(rdfDescriptionQName.getPrefix(), rdfDescriptionQName.getLocalPart(), rdfDescriptionQName.getNamespaceURI());
- QName memberQName = convertIriToQName((IRI) member, USE_GENERATED_PREFIXES);
- if ((memberQName == null) || (memberQName.getPrefix() == null) || (memberQName.getPrefix().length() < 1)) {
- output.writeAttribute(rdfAboutQName.getPrefix(), rdfAboutQName.getNamespaceURI(), rdfAboutQName.getLocalPart(), member.stringValue());
- } else {
- output.writeStartAttribute(rdfAboutQName.getPrefix(), rdfAboutQName.getNamespaceURI(), rdfAboutQName.getLocalPart());
- output.writeAttributeEntityRef(memberQName.getPrefix());
- output.writeAttributeCharacters(memberQName.getLocalPart());
- output.endAttribute();
- }
- output.writeEndElement();
- } else {
- QName rdfDescriptionQName = convertIriToQName(rdfDescription, USE_GENERATED_PREFIXES);
- output.writeStartElement(rdfDescriptionQName.getPrefix(), rdfDescriptionQName.getLocalPart(), rdfDescriptionQName.getNamespaceURI());
- if (member instanceof Literal) {
- if (((Literal)member).getDatatype() != null) {
- boolean useExplicit = (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(xsString.equals(((Literal)member).getDatatype()) || rdfLangString.equals(((Literal)member).getDatatype()));
- if (useExplicit) {
- output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "datatype");
- QName datatypeQName = convertIriToQName(((Literal) member).getDatatype(),
- USE_GENERATED_PREFIXES);
- if ((datatypeQName == null) || (datatypeQName.getPrefix() == null) || (datatypeQName.getPrefix().length() < 1)) {
- output.writeAttributeCharacters(((Literal) member).getDatatype().stringValue());
- } else {
- output.writeAttributeEntityRef(datatypeQName.getPrefix());
- output.writeAttributeCharacters(datatypeQName.getLocalPart());
- }
- output.endAttribute();
- }
- }
- if (((Literal)member).getLanguage().isPresent() || ((overrideStringLanguage != null) && (((Literal)member).getDatatype().stringValue().equals(xsString.stringValue())))) {
- String lang = overrideStringLanguage == null ? ((Literal)member).getLanguage().get() : overrideStringLanguage;
- output.writeAttribute(xmlPrefix, XML_NS_URI, "lang", lang);
- }
- output.writeCharacters(member.stringValue());
- } else {
- output.writeCharacters(member.stringValue());
- }
- output.writeEndElement();
- }
- }
- output.writeEndElement();
- } else {
- output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(), predicateQName.getNamespaceURI());
- writeSubjectTriples(out, bnode);
- output.writeEndElement();
- }
- } else { // not an inline blank node`
- if ((value instanceof BNode) || (value instanceof IRI)) {
- output.writeEmptyElement(predicateQName.getPrefix(), predicateQName.getLocalPart(), predicateQName.getNamespaceURI());
- } else {
- output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(), predicateQName.getNamespaceURI());
- }
- if (value instanceof BNode) {
- output.writeAttribute(rdfPrefix, RDF_NS_URI, "nodeID", blankNodeNameMap.get(value));
- } else if (value instanceof IRI) {
- output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "resource");
- QName iriQName = convertIriToQName((IRI) value, USE_GENERATED_PREFIXES);
- if (iriQName == null) {
- output.writeAttributeCharacters(value.stringValue());
+ // Write other predicate/object pairs.
+ for (IRI predicate : poMap.sortedKeys()) {
+ if (!firstPredicates.contains(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ writePredicateAndObjectValues(out, predicate, values);
+ }
+ }
+
+ // Close enclosing element.
+ output.writeEndElement();
+ if (!inlineBlankNodes || !(subject instanceof BNode)) {
+ output.writeEOL();
+ }
+ }
+
+ protected void writePredicateAndObjectValues(Writer out, IRI predicate, Collection values) throws Exception {
+ // Get prefixes used for the XML
+ rdfPrefix = reverseNamespaceTable.get(RDF_NS_URI);
+ String xmlPrefix = reverseNamespaceTable.get(XML_NS_URI);
+
+ QName predicateQName = convertIriToQName(predicate, USE_GENERATED_PREFIXES);
+ for (Value value : values) {
+ if (inlineBlankNodes && (value instanceof BNode)) {
+ BNode bnode = (BNode) value;
+ if (isCollection(comparisonContext, bnode, COLLECTION_CLASS)) {
+ List members = getCollectionMembers(unsortedTripleMap, bnode, COLLECTION_CLASS, comparisonContext);
+ output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(),
+ predicateQName.getNamespaceURI());
+ QName rdfParseTypeQName = convertIriToQName(rdfParseType, USE_GENERATED_PREFIXES);
+ output.writeAttribute(rdfParseTypeQName.getPrefix(), rdfParseTypeQName.getNamespaceURI(),
+ rdfParseTypeQName.getLocalPart(), "Collection");
+ for (Value member : members) {
+ if (member instanceof BNode) {
+ writeSubjectTriples(out, (Resource) member);
+ } else if (member instanceof IRI) {
+ QName rdfDescriptionQName = convertIriToQName(rdfDescription, USE_GENERATED_PREFIXES);
+ QName rdfAboutQName = convertIriToQName(rdfAbout, USE_GENERATED_PREFIXES);
+ output.writeStartElement(rdfDescriptionQName.getPrefix(), rdfDescriptionQName.getLocalPart(),
+ rdfDescriptionQName.getNamespaceURI());
+ QName memberQName = convertIriToQName((IRI) member, USE_GENERATED_PREFIXES);
+ if ((memberQName == null) || (memberQName.getPrefix() == null) || (memberQName.getPrefix().length()
+ < 1)) {
+ output.writeAttribute(rdfAboutQName.getPrefix(), rdfAboutQName.getNamespaceURI(),
+ rdfAboutQName.getLocalPart(), member.stringValue());
+ } else {
+ output.writeStartAttribute(rdfAboutQName.getPrefix(), rdfAboutQName.getNamespaceURI(),
+ rdfAboutQName.getLocalPart());
+ output.writeAttributeEntityRef(memberQName.getPrefix());
+ output.writeAttributeCharacters(memberQName.getLocalPart());
+ output.endAttribute();
+ }
+ output.writeEndElement();
+ } else {
+ QName rdfDescriptionQName = convertIriToQName(rdfDescription, USE_GENERATED_PREFIXES);
+ output.writeStartElement(rdfDescriptionQName.getPrefix(), rdfDescriptionQName.getLocalPart(),
+ rdfDescriptionQName.getNamespaceURI());
+ if (member instanceof Literal) {
+ if (((Literal) member).getDatatype() != null) {
+ boolean useExplicit = (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(
+ xsString.equals(((Literal) member).getDatatype()) || rdfLangString.equals(
+ ((Literal) member).getDatatype()));
+ if (useExplicit) {
+ output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "datatype");
+ QName datatypeQName = convertIriToQName(((Literal) member).getDatatype(),
+ USE_GENERATED_PREFIXES);
+ if ((datatypeQName == null) || (datatypeQName.getPrefix() == null) || (
+ datatypeQName.getPrefix().length() < 1)) {
+ output.writeAttributeCharacters(((Literal) member).getDatatype().stringValue());
} else {
- if ((iriQName.getPrefix() != null) && (iriQName.getPrefix().length() >= 1)) {
- output.writeAttributeEntityRef(iriQName.getPrefix());
- output.writeAttributeCharacters(iriQName.getLocalPart());
- } else {
- output.writeAttributeCharacters(value.stringValue());
- }
+ output.writeAttributeEntityRef(datatypeQName.getPrefix());
+ output.writeAttributeCharacters(datatypeQName.getLocalPart());
}
output.endAttribute();
- } else if (value instanceof Literal) {
- if (((Literal)value).getDatatype() != null) {
- boolean useExplicit = (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(xsString.equals(((Literal)value).getDatatype()) || rdfLangString.equals(((Literal)value).getDatatype()));
- if (useExplicit) {
- output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "datatype");
- QName datatypeQName = convertIriToQName(((Literal) value).getDatatype(),
- USE_GENERATED_PREFIXES);
- if ((datatypeQName == null) || (datatypeQName.getPrefix() == null) || (datatypeQName.getPrefix().length() < 1)) {
- output.writeAttributeCharacters(((Literal) value).getDatatype().stringValue());
- } else {
- output.writeAttributeEntityRef(datatypeQName.getPrefix());
- output.writeAttributeCharacters(datatypeQName.getLocalPart());
- }
- output.endAttribute();
- }
- }
- if (((Literal)value).getLanguage().isPresent() || ((overrideStringLanguage != null) && (((Literal)value).getDatatype().stringValue().equals(xsString.stringValue())))) {
- String lang = overrideStringLanguage == null ?
- ((Literal) value).getLanguage().orElse(overrideStringLanguage) :
- overrideStringLanguage;
- output.writeAttribute(xmlPrefix, XML_NS_URI, "lang", lang);
- }
- output.writeCharacters(value.stringValue().trim()); // trim the value, because leading/closing spaces will be lost on subsequent parses/serialisations.
- } else {
- output.writeCharacters(value.stringValue().trim()); // trim the value, because leading/closing spaces will be lost on subsequent parses/serialisations.
+ }
+ }
+ if (((Literal) member).getLanguage().isPresent() || ((overrideStringLanguage != null)
+ && (((Literal) member).getDatatype().stringValue().equals(xsString.stringValue())))) {
+ String lang =
+ overrideStringLanguage == null ? ((Literal) member).getLanguage().get() : overrideStringLanguage;
+ output.writeAttribute(xmlPrefix, XML_NS_URI, "lang", lang);
}
- output.writeEndElement();
+ output.writeCharacters(member.stringValue());
+ } else {
+ output.writeCharacters(member.stringValue());
+ }
+ output.writeEndElement();
+ }
+ }
+ output.writeEndElement();
+ } else {
+ output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(),
+ predicateQName.getNamespaceURI());
+ writeSubjectTriples(out, bnode);
+ output.writeEndElement();
+ }
+ } else { // not an inline blank node`
+ if ((value instanceof BNode) || (value instanceof IRI)) {
+ output.writeEmptyElement(predicateQName.getPrefix(), predicateQName.getLocalPart(),
+ predicateQName.getNamespaceURI());
+ } else {
+ output.writeStartElement(predicateQName.getPrefix(), predicateQName.getLocalPart(),
+ predicateQName.getNamespaceURI());
+ }
+ if (value instanceof BNode) {
+ output.writeAttribute(rdfPrefix, RDF_NS_URI, "nodeID", blankNodeNameMap.get(value));
+ } else if (value instanceof IRI) {
+ output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "resource");
+ QName iriQName = convertIriToQName((IRI) value, USE_GENERATED_PREFIXES);
+ if (iriQName == null) {
+ output.writeAttributeCharacters(value.stringValue());
+ } else {
+ if ((iriQName.getPrefix() != null) && (iriQName.getPrefix().length() >= 1)) {
+ output.writeAttributeEntityRef(iriQName.getPrefix());
+ output.writeAttributeCharacters(iriQName.getLocalPart());
+ } else {
+ output.writeAttributeCharacters(value.stringValue());
+ }
+ }
+ output.endAttribute();
+ } else if (value instanceof Literal) {
+ if (((Literal) value).getDatatype() != null) {
+ boolean useExplicit = (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(
+ xsString.equals(((Literal) value).getDatatype()) || rdfLangString.equals(
+ ((Literal) value).getDatatype()));
+ if (useExplicit) {
+ output.writeStartAttribute(rdfPrefix, RDF_NS_URI, "datatype");
+ QName datatypeQName = convertIriToQName(((Literal) value).getDatatype(),
+ USE_GENERATED_PREFIXES);
+ if ((datatypeQName == null) || (datatypeQName.getPrefix() == null) || (datatypeQName.getPrefix().length()
+ < 1)) {
+ output.writeAttributeCharacters(((Literal) value).getDatatype().stringValue());
+ } else {
+ output.writeAttributeEntityRef(datatypeQName.getPrefix());
+ output.writeAttributeCharacters(datatypeQName.getLocalPart());
+ }
+ output.endAttribute();
}
+ }
+ if (((Literal) value).getLanguage().isPresent() || ((overrideStringLanguage != null)
+ && (((Literal) value).getDatatype().stringValue().equals(xsString.stringValue())))) {
+ String lang = overrideStringLanguage == null ?
+ ((Literal) value).getLanguage().orElse(overrideStringLanguage) :
+ overrideStringLanguage;
+ output.writeAttribute(xmlPrefix, XML_NS_URI, "lang", lang);
+ }
+ output.writeCharacters(value.stringValue()
+ .trim()); // trim the value, because leading/closing spaces will be lost on subsequent parses/serialisations.
+ } else {
+ output.writeCharacters(value.stringValue()
+ .trim()); // trim the value, because leading/closing spaces will be lost on subsequent parses/serialisations.
}
+ output.writeEndElement();
+ }
}
+ }
- protected void writeFooter(Writer out, String[] trailingComments) throws Exception {
- writeSpecialComments(out, trailingComments);
+ protected void writeFooter(Writer out, String[] trailingComments) throws Exception {
+ writeSpecialComments(out, trailingComments);
- output.writeEndElement(); //
- output.writeEndDocument();
- }
+ output.writeEndElement(); //
+ output.writeEndDocument();
+ }
- public static String escapeCommentText(String comment) {
- if (comment == null) { return null; }
- return comment.replace("--", "--");
+ public static String escapeCommentText(String comment) {
+ if (comment == null) {
+ return null;
}
+ return comment.replace("--", "--");
+ }
}
diff --git a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedTurtleWriter.java b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedTurtleWriter.java
index 0bb97dc..94bea57 100644
--- a/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedTurtleWriter.java
+++ b/src/main/java/org/edmcouncil/rdf_toolkit/writer/SortedTurtleWriter.java
@@ -28,6 +28,16 @@
import static org.edmcouncil.rdf_toolkit.comparator.ComparisonUtils.isCollection;
import static org.edmcouncil.rdf_toolkit.util.Constants.INDENT;
import static org.edmcouncil.rdf_toolkit.util.Constants.LINE_END;
+
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Literal;
@@ -39,516 +49,530 @@
import org.edmcouncil.rdf_toolkit.util.Constants;
import org.edmcouncil.rdf_toolkit.util.StringDataTypeOptions;
import org.edmcouncil.rdf_toolkit.util.TextUtils;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
/**
- * Equivalent to Sesame's built-in Turtle writer, but the triples are sorted into a consistent order.
- * In order to do the sorting, it must be possible to load all of the RDF statements into memory.
- * NOTE: comments are suppressed, as there isn't a clear way to sort them along with triples.
+ * Equivalent to Sesame's built-in Turtle writer, but the triples are sorted into a consistent order. In order to do the
+ * sorting, it must be possible to load all of the RDF statements into memory. NOTE: comments are suppressed, as there
+ * isn't a clear way to sort them along with triples.
*/
public class SortedTurtleWriter extends SortedRdfWriter {
- // no need to use namespace prefixes generated by the serializer for Turtle.
- private static final boolean USE_GENERATED_PREFIXES = false;
-
- // Turtle allows "values" in RDF collections
- private static final Class COLLECTION_CLASS = Value.class;
-
- /**
- * RDF Types that are preferred to be used first.
- */
- private final List preferredRdfTypes = new ArrayList<>(PREFERRED_RDF_TYPES);
-
- /** Output stream for this Turtle writer. */
- private final IndentingWriter output;
-
- /**
- * Creates an RDFWriter instance that will write sorted Turtle to the supplied output stream.
- *
- * @param out The OutputStream to write the Turtle to.
- */
- public SortedTurtleWriter(OutputStream out) {
- super(out);
- this.output = new IndentingWriter(new OutputStreamWriter(out));
- this.output.setLineEnd(DEFAULT_LINE_END);
- this.out = this.output;
+ // no need to use namespace prefixes generated by the serializer for Turtle.
+ private static final boolean USE_GENERATED_PREFIXES = false;
+
+ // Turtle allows "values" in RDF collections
+ private static final Class COLLECTION_CLASS = Value.class;
+
+ /**
+ * RDF Types that are preferred to be used first.
+ */
+ private final List preferredRdfTypes = new ArrayList<>(PREFERRED_RDF_TYPES);
+
+ /**
+ * Output stream for this Turtle writer.
+ */
+ private final IndentingWriter output;
+
+ /**
+ * Creates an RDFWriter instance that will write sorted Turtle to the supplied output stream.
+ *
+ * @param out The OutputStream to write the Turtle to.
+ */
+ public SortedTurtleWriter(OutputStream out) {
+ super(out);
+ this.output = new IndentingWriter(new OutputStreamWriter(out));
+ this.output.setLineEnd(DEFAULT_LINE_END);
+ this.out = this.output;
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted Turtle to the supplied writer.
+ *
+ * @param writer The Writer to write the Turtle to.
+ */
+ public SortedTurtleWriter(Writer writer) {
+ super(writer);
+ this.output = new IndentingWriter(writer);
+ this.output.setLineEnd(DEFAULT_LINE_END);
+ this.out = this.output;
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted Turtle to the supplied output stream.
+ *
+ * @param out The OutputStream to write the Turtle to.
+ * @param options options for the Turtle writer.
+ */
+ public SortedTurtleWriter(OutputStream out, Map options) {
+ super(out, options);
+ this.output = new IndentingWriter(new OutputStreamWriter(out));
+ this.out = this.output;
+ if (options.containsKey(INDENT)) {
+ this.output.setIndentationString((String) options.get(INDENT));
}
-
- /**
- * Creates an RDFWriter instance that will write sorted Turtle to the supplied writer.
- *
- * @param writer The Writer to write the Turtle to.
- */
- public SortedTurtleWriter(Writer writer) {
- super(writer);
- this.output = new IndentingWriter(writer);
- this.output.setLineEnd(DEFAULT_LINE_END);
- this.out = this.output;
+ String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
+ this.output.setLineEnd(lineEnd);
+ }
+
+ /**
+ * Creates an RDFWriter instance that will write sorted Turtle to the supplied writer.
+ *
+ * @param writer The Writer to write the Turtle to.
+ * @param options options for the Turtle writer.
+ */
+ public SortedTurtleWriter(Writer writer, Map options) {
+ super(writer, options);
+ this.output = new IndentingWriter(writer);
+ this.out = this.output;
+ if (options.containsKey(INDENT)) {
+ this.output.setIndentationString((String) options.get(INDENT));
+ }
+ String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
+ this.output.setLineEnd(lineEnd);
+ }
+
+ /**
+ * Signals the start of the RDF data. This method is called before any data is reported.
+ *
+ * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
+ */
+ @Override
+ public void startRDF() throws RDFHandlerException {
+ super.startRDF();
+ output.setIndentationLevel(0);
+ }
+
+ /**
+ * Signals the end of the RDF data. This method is called when all data has been reported.
+ *
+ * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
+ */
+ @Override
+ public void endRDF() throws RDFHandlerException {
+ if (suppressNamedIndividuals) {
+ preferredRdfTypes.remove(Constants.owlNamedIndividual);
}
- /**
- * Creates an RDFWriter instance that will write sorted Turtle to the supplied output stream.
- *
- * @param out The OutputStream to write the Turtle to.
- * @param options options for the Turtle writer.
- */
- public SortedTurtleWriter(OutputStream out, Map options) {
- super(out, options);
- this.output = new IndentingWriter(new OutputStreamWriter(out));
- this.out = this.output;
- if (options.containsKey(INDENT)) {
- this.output.setIndentationString((String) options.get(INDENT));
- }
- String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
- this.output.setLineEnd(lineEnd);
+ try {
+ // Sort triples, etc.
+ sortedOntologies = unsortedOntologies.toSorted(COLLECTION_CLASS, comparisonContext);
+ if (sortedOntologies.size() != unsortedOntologies.size()) {
+ System.err.printf("**** ontologies unexpectedly lost or gained during sorting: %d != %d%n",
+ sortedOntologies.size(),
+ unsortedOntologies.size());
+ System.err.flush();
+ }
+
+ sortedTripleMap = unsortedTripleMap.toSorted(COLLECTION_CLASS, comparisonContext);
+ compareSortedToUnsortedTripleMap(sortedTripleMap, unsortedTripleMap, "Turtle"); // TODO
+
+ sortedBlankNodes = unsortedBlankNodes.toSorted(COLLECTION_CLASS, comparisonContext);
+ if (sortedBlankNodes.size() != unsortedBlankNodes.size()) {
+ System.err.printf("**** blank nodes unexpectedly lost or gained during sorting: %d != %d%n",
+ sortedBlankNodes.size(),
+ unsortedBlankNodes.size());
+ System.err.flush();
+ }
+
+ super.endRDF();
+ } catch (Throwable t) {
+ throw new RDFHandlerException("unable to generate/write RDF output", t);
+ }
+ }
+
+ protected void writeHeader(Writer out, SortedTurtleObjectList importList, String[] leadingComments)
+ throws Exception {
+ // Write TopBraid-specific special comments, if any.
+ if ((baseIri != null) || (importList.size() >= 1)) {
+ // Write the base IRI, if any.
+ if (baseIri != null) {
+ output.write("# baseURI: " + baseIri);
+ output.writeEOL();
+ }
+ // Write ontology imports, if any.
+ for (Value anImport : importList) {
+ output.write("# imports: " + anImport.stringValue());
+ output.writeEOL();
+ }
+ output.writeEOL();
}
- /**
- * Creates an RDFWriter instance that will write sorted Turtle to the supplied writer.
- *
- * @param writer The Writer to write the Turtle to.
- * @param options options for the Turtle writer.
- */
- public SortedTurtleWriter(Writer writer, Map options) {
- super(writer, options);
- this.output = new IndentingWriter(writer);
- this.out = this.output;
- if (options.containsKey(INDENT)) {
- this.output.setIndentationString((String) options.get(INDENT));
- }
- String lineEnd = options.containsKey(LINE_END) ? options.get(LINE_END).toString() : DEFAULT_LINE_END;
- this.output.setLineEnd(lineEnd);
+ // Write leading comments, if any.
+ if ((leadingComments != null) && (leadingComments.length >= 1)) {
+ output.write("####");
+ output.writeEOL();
+ for (String line : leadingComments) {
+ output.write("## " + line);
+ output.writeEOL();
+ }
+ output.write("####");
+ output.writeEOL();
+ output.writeEOL();
}
- /**
- * Signals the start of the RDF data. This method is called before any data
- * is reported.
- *
- * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
- */
- @Override
- public void startRDF() throws RDFHandlerException {
- super.startRDF();
- output.setIndentationLevel(0);
+ // Write the base IRI, if any.
+ if (baseIri != null) {
+ output.write("@base <" + baseIri + "> .");
+ output.writeEOL();
}
- /**
- * Signals the end of the RDF data. This method is called when all data has
- * been reported.
- *
- * @throws org.eclipse.rdf4j.rio.RDFHandlerException If the RDF handler has encountered an unrecoverable error.
- */
- @Override
- public void endRDF() throws RDFHandlerException {
- if (suppressNamedIndividuals) {
- preferredRdfTypes.remove(Constants.owlNamedIndividual);
+ // Write out prefixes and namespaces IRIs.
+ if (namespaceTable.size() > 0) {
+ Set prefixes = new TreeSet<>(namespaceTable.keySet());
+ for (String prefix : prefixes) {
+ if (USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) {
+ output.write("@prefix " + prefix + ": <" + namespaceTable.get(prefix) + "> .");
+ output.writeEOL();
}
+ }
+ output.writeEOL();
+ }
+ }
- try {
- // Sort triples, etc.
- sortedOntologies = unsortedOntologies.toSorted(COLLECTION_CLASS, comparisonContext);
- if (sortedOntologies.size() != unsortedOntologies.size()) {
- System.err.printf("**** ontologies unexpectedly lost or gained during sorting: %d != %d%n",
- sortedOntologies.size(),
- unsortedOntologies.size());
- System.err.flush();
- }
-
- sortedTripleMap = unsortedTripleMap.toSorted(COLLECTION_CLASS, comparisonContext);
- compareSortedToUnsortedTripleMap(sortedTripleMap, unsortedTripleMap, "Turtle"); // TODO
-
- sortedBlankNodes = unsortedBlankNodes.toSorted(COLLECTION_CLASS, comparisonContext);
- if (sortedBlankNodes.size() != unsortedBlankNodes.size()) {
- System.err.printf("**** blank nodes unexpectedly lost or gained during sorting: %d != %d%n",
- sortedBlankNodes.size(),
- unsortedBlankNodes.size());
- System.err.flush();
- }
+ protected void writeSubjectSeparator(Writer out) {
+ // nothing to do here for Turtle
+ }
- super.endRDF();
- } catch (Throwable t) {
- throw new RDFHandlerException("unable to generate/write RDF output", t);
+ protected void writeSubjectTriples(Writer out, Resource subject) throws Exception {
+ SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(subject);
+ if (poMap == null) {
+ poMap = new SortedTurtlePredicateObjectMap();
+ }
+ if (subject instanceof BNode) {
+ if (inlineBlankNodes) {
+ if (objectBlankNodes.contains(subject)) {
+ out.write("[");
+ } else {
+ out.write("[]");
}
+ } else {
+ out.write("_:" + blankNodeNameMap.get(subject));
+ }
+ } else {
+ writeIri(out, (IRI) subject);
+ }
+ if (out instanceof IndentingWriter) {
+ IndentingWriter intendedOutput = (IndentingWriter) out;
+ intendedOutput.writeEOL();
+ intendedOutput.increaseIndentation();
+ } else {
+ out.write("\n");
}
- protected void writeHeader(Writer out, SortedTurtleObjectList importList, String[] leadingComments)
- throws Exception {
- // Write TopBraid-specific special comments, if any.
- if ((baseIri != null) || (importList.size() >= 1)) {
- // Write the base IRI, if any.
- if (baseIri != null) {
- output.write("# baseURI: " + baseIri);
- output.writeEOL();
- }
- // Write ontology imports, if any.
- for (Value anImport : importList) {
- output.write("# imports: " + anImport.stringValue());
- output.writeEOL();
- }
- output.writeEOL();
+ // Write predicate/object pairs rendered first.
+ for (IRI predicate : firstPredicates) {
+ if (poMap.containsKey(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ if (values != null) { // make a copy so we don't delete anything from the original
+ values = (SortedTurtleObjectList) values.clone();
}
-
- // Write leading comments, if any.
- if ((leadingComments != null) && (leadingComments.length >= 1)) {
- output.write("####"); output.writeEOL();
- for (String line : leadingComments) {
- output.write("## " + line); output.writeEOL();
+ List valuesList = new ArrayList<>();
+ if (values != null && !values.isEmpty()) {
+ if (predicate == Constants.RDF_TYPE) {
+ for (IRI preferredType : preferredRdfTypes) {
+ if (values.contains(preferredType)) {
+ valuesList.add(preferredType);
+ values.remove(preferredType);
+ }
}
- output.write("####"); output.writeEOL();
- output.writeEOL();
- }
-
- // Write the base IRI, if any.
- if (baseIri != null) {
- output.write("@base <" + baseIri + "> ."); output.writeEOL();
- }
-
- // Write out prefixes and namespaces IRIs.
- if (namespaceTable.size() > 0) {
- Set prefixes = new TreeSet<>(namespaceTable.keySet());
- for (String prefix : prefixes) {
- if (USE_GENERATED_PREFIXES || !generatedNamespaceTable.containsKey(prefix)) {
- output.write("@prefix " + prefix + ": <" + namespaceTable.get(prefix) + "> ."); output.writeEOL();
- }
+ if (suppressNamedIndividuals) {
+ values.remove(Constants.owlNamedIndividual);
}
- output.writeEOL();
+ }
+ valuesList.addAll(values);
}
+ if (!valuesList.isEmpty()) {
+ writePredicateAndObjectValues(out, predicate, valuesList);
+ }
+ }
}
- protected void writeSubjectSeparator(Writer out) {
- // nothing to do here for Turtle
+ // Write other predicate/object pairs.
+ for (IRI predicate : poMap.sortedKeys()) {
+ if (!firstPredicates.contains(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ writePredicateAndObjectValues(out, predicate, values);
+ }
}
- protected void writeSubjectTriples(Writer out, Resource subject) throws Exception {
- SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(subject);
- if (poMap == null) {
- poMap = new SortedTurtlePredicateObjectMap();
+ // Close statement
+ boolean unindentBlankNode = inlineBlankNodes &&
+ (subject instanceof BNode) &&
+ objectBlankNodes.contains(subject);
+
+ if (unindentBlankNode) {
+ if (out instanceof IndentingWriter) {
+ IndentingWriter intendedOutput = (IndentingWriter) out;
+ intendedOutput.writeEOL();
+ intendedOutput.decreaseIndentation();
+ } else {
+ out.write("\n");
+ }
+ out.write("]");
+ if (out instanceof IndentingWriter) {
+ IndentingWriter indentedOutput = (IndentingWriter) out;
+ indentedOutput.writeEOL();
+ } else {
+ out.write("\n");
+ }
+ } else {
+ out.write(".");
+ if (out instanceof IndentingWriter) {
+ IndentingWriter indentedOutput = (IndentingWriter) out;
+ indentedOutput.writeEOL();
+ indentedOutput.decreaseIndentation();
+ indentedOutput.writeEOL(); // blank line
+ } else {
+ out.write("\n\n");
+ }
+ }
+ }
+
+ protected void writePredicateAndObjectValues(Writer out, IRI predicate, Collection values) throws Exception {
+ writePredicate(out, predicate);
+ if (values.size() == 1) {
+ out.write(" ");
+ writeObject(out, (Value) values.toArray()[0]);
+ out.write(" ;");
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ } else {
+ out.write("\n");
+ }
+ } else if (values.size() > 1) {
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ output.increaseIndentation();
+ } else {
+ out.write("\n");
+ }
+ int numValues = values.size();
+ int valueIndex = 0;
+ for (Value value : values) {
+ valueIndex += 1;
+ writeObject(out, value);
+ if (valueIndex < numValues) {
+ out.write(" ,");
}
- if (subject instanceof BNode) {
- if (inlineBlankNodes) {
- if (objectBlankNodes.contains(subject)) {
- out.write("[");
- } else {
- out.write("[]");
- }
- } else {
- out.write("_:" + blankNodeNameMap.get(subject));
- }
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
} else {
- writeIri(out, (IRI) subject);
+ out.write("\n");
}
+ }
+ out.write(";");
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ output.decreaseIndentation();
+ } else {
+ out.write("\n");
+ }
+ }
+ }
+
+ protected void writePredicate(Writer out, IRI predicate) throws Exception {
+ out.write(
+ convertVerbIriToString(
+ predicate,
+ USE_GENERATED_PREFIXES,
+ true,
+ false));
+ }
+
+ protected void writeIri(Writer out, IRI iri) throws Exception {
+ out.write(
+ convertIriToString(
+ iri,
+ USE_GENERATED_PREFIXES,
+ true,
+ false));
+ }
+
+ protected void writeObject(Writer out, Value value) throws Exception {
+ if (value instanceof BNode) {
+ writeObject(out, (BNode) value);
+ } else if (value instanceof IRI) {
+ writeObject(out, (IRI) value);
+ } else if (value instanceof Literal) {
+ writeObject(out, (Literal) value);
+ } else {
+ out.write("\"" + value.stringValue() + "\"");
+ out.write(" ");
+ }
+ }
+
+ protected void writeObject(Writer out, BNode bnode) throws Exception {
+ if (inlineBlankNodes) {
+ if (isCollection(comparisonContext, bnode, COLLECTION_CLASS)) {
+ // Open parentheses
+ out.write("(");
if (out instanceof IndentingWriter) {
- IndentingWriter intendedOutput = (IndentingWriter) out;
- intendedOutput.writeEOL();
- intendedOutput.increaseIndentation();
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ output.increaseIndentation();
} else {
- out.write("\n");
+ out.write("\n");
}
- // Write predicate/object pairs rendered first.
- for (IRI predicate : firstPredicates) {
- if (poMap.containsKey(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- if (values != null) { // make a copy so we don't delete anything from the original
- values = (SortedTurtleObjectList) values.clone();
- }
- List valuesList = new ArrayList<>();
- if (values != null && !values.isEmpty()) {
- if (predicate == Constants.RDF_TYPE) {
- for (IRI preferredType : preferredRdfTypes) {
- if (values.contains(preferredType)) {
- valuesList.add(preferredType);
- values.remove(preferredType);
- }
- }
- }
- valuesList.addAll(values);
- }
- if (! valuesList.isEmpty()) {
- writePredicateAndObjectValues(out, predicate, valuesList);
- }
- }
+ // Write collection members
+ for (Value member : getCollectionMembers(unsortedTripleMap, bnode, COLLECTION_CLASS, comparisonContext)) {
+ writeObject(out, member);
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ } else {
+ out.write("\n");
+ }
}
- // Write other predicate/object pairs.
- for (IRI predicate : poMap.sortedKeys()) {
- if (!firstPredicates.contains(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- writePredicateAndObjectValues(out, predicate, values);
- }
+ // Close parentheses
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.decreaseIndentation();
+ out.write(")");
+ } else {
+ out.write(")");
+ }
+ } else { // not a collection
+ SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(bnode);
+ if (poMap == null) {
+ poMap = new SortedTurtlePredicateObjectMap();
}
- // Close statement
- boolean unindentBlankNode = inlineBlankNodes &&
- (subject instanceof BNode) &&
- objectBlankNodes.contains(subject);
-
- if (unindentBlankNode) {
- if (out instanceof IndentingWriter) {
- IndentingWriter intendedOutput = (IndentingWriter) out;
- intendedOutput.writeEOL();
- intendedOutput.decreaseIndentation();
- } else {
- out.write("\n");
- }
- out.write("]");
- if (out instanceof IndentingWriter) {
- IndentingWriter indentedOutput = (IndentingWriter) out;
- indentedOutput.writeEOL();
- } else {
- out.write("\n");
- }
+ // Open brackets
+ out.write("[");
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.writeEOL();
+ output.increaseIndentation();
} else {
- out.write(".");
- if (out instanceof IndentingWriter) {
- IndentingWriter indentedOutput = (IndentingWriter) out;
- indentedOutput.writeEOL();
- indentedOutput.decreaseIndentation();
- indentedOutput.writeEOL(); // blank line
- } else {
- out.write("\n\n");
- }
+ out.write("\n");
}
- }
- protected void writePredicateAndObjectValues(Writer out, IRI predicate, Collection values) throws Exception {
- writePredicate(out, predicate);
- if (values.size() == 1) {
- out.write(" ");
- writeObject(out, (Value) values.toArray()[0]);
- out.write(" ;");
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- } else {
- out.write("\n");
- }
- } else if (values.size() > 1) {
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- output.increaseIndentation();
- } else {
- out.write("\n");
- }
- int numValues = values.size();
- int valueIndex = 0;
- for (Value value : values) {
- valueIndex += 1;
- writeObject(out, value);
- if (valueIndex < numValues) { out.write(" ,"); }
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- } else {
- out.write("\n");
- }
- }
- out.write(";");
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- output.decreaseIndentation();
- } else {
- out.write("\n");
- }
+ // Write predicate/object pairs rendered first.
+ for (IRI predicate : firstPredicates) {
+ if (poMap.containsKey(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ writePredicateAndObjectValues(out, predicate, values);
+ }
}
- }
- protected void writePredicate(Writer out, IRI predicate) throws Exception {
- out.write(
- convertVerbIriToString(
- predicate,
- USE_GENERATED_PREFIXES,
- true,
- false));
- }
-
- protected void writeIri(Writer out, IRI iri) throws Exception {
- out.write(
- convertIriToString(
- iri,
- USE_GENERATED_PREFIXES,
- true,
- false));
- }
+ // Write other predicate/object pairs.
+ for (IRI predicate : poMap.sortedKeys()) {
+ if (!firstPredicates.contains(predicate)) {
+ SortedTurtleObjectList values = poMap.get(predicate);
+ writePredicateAndObjectValues(out, predicate, values);
+ }
+ }
- protected void writeObject(Writer out, Value value) throws Exception {
- if (value instanceof BNode) {
- writeObject(out, (BNode) value);
- } else if (value instanceof IRI) {
- writeObject(out, (IRI)value);
- } else if (value instanceof Literal) {
- writeObject(out, (Literal)value);
+ // Close brackets
+ if (out instanceof IndentingWriter) {
+ IndentingWriter output = (IndentingWriter) out;
+ output.decreaseIndentation();
+ out.write("]");
} else {
- out.write("\"" + value.stringValue() + "\"");
- out.write(" ");
+ out.write("]");
}
+ }
+ } else { // no inlining of blank nodes
+ if (unsortedTripleMap.containsKey(bnode)) {
+ out.write("_:" + blankNodeNameMap.get(bnode));
+ } else {
+ System.out.println("**** blank node not a subject: " + bnode.stringValue());
+ System.out.flush();
+ out.write("[]"); // last resort - this should never happen
+ }
}
-
- protected void writeObject(Writer out, BNode bnode) throws Exception {
- if (inlineBlankNodes) {
- if (isCollection(comparisonContext, bnode, COLLECTION_CLASS)) {
- // Open parentheses
- out.write("(");
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- output.increaseIndentation();
- } else {
- out.write("\n");
- }
-
- // Write collection members
- for (Value member : getCollectionMembers(unsortedTripleMap, bnode, COLLECTION_CLASS, comparisonContext)) {
- writeObject(out, member);
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- } else {
- out.write("\n");
- }
- }
-
- // Close parentheses
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.decreaseIndentation();
- out.write(")");
- } else {
- out.write(")");
- }
- } else { // not a collection
- SortedTurtlePredicateObjectMap poMap = sortedTripleMap.get(bnode);
- if (poMap == null) { poMap = new SortedTurtlePredicateObjectMap(); }
-
- // Open brackets
- out.write("[");
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.writeEOL();
- output.increaseIndentation();
- } else {
- out.write("\n");
- }
-
- // Write predicate/object pairs rendered first.
- for (IRI predicate : firstPredicates) {
- if (poMap.containsKey(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- writePredicateAndObjectValues(out, predicate, values);
- }
- }
-
- // Write other predicate/object pairs.
- for (IRI predicate : poMap.sortedKeys()) {
- if (!firstPredicates.contains(predicate)) {
- SortedTurtleObjectList values = poMap.get(predicate);
- writePredicateAndObjectValues(out, predicate, values);
- }
- }
-
- // Close brackets
- if (out instanceof IndentingWriter) {
- IndentingWriter output = (IndentingWriter)out;
- output.decreaseIndentation();
- out.write("]");
- } else {
- out.write("]");
- }
- }
- } else { // no inlining of blank nodes
- if (unsortedTripleMap.containsKey(bnode)) {
- out.write("_:" + blankNodeNameMap.get(bnode));
- } else {
- System.out.println("**** blank node not a subject: " + bnode.stringValue()); System.out.flush();
- out.write("[]"); // last resort - this should never happen
- }
- }
+ }
+
+ protected void writeObject(Writer out, IRI iri) throws Exception {
+ writeIri(out, iri);
+ }
+
+ protected void writeObject(Writer out, Literal literal) throws Exception {
+ if (literal == null) {
+ out.write("null");
+ } else if (literal.getLanguage().isPresent() || ((overrideStringLanguage != null) && (literal.getDatatype()
+ .stringValue().equals(Constants.xsString.stringValue())))) {
+ writeString(out, literal.stringValue());
+ String lang = overrideStringLanguage == null ? literal.getLanguage().get() : overrideStringLanguage;
+ out.write("@" + lang);
+ } else if (literal.getDatatype() != null) {
+ boolean useExplicit =
+ (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(Constants.xsString.equals(literal.getDatatype())
+ || Constants.rdfLangString.equals(literal.getDatatype()));
+ writeString(out, literal.stringValue());
+ if (useExplicit) {
+ out.write("^^");
+ writeIri(out, literal.getDatatype());
+ }
+ } else {
+ writeString(out, literal.stringValue());
}
+ }
- protected void writeObject(Writer out, IRI iri) throws Exception {
- writeIri(out, iri);
+ protected void writeString(Writer out, String str) throws Exception {
+ if (str == null) {
+ return;
}
-
- protected void writeObject(Writer out, Literal literal) throws Exception {
- if (literal == null) {
- out.write("null");
- } else if (literal.getLanguage().isPresent() || ((overrideStringLanguage != null) && (literal.getDatatype().stringValue().equals(Constants.xsString.stringValue())))) {
- writeString(out, literal.stringValue());
- String lang = overrideStringLanguage == null ? literal.getLanguage().get() : overrideStringLanguage;
- out.write("@" + lang);
- } else if (literal.getDatatype() != null) {
- boolean useExplicit = (stringDataTypeOption == StringDataTypeOptions.EXPLICIT) || !(Constants.xsString.equals(literal.getDatatype()) || Constants.rdfLangString.equals(literal.getDatatype()));
- writeString(out, literal.stringValue());
- if (useExplicit) {
- out.write("^^");
- writeIri(out, literal.getDatatype());
- }
- } else {
- writeString(out, literal.stringValue());
+ if (TextUtils.isMultilineString(str)) { // multi-line string
+ if (str.contains("\"")) { // string contains double quote chars
+ if (str.contains("'")) { // string contains both single and double quote chars
+ out.write("\"\"\"");
+ out.write(escapeString(str).replaceAll("\"", "\\\\\""));
+ out.write("\"\"\"");
+ } else { // string contains double quote chars but no single quote chars
+ out.write("'''");
+ out.write(escapeString(str));
+ out.write("'''");
}
- }
-
- protected void writeString(Writer out, String str) throws Exception {
- if (str == null) { return; }
- if (TextUtils.isMultilineString(str)) { // multi-line string
- if (str.contains("\"")) { // string contains double quote chars
- if (str.contains("'")) { // string contains both single and double quote chars
- out.write("\"\"\"");
- out.write(escapeString(str).replaceAll("\"", "\\\\\""));
- out.write("\"\"\"");
- } else { // string contains double quote chars but no single quote chars
- out.write("'''");
- out.write(escapeString(str));
- out.write("'''");
- }
- } else { // string has no double quote chars
- out.write("\"\"\"");
- out.write(escapeString(str));
- out.write("\"\"\"");
- }
- } else { // single-line string
- if (str.contains("\"")) { // string contains double quote chars
- if (str.contains("'")) { // string contains both single and double quote chars
- out.write("\"");
- out.write(escapeString(str).replaceAll("\"", "\\\\\""));
- out.write("\"");
- } else { // string contains double quote chars but no single quote chars
- out.write("'");
- out.write(escapeString(str));
- out.write("'");
- }
- } else { // string has no double quote chars
- out.write("\"");
- out.write(escapeString(str));
- out.write("\"");
- }
+ } else { // string has no double quote chars
+ out.write("\"\"\"");
+ out.write(escapeString(str));
+ out.write("\"\"\"");
+ }
+ } else { // single-line string
+ if (str.contains("\"")) { // string contains double quote chars
+ if (str.contains("'")) { // string contains both single and double quote chars
+ out.write("\"");
+ out.write(escapeString(str).replaceAll("\"", "\\\\\""));
+ out.write("\"");
+ } else { // string contains double quote chars but no single quote chars
+ out.write("'");
+ out.write(escapeString(str));
+ out.write("'");
}
+ } else { // string has no double quote chars
+ out.write("\"");
+ out.write(escapeString(str));
+ out.write("\"");
+ }
}
-
- protected void writeFooter(Writer out, String[] trailingComments) throws Exception {
- // Write traiing comments, if any.
- if ((trailingComments != null) && (trailingComments.length >= 1)) {
- output.write("####"); output.writeEOL();
- for (String line : trailingComments) {
- output.write("## " + line); output.writeEOL();
- }
- output.write("####"); output.writeEOL();
- }
+ }
+
+ protected void writeFooter(Writer out, String[] trailingComments) throws Exception {
+ // Write traiing comments, if any.
+ if ((trailingComments != null) && (trailingComments.length >= 1)) {
+ output.write("####");
+ output.writeEOL();
+ for (String line : trailingComments) {
+ output.write("## " + line);
+ output.writeEOL();
+ }
+ output.write("####");
+ output.writeEOL();
}
+ }
- private String escapeString(String str) {
- if (str == null) { return null; }
- return str.replaceAll("\\\\", "\\\\\\\\");
+ private String escapeString(String str) {
+ if (str == null) {
+ return null;
}
+ return str.replaceAll("\\\\", "\\\\\\\\");
+ }
}