From ef9f231e6728e511819e1b77560e54b23b7aebfd Mon Sep 17 00:00:00 2001 From: Gaurav Vaidya Date: Tue, 26 Mar 2024 14:38:36 -0400 Subject: [PATCH 1/3] Added a DocumentLoader to catch errors. --- pom.xml | 4 +-- .../jphyloref/helpers/JSONLDHelper.java | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 13b2a0d..bba1b69 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ org.eclipse.rdf4j rdf4j-rio-jsonld - 2.3.2 + 3.7.7 runtime @@ -94,7 +94,7 @@ org.eclipse.rdf4j rdf4j-rio-api - 2.3.2 + 3.7.7 diff --git a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java index 43d071c..c28b8c0 100644 --- a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java +++ b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java @@ -1,14 +1,20 @@ package org.phyloref.jphyloref.helpers; +import com.github.jsonldjava.core.DocumentLoader; +import com.github.jsonldjava.core.JsonLdError; +import com.github.jsonldjava.core.RemoteDocument; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.rio.RDFParser; import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.rio.helpers.JSONLDSettings; import org.semanticweb.owlapi.formats.RDFJsonLDDocumentFormat; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyLoaderConfiguration; import org.semanticweb.owlapi.rio.RioOWLRDFConsumerAdapter; import org.semanticweb.owlapi.util.AnonymousNodeChecker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JSONLDHelper provides methods to help read and process JSON-LD files. @@ -16,6 +22,8 @@ * @author Gaurav Vaidya */ public class JSONLDHelper { + private static final Logger logger = LoggerFactory.getLogger(JSONLDHelper.class); + /** * Create an RDFParser for JSON-LD files. When the parser's parse() method is called, * its contents will be added to the OWLOntology passed to this method. @@ -60,6 +68,23 @@ public boolean isAnonymousNode(IRI iri) { RDFParser parser = Rio.createParser(RDFFormat.JSONLD); parser.setRDFHandler(rdfHandler); + // We get some indistinct errors if any of the context URLs in the JSON-LD file are + // incorrect or inaccessible. However, we can set up our own document loader so we + // can detect when this occurs.) + parser.set( + JSONLDSettings.DOCUMENT_LOADER, + new DocumentLoader() { + @Override + public RemoteDocument loadDocument(String url) throws JsonLdError { + try { + return super.loadDocument(url); + } catch (Exception err) { + logger.error("Error occurred while loading document " + url + ": " + err); + throw new JsonLdError(JsonLdError.Error.LOADING_REMOTE_CONTEXT_FAILED, url, err); + } + } + }); + return parser; } } From 3639ff54df399cf1446bb0cb22812ebbefa5250a Mon Sep 17 00:00:00 2001 From: Gaurav Vaidya Date: Tue, 26 Mar 2024 15:06:19 -0400 Subject: [PATCH 2/3] Added ability of JPhyloRef to load the context from resources. --- .../jphyloref/helpers/JSONLDHelper.java | 41 +++++ .../context/phyx-context-v1.0.0.json | 143 +++++++++++++++++ .../context/phyx-context-v1.1.0.json | 146 ++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 src/main/resources/context/phyx-context-v1.0.0.json create mode 100644 src/main/resources/context/phyx-context-v1.1.0.json diff --git a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java index c28b8c0..59d3669 100644 --- a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java +++ b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java @@ -3,6 +3,11 @@ import com.github.jsonldjava.core.DocumentLoader; import com.github.jsonldjava.core.JsonLdError; import com.github.jsonldjava.core.RemoteDocument; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.stream.Collectors; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.rio.RDFParser; import org.eclipse.rdf4j.rio.Rio; @@ -74,6 +79,42 @@ public boolean isAnonymousNode(IRI iri) { parser.set( JSONLDSettings.DOCUMENT_LOADER, new DocumentLoader() { + { + // Load built-in context files as injected documents. + try { + this.addInjectedDoc( + "https://ww.phyloref.org/phyx.js/context/v1.0.0/phyx.json", + loadResourceFileAsString("context/phyx-context-v1.0.0.json")); + } catch (IOException e) { + logger.error("Could not load Phyx context v1.0.0: " + e); + } + + try { + this.addInjectedDoc( + "https://www.phyloref.org/phyx.js/context/v1.1.0/phyx.json", + loadResourceFileAsString("context/phyx-context-v1.1.0.json")); + } catch (IOException e) { + logger.error("Could not load Phyx context v1.1.0: " + e); + } + } + + /** + * Load a text Resource as a String. Based on the code at + * https://stackoverflow.com/a/46613809/27310 + * + * @return A String representation of the Resource specified. + */ + private String loadResourceFileAsString(String fileName) throws IOException { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try (InputStream is = classLoader.getResourceAsStream(fileName)) { + if (is == null) throw new IOException("Could not find resource: " + fileName); + try (InputStreamReader isr = new InputStreamReader(is); + BufferedReader reader = new BufferedReader(isr)) { + return reader.lines().collect(Collectors.joining(System.lineSeparator())); + } + } + } + @Override public RemoteDocument loadDocument(String url) throws JsonLdError { try { diff --git a/src/main/resources/context/phyx-context-v1.0.0.json b/src/main/resources/context/phyx-context-v1.0.0.json new file mode 100644 index 0000000..523d06d --- /dev/null +++ b/src/main/resources/context/phyx-context-v1.0.0.json @@ -0,0 +1,143 @@ +{ + "@context": { + "xsd": "http://www.w3.org/2001/XMLSchema#", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "owl": "http://www.w3.org/2002/07/owl#", + "skos": "http://www.w3.org/2004/02/skos/core#", + "obo": "http://purl.obolibrary.org/obo/", + "dwc": "http://rs.tdwg.org/dwc/terms/", + "dct": "http://purl.org/dc/terms/", + "tc": "http://rs.tdwg.org/ontology/voc/TaxonConcept#", + "tn": "http://rs.tdwg.org/ontology/voc/TaxonName#", + "testcase": "http://vocab.phyloref.org/phyloref/testcase.owl#", + "pso": "http://purl.org/spar/pso/", + "tvc": "http://www.essepuntato.it/2012/04/tvc/", + "timeinterval": "http://www.ontologydesignpatterns.org/cp/owl/timeinterval.owl#", + "phyloref": "http://ontology.phyloref.org/phyloref.owl#", + "opentree": "http://purl.org/opentree/nexson#", + "subClasses": { + "@reverse": "rdfs:subClassOf" + }, + "label": { + "@id": "rdfs:label", + "@type": "xsd:string" + }, + "labels": { + "@id": "rdfs:label", + "@type": "xsd:string", + "@container": "@set" + }, + "namePublishedIn": "dwc:namePublishedIn", + "definitionSource": "obo:IAO_0000119", + "definition": { + "@id": "obo:IAO_0000115", + "@type": "xsd:string" + }, + "hasName": { + "@id": "tc:hasName", + "@type": "tn:TaxonName" + }, + "nameComplete": { + "@id": "tn:nameComplete", + "@type": "xsd:string" + }, + "nomenclaturalCode": { + "@id": "tn:nomenclaturalCode", + "@type": "@id" + }, + "scientificName": { + "@id": "dwc:scientificName", + "@type": "xsd:string" + }, + "genusPart": { + "@id": "tn:genusPart", + "@type": "xsd:string" + }, + "specificEpithet": { + "@id": "tn:specificEpithet", + "@type": "xsd:string" + }, + "basisOfRecord": "dwc:basisOfRecord", + "occurrenceID": "dwc:occurrenceID", + "catalogNumber": "dwc:catalogNumber", + "collectionCode": "dwc:collectionCode", + "institutionCode": "dwc:institutionCode", + "subClassOf": { + "@id": "rdfs:subClassOf", + "@type": "@id" + }, + "parent": { + "@id": "obo:CDAO_0000179", + "@type": "@id" + }, + "children": { + "@id": "obo:CDAO_0000149", + "@type": "@id" + }, + "siblings": { + "@id": "phyloref:has_Sibling", + "@type": "@id" + }, + "owl:imports": { + "@id": "owl:imports", + "@type": "@id" + }, + "equivalentClass": "owl:equivalentClass", + "intersectionOf": { + "@id": "owl:intersectionOf", + "@container": "@list" + }, + "onProperty": { + "@id": "owl:onProperty", + "@type": "@id" + }, + "someValuesFrom": { + "@id": "owl:someValuesFrom", + "@container": "@set" + }, + "unionOf": { + "@id": "owl:unionOf", + "@container": "@list" + }, + "hasValue": { + "@id": "owl:hasValue", + "@type": "xsd:string" + }, + "nodes": { + "@reverse": "obo:CDAO_0000200", + "@container": "@set" + }, + "hasRootNode": { + "@id": "obo:CDAO_0000148", + "@type": "@id" + }, + "newick": { + "@id": "phyloref:newick_expression", + "@type": "xsd:string" + }, + "curator": { + "@id": "opentree:curatorName", + "@type": "xsd:string" + }, + "scientificNameAuthorship": { + "@id": "dwc:scientificNameAuthorship", + "@type": "xsd:string" + }, + "nameAccordingTo": "tc:accordingTo", + "phylogenies": { + "@reverse": "rdfs:isDefinedBy", + "@container": "@set" + }, + "phylorefs": { + "@reverse": "rdfs:isDefinedBy", + "@container": "@set" + }, + "title": "dct:title", + "source": "dct:source", + "bibliographicCitation": "dct:bibliographicCitation", + "doi": "http://prismstandard.org/namespaces/basic/2.0/doi", + "representsTaxonomicUnits": "obo:CDAO_0000187", + "apomorphy": "phyloref:apomorphy" + } +} diff --git a/src/main/resources/context/phyx-context-v1.1.0.json b/src/main/resources/context/phyx-context-v1.1.0.json new file mode 100644 index 0000000..2471e0d --- /dev/null +++ b/src/main/resources/context/phyx-context-v1.1.0.json @@ -0,0 +1,146 @@ +{ + "@context": { + "xsd": "http://www.w3.org/2001/XMLSchema#", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "owl": "http://www.w3.org/2002/07/owl#", + "skos": "http://www.w3.org/2004/02/skos/core#", + "obo": "http://purl.obolibrary.org/obo/", + "dwc": "http://rs.tdwg.org/dwc/terms/", + "dct": "http://purl.org/dc/terms/", + "tc": "http://rs.tdwg.org/ontology/voc/TaxonConcept#", + "tn": "http://rs.tdwg.org/ontology/voc/TaxonName#", + "pso": "http://purl.org/spar/pso/", + "tvc": "http://www.essepuntato.it/2012/04/tvc/", + "timeinterval": "http://www.ontologydesignpatterns.org/cp/owl/timeinterval.owl#", + "phyloref": "http://ontology.phyloref.org/phyloref.owl#", + "subClasses": { + "@reverse": "rdfs:subClassOf" + }, + "label": { + "@id": "rdfs:label", + "@type": "xsd:string" + }, + "labels": { + "@id": "rdfs:label", + "@type": "xsd:string", + "@container": "@set" + }, + "namePublishedIn": "dwc:namePublishedIn", + "definitionSource": "obo:IAO_0000119", + "definition": { + "@id": "obo:IAO_0000115", + "@type": "xsd:string" + }, + "hasName": { + "@id": "tc:hasName", + "@type": "tn:TaxonName" + }, + "nameComplete": { + "@id": "tn:nameComplete", + "@type": "xsd:string" + }, + "nomenclaturalCode": { + "@id": "tn:nomenclaturalCode", + "@type": "@id" + }, + "scientificName": { + "@id": "dwc:scientificName", + "@type": "xsd:string" + }, + "genusPart": { + "@id": "tn:genusPart", + "@type": "xsd:string" + }, + "specificEpithet": { + "@id": "tn:specificEpithet", + "@type": "xsd:string" + }, + "basisOfRecord": "dwc:basisOfRecord", + "occurrenceID": "dwc:occurrenceID", + "catalogNumber": "dwc:catalogNumber", + "collectionCode": "dwc:collectionCode", + "institutionCode": "dwc:institutionCode", + "subClassOf": { + "@id": "rdfs:subClassOf", + "@type": "@id" + }, + "parent": { + "@id": "obo:CDAO_0000179", + "@type": "@id" + }, + "children": { + "@id": "obo:CDAO_0000149", + "@type": "@id" + }, + "siblings": { + "@id": "phyloref:has_Sibling", + "@type": "@id" + }, + "owl:imports": { + "@id": "owl:imports", + "@type": "@id" + }, + "equivalentClass": "owl:equivalentClass", + "intersectionOf": { + "@id": "owl:intersectionOf", + "@container": "@list" + }, + "onProperty": { + "@id": "owl:onProperty", + "@type": "@id" + }, + "someValuesFrom": { + "@id": "owl:someValuesFrom", + "@container": "@set" + }, + "unionOf": { + "@id": "owl:unionOf", + "@container": "@list" + }, + "hasValue": { + "@id": "owl:hasValue", + "@type": "xsd:string" + }, + "nodes": { + "@reverse": "obo:CDAO_0000200", + "@container": "@set" + }, + "hasRootNode": { + "@id": "obo:CDAO_0000148", + "@type": "@id" + }, + "newick": { + "@id": "phyloref:newick_expression", + "@type": "xsd:string" + }, + "curatorNotes": { + "@id": "obo:IAO_0000232", + "@type": "xsd:string" + }, + "scientificNameAuthorship": { + "@id": "dwc:scientificNameAuthorship", + "@type": "xsd:string" + }, + "nameAccordingTo": "tc:accordingTo", + "phylogenies": { + "@reverse": "rdfs:isDefinedBy", + "@container": "@set" + }, + "phylorefs": { + "@reverse": "rdfs:isDefinedBy", + "@container": "@set" + }, + "title": "dct:title", + "source": "dct:source", + "bibliographicCitation": "dct:bibliographicCitation", + "doi": "http://prismstandard.org/namespaces/basic/2.0/doi", + "representsTaxonomicUnits": "obo:CDAO_0000187", + "apomorphy": "phyloref:apomorphy", + "contributors": { + "@id": "http://purl.org/dc/terms/contributor", + "@container": "@set" + }, + "name": "http://xmlns.com/foaf/0.1/name" + } +} From fda11fc7fb02c878c843cdfb3984475da7efb90a Mon Sep 17 00:00:00 2001 From: Gaurav Vaidya Date: Tue, 26 Mar 2024 15:26:16 -0400 Subject: [PATCH 3/3] Fixed incorrect URL. --- src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java index 59d3669..3902fbe 100644 --- a/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java +++ b/src/main/java/org/phyloref/jphyloref/helpers/JSONLDHelper.java @@ -83,7 +83,7 @@ public boolean isAnonymousNode(IRI iri) { // Load built-in context files as injected documents. try { this.addInjectedDoc( - "https://ww.phyloref.org/phyx.js/context/v1.0.0/phyx.json", + "https://www.phyloref.org/phyx.js/context/v1.0.0/phyx.json", loadResourceFileAsString("context/phyx-context-v1.0.0.json")); } catch (IOException e) { logger.error("Could not load Phyx context v1.0.0: " + e);