Skip to content

Commit da00d89

Browse files
committed
Add a check for deprecated references.
Add a new `check` command intended to perform some additional checks (beyond those already performed by ROBOT) on an ontology. For now, the only check is a check that no class and no object property is defined relatively to a deprecated entity.
1 parent 0b6bd53 commit da00d89

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* ODK ROBOT Plugin
3+
* Copyright © 2025 Damien Goutte-Gattat
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
package org.incenp.obofoundry.odk;
20+
21+
import java.util.HashSet;
22+
import java.util.Set;
23+
24+
import org.apache.commons.cli.CommandLine;
25+
import org.obolibrary.robot.CommandLineHelper;
26+
import org.obolibrary.robot.CommandState;
27+
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
28+
import org.semanticweb.owlapi.model.OWLAxiom;
29+
import org.semanticweb.owlapi.model.OWLClass;
30+
import org.semanticweb.owlapi.model.OWLEntity;
31+
import org.semanticweb.owlapi.model.OWLObjectProperty;
32+
import org.semanticweb.owlapi.model.OWLOntology;
33+
import org.semanticweb.owlapi.model.parameters.Imports;
34+
import org.slf4j.Logger;
35+
import org.slf4j.LoggerFactory;
36+
37+
public class CheckCommand extends BasePlugin {
38+
39+
private static final Logger logger = LoggerFactory.getLogger(CheckCommand.class);
40+
41+
private Set<String> basePrefixes = new HashSet<>();
42+
43+
public CheckCommand() {
44+
super("check", "perform some checks on an ontology", "robot check --checks [CHECK,...]");
45+
46+
options.addOption("c", "checks", true, "list of checks to perform");
47+
options.addOption(null, "base-iri", true, "only check entities in the indicated namespace(s)");
48+
options.addOption("x", "fail", true, "if true, fail if any of the checks fails");
49+
}
50+
51+
@Override
52+
public void performOperation(CommandState state, CommandLine line) throws Exception {
53+
for ( String prefix : CommandLineHelper.getOptionalValues(line, "base-iri") ) {
54+
basePrefixes.add(getIRI(prefix, "base-iri").toString());
55+
}
56+
57+
int failed = 0;
58+
for ( String check : line.getOptionValues("checks") ) {
59+
switch ( check ) {
60+
case "deprecated-references":
61+
if ( !checkDeprecatedReferences(state.getOntology()) ) {
62+
logger.error("The ontology contains references to deprecated entities");
63+
failed += 1;
64+
}
65+
break;
66+
}
67+
}
68+
69+
if ( failed > 0 && CommandLineHelper.getBooleanValue(line, "fail", false) ) {
70+
System.exit(1);
71+
}
72+
}
73+
74+
private boolean checkDeprecatedReferences(OWLOntology ontology) {
75+
boolean pass = true;
76+
for ( OWLEntity entity : ontology.getSignature(Imports.INCLUDED) ) {
77+
if ( !isInBase(entity.getIRI().toString()) || isDeprecated(ontology, entity) ) {
78+
continue;
79+
}
80+
81+
Set<OWLAxiom> axioms = new HashSet<>();
82+
if ( entity instanceof OWLClass ) {
83+
axioms.addAll(ontology.getAxioms((OWLClass) entity, Imports.INCLUDED));
84+
} else if ( entity instanceof OWLObjectProperty ) {
85+
axioms.addAll(ontology.getAxioms((OWLObjectProperty) entity, Imports.INCLUDED));
86+
}
87+
88+
for ( OWLAxiom axiom : axioms ) {
89+
for ( OWLEntity referenced : axiom.getSignature() ) {
90+
if ( isDeprecated(ontology, referenced) ) {
91+
pass = false;
92+
logger.warn("{} references deprecated entity {}", entity.getIRI(), referenced.getIRI());
93+
}
94+
}
95+
}
96+
}
97+
98+
return pass;
99+
}
100+
101+
private boolean isDeprecated(OWLOntology ontology, OWLEntity entity) {
102+
for ( OWLOntology ont : ontology.getImportsClosure() ) {
103+
for ( OWLAnnotationAssertionAxiom ax : ont.getAnnotationAssertionAxioms(entity.getIRI()) ) {
104+
if ( ax.isDeprecatedIRIAssertion() ) {
105+
return true;
106+
}
107+
}
108+
}
109+
return false;
110+
}
111+
112+
private boolean isInBase(String iri) {
113+
for ( String base : basePrefixes ) {
114+
if ( iri.startsWith(base) ) {
115+
return true;
116+
}
117+
}
118+
return basePrefixes.isEmpty();
119+
}
120+
}

src/main/resources/META-INF/services/org.obolibrary.robot.Command

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ org.incenp.obofoundry.odk.NormalizeCommand
22
org.incenp.obofoundry.odk.SubsetCommand
33
org.incenp.obofoundry.odk.CheckAlignmentCommand
44
org.incenp.obofoundry.odk.ImportCommand
5+
org.incenp.obofoundry.odk.CheckCommand

0 commit comments

Comments
 (0)