org.obolibrary.robot.DiffOperation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robot-core Show documentation
Show all versions of robot-core Show documentation
Core library for ROBOT: Library for working with OWL ontologies, especially Open Biological and Biomedical Ontologes (OBO).
The newest version!
package org.obolibrary.robot;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import org.geneontology.owl.differ.Differ;
import org.geneontology.owl.differ.render.BasicDiffRenderer;
import org.geneontology.owl.differ.render.HTMLDiffRenderer;
import org.geneontology.owl.differ.render.MarkdownGroupedDiffRenderer;
import org.geneontology.owl.differ.shortform.DoubleShortFormProvider;
import org.geneontology.owl.differ.shortform.OBOShortenerShortFormProvider;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.util.AnnotationValueShortFormProvider;
import org.semanticweb.owlapi.util.DefaultPrefixManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Get the differences between two ontology files.
*
* @author James A. Overton
*/
public class DiffOperation {
/** Logger. */
private static final Logger logger = LoggerFactory.getLogger(DiffOperation.class);
/** The base IRI for OBO terms. */
private static String oboBase = "http://purl.obolibrary.org/obo/";
/** A pattern for matching IRI strings. */
private static Pattern iriPattern = Pattern.compile("<(http\\S+)>");
/**
* Return default diff options.
*
* @return diff options
*/
public static Map getDefaultOptions() {
Map options = new HashMap<>();
options.put("labels", "false");
return options;
}
/**
* Given two ontologies, compare their sets of axioms, annotations, imports, and ontology IDs,
* returning true if they are identical and false otherwise.
*
* @param ontology1 the first ontology
* @param ontology2 the second ontology
* @return true if the ontologies are the same, false otherwise
*/
public static boolean equals(OWLOntology ontology1, OWLOntology ontology2) {
try {
return compare(ontology1, ontology2, null);
} catch (IOException e) {
return false;
}
}
/**
* Given two ontologies and a Writer, get their differences and write then to the writer. The
* ontologies are not changed.
*
* @param ontology1 the first ontology
* @param ontology2 the second ontology
* @param writer the Writer for the report, or null
* @return true if the ontologies are the same, false otherwise
* @throws IOException on writer failure
*/
public static boolean compare(OWLOntology ontology1, OWLOntology ontology2, Writer writer)
throws IOException {
return compare(ontology1, ontology2, new IOHelper(), writer, getDefaultOptions());
}
/**
* Given two ontologies, a Writer, and a set of diff options, get their differences and write then
* to the writer. The ontologies are not changed.
*
* @param ontology1 the first ontology
* @param ontology2 the second ontology
* @param ioHelper IOHelper to use for prefixes
* @param writer the Writer for the report, or null
* @param options diff options
* @return true if the ontologies are the same, false otherwise
* @throws IOException on writer failure
*/
public static boolean compare(
OWLOntology ontology1,
OWLOntology ontology2,
IOHelper ioHelper,
Writer writer,
Map options)
throws IOException {
boolean useLabels = OptionsHelper.optionIsTrue(options, "labels");
String format = OptionsHelper.getOption(options, "format", "plain");
format = format.toLowerCase();
if (useLabels && format.equals("plain")) {
format = "pretty";
}
Differ.BasicDiff diff = Differ.diff(ontology1, ontology2);
if (diff.isEmpty()) {
if (writer != null) {
writer.write("Ontologies are identical\n");
}
return true;
}
if (writer == null) {
return false;
}
OWLOntologySetProvider ontologyProvider =
new DualOntologySetProvider(
ontology1.getOWLOntologyManager(), ontology2.getOWLOntologyManager());
switch (format) {
case "plain":
writer.write(BasicDiffRenderer.renderPlain(diff));
break;
case "pretty":
DefaultPrefixManager pm = ioHelper.getPrefixManager();
AnnotationValueShortFormProvider labelProvider =
new AnnotationValueShortFormProvider(
ontologyProvider,
pm,
pm,
Collections.singletonList(OWLManager.getOWLDataFactory().getRDFSLabel()),
Collections.emptyMap());
OBOShortenerShortFormProvider iriProvider = new OBOShortenerShortFormProvider(pm);
DoubleShortFormProvider doubleProvider =
new DoubleShortFormProvider(iriProvider, labelProvider);
writer.write(BasicDiffRenderer.render(diff, doubleProvider));
break;
case "markdown":
Differ.GroupedDiff groupedForMarkdown = Differ.groupedDiff(diff);
writer.write(MarkdownGroupedDiffRenderer.render(groupedForMarkdown, ontologyProvider));
break;
case "html":
Differ.GroupedDiff groupedForHTML = Differ.groupedDiff(diff);
writer.write(HTMLDiffRenderer.render(groupedForHTML, ontologyProvider));
break;
default:
throw new IOException("Unknown diff format: " + format);
}
return false;
}
/** OWLOntologySetProvider for two (left and right) ontologies. */
private static class DualOntologySetProvider implements OWLOntologySetProvider {
private static final long serialVersionUID = -8942374248162307075L;
private final Set ontologies = Sets.newIdentityHashSet();
/**
* Init a new DualOntologySetProvider for a left and right ontology.
*
* @param left OWLOntologySetProvider for left ontology
* @param right OWLOntologySetProvider for right ontology
*/
public DualOntologySetProvider(OWLOntologySetProvider left, OWLOntologySetProvider right) {
ontologies.addAll(left.getOntologies());
ontologies.addAll(right.getOntologies());
}
/**
* Get the ontologies in the provider.
*
* @return Set of OWLOntologies
*/
@Nonnull
@Override
public Set getOntologies() {
return Collections.unmodifiableSet(ontologies);
}
}
/**
* Given a map from IRIs to labels and an axiom string, add labels next to any IRIs in the string,
* shorten OBO IRIs, and return the updated string.
*
* @param labels a map from IRIs to label strings
* @param axiom a string representation of an OWLAxiom
* @return a string with labels inserted next to IRIs
* @deprecated This functionality is now provided by the owl-diff library and no longer used to
* format results in DiffOperation.
*/
@Deprecated
public static String addLabels(Map labels, String axiom) {
Matcher matcher = iriPattern.matcher(axiom);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
IRI iri = IRI.create(matcher.group(1));
String id = iri.toString();
if (id.startsWith(oboBase)) {
id = id.substring(oboBase.length()).replace("_", ":");
}
String replacement = "<" + id + ">";
if (labels.containsKey(iri)) {
replacement = "<" + id + ">[" + labels.get(iri) + "]";
}
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* Given an IOHelper to get short form of IRIs, a map from IRIs to labels, and an axiom string,
* add labels next to any IRIs in the string, shorten OBO IRIs, and return the updated string.
*
* @param ioHelper IOHelper to use for prefixes
* @param labels a map from IRIs to label strings
* @param axiom a string representation of an OWLAxiom
* @return a string with labels inserted next to CURIEs
* @deprecated This functionality is now provided by the owl-diff library and no longer used to
* format results in DiffOperation.
*/
@Deprecated
public static String addLabels(IOHelper ioHelper, Map labels, String axiom) {
DefaultPrefixManager pm = ioHelper.getPrefixManager();
Matcher matcher = iriPattern.matcher(axiom);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
IRI iri = IRI.create(matcher.group(1));
String id = pm.getShortForm(iri);
if (id.startsWith("obo:")) {
id = id.substring(4).replace("_", ":");
}
if (!id.startsWith("<") && !id.endsWith(">")) {
id = "<" + id + ">";
}
String replacement = id;
if (labels.containsKey(iri)) {
replacement = id + "[" + labels.get(iri) + "]";
}
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* Given an ontology, return a list of strings for all the axioms of that ontology.
*
* @param ontology the ontology to use
* @return a set of strings, one for each axiom in the ontology
* @deprecated This functionality is no longer used within DiffOperation.
*/
@Deprecated
public static Set getAxiomStrings(OWLOntology ontology) {
Set strings = new HashSet<>();
strings.add(ontology.getOntologyID().toString());
for (OWLAxiom axiom : ontology.getAxioms()) {
strings.add(axiom.toString().replaceAll("\\n", "\\n"));
}
for (OWLAnnotation annotation : ontology.getAnnotations()) {
strings.add(annotation.toString().replaceAll("\\n", "\\n"));
}
return strings;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy