diff --git a/build.sbt b/build.sbt
index d55a8bb..8d21ef7 100644
--- a/build.sbt
+++ b/build.sbt
@@ -2,7 +2,7 @@ organization := "org.geneontology"
name := "owl-diff"
-version := "1.2.2"
+version := "1.3-SNAPSHOT"
publishMavenStyle := true
@@ -22,7 +22,7 @@ homepage := Some(url("https://github.com/balhoff/owl-diff"))
scalaVersion := "2.13.15"
-crossScalaVersions := Seq("2.12.20", "2.13.15")
+crossScalaVersions := Seq("2.13.15")
scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")
diff --git a/src/main/scala/org/geneontology/owl/differ/Differ.scala b/src/main/scala/org/geneontology/owl/differ/Differ.scala
index 52bda1e..34a0788 100644
--- a/src/main/scala/org/geneontology/owl/differ/Differ.scala
+++ b/src/main/scala/org/geneontology/owl/differ/Differ.scala
@@ -4,7 +4,7 @@ import org.semanticweb.owlapi.model._
import org.semanticweb.owlapi.model.parameters.Imports
import org.semanticweb.owlapi.util.AxiomSubjectProvider
-import scala.collection.JavaConverters._
+import scala.jdk.CollectionConverters._
object Differ {
diff --git a/src/main/scala/org/geneontology/owl/differ/render/BasicDiffRenderer.scala b/src/main/scala/org/geneontology/owl/differ/render/BasicDiffRenderer.scala
index 3e214f5..fd26023 100644
--- a/src/main/scala/org/geneontology/owl/differ/render/BasicDiffRenderer.scala
+++ b/src/main/scala/org/geneontology/owl/differ/render/BasicDiffRenderer.scala
@@ -1,40 +1,69 @@
package org.geneontology.owl.differ.render
+import org.apache.commons.io.output.ByteArrayOutputStream
import org.geneontology.owl.differ.Differ.BasicDiff
import org.geneontology.owl.differ.ShortFormFunctionalSyntaxObjectRenderer
import org.semanticweb.owlapi.model.{OWLImportsDeclaration, OWLObject}
import org.semanticweb.owlapi.util.ShortFormProvider
+import java.io.{OutputStream, PrintWriter, Writer}
+import java.nio.charset.StandardCharsets
+import scala.util.Using
+
object BasicDiffRenderer {
- def renderPlain(diff: BasicDiff): String = {
- if (diff.isEmpty) "Ontologies are identical"
- else {
- val (left, right) = groups(diff)
- val leftRendered = left.map(_.item.toString)
- val rightRendered = right.map(_.item.toString)
- if ((diff.left.id == diff.right.id) || (diff.left.id.isAnonymous && diff.right.id.isAnonymous)) format(leftRendered, rightRendered)
- else format(leftRendered + diff.left.id.toString, rightRendered + diff.right.id.toString)
+ def renderPlainStream(diff: BasicDiff, stream: OutputStream): Unit =
+ Using.resource(new PrintWriter(stream)) { writer =>
+ renderPlainWriter(diff, writer)
}
- }
- def render(diff: BasicDiff, shortFormProvider: ShortFormProvider): String = {
- if (diff.isEmpty) "Ontologies are identical"
- else {
- val renderer = new ShortFormFunctionalSyntaxObjectRenderer(shortFormProvider)
- val (left, right) = groups(diff)
- val leftRendered = left.map {
- case OWLObjectItem(item) => renderer.render(item)
- case OWLImportItem(item) => item.toString
+ def renderPlainWriter(diff: BasicDiff, givenWriter: Writer): Unit =
+ Using.resource(new PrintWriter(givenWriter)) { writer =>
+ if (diff.isEmpty) writer.println("Ontologies are identical")
+ else {
+ val (left, right) = groups(diff)
+ val leftRendered = left.map(_.item.toString)
+ val rightRendered = right.map(_.item.toString)
+ if ((diff.left.id == diff.right.id) || (diff.left.id.isAnonymous && diff.right.id.isAnonymous)) format(leftRendered, rightRendered, writer)
+ else format(leftRendered + diff.left.id.toString, rightRendered + diff.right.id.toString, writer)
}
- val rightRendered = right.map {
- case OWLObjectItem(item) => renderer.render(item)
- case OWLImportItem(item) => item.toString
+ }
+
+ def renderPlain(diff: BasicDiff): String =
+ Using.resource(new ByteArrayOutputStream()) { stream =>
+ renderPlainStream(diff, stream)
+ stream.toString(StandardCharsets.UTF_8)
+ }
+
+ def renderStream(diff: BasicDiff, shortFormProvider: ShortFormProvider, stream: OutputStream): Unit =
+ Using.resource(new PrintWriter(stream)) { writer =>
+ renderWriter(diff, shortFormProvider, writer)
+ }
+
+ def renderWriter(diff: BasicDiff, shortFormProvider: ShortFormProvider, givenWriter: Writer): Unit =
+ Using.resource(new PrintWriter(givenWriter)) { writer =>
+ if (diff.isEmpty) writer.println("Ontologies are identical")
+ else {
+ val renderer = new ShortFormFunctionalSyntaxObjectRenderer(shortFormProvider)
+ val (left, right) = groups(diff)
+ val leftRendered = left.map {
+ case OWLObjectItem(item) => renderer.render(item)
+ case OWLImportItem(item) => item.toString
+ }
+ val rightRendered = right.map {
+ case OWLObjectItem(item) => renderer.render(item)
+ case OWLImportItem(item) => item.toString
+ }
+ if ((diff.left.id == diff.right.id) || (diff.left.id.isAnonymous && diff.right.id.isAnonymous)) format(leftRendered, rightRendered, writer)
+ else format(leftRendered + diff.left.id.toString, rightRendered + diff.right.id.toString, writer)
}
- if ((diff.left.id == diff.right.id) || (diff.left.id.isAnonymous && diff.right.id.isAnonymous)) format(leftRendered, rightRendered)
- else format(leftRendered + diff.left.id.toString, rightRendered + diff.right.id.toString)
}
- }
+
+ def render(diff: BasicDiff, shortFormProvider: ShortFormProvider): String =
+ Using.resource(new ByteArrayOutputStream()) { stream =>
+ renderStream(diff, shortFormProvider, stream)
+ stream.toString(StandardCharsets.UTF_8)
+ }
private def groups(diff: BasicDiff): (Set[OWLItem[_]], Set[OWLItem[_]]) = {
val leftUnique: Set[OWLItem[_]] = diff.left.imports.map(OWLImportItem) ++ diff.left.annotations.map(OWLObjectItem) ++ diff.left.axioms.map(OWLObjectItem)
@@ -42,15 +71,15 @@ object BasicDiffRenderer {
(leftUnique, rightUnique)
}
- private def format(removedLines: Set[String], addedLines: Set[String]): String = {
+ private def format(removedLines: Set[String], addedLines: Set[String], writer: PrintWriter): Unit = {
import org.geneontology.owl.differ.Util.replaceNewlines
- val removedSorted = removedLines.map(replaceNewlines).map(ax => s"- $ax").toSeq.sorted.mkString("\n")
- val addedSorted = addedLines.map(replaceNewlines).map(ax => s"+ $ax").toSeq.sorted.mkString("\n")
- s"""${removedLines.size} axioms in left ontology but not in right ontology:
-$removedSorted${if (removedSorted.nonEmpty) "\n" else ""}
-${addedLines.size} axioms in right ontology but not in left ontology:
-$addedSorted
-"""
+ val removedSorted = removedLines.map(replaceNewlines).map(ax => s"- $ax").toSeq.sorted
+ val addedSorted = addedLines.map(replaceNewlines).map(ax => s"+ $ax").toSeq.sorted
+ writer.println(s"${removedLines.size} axioms in left ontology but not in right ontology:")
+ removedSorted.foreach(writer.println)
+ writer.println()
+ writer.println(s"${addedLines.size} axioms in right ontology but not in left ontology:")
+ addedSorted.foreach(writer.println)
}
private sealed trait OWLItem[T] {
diff --git a/src/main/scala/org/geneontology/owl/differ/render/HTMLDiffRenderer.scala b/src/main/scala/org/geneontology/owl/differ/render/HTMLDiffRenderer.scala
index 4b57747..a31edcc 100644
--- a/src/main/scala/org/geneontology/owl/differ/render/HTMLDiffRenderer.scala
+++ b/src/main/scala/org/geneontology/owl/differ/render/HTMLDiffRenderer.scala
@@ -1,6 +1,7 @@
package org.geneontology.owl.differ.render
import com.google.common.base.Optional
+import org.apache.commons.io.output.ByteArrayOutputStream
import org.apache.commons.text.StringEscapeUtils
import org.geneontology.owl.differ.Differ._
import org.geneontology.owl.differ.ManchesterSyntaxOWLObjectRenderer
@@ -10,7 +11,10 @@ import org.semanticweb.owlapi.apibinding.OWLManager
import org.semanticweb.owlapi.model._
import org.semanticweb.owlapi.util.{AnnotationValueShortFormProvider, SimpleIRIShortFormProvider, SimpleShortFormProvider}
-import scala.collection.JavaConverters._
+import java.io.{OutputStream, PrintWriter, Writer}
+import java.nio.charset.StandardCharsets
+import scala.jdk.CollectionConverters._
+import scala.util.Using
object HTMLDiffRenderer {
@@ -18,123 +22,141 @@ object HTMLDiffRenderer {
private val rdfsLabel = factory.getRDFSLabel
- def render(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider): String = {
- val shortFormProvider = new HTMLSafeShortFormProvider(new AnnotationValueShortFormProvider(renderingOntologyProvider, new SimpleShortFormProvider(), new HTMLSafeIRIShortFormProvider(new SimpleIRIShortFormProvider()), List(rdfsLabel).asJava, Map.empty[OWLAnnotationProperty, java.util.List[String]].asJava))
- val htmlLinkShortFormProvider = new HTMLLinkShortFormProvider(shortFormProvider)
- val labelRenderer = new ManchesterSyntaxOWLObjectRenderer()
- labelRenderer.setShortFormProvider(shortFormProvider)
- val htmlRenderer = new ManchesterSyntaxOWLObjectRenderer()
- htmlRenderer.setShortFormProvider(htmlLinkShortFormProvider)
- val groupsToLabels: Map[Grouping, String] = diff.groups.keys.map {
- case group @ IRIGrouping(iri) => group -> labelRenderer.render(factory.getOWLClass(iri)) // send as OWLClass because labels aren't rendered for IRIs
- case group @ GCIGrouping => group -> "GCIs"
- case group @ RuleGrouping => group -> "Rules"
- case group @ NonIRIGrouping(obj) => group -> labelRenderer.render(obj)
- case group @ OntologyImportGrouping => group -> "Ontology imports"
- case group @ OntologyAnnotationGrouping => group -> "Ontology annotations"
- }.toMap
- val sortedGroups = OntologyImportGrouping :: OntologyAnnotationGrouping :: (diff.groups - OntologyImportGrouping - OntologyAnnotationGrouping).keys.toList.sortBy(groupsToLabels)
-
- def htmlForObject(obj: OWLObject): String = {
- val (annotations, objToRender) = obj match {
- case hasAnnotations: HasAnnotations =>
- val inner = hasAnnotations.getAnnotations.asScala.map(htmlForObject(_)).mkString("\n")
- val objWithoutAnnotations = obj match {
- case ax: OWLAxiom => ax.getAxiomWithoutAnnotations
- case ann: OWLAnnotation => factory.getOWLAnnotation(ann.getProperty, ann.getValue)
- case _ => obj
- }
- s"
" -> objWithoutAnnotations
- case _ => "" -> obj
+ def renderWriter(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider, givenWriter: Writer): Unit =
+ Using.resource(new PrintWriter(givenWriter)) { writer =>
+ val shortFormProvider = new HTMLSafeShortFormProvider(new AnnotationValueShortFormProvider(renderingOntologyProvider, new SimpleShortFormProvider(), new HTMLSafeIRIShortFormProvider(new SimpleIRIShortFormProvider()), List(rdfsLabel).asJava, Map.empty[OWLAnnotationProperty, java.util.List[String]].asJava))
+ val htmlLinkShortFormProvider = new HTMLLinkShortFormProvider(shortFormProvider)
+ val labelRenderer = new ManchesterSyntaxOWLObjectRenderer()
+ labelRenderer.setShortFormProvider(shortFormProvider)
+ val htmlRenderer = new ManchesterSyntaxOWLObjectRenderer()
+ htmlRenderer.setShortFormProvider(htmlLinkShortFormProvider)
+ val groupsToLabels: Map[Grouping, String] = diff.groups.keys.map {
+ case group @ IRIGrouping(iri) => group -> labelRenderer.render(factory.getOWLClass(iri)) // send as OWLClass because labels aren't rendered for IRIs
+ case group @ GCIGrouping => group -> "GCIs"
+ case group @ RuleGrouping => group -> "Rules"
+ case group @ NonIRIGrouping(obj) => group -> labelRenderer.render(obj)
+ case group @ OntologyImportGrouping => group -> "Ontology imports"
+ case group @ OntologyAnnotationGrouping => group -> "Ontology annotations"
+ }.toMap
+ val sortedGroups = OntologyImportGrouping :: OntologyAnnotationGrouping :: (diff.groups - OntologyImportGrouping - OntologyAnnotationGrouping).keys.toList.sortBy(groupsToLabels)
+ val header =
+ s"""
+
+
+
+
+
+
+ OWL diff
+
+
+
+ Ontology comparison
+ Left
+
+ - Ontology IRI: ${optionalIRI(diff.left.getOntologyIRI)}
+ - Version IRI: ${optionalIRI(diff.left.getVersionIRI)}
+ - Loaded from: ${StringEscapeUtils.escapeHtml4(diff.leftSource.toQuotedString)}
+
+ Right
+
+ - Ontology IRI: ${optionalIRI(diff.right.getOntologyIRI)}
+ - Version IRI: ${optionalIRI(diff.right.getVersionIRI)}
+ - Loaded from: ${StringEscapeUtils.escapeHtml4(diff.rightSource.toQuotedString)}
+
+ """
+ writer.println(header)
+
+ def htmlForObject(obj: OWLObject): String = {
+ val (annotations, objToRender) = obj match {
+ case hasAnnotations: HasAnnotations =>
+ val inner = hasAnnotations.getAnnotations.asScala.map(htmlForObject(_)).mkString("\n")
+ val objWithoutAnnotations = obj match {
+ case ax: OWLAxiom => ax.getAxiomWithoutAnnotations
+ case ann: OWLAnnotation => factory.getOWLAnnotation(ann.getProperty, ann.getValue)
+ case _ => obj
+ }
+ s"" -> objWithoutAnnotations
+ case _ => "" -> obj
+ }
+ s""" ${htmlRenderer.render(objToRender)} $annotations"""
}
- s"""${htmlRenderer.render(objToRender)} $annotations """
- }
- def changeList(header: String, axioms: Seq[OWLObject]) =
- s"""
-
+ def changeList(header: String, axioms: Seq[OWLObject]) =
+ s"""
+
- ${axioms.map(htmlForObject).mkString("\n")}
+ ${axioms.map(htmlForObject).mkString("\n")}
- """
-
- def frameElement(header: String, headerIRI: String, removedList: String, addedList: String) =
- s"""
-
$header $headerIRI
- $removedList
- $addedList
- """
-
- val content = (for {
- group <- sortedGroups
- } yield {
- def sortKey(modifiedItem: ModifiedOntologyContent[_]): String = modifiedItem match {
- case ModifiedOntologyAnnotation(item, _) => item.toString
- case ModifiedImport(item, _) => item.toString
- case ModifiedAxiom(item, _) => item.getAxiomType match {
- case AxiomType.DECLARATION => s"1-${item.toString}"
- case _ => s"2-${item.toString}"
+ """
+
+ def frameElement(header: String, headerIRI: String, removedList: String, addedList: String) =
+ s"""
+
$header
+ $headerIRI
+
+ $removedList
+ $addedList
+
+ """
+
+ for {
+ group <- sortedGroups
+ } yield {
+ def sortKey(modifiedItem: ModifiedOntologyContent[_]): String = modifiedItem match {
+ case ModifiedOntologyAnnotation(item, _) => item.toString
+ case ModifiedImport(item, _) => item.toString
+ case ModifiedAxiom(item, _) => item.getAxiomType match {
+ case AxiomType.DECLARATION => s"1-${item.toString}"
+ case _ => s"2-${item.toString}"
+ }
}
- }
- val removed = diff.groups(group).filterNot(_.added).toSeq.sortBy(sortKey)
- val added = diff.groups(group).filter(_.added).toSeq.sortBy(sortKey)
- val removedList = if (removed.nonEmpty) changeList("Removed", removed.map(_.owlObject)) else ""
- val addedList = if (added.nonEmpty) changeList("Added", added.map(_.owlObject)) else ""
- val header = groupsToLabels(group)
- val headerIRI = group match {
- case IRIGrouping(iri) => s"- $iri"
- case _ => ""
+ writer.println()
+ val removed = diff.groups(group).filterNot(_.added).toSeq.sortBy(sortKey)
+ val added = diff.groups(group).filter(_.added).toSeq.sortBy(sortKey)
+ val removedList = if (removed.nonEmpty) changeList("Removed", removed.map(_.owlObject)) else ""
+ val addedList = if (added.nonEmpty) changeList("Added", added.map(_.owlObject)) else ""
+ val header = groupsToLabels(group)
+ val headerIRI = group match {
+ case IRIGrouping(iri) => s"- $iri"
+ case _ => ""
+ }
+ val frame = frameElement(header, headerIRI, removedList, addedList)
+ writer.println(frame)
}
- frameElement(header, headerIRI, removedList, addedList)
- }).mkString("\n\n")
- s"""
-
-
-
-
-
-
- OWL diff
-
-
-
-Ontology comparison
-Left
-
-- Ontology IRI: ${optionalIRI(diff.left.getOntologyIRI)}
-- Version IRI: ${optionalIRI(diff.left.getVersionIRI)}
-- Loaded from: ${StringEscapeUtils.escapeHtml4(diff.leftSource.toQuotedString)}
-
-Right
-
-- Ontology IRI: ${optionalIRI(diff.right.getOntologyIRI)}
-- Version IRI: ${optionalIRI(diff.right.getVersionIRI)}
-- Loaded from: ${StringEscapeUtils.escapeHtml4(diff.rightSource.toQuotedString)}
-
-$content
-
- """
- }
+ writer.println("")
+ }
+
+ def renderStream(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider, stream: OutputStream): Unit =
+ Using.resource(new PrintWriter(stream)) { writer =>
+ renderWriter(diff, renderingOntologyProvider, writer)
+ }
+
+ def render(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider): String =
+ Using.resource(new ByteArrayOutputStream()) { stream =>
+ renderStream(diff, renderingOntologyProvider, stream)
+ stream.toString(StandardCharsets.UTF_8)
+ }
private def optionalIRI(iriOpt: Optional[IRI]): String = (for {
iri <- iriOpt.toOption
diff --git a/src/main/scala/org/geneontology/owl/differ/render/MarkdownGroupedDiffRenderer.scala b/src/main/scala/org/geneontology/owl/differ/render/MarkdownGroupedDiffRenderer.scala
index 3171517..86e37ab 100644
--- a/src/main/scala/org/geneontology/owl/differ/render/MarkdownGroupedDiffRenderer.scala
+++ b/src/main/scala/org/geneontology/owl/differ/render/MarkdownGroupedDiffRenderer.scala
@@ -1,6 +1,7 @@
package org.geneontology.owl.differ.render
import com.google.common.base.Optional
+import org.apache.commons.io.output.ByteArrayOutputStream
import org.geneontology.owl.differ.Differ._
import org.geneontology.owl.differ.ManchesterSyntaxOWLObjectRenderer
import org.geneontology.owl.differ.Util.OptionalOption
@@ -10,7 +11,10 @@ import org.semanticweb.owlapi.io.OWLObjectRenderer
import org.semanticweb.owlapi.model._
import org.semanticweb.owlapi.util.AnnotationValueShortFormProvider
-import scala.collection.JavaConverters._
+import java.io.{OutputStream, PrintWriter, Writer}
+import java.nio.charset.StandardCharsets
+import scala.jdk.CollectionConverters._
+import scala.util.Using
object MarkdownGroupedDiffRenderer {
@@ -18,50 +22,25 @@ object MarkdownGroupedDiffRenderer {
private val rdfsLabel = factory.getRDFSLabel
- def render(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider): String = {
- val labelProvider = new AnnotationValueShortFormProvider(List(rdfsLabel).asJava, Map.empty[OWLAnnotationProperty, java.util.List[String]].asJava, renderingOntologyProvider)
- val markdownLinkProvider = new MarkdownLinkShortFormProvider(labelProvider)
- val labelRenderer = new ManchesterSyntaxOWLObjectRenderer()
- labelRenderer.setShortFormProvider(labelProvider)
- val markdownRenderer = new ManchesterSyntaxOWLObjectRenderer()
- markdownRenderer.setShortFormProvider(markdownLinkProvider)
- val groupsToLabels: Map[Grouping, String] = diff.groups.keys.map {
- case group @ IRIGrouping(iri) => group -> labelRenderer.render(factory.getOWLClass(iri)) // send as OWLClass because labels aren't rendered for IRIs
- case group @ GCIGrouping => group -> "GCIs"
- case group @ RuleGrouping => group -> "Rules"
- case group @ NonIRIGrouping(obj) => group -> labelRenderer.render(obj)
- case group @ OntologyImportGrouping => group -> "Ontology imports"
- case group @ OntologyAnnotationGrouping => group -> "Ontology annotations"
- }.toMap
- val sortedGroups = OntologyImportGrouping :: OntologyAnnotationGrouping :: (diff.groups - OntologyImportGrouping - OntologyAnnotationGrouping).keys.toList.sortBy(groupsToLabels)
- val content = (for {
- group <- sortedGroups
- } yield {
- def sortKey(modifiedItem: ModifiedOntologyContent[_]): String = {
- modifiedItem match {
- case ModifiedOntologyAnnotation(item, _) => item.toString
- case ModifiedImport(item, _) => item.toString
- case ModifiedAxiom(item, _) => item.getAxiomType match {
- case AxiomType.DECLARATION => s"1-${item.toString}"
- case _ => s"2-${item.toString}"
- }
- }
- }
-
- val removed = diff.groups(group).filterNot(_.added).toSeq.sortBy(sortKey)
- val added = diff.groups(group).filter(_.added).toSeq.sortBy(sortKey)
- val removedList = if (removed.nonEmpty) changeList("Removed", removed.map(_.owlObject).map(item => markdownForObject(item, markdownRenderer))) else ""
- val addedList = if (added.nonEmpty) changeList("Added", added.map(_.owlObject).map(item => markdownForObject(item, markdownRenderer))) else ""
- val header = groupsToLabels(group)
- val headerIRI = group match {
- case IRIGrouping(iri) => Some(iri.toString)
- case _ => None
- }
- frameElement(header, headerIRI, removedList, addedList)
- }).mkString("\n\n")
-
- val header =
- s"""# Ontology comparison
+ def renderWriter(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider, givenWriter: Writer): Unit = {
+ Using.resource(new PrintWriter(givenWriter)) { writer =>
+ val labelProvider = new AnnotationValueShortFormProvider(List(rdfsLabel).asJava, Map.empty[OWLAnnotationProperty, java.util.List[String]].asJava, renderingOntologyProvider)
+ val markdownLinkProvider = new MarkdownLinkShortFormProvider(labelProvider)
+ val labelRenderer = new ManchesterSyntaxOWLObjectRenderer()
+ labelRenderer.setShortFormProvider(labelProvider)
+ val markdownRenderer = new ManchesterSyntaxOWLObjectRenderer()
+ markdownRenderer.setShortFormProvider(markdownLinkProvider)
+ val groupsToLabels: Map[Grouping, String] = diff.groups.keys.map {
+ case group @ IRIGrouping(iri) => group -> labelRenderer.render(factory.getOWLClass(iri)) // send as OWLClass because labels aren't rendered for IRIs
+ case group @ GCIGrouping => group -> "GCIs"
+ case group @ RuleGrouping => group -> "Rules"
+ case group @ NonIRIGrouping(obj) => group -> labelRenderer.render(obj)
+ case group @ OntologyImportGrouping => group -> "Ontology imports"
+ case group @ OntologyAnnotationGrouping => group -> "Ontology annotations"
+ }.toMap
+ val sortedGroups = OntologyImportGrouping :: OntologyAnnotationGrouping :: (diff.groups - OntologyImportGrouping - OntologyAnnotationGrouping).keys.toList.sortBy(groupsToLabels)
+ val header =
+ s"""# Ontology comparison
## Left
- Ontology IRI: ${optionalIRI(diff.left.getOntologyIRI)}
@@ -72,9 +51,49 @@ object MarkdownGroupedDiffRenderer {
- Ontology IRI: ${optionalIRI(diff.right.getOntologyIRI)}
- Version IRI: ${optionalIRI(diff.right.getVersionIRI)}
- Loaded from: `${diff.rightSource}`"""
- s"$header\n\n$content"
+ writer.println(header)
+
+ for {
+ group <- sortedGroups
+ } {
+ def sortKey(modifiedItem: ModifiedOntologyContent[_]): String = {
+ modifiedItem match {
+ case ModifiedOntologyAnnotation(item, _) => item.toString
+ case ModifiedImport(item, _) => item.toString
+ case ModifiedAxiom(item, _) => item.getAxiomType match {
+ case AxiomType.DECLARATION => s"1-${item.toString}"
+ case _ => s"2-${item.toString}"
+ }
+ }
+ }
+
+ writer.println()
+ val removed = diff.groups(group).filterNot(_.added).toSeq.sortBy(sortKey)
+ val added = diff.groups(group).filter(_.added).toSeq.sortBy(sortKey)
+ val removedList = if (removed.nonEmpty) changeList("Removed", removed.map(_.owlObject).map(item => markdownForObject(item, markdownRenderer))) else ""
+ val addedList = if (added.nonEmpty) changeList("Added", added.map(_.owlObject).map(item => markdownForObject(item, markdownRenderer))) else ""
+ val header = groupsToLabels(group)
+ val headerIRI = group match {
+ case IRIGrouping(iri) => Some(iri.toString)
+ case _ => None
+ }
+ val frame = frameElement(header, headerIRI, removedList, addedList)
+ writer.println(frame)
+ }
+ }
}
+ def renderStream(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider, stream: OutputStream): Unit =
+ Using.resource(new PrintWriter(stream)) { writer =>
+ renderWriter(diff, renderingOntologyProvider, writer)
+ }
+
+ def render(diff: GroupedDiff, renderingOntologyProvider: OWLOntologySetProvider): String =
+ Using.resource(new ByteArrayOutputStream()) { stream =>
+ renderStream(diff, renderingOntologyProvider, stream)
+ stream.toString(StandardCharsets.UTF_8)
+ }
+
def markdownForObject(obj: OWLObject, renderer: OWLObjectRenderer, level: Int = 0): String = {
val (annotations, objToRender) = obj match {
case hasAnnotations: HasAnnotations =>
@@ -100,5 +119,4 @@ object MarkdownGroupedDiffRenderer {
private def optionalIRI(iriOpt: Optional[IRI]): String = iriOpt.toOption.map(iri => s"`$iri`").getOrElse("*None*")
-
}