diff --git a/contract/src/test/java/org/obolibrary/oboformat/TagIRIsTest.java b/contract/src/test/java/org/obolibrary/oboformat/TagIRIsTest.java new file mode 100644 index 0000000000..d2797be6ab --- /dev/null +++ b/contract/src/test/java/org/obolibrary/oboformat/TagIRIsTest.java @@ -0,0 +1,54 @@ +package org.obolibrary.oboformat; + +import org.junit.jupiter.api.Test; +import org.semanticweb.owlapi.api.test.baseclasses.TestBase; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.*; +import org.semanticweb.owlapi.vocab.OWL2Datatype; + +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TagIRIsTest extends TestBase { + + @Test + public void testTagIRIMapping() { + OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); + OWLDataFactory factory = manager.getOWLDataFactory(); + OWLAnnotationProperty definition = factory.getOWLAnnotationProperty(IRI.create("http://purl.obolibrary.org/obo/IAO_0000115")); + OWLAnnotationProperty oioCreatedBy = factory.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#created_by")); + OWLAnnotationProperty oioInventedBy = factory.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#invented_by")); + OWLAnnotationProperty source = factory.getOWLAnnotationProperty(IRI.create("http://purl.obolibrary.org/obo/MYONT_20")); + OWLOntology ont = loadOntology("obo/tag_iris.obo", manager); + Set axioms = ont.getAxioms(); + OWLClass term1 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_1")); + OWLClass term2 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_2")); + OWLClass term3 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_3")); + OWLClass term4 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_4")); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(definition, term1.getIRI(), factory.getOWLLiteral("Definition of term one.", OWL2Datatype.XSD_STRING), + Stream.of( + factory.getOWLAnnotation(factory.getRDFSComment(), factory.getOWLLiteral("Here is a sub-annotation.", OWL2Datatype.XSD_STRING)), + factory.getOWLAnnotation(factory.getRDFSSeeAlso(), factory.getOWLLiteral("A nested see also value.", OWL2Datatype.XSD_STRING))) + .collect(Collectors.toSet()) + ))); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(factory.getRDFSSeeAlso(), term1.getIRI(), factory.getOWLLiteral("See also value.", OWL2Datatype.XSD_STRING)))); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(definition, term2.getIRI(), factory.getOWLLiteral("Definition of term two.", OWL2Datatype.XSD_STRING), + Collections.singleton(factory.getOWLAnnotation(source, factory.getOWLLiteral("A nested annotation value.", OWL2Datatype.XSD_STRING)))))); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(definition, term3.getIRI(), factory.getOWLLiteral("Definition of term three.", OWL2Datatype.XSD_STRING), + Collections.singleton(factory.getOWLAnnotation(source, factory.getOWLLiteral("A definition source value.", OWL2Datatype.XSD_STRING)))))); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(oioCreatedBy, term3.getIRI(), factory.getOWLLiteral("goc:bro", OWL2Datatype.XSD_STRING))), "created_by is built in and should not be overridden by a typedef"); + assertTrue(axioms.contains( + factory.getOWLAnnotationAssertionAxiom(definition, term4.getIRI(), factory.getOWLLiteral("Definition of term four.", OWL2Datatype.XSD_STRING), + Collections.singleton(factory.getOWLAnnotation(oioInventedBy, factory.getOWLLiteral("An inventor value.", OWL2Datatype.XSD_STRING))))), "An undeclared tag should have oio namespace"); + + } +} diff --git a/contract/src/test/resources/obo/tag_iris.obo b/contract/src/test/resources/obo/tag_iris.obo new file mode 100644 index 0000000000..9e463e4faa --- /dev/null +++ b/contract/src/test/resources/obo/tag_iris.obo @@ -0,0 +1,56 @@ +format-version: 1.2 +ontology: myont + +[Term] +id: MYONT:1 +name: term one +def: "Definition of term one." [] {comment="Here is a sub-annotation.", seeAlso="A nested see also value."} +property_value: seeAlso "See also value." xsd:string + +[Term] +id: MYONT:2 +name: term two +def: "Definition of term two." [] {MYONT:20="A nested annotation value."} +property_value: MYONT:21 "A top level annotation value." xsd:string + +[Term] +id: MYONT:3 +name: term three +def: "Definition of term three." [] {source="A definition source value."} +intersection_of: MYONT:2 ! term two +intersection_of: results_in_transport_across GO:0005739 ! mitochondrion +created_by: goc:bro + +[Term] +id: MYONT:4 +name: term four +def: "Definition of term four." [] {invented_by="An inventor value."} + +[Typedef] +id: source +name: source +xref: MYONT:20 +is_metadata_tag: true + +[Typedef] +id: MYONT:21 +name: source2 +is_metadata_tag: true + +[Typedef] +id: seeAlso +name: see also +xref: http://www.w3.org/2000/01/rdf-schema#seeAlso +is_metadata_tag: true + +[Typedef] +id: results_in_transport_across +name: results in transport across +namespace: external +xref: RO:0002342 + +[Typedef] +id: created_by +name: created by +namespace: external +xref: http://purl.org/dc/terms/creator diff --git a/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIObo2Owl.java b/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIObo2Owl.java index 300ae4518a..8d826d13a6 100644 --- a/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIObo2Owl.java +++ b/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIObo2Owl.java @@ -1,6 +1,7 @@ package org.obolibrary.obo2owl; import static org.obolibrary.obo2owl.Obo2OWLConstants.DEFAULT_IRI_PREFIX; +import static org.obolibrary.obo2owl.Obo2OWLConstants.OIOVOCAB_IRI_PREFIX; import static org.semanticweb.owlapi.util.OWLAPIPreconditions.verifyNotNull; import java.io.File; @@ -1518,6 +1519,15 @@ public static IRI trTagToIRI(String tag) { return iri; } + @Nonnull + private IRI trTagToIRIIncludingTypedefs(String tag) { + IRI iri = ANNOTATIONPROPERTYMAP.get(tag); + if (iri == null) { + iri = oboIdToIRI(tag, true); + } + return iri; + } + /** * Translate tag to annotation prop. * @@ -1526,7 +1536,7 @@ public static IRI trTagToIRI(String tag) { */ @Nonnull protected OWLAnnotationProperty trTagToAnnotationProp(@Nonnull String tag) { - IRI iri = trTagToIRI(tag); + IRI iri = trTagToIRIIncludingTypedefs(tag); OWLAnnotationProperty ap = fac.getOWLAnnotationProperty(iri); if (!apToDeclare.contains(ap)) { apToDeclare.add(ap); @@ -1624,14 +1634,23 @@ protected OWLAnnotationValue trLiteral(@Nonnull Object inputValue) { */ @Nonnull public IRI oboIdToIRI(@Nonnull String id) { + return oboIdToIRI(id, false); + } + + private IRI oboIdToIRI(@Nonnull String id, boolean oboInOwlDefault) { IRI iri = idToIRICache.get(id); if (iri == null) { - iri = oboIdToIRI_load(id); + iri = oboIdToIRI_load(id, oboInOwlDefault); idToIRICache.put(id, iri); } return iri; } + @Nonnull + public IRI oboIdToIRI_load(@Nonnull String id) { + return oboIdToIRI_load(id, false); + } + /** * Obo id to iri. * @@ -1639,7 +1658,7 @@ public IRI oboIdToIRI(@Nonnull String id) { * @return the iri */ @Nonnull - public IRI oboIdToIRI_load(@Nonnull String id) { + public IRI oboIdToIRI_load(@Nonnull String id, boolean oboInOwlDefault) { if (id.contains(" ")) { LOG.error("id contains space: \"{}\"", id); throw new OWLParserException("spaces not allowed: '" + id + '\''); @@ -1704,10 +1723,16 @@ public IRI oboIdToIRI_load(@Nonnull String id) { // if(id.contains("_")) // db += "_"; localId = idParts[0];// Unprefixed-ID + } - String uriPrefix = DEFAULT_IRI_PREFIX + db; - if (idSpaceMap.containsKey(db)) { - uriPrefix = idSpaceMap.get(db); + String uriPrefix; + if (oboInOwlDefault) { + uriPrefix = OIOVOCAB_IRI_PREFIX; + } else { + uriPrefix = DEFAULT_IRI_PREFIX + db; + if (idSpaceMap.containsKey(db)) { + uriPrefix = idSpaceMap.get(db); + } } String safeId; try { diff --git a/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIOwl2Obo.java b/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIOwl2Obo.java index 844fc54fe2..1400e68e14 100644 --- a/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIOwl2Obo.java +++ b/oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIOwl2Obo.java @@ -1869,6 +1869,8 @@ public static String owlObjectToTag(OWLObject obj) { String prefix = Obo2OWLConstants.OIOVOCAB_IRI_PREFIX; if (iri.startsWith(prefix)) { tag = iri.substring(prefix.length()); + } else { + tag = getIdentifier(iriObj); } } return tag; diff --git a/oboformat/src/main/java/org/obolibrary/obo2owl/Obo2OWLConstants.java b/oboformat/src/main/java/org/obolibrary/obo2owl/Obo2OWLConstants.java index 970be0f38c..e41f7157a4 100644 --- a/oboformat/src/main/java/org/obolibrary/obo2owl/Obo2OWLConstants.java +++ b/oboformat/src/main/java/org/obolibrary/obo2owl/Obo2OWLConstants.java @@ -55,6 +55,9 @@ public enum Obo2OWLVocabulary implements HasIRI { /**IRI_IAO_0100001*/ IRI_IAO_0100001(DEFAULT_IRI_PREFIX, "IAO_0100001", "term replaced by", OboFormatTag.TAG_REPLACED_BY.getTag()), /**IRI_OIO_shorthand*/ IRI_OIO_shorthand(OIOVOCAB_IRI_PREFIX, "shorthand", "shorthand", "shorthand"), /**IRI_OIO_consider*/ IRI_OIO_consider(OIOVOCAB_IRI_PREFIX, "consider", "consider", OboFormatTag.TAG_CONSIDER.getTag()), + /**IRI_OIO_id*/ IRI_OIO_id(OIOVOCAB_IRI_PREFIX, "id", "id", OboFormatTag.TAG_ID.getTag()), + /**IRI_OIO_created_by*/ IRI_OIO_created_by(OIOVOCAB_IRI_PREFIX, "created_by", "created by", OboFormatTag.TAG_CREATED_BY.getTag()), + /**IRI_OIO_creation_date*/ IRI_OIO_creation_date(OIOVOCAB_IRI_PREFIX, "creation_date", "creation date", OboFormatTag.TAG_CREATION_DATE.getTag()), /**IRI_OIO_hasOBOFormatVersion*/ IRI_OIO_hasOBOFormatVersion(OIOVOCAB_IRI_PREFIX, "hasOBOFormatVersion", "has_obo_format_version", OboFormatTag.TAG_FORMAT_VERSION.getTag()), /**IRI_OIO_treatXrefsAsIsA*/ IRI_OIO_treatXrefsAsIsA(OIOVOCAB_IRI_PREFIX, "treat-xrefs-as-is_a", "treat-xrefs-as-is_a", OboFormatTag.TAG_TREAT_XREFS_AS_IS_A.getTag()), /**IRI_OIO_treatXrefsAsHasSubClass*/ IRI_OIO_treatXrefsAsHasSubClass(OIOVOCAB_IRI_PREFIX, "treat-xrefs-as-has-subclass", "treat-xrefs-as-has-subclass", OboFormatTag.TAG_TREAT_XREFS_AS_HAS_SUBCLASS.getTag()),