diff --git a/owldiff-cli/pom.xml b/owldiff-cli/pom.xml index d3a566a..b8ae004 100644 --- a/owldiff-cli/pom.xml +++ b/owldiff-cli/pom.xml @@ -11,7 +11,7 @@ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. --> - cz.cvut.kbss @@ -33,22 +33,27 @@ org.slf4j slf4j-api - 1.7.26 + 2.0.3 + + + ch.qos.logback + logback-core + 1.4.4 ch.qos.logback logback-classic - 1.2.3 + 1.4.4 org.projectlombok lombok - 1.18.22 + 1.18.24 - com.github.rvesse - airline - 2.8.0 + info.picocli + picocli + 4.7.0 diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/ChangeTypeUtils.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/ChangeTypeUtils.java new file mode 100644 index 0000000..5a7969c --- /dev/null +++ b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/ChangeTypeUtils.java @@ -0,0 +1,24 @@ +package cz.cvut.kbss.owldiff.cli; + +import cz.cvut.kbss.owldiff.change.OWLChangeType; + +public class ChangeTypeUtils { + + public static String changeTypeName(OWLChangeType ct) { + switch (ct) { + case SYNTACTIC_ORIG_REST: + return "-"; + case SYNTACTIC_UPD_REST: + return "+"; + case ENTAILEXPL_INFERRED: + case ENTAILEXPL_POSSIBLY_REMOVE: + case CEX_ISIN_DIFFR_DIFFL: + case CEX_ISIN_DIFFR: + case CEX_ISIN_DIFFL: + case HEURISTIC_SAME_SUB_AND_SUPER_CLASSES: + case HEURISTIC_SINGLE_UNMATCHED_SIBLING: + default: + throw new UnsupportedOperationException(); + } + } +} diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/Diff.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/Diff.java index 50704b9..acf3a97 100644 --- a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/Diff.java +++ b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/Diff.java @@ -1,153 +1,83 @@ package cz.cvut.kbss.owldiff.cli; -import com.github.rvesse.airline.annotations.Arguments; -import com.github.rvesse.airline.annotations.Command; -import cz.cvut.kbss.owldiff.change.OWLChangeType; -import cz.cvut.kbss.owldiff.change.SyntacticAxiomChange; import cz.cvut.kbss.owldiff.diff.syntactic.SyntacticDiff; import cz.cvut.kbss.owldiff.diff.syntactic.SyntacticDiffOutput; import cz.cvut.kbss.owldiff.ontology.OntologyHandler; import cz.cvut.kbss.owldiff.syntax.ManchesterSyntax; +import lombok.extern.slf4j.Slf4j; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.io.IRIDocumentSource; +import org.semanticweb.owlapi.model.*; + import java.io.File; import java.net.URI; import java.text.MessageFormat; -import java.util.Comparator; -import java.util.List; import java.util.regex.Pattern; -import lombok.extern.slf4j.Slf4j; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.io.IRIDocumentSource; -import org.semanticweb.owlapi.io.OWLRendererException; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.MissingImportHandlingStrategy; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyCreationException; -import org.semanticweb.owlapi.model.OWLOntologyManager; -import org.semanticweb.owlapi.model.OntologyConfigurator; + +import static cz.cvut.kbss.owldiff.cli.ChangeTypeUtils.changeTypeName; @Slf4j -@Command(name = "diff") public class Diff { - @Arguments(title = "File paths", description = "Path of the oldFile and newFile") - private List paths; - - public void run() throws OWLOntologyCreationException, OWLRendererException { - if (paths.size() != 2) { - log.error("Exactly two files must be provided, but got {0} only", paths.size()); - return; - } - - String oldFF = paths.get(0); - String newFF = paths.get(1); - - URI oldF; - URI newF; - if (new File(oldFF).exists()) { - oldF = new File(oldFF).getAbsoluteFile().toURI(); - } else { - log.error("File does not exist {}"); - throw new RuntimeException(); - } - - if (new File(newFF).exists()) { - newF = new File(newFF).getAbsoluteFile().toURI(); - } else { - log.error("File does not exist {}"); - throw new RuntimeException(); - } - - if (oldF.isAbsolute() && newF.isAbsolute()) { - final OWLOntologyManager originalM = OWLManager - .createOWLOntologyManager(); - originalM.setOntologyConfigurator( - new OntologyConfigurator() - .setMissingImportHandlingStrategy(MissingImportHandlingStrategy.SILENT) - .setReportStackTraces(true) - .setStrict(false)); - originalM.getIRIMappers().add( (ontologyIRI) -> { - if (Pattern.compile(oldFF).matcher(ontologyIRI.toString()).matches()) { - return ontologyIRI; - } else { - return IRI.create(String.format("file://%s", ontologyIRI.toString())); - }}); - final OWLOntology originalO = - originalM.loadOntologyFromOntologyDocument(new IRIDocumentSource( - IRI.create(oldF))); - - final OWLOntologyManager updateM = OWLManager.createOWLOntologyManager(); - updateM.setOntologyConfigurator(new OntologyConfigurator().setMissingImportHandlingStrategy( - MissingImportHandlingStrategy.SILENT) - .setReportStackTraces(true) - .setStrict(false) - ); - updateM.getIRIMappers().add( (ontologyIRI) -> { - if (Pattern.compile(newFF).matcher(ontologyIRI.toString()).matches()) { - return ontologyIRI; - } else { - return IRI.create(String.format("file://%s", ontologyIRI.toString())); - }}); - - OWLOntology updateO = - updateM.loadOntologyFromOntologyDocument(new IRIDocumentSource(IRI.create(newF))); + public void run(final String original, final String updated) throws OWLOntologyCreationException { + final OWLOntology originalO = createFreshOntology(original); + final OWLOntology updateO = createFreshOntology(updated); - SyntacticDiff d = new SyntacticDiff(new OntologyHandler() { - @Override public OWLOntology getOriginalOntology() { - return originalO; - } - - @Override public OWLOntology getUpdateOntology() { - return updateO; - } - }); + final SyntacticDiff d = new SyntacticDiff(new OntologyHandler() { + @Override + public OWLOntology getOriginalOntology() { + return originalO; + } - final SyntacticDiffOutput o = d.diff(); + @Override + public OWLOntology getUpdateOntology() { + return updateO; + } + }); - ManchesterSyntax s = new ManchesterSyntax(); - o.getOWLChanges() + final SyntacticDiffOutput o = d.diff(); + final ManchesterSyntax s = new ManchesterSyntax(); + o.getOWLChanges() .stream().sorted( - new ChangeComparator() - .thenComparing(SyntacticAxiomChange::getOWLChangeType)) + new SyntacticChangeComparator()) .forEach(c -> - System.out.println(MessageFormat.format("{0} {1}", changeTypeName(c.getOWLChangeType()), - s.writeAxiom(c.getAxiom(), false, null, false))) + System.out.println(MessageFormat.format("{0} {1}", + changeTypeName(c.getOWLChangeType()), + s.writeAxiom(c.getAxiom(), false, null, false))) ); - - } else { - log.error("Files are not absolute"); - } } - private class ChangeComparator implements Comparator { - - private MainOwlEntityResolver resolver; + private URI ensureFileExists(final String file) { + final File f = new File(file); - public ChangeComparator() { - this.resolver = new MainOwlEntityResolver(); + if (!f.exists()) { + throw new IllegalArgumentException(MessageFormat.format("File \"{0}\" does not exist.", file)); + } else if (!f.isAbsolute()) { + throw new IllegalArgumentException(MessageFormat.format("File \"{0}\" is not absolute.", file)); + } else { + return f.getAbsoluteFile().toURI(); } + } - public int compare(SyntacticAxiomChange c1, SyntacticAxiomChange c2) { - c1.getAxiom().accept(resolver); - final IRI c1Iri = resolver.getEntity(); - - c2.getAxiom().accept(resolver); - final IRI c2Iri = resolver.getEntity(); - - if ( c1Iri != null && c1Iri.equals(c2Iri) ) { - return 0; - } else if (c1Iri != null && c2Iri != null) { - return c1Iri.compareTo(c2Iri); - } else { - return c1.getAxiom().compareTo(c2.getAxiom()); - } - } + private OWLOntology createFreshOntology(final String original) throws OWLOntologyCreationException { + final OntologyConfigurator configurator = new OntologyConfigurator() + .setMissingImportHandlingStrategy( + MissingImportHandlingStrategy.SILENT) + .setReportStackTraces(true) + .setStrict(false); + final OWLOntologyManager originalM = OWLManager + .createOWLOntologyManager(); + originalM.setOntologyConfigurator(configurator); + originalM.getIRIMappers().add(createIRIMapper(original)); + return + originalM.loadOntologyFromOntologyDocument(new IRIDocumentSource( + IRI.create(ensureFileExists(original)))); } - private String changeTypeName(OWLChangeType ct) { - switch (ct) { - case SYNTACTIC_ORIG_REST: return "-"; - case SYNTACTIC_UPD_REST: return "+"; - default: throw new UnsupportedOperationException(); - } + private OWLOntologyIRIMapper createIRIMapper(final String file) { + final Pattern p = Pattern.compile(file); + return (ontologyIRI) -> p.matcher(ontologyIRI.toString()).matches() ? + ontologyIRI : + IRI.create(String.format("file://%s", ontologyIRI)); } } diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/DiffCommand.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/DiffCommand.java new file mode 100644 index 0000000..4882470 --- /dev/null +++ b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/DiffCommand.java @@ -0,0 +1,33 @@ +package cz.cvut.kbss.owldiff.cli; + +import lombok.extern.slf4j.Slf4j; +import picocli.CommandLine; + +import java.util.concurrent.Callable; + +@Slf4j +@CommandLine.Command(name = "diff", mixinStandardHelpOptions = true, + description = "Compares OWL ontologies.") +public class DiffCommand implements Callable { + + @CommandLine.Parameters(description = "Original ontology file.") + private String original; + + @CommandLine.Parameters(description = "Updated ontology file.") + private String updated; + + public static void main(String[] args) { + new CommandLine(new DiffCommand()).execute(args); + } + + public Integer call() { + try { + new Diff().run(original, updated); + } catch (Exception e) { + log.error("Exception during command execution: {}", e.getMessage()); + log.debug("Details:", e); + return -1; + } + return 0; + } +} diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/GitDiff.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/GitDiff.java deleted file mode 100644 index 533dd05..0000000 --- a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/GitDiff.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012 Czech Technical University in Prague. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser Public License v2.1 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -package cz.cvut.kbss.owldiff.cli; - -import com.github.rvesse.airline.SingleCommand; -import java.util.logging.LogManager; -import org.semanticweb.owlapi.io.OWLRendererException; -import org.semanticweb.owlapi.model.OWLOntologyCreationException; - -public class GitDiff { - - static { - LogManager.getLogManager().reset(); - } - - public static void main(String[] args) throws OWLOntologyCreationException, - OWLRendererException { - SingleCommand parser = SingleCommand.singleCommand(Diff.class); - Diff cmd = parser.parse(args); - cmd.run(); - } -} diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/MainOwlEntityResolver.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/MainOwlEntityResolver.java index f9ed2f9..c61e9be 100644 --- a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/MainOwlEntityResolver.java +++ b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/MainOwlEntityResolver.java @@ -13,321 +13,272 @@ package cz.cvut.kbss.owldiff.cli; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; -import org.semanticweb.owlapi.model.OWLAnnotationPropertyDomainAxiom; -import org.semanticweb.owlapi.model.OWLAnnotationPropertyRangeAxiom; -import org.semanticweb.owlapi.model.OWLAsymmetricObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLAxiomVisitor; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; -import org.semanticweb.owlapi.model.OWLDataProperty; -import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom; -import org.semanticweb.owlapi.model.OWLDataPropertyExpression; -import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom; -import org.semanticweb.owlapi.model.OWLDatatypeDefinitionAxiom; -import org.semanticweb.owlapi.model.OWLDeclarationAxiom; -import org.semanticweb.owlapi.model.OWLDifferentIndividualsAxiom; -import org.semanticweb.owlapi.model.OWLDisjointDataPropertiesAxiom; -import org.semanticweb.owlapi.model.OWLDisjointObjectPropertiesAxiom; -import org.semanticweb.owlapi.model.OWLDisjointUnionAxiom; -import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; -import org.semanticweb.owlapi.model.OWLEquivalentDataPropertiesAxiom; -import org.semanticweb.owlapi.model.OWLEquivalentObjectPropertiesAxiom; -import org.semanticweb.owlapi.model.OWLFunctionalDataPropertyAxiom; -import org.semanticweb.owlapi.model.OWLFunctionalObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLHasKeyAxiom; -import org.semanticweb.owlapi.model.OWLInverseFunctionalObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLInverseObjectPropertiesAxiom; -import org.semanticweb.owlapi.model.OWLIrreflexiveObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLNaryClassAxiom; -import org.semanticweb.owlapi.model.OWLNaryIndividualAxiom; -import org.semanticweb.owlapi.model.OWLNaryPropertyAxiom; -import org.semanticweb.owlapi.model.OWLNegativeDataPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLNegativeObjectPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom; -import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; -import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom; -import org.semanticweb.owlapi.model.OWLReflexiveObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLSameIndividualAxiom; -import org.semanticweb.owlapi.model.OWLSubAnnotationPropertyOfAxiom; -import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; -import org.semanticweb.owlapi.model.OWLSubDataPropertyOfAxiom; -import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom; -import org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom; -import org.semanticweb.owlapi.model.OWLSymmetricObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom; -import org.semanticweb.owlapi.model.OWLUnaryPropertyAxiom; -import org.semanticweb.owlapi.model.SWRLRule; +import org.semanticweb.owlapi.model.*; public class MainOwlEntityResolver implements OWLAxiomVisitor { - private IRI entity; + private IRI entity = null; public IRI getEntity() { return entity; } - @Override public void visit(OWLDeclarationAxiom axiom) { + @Override + public void visit(OWLDeclarationAxiom axiom) { entity = axiom.getEntity().getIRI(); } - @Override public void visit(OWLDatatypeDefinitionAxiom axiom) { + @Override + public void visit(OWLDatatypeDefinitionAxiom axiom) { entity = axiom.getDatatype().getIRI(); } - @Override public void visit(OWLAnnotationAssertionAxiom axiom) { + @Override + public void visit(OWLAnnotationAssertionAxiom axiom) { if (axiom.getSubject().isNamed()) { - entity = axiom.getSubject().asIRI().get(); - } else { - entity = null; + entity = axiom.getSubject().asIRI().orElse(null); } } - @Override public void visit(OWLSubAnnotationPropertyOfAxiom axiom) { + @Override + public void visit(OWLSubAnnotationPropertyOfAxiom axiom) { entity = axiom.getSubProperty().getIRI(); } - @Override public void visit(OWLAnnotationPropertyDomainAxiom axiom) { + @Override + public void visit(OWLAnnotationPropertyDomainAxiom axiom) { entity = axiom.getProperty().getIRI(); } - @Override public void visit(OWLAnnotationPropertyRangeAxiom axiom) { + @Override + public void visit(OWLAnnotationPropertyRangeAxiom axiom) { entity = axiom.getProperty().getIRI(); } - @Override public void visit(OWLSubClassOfAxiom axiom) { + @Override + public void visit(OWLSubClassOfAxiom axiom) { if (axiom.getSubClass().isNamed()) { entity = axiom.getSubClass().asOWLClass().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLNegativeObjectPropertyAssertionAxiom axiom) { + @Override + public void visit(OWLNegativeObjectPropertyAssertionAxiom axiom) { if (axiom.getProperty().isNamed()) { entity = axiom.getProperty().asOWLObjectProperty().getIRI(); - } else { - entity = null; } } private void visitOWLObjectPropertyAxiom( - OWLUnaryPropertyAxiom axiom) { + OWLUnaryPropertyAxiom axiom) { if (axiom.getProperty().isOWLObjectProperty()) { entity = axiom.getProperty().asOWLObjectProperty().getIRI(); - } else { - entity = null; } } private void visitOWLDatatypePropertyAxiom( - OWLUnaryPropertyAxiom axiom) { + OWLUnaryPropertyAxiom axiom) { if (axiom.getProperty().isOWLDataProperty()) { entity = axiom.getProperty().asOWLDataProperty().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLAsymmetricObjectPropertyAxiom axiom) { + @Override + public void visit(OWLAsymmetricObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLReflexiveObjectPropertyAxiom axiom) { + @Override + public void visit(OWLReflexiveObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } private void visitNaryClassAxiom(OWLNaryClassAxiom axiom) { - final OWLClass c = (OWLClass) axiom.components() - .sorted() - .filter(cx -> cx instanceof OWLClass) - .findFirst() - .orElseGet(null); - entity = c != null ? c.getIRI() : null; + entity = find(axiom, OWLClass.class); } private void visitNaryObjectPropertyAxiom( - OWLNaryPropertyAxiom axiom) { - final OWLObjectProperty c = (OWLObjectProperty) axiom.components() - .sorted() - .filter(cx -> cx instanceof OWLObjectProperty) - .findFirst() - .orElseGet(null); - entity = c != null ? c.getIRI() : null; + OWLNaryPropertyAxiom axiom) { + entity = find(axiom, OWLObjectProperty.class); } private void visitNaryDatatypePropertyAxiom( - OWLNaryPropertyAxiom axiom) { - final OWLDataProperty c = (OWLDataProperty) axiom.components() - .sorted() - .filter(cx -> cx instanceof OWLDataProperty) - .findFirst() - .orElseGet(null); - entity = c != null ? c.getIRI() : null; + OWLNaryPropertyAxiom axiom) { + entity = find(axiom, OWLDataProperty.class); } - private void visitNaryIndividualsAxiom(OWLNaryIndividualAxiom axiom) { - final OWLNamedIndividual c = (OWLNamedIndividual) axiom.components() - .sorted() - .filter(cx -> cx instanceof OWLNamedIndividual) - .findFirst() - .get(); - entity = c.asOWLNamedIndividual().getIRI(); + entity = find(axiom, OWLNamedIndividual.class); + } + + private IRI find(final OWLAxiom axiom, final Class entityType) { + return axiom.components() + .filter(entityType::isInstance) + .sorted() + .map(cc -> ((T) cc).getIRI()) + .findFirst() + .orElse(null); } - @Override public void visit(OWLDataPropertyDomainAxiom axiom) { + @Override + public void visit(OWLDataPropertyDomainAxiom axiom) { visitOWLDatatypePropertyAxiom(axiom); } - @Override public void visit(OWLObjectPropertyDomainAxiom axiom) { + @Override + public void visit(OWLObjectPropertyDomainAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLEquivalentObjectPropertiesAxiom axiom) { + @Override + public void visit(OWLEquivalentObjectPropertiesAxiom axiom) { visitNaryObjectPropertyAxiom(axiom); } - @Override public void visit(OWLNegativeDataPropertyAssertionAxiom axiom) { + @Override + public void visit(OWLNegativeDataPropertyAssertionAxiom axiom) { if (axiom.getSubject().isIRI()) { entity = axiom.getSubject().asOWLNamedIndividual().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLDifferentIndividualsAxiom axiom) { + @Override + public void visit(OWLDifferentIndividualsAxiom axiom) { visitNaryIndividualsAxiom(axiom); } - @Override public void visit(OWLDisjointDataPropertiesAxiom axiom) { + @Override + public void visit(OWLDisjointDataPropertiesAxiom axiom) { visitNaryDatatypePropertyAxiom(axiom); } - @Override public void visit(OWLDisjointObjectPropertiesAxiom axiom) { + @Override + public void visit(OWLDisjointObjectPropertiesAxiom axiom) { visitNaryObjectPropertyAxiom(axiom); } - @Override public void visit(OWLObjectPropertyRangeAxiom axiom) { + @Override + public void visit(OWLObjectPropertyRangeAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLObjectPropertyAssertionAxiom axiom) { + @Override + public void visit(OWLObjectPropertyAssertionAxiom axiom) { if (axiom.getSubject().isNamed()) { entity = axiom.getSubject().asOWLNamedIndividual().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLFunctionalObjectPropertyAxiom axiom) { + @Override + public void visit(OWLFunctionalObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLSubObjectPropertyOfAxiom axiom) { + @Override + public void visit(OWLSubObjectPropertyOfAxiom axiom) { if (axiom.getSubProperty().isNamed()) { entity = axiom.getSubProperty().asOWLObjectProperty().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLDisjointUnionAxiom axiom) { + @Override + public void visit(OWLDisjointUnionAxiom axiom) { final OWLClass c = (OWLClass) axiom.components() - .sorted() - .filter(cx -> cx instanceof OWLClass) - .findFirst() - .orElseGet(null); + .sorted() + .filter(cx -> cx instanceof OWLClass) + .findFirst() + .orElse(null); entity = c != null ? c.getIRI() : null; } - @Override public void visit(OWLSymmetricObjectPropertyAxiom axiom) { + @Override + public void visit(OWLSymmetricObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLDataPropertyRangeAxiom axiom) { + @Override + public void visit(OWLDataPropertyRangeAxiom axiom) { visitOWLDatatypePropertyAxiom(axiom); } - @Override public void visit(OWLFunctionalDataPropertyAxiom axiom) { + @Override + public void visit(OWLFunctionalDataPropertyAxiom axiom) { visitOWLDatatypePropertyAxiom(axiom); } - @Override public void visit(OWLEquivalentDataPropertiesAxiom axiom) { + @Override + public void visit(OWLEquivalentDataPropertiesAxiom axiom) { visitNaryDatatypePropertyAxiom(axiom); } - @Override public void visit(OWLClassAssertionAxiom axiom) { + @Override + public void visit(OWLClassAssertionAxiom axiom) { if (axiom.getIndividual().isNamed()) { entity = axiom.getIndividual().asOWLNamedIndividual().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLEquivalentClassesAxiom axiom) { + @Override + public void visit(OWLEquivalentClassesAxiom axiom) { visitNaryClassAxiom(axiom); } - @Override public void visit(OWLDataPropertyAssertionAxiom axiom) { + @Override + public void visit(OWLDataPropertyAssertionAxiom axiom) { if (axiom.getSubject().isNamed()) { entity = axiom.getSubject().asOWLNamedIndividual().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLTransitiveObjectPropertyAxiom axiom) { + @Override + public void visit(OWLTransitiveObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLIrreflexiveObjectPropertyAxiom axiom) { + @Override + public void visit(OWLIrreflexiveObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLSubDataPropertyOfAxiom axiom) { + @Override + public void visit(OWLSubDataPropertyOfAxiom axiom) { if (axiom.getSubProperty().isNamed()) { entity = axiom.getSubProperty().asOWLDataProperty().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLInverseFunctionalObjectPropertyAxiom axiom) { + @Override + public void visit(OWLInverseFunctionalObjectPropertyAxiom axiom) { visitOWLObjectPropertyAxiom(axiom); } - @Override public void visit(OWLSameIndividualAxiom axiom) { + @Override + public void visit(OWLSameIndividualAxiom axiom) { visitNaryIndividualsAxiom(axiom); } - @Override public void visit(OWLSubPropertyChainOfAxiom axiom) { + @Override + public void visit(OWLSubPropertyChainOfAxiom axiom) { if (axiom.getSuperProperty().isNamed()) { entity = axiom.getSuperProperty().asOWLObjectProperty().getIRI(); - } else { - entity = null; } } - @Override public void visit(OWLInverseObjectPropertiesAxiom axiom) { + @Override + public void visit(OWLInverseObjectPropertiesAxiom axiom) { visitNaryObjectPropertyAxiom(axiom); } - @Override public void visit(OWLHasKeyAxiom axiom) { + @Override + public void visit(OWLHasKeyAxiom axiom) { if (axiom.getClassExpression().isIRI()) { entity = axiom.getClassExpression().asOWLClass().getIRI(); - } else { - entity = null; } } - @Override public void visit(SWRLRule node) { + @Override + public void visit(SWRLRule node) { entity = null; } } diff --git a/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/SyntacticChangeComparator.java b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/SyntacticChangeComparator.java new file mode 100644 index 0000000..fade8db --- /dev/null +++ b/owldiff-cli/src/main/java/cz/cvut/kbss/owldiff/cli/SyntacticChangeComparator.java @@ -0,0 +1,26 @@ +package cz.cvut.kbss.owldiff.cli; + +import cz.cvut.kbss.owldiff.change.SyntacticAxiomChange; +import org.semanticweb.owlapi.model.IRI; + +import java.util.Comparator; + +public class SyntacticChangeComparator implements Comparator { + + private IRI getIRI(SyntacticAxiomChange c) { + final MainOwlEntityResolver resolver = new MainOwlEntityResolver(); + c.getAxiom().accept(resolver); + return resolver.getEntity(); + } + + public int compare(final SyntacticAxiomChange c1, final SyntacticAxiomChange c2) { + return Comparator.nullsFirst((cx1, cx2) -> { + final SyntacticAxiomChange cc1 = (SyntacticAxiomChange) cx1; + final SyntacticAxiomChange cc2 = (SyntacticAxiomChange) cx2; + // Compare entities first + int c = Comparator.nullsFirst(IRI::compareTo).compare(getIRI(cc1), getIRI(cc2)); + // ... then axioms inside these entities. + return c != 0 ? c : cc1.getAxiom().compareTo(cc2.getAxiom()); + }).compare(c1, c2); + } +} diff --git a/owldiff-cli/src/main/resources/logback.xml b/owldiff-cli/src/main/resources/logback.xml index 05bd7f0..caf830c 100644 --- a/owldiff-cli/src/main/resources/logback.xml +++ b/owldiff-cli/src/main/resources/logback.xml @@ -8,7 +8,7 @@ - +