From 76352eab6674e0380cce3d239d5f31e4a78409be Mon Sep 17 00:00:00 2001 From: Daniel Garijo Date: Mon, 19 Jun 2023 12:51:32 +0200 Subject: [PATCH 01/36] citation info --- CITATION.cff | 25 +++++++++++++++++++++++++ README.md | 18 +++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..8f5475b --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,25 @@ +title: "OBA: Ontology-Based APIs" +license: Apache-2.0 +authors: + - family-names: Osorio + given-names: Maximiliano + orcid: "https://orcid.org/0000-0002-3611-6510" + - family-names: Garijo + given-names: Daniel + orcid: "https://orcid.org/0000-0003-0454-7145" +cff-version: 1.2.0 +message: "If you use this software, please cite both the article from preferred-citation and the software itself." +preferred-citation: + authors: + - family-names: Osorio + given-names: Maximiliano + - family-names: Garijo + given-names: Daniel + title: "OBA: An Ontology-Based Framework for Creating REST APIs for Knowledge Graphs" + type: article + year: 2021 + doi: 10.1007/978-3-030-62466-8_4 +identifiers: + - description: "Collection of archived snapshots for OBA" + type: doi + value: 10.5281/zenodo.6639554 diff --git a/README.md b/README.md index 9b07e28..d8b62fc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Ontology-Based APIs (OBA) [![Test](https://github.com/KnowledgeCaptureAndDiscovery/OBA/actions/workflows/build.yaml/badge.svg)](https://github.com/KnowledgeCaptureAndDiscovery/OBA/actions/workflows/build.yaml) +# Ontology-Based APIs (OBA) [![Test](https://github.com/KnowledgeCaptureAndDiscovery/OBA/actions/workflows/build.yaml/badge.svg)](https://github.com/KnowledgeCaptureAndDiscovery/OBA/actions/workflows/build.yaml) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6639554.svg)](https://doi.org/10.5281/zenodo.6639554) OBA reads ontologies (OWL) and generates an OpenAPI Specification (OAS). Using this definition, OBA creates a REST API server automatically. @@ -35,3 +35,19 @@ $ java -jar oba-*-jar-with-dependencies.jar -c config.yaml Congratulations! You have generated an Open Api Specification. For instructions on using OBA to create your API server, go to the [documentation](https://oba.readthedocs.io/en/latest/) + +## Citation +Please cite our work as follows: + +``` +@inproceedings{garijo2020OBA, + title = {{OBA}: An Ontology-Based Framework for Creating REST APIs for Knowledge Graphs}, + author = {Garijo, Daniel and Osorio, Maximiliano}, + booktitle={International Semantic Web Conference}, + pages={48--64}, + year={2020}, + doi={https://doi.org/10.1007/978-3-030-62466-8_4}, + organization = {Springer, Cham}, + isbn={978-3-030-62466-8} +} +``` From 2bb462e4488ae3f4e4415cf4de2d05824e61c56d Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Sun, 14 Apr 2024 09:48:32 -0500 Subject: [PATCH 02/36] ignore local VS Codes settings --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 8263487..ae9493e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,9 @@ example.yaml # .idea/*.iml # .idea/modules +# Generated files +.vscode/settings.json + # CMake cmake-build-*/ From 9f2c3cf6abd79468fe0ec632e41b1732e5264ea5 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Sun, 14 Apr 2024 09:49:08 -0500 Subject: [PATCH 03/36] update old ontology URLs --- src/test/java/edu/isi/oba/ObaUtilsTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index 4609d09..1c8b978 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -78,8 +78,10 @@ public void missing_file () throws OWLOntologyCreationException{ @Test public void run() { - String ontology1 = "https://mintproject.github.io/Mint-ModelCatalog-Ontology/release/1.4.0/ontology.xml"; - String ontology2 = "https://knowledgecaptureanddiscovery.github.io/SoftwareDescriptionOntology/release/1.5.0/ontology.xml"; + //See: https://github.com/mintproject/Mint-ModelCatalog-Ontology/tree/master/release/1.8.0/ontology.owl + String ontology1 = "https://raw.githubusercontent.com/mintproject/Mint-ModelCatalog-Ontology/master/release/1.8.0/ontology.owl"; + //See: https://github.com/KnowledgeCaptureAndDiscovery/SoftwareDescriptionOntology/tree/master/release/1.9.0/ontology.owl + String ontology2 = "https://raw.githubusercontent.com/KnowledgeCaptureAndDiscovery/SoftwareDescriptionOntology/master/release/1.9.0/ontology.owl"; File ont1 = new File("ontology1"); File ont2 = new File("ontology2"); ObaUtils.downloadOntology(ontology1, ont1.getPath()); From 0ee2012f757204ae69d9bb35a763609509fd8c8b Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:38:26 -0500 Subject: [PATCH 04/36] updated to use non-raw links --- src/test/java/edu/isi/oba/ObaUtilsTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index 1c8b978..2cb1317 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -78,10 +78,8 @@ public void missing_file () throws OWLOntologyCreationException{ @Test public void run() { - //See: https://github.com/mintproject/Mint-ModelCatalog-Ontology/tree/master/release/1.8.0/ontology.owl - String ontology1 = "https://raw.githubusercontent.com/mintproject/Mint-ModelCatalog-Ontology/master/release/1.8.0/ontology.owl"; - //See: https://github.com/KnowledgeCaptureAndDiscovery/SoftwareDescriptionOntology/tree/master/release/1.9.0/ontology.owl - String ontology2 = "https://raw.githubusercontent.com/KnowledgeCaptureAndDiscovery/SoftwareDescriptionOntology/master/release/1.9.0/ontology.owl"; + String ontology1 = "https://mintproject.github.io/Mint-ModelCatalog-Ontology/release/1.8.0/ontology.owl"; + String ontology2 = "https://knowledgecaptureanddiscovery.github.io/SoftwareDescriptionOntology/release/1.9.0/ontology.owl"; File ont1 = new File("ontology1"); File ont2 = new File("ontology2"); ObaUtils.downloadOntology(ontology1, ont1.getPath()); From 306efa65d08801fb26a41455ab5a66c6b2717471 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 15 Apr 2024 07:33:39 -0500 Subject: [PATCH 05/36] updated dependencies/plugins; plus junit updates (#173) * updated dependencies/plugins; plus junit updates * Java 8 doesn't build in Github due to a dependency. Use 11 instead. * @Disabled ignored without plugin --- .github/workflows/build.yaml | 8 +- README.md | 8 +- pom.xml | 111 ++++++++------ src/main/java/edu/isi/oba/ObaUtils.java | 31 ++-- src/main/java/edu/isi/oba/Serializer.java | 13 +- src/test/java/edu/isi/oba/MapperTest.java | 29 ++-- src/test/java/edu/isi/oba/ObaUtilsTest.java | 41 ++--- .../java/edu/isi/oba/RestrictionsTest.java | 142 +++++++++--------- .../java/edu/isi/oba/config/ProviderTest.java | 6 +- .../edu/isi/oba/config/YamlConfigTest.java | 9 +- 10 files changed, 214 insertions(+), 184 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 98ffd76..9eca45e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -12,16 +12,16 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - java: [ '8', '11', '13', '15' ] + java: ["11", "17", "21"] name: Java ${{ matrix.Java }} steps: - uses: actions/checkout@v3 - name: Setup java uses: actions/setup-java@v3 with: - distribution: 'adopt' + distribution: "adopt" java-version: ${{ matrix.java }} - name: Build with Maven - run: mvn -B package --file pom.xml + run: mvn -B package --file pom.xml - name: Test with Maven - run: mvn -B test --file pom.xml \ No newline at end of file + run: mvn -B test --file pom.xml diff --git a/README.md b/README.md index d8b62fc..fa63d4a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ OBA reads ontologies (OWL) and generates an OpenAPI Specification (OAS). Using this definition, OBA creates a REST API server automatically. -![Diagram](docs/figures/oba.svg) +![Diagram](docs/figures/oba.svg) ## Quickstart @@ -11,6 +11,11 @@ There are two option to run OBA: 1. Download the binary. 2. Build the binary from the repository. +### Pre-requisites + +Due to recent versions of the OpenAPI generator being built with Java 11, you will need Java 11 or higher to run OBA v3.7.0. The current recommended distribution of Java 11+ JDKs (and "JREs") is at [Adoptium's releases page](https://adoptium.net/temurin/releases/?version=11). + +Java versions higher than 11 are also available to use. Java 11 is simply the minimum version. ### Downloading binary @@ -37,6 +42,7 @@ Congratulations! You have generated an Open Api Specification. For instructions on using OBA to create your API server, go to the [documentation](https://oba.readthedocs.io/en/latest/) ## Citation + Please cite our work as follows: ``` diff --git a/pom.xml b/pom.xml index 6b6b3b7..19d55bb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,17 +6,17 @@ jar edu.isi.oba oba - 3.6.1 + 3.7.0 core https://github.com/KnowledgeCaptureAndDiscovery/OBA UTF-8 - 1.8 - 1.8 - 1.8 - 3.1.1 + 11 + 11 + + 3.5.2 @@ -24,79 +24,89 @@ org.json json - 20190722 + 20240303 + - com.github.jsonld-java - jsonld-java - 0.11.1 + org.junit.jupiter + junit-jupiter-api + 5.10.2 + test - - - - - log4j - log4j - 1.2.17 + io.swagger + swagger-compat-spec-parser + 1.0.70 - + + + io.swagger.core.v3 + swagger-models + 2.2.21 + + + + io.swagger.parser.v3 + swagger-parser + 2.1.21 + + - org.slf4j - slf4j-simple - 1.7.28 + io.swagger.parser.v3 + swagger-parser-core + 2.1.21 - --> + - junit - junit - 4.13.1 - test + org.openapitools + openapi-generator + 7.4.0 + + net.sourceforge.owlapi owlapi-api - 5.1.10 + 5.5.0 + net.sourceforge.owlapi owlapi-apibinding - 5.1.10 - - - - org.openapitools - openapi-generator - 4.0.0 - + 5.5.0 + net.sourceforge.owlapi - owlapi-compatibility - 5.1.10 + owlapi-impl + 5.5.0 + org.yaml snakeyaml - 1.25 - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 + 2.2 + commons-cli commons-cli - 1.3.1 + 1.6.0 + + + + com.fasterxml.jackson.core + jackson-core + 2.17.0 + @@ -106,26 +116,35 @@ + org.apache.maven.plugins maven-eclipse-plugin - 2.9 + 2.10 true false + org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.13.0 ${jdk.version} ${jdk.version} + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + maven-assembly-plugin diff --git a/src/main/java/edu/isi/oba/ObaUtils.java b/src/main/java/edu/isi/oba/ObaUtils.java index 6088281..06793b3 100644 --- a/src/main/java/edu/isi/oba/ObaUtils.java +++ b/src/main/java/edu/isi/oba/ObaUtils.java @@ -1,33 +1,38 @@ package edu.isi.oba; +import static edu.isi.oba.Oba.logger; import edu.isi.oba.config.YamlConfig; -import org.apache.commons.cli.*; -import org.json.JSONException; -import org.json.JSONObject; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; import java.io.*; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.logging.Level; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import static edu.isi.oba.Oba.logger; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.file.Files; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.logging.Level; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.commons.cli.*; + +import org.json.JSONException; +import org.json.JSONObject; + import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLAnnotation; import org.semanticweb.owlapi.model.OWLEntity; import org.semanticweb.owlapi.model.OWLLiteral; import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.search.EntitySearcher; + +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + import uk.ac.manchester.cs.owl.owlapi.OWLAnnotationPropertyImpl; public class ObaUtils { @@ -180,7 +185,7 @@ public static String get_config_yaml(String[] args) { } public static YamlConfig get_yaml_data(String config_yaml) { - Constructor constructor = new Constructor(YamlConfig.class); + Constructor constructor = new Constructor(YamlConfig.class, new LoaderOptions()); Yaml yaml = new Yaml(constructor); InputStream config_input = null; diff --git a/src/main/java/edu/isi/oba/Serializer.java b/src/main/java/edu/isi/oba/Serializer.java index d57dc92..ffba9b3 100644 --- a/src/main/java/edu/isi/oba/Serializer.java +++ b/src/main/java/edu/isi/oba/Serializer.java @@ -1,20 +1,17 @@ package edu.isi.oba; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.*; import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.*; import io.swagger.v3.oas.models.security.SecurityScheme; - import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.core.models.SwaggerParseResult; -import org.openapitools.codegen.serializer.SerializerUtils; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.util.*; +import org.openapitools.codegen.serializer.SerializerUtils; class Serializer { //TODO: validate the yaml diff --git a/src/test/java/edu/isi/oba/MapperTest.java b/src/test/java/edu/isi/oba/MapperTest.java index 9048d5a..e3071a7 100644 --- a/src/test/java/edu/isi/oba/MapperTest.java +++ b/src/test/java/edu/isi/oba/MapperTest.java @@ -1,26 +1,27 @@ package edu.isi.oba; +import static edu.isi.oba.ObaUtils.get_yaml_data; import edu.isi.oba.config.AuthConfig; import edu.isi.oba.config.YamlConfig; -import io.swagger.v3.oas.models.PathItem; -import io.swagger.v3.oas.models.media.Schema; -import org.junit.Assert; -import org.junit.Test; -import org.semanticweb.owlapi.model.OWLClass; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; -import static edu.isi.oba.ObaUtils.get_yaml_data; +import io.swagger.v3.oas.models.media.Schema; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import org.semanticweb.owlapi.model.OWLClass; public class MapperTest { @Test @@ -36,7 +37,7 @@ public void testFilter() throws Exception{ } Collections.sort(filter_classes); Collections.sort(config); - Assert.assertEquals(config, filter_classes); + Assertions.assertEquals(config, filter_classes); } @@ -49,7 +50,7 @@ public void testLocalFile() throws Exception{ String local_ontology = "src/test/config/mcat_reduced.yaml"; YamlConfig config_data = get_yaml_data(local_ontology); Mapper mapper = new Mapper(config_data); - Assert.assertEquals(false, mapper.ontologies.isEmpty()); + Assertions.assertEquals(false, mapper.ontologies.isEmpty()); } /** @@ -61,7 +62,7 @@ public void testSpacesInPath() throws Exception{ String local_ontology = "examples/example with spaces/config.yaml"; YamlConfig config_data = get_yaml_data(local_ontology); Mapper mapper = new Mapper(config_data); - Assert.assertEquals(false, mapper.ontologies.isEmpty()); + Assertions.assertEquals(false, mapper.ontologies.isEmpty()); } /** @@ -75,7 +76,7 @@ public void testRemoteOntology() throws Exception{ String example_remote = "src/test/config/pplan.yaml"; YamlConfig config_data = get_yaml_data(example_remote); Mapper mapper = new Mapper(config_data); - Assert.assertEquals(false, mapper.ontologies.isEmpty()); + Assertions.assertEquals(false, mapper.ontologies.isEmpty()); } @@ -87,7 +88,7 @@ public void testMissingImportOntology() throws Exception{ String example_remote = "src/test/resources/missing_import/config.yaml"; YamlConfig config_data = get_yaml_data(example_remote); Mapper mapper = new Mapper(config_data); - Assert.assertEquals(false, mapper.ontologies.isEmpty()); + Assertions.assertEquals(false, mapper.ontologies.isEmpty()); } /** @@ -115,7 +116,7 @@ public void testComplexOntology() throws Exception{ MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); Schema schema = mapperSchema.getSchema(); // The person schema must not be null. - Assert.assertNotNull(schema); - Assert.assertEquals(schema.getName(),"Person"); + Assertions.assertNotNull(schema); + Assertions.assertEquals(schema.getName(),"Person"); } } diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index 2cb1317..afc1624 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -2,24 +2,26 @@ import static edu.isi.oba.ObaUtils.get_yaml_data; import edu.isi.oba.config.YamlConfig; -import java.io.File; -import org.json.JSONObject; -import org.junit.Assert; -import org.junit.Test; +import java.io.File; import java.io.IOException; -import static org.junit.Assert.*; +import org.json.JSONObject; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLOntologyCreationException; +@Disabled public class ObaUtilsTest { @Test public void read_json_file() throws IOException { JSONObject actual = ObaUtils.read_json_file("json_one.json"); - Assert.assertNotNull(actual.get("@context")); + Assertions.assertNotNull(actual.get("@context")); } @Test @@ -27,8 +29,8 @@ public void mergeJSONObjects() throws IOException { JSONObject one = ObaUtils.read_json_file("json_one.json"); JSONObject two = ObaUtils.read_json_file("json_two.json"); JSONObject merge = ObaUtils.mergeJSONObjects(one, two); - Assert.assertNotNull(merge.get("@context")); - Assert.assertNotNull(merge.get("@context")); + Assertions.assertNotNull(merge.get("@context")); + Assertions.assertNotNull(merge.get("@context")); } @Test @@ -39,9 +41,9 @@ public void concat_json_common_key() throws IOException { JSONObject[] jsons = new JSONObject[]{ one, two, three}; JSONObject merge = ObaUtils.concat_json_common_key(jsons, "@context"); JSONObject o = (JSONObject) merge.get("@context"); - assertNotNull(o.get("Entity")); - assertNotNull(o.get("Model")); - assertNotNull(o.get("Setup")); + Assertions.assertNotNull(o.get("Entity")); + Assertions.assertNotNull(o.get("Model")); + Assertions.assertNotNull(o.get("Setup")); } @Test @@ -52,9 +54,9 @@ public void getDescription () throws OWLOntologyCreationException{ Mapper mapper = new Mapper(config_data); OWLClass planClass = mapper.manager.getOWLDataFactory().getOWLClass("http://purl.org/net/p-plan#Plan"); String desc = ObaUtils.getDescription(planClass, mapper.ontologies.get(0)); - assertNotEquals(desc, ""); + Assertions.assertNotEquals(desc, ""); }catch(Exception e){ - fail(); + Assertions.fail("Failed to get description.", e); } } @@ -69,8 +71,7 @@ public void missing_file () throws OWLOntologyCreationException{ YamlConfig config_data = get_yaml_data(missing_file); try { Mapper mapper = new Mapper(config_data); - //if no exception is launched, fail test - fail(); + Assertions.fail("Missing file: If no exception is launched, fail test"); }catch(Exception e){ //pass test if there is an exception } @@ -91,17 +92,17 @@ public void run() { } catch (Exception e) { e.printStackTrace(); } + JSONObject o = (JSONObject) context.get("@context"); - assertEquals(o.get("id"), "@id"); - assertEquals(o.get("type"), "@type"); - assertNotNull(o.get("Entity")); - assertNotNull(o.get("Model")); + Assertions.assertEquals(o.get("id"), "@id"); + Assertions.assertEquals(o.get("type"), "@type"); + Assertions.assertNotNull(o.get("Entity")); + Assertions.assertNotNull(o.get("Model")); try{ java.nio.file.Files.delete(ont1.toPath()); java.nio.file.Files.delete(ont2.toPath()); }catch(Exception e){ } - } } \ No newline at end of file diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 4cdea86..2450394 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -1,8 +1,7 @@ package edu.isi.oba; - import static edu.isi.oba.ObaUtils.get_yaml_data; -import static org.junit.Assert.*; +import edu.isi.oba.config.YamlConfig; import java.io.IOException; import java.io.InputStream; @@ -13,13 +12,13 @@ import java.util.logging.LogManager; import java.util.logging.Logger; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLOntologyCreationException; - -import edu.isi.oba.config.YamlConfig; import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.ObjectSchema; @@ -62,10 +61,10 @@ public void testFunctionalObjectProperty() throws OWLOntologyCreationException, Object property= schema.getProperties().get("hasRector"); if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { Integer maxItems = ((ArraySchema) property).getMaxItems(); - assertEquals(expectedResult,maxItems); + Assertions.assertEquals(expectedResult, maxItems); } } catch (OWLOntologyCreationException e) { - assertTrue("error in ontology creation", false); + Assertions.fail("Error in ontology creation: ", e); } } @@ -93,12 +92,12 @@ public void testObjectUnionOf() throws OWLOntologyCreationException, Exception { itemsValue =((ComposedSchema) items).getAnyOf(); for (int i=0; i expected = Arrays.asList("http://dbpedia.org/ontology/Genre", "http://dbpedia.org/ontology/Band"); List config = config_data.getClasses(); - Assert.assertEquals(expected, config); + Assertions.assertEquals(expected, config); } } From e84ce5f18f71c44429860c77995fc94ee98b296c Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:01:44 -0500 Subject: [PATCH 06/36] use .isEmpty() where possible --- src/main/java/edu/isi/oba/MapperDataProperty.java | 5 +++-- src/main/java/edu/isi/oba/Serializer.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperDataProperty.java b/src/main/java/edu/isi/oba/MapperDataProperty.java index cdfc631..d0ff814 100644 --- a/src/main/java/edu/isi/oba/MapperDataProperty.java +++ b/src/main/java/edu/isi/oba/MapperDataProperty.java @@ -99,10 +99,10 @@ public MapperDataProperty(String name, String description, Boolean isFunctional, public Schema getSchemaByDataProperty(){ - if (this.type.size() == 0) { + if (this.type.isEmpty()) { return (array) ? arraySchema(new StringSchema(), nullable) : new StringSchema().nullable(nullable).description(description); } - else if (this.type.size() > 1){ + else if (this.type.size() > 1) { return (array) ? composedSchema(this.type, nullable) : new Schema().nullable(nullable).description(description); } @@ -110,6 +110,7 @@ else if (this.type.size() > 1){ if (schemaType == null){ logger.severe("property " + this.name + " type " + this.type); } + switch (schemaType) { case STRING_TYPE: return (array) ? arraySchema(new StringSchema(), nullable) : new StringSchema().nullable(nullable).description(description); diff --git a/src/main/java/edu/isi/oba/Serializer.java b/src/main/java/edu/isi/oba/Serializer.java index ffba9b3..7d72503 100644 --- a/src/main/java/edu/isi/oba/Serializer.java +++ b/src/main/java/edu/isi/oba/Serializer.java @@ -62,7 +62,7 @@ private void validate() throws Exception { List messageList = result.getMessages(); Set errors = new HashSet<>(messageList); Set warnings = new HashSet<>(); - if (errors.size() > 0) { + if (!errors.isEmpty()) { throw new Exception("Error when validating the API specification. " + errors.iterator().next()); } } From 91e8562b90a786b04809f0a47964cba473a0a0a3 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:03:30 -0500 Subject: [PATCH 07/36] make sure enum arrays are generated; plus assorted cleanup items --- .../edu/isi/oba/MapperObjectProperty.java | 158 ++++++++------- src/main/java/edu/isi/oba/MapperSchema.java | 177 ++++++++++------ .../java/edu/isi/oba/RestrictionVisitor.java | 191 +++++++++--------- 3 files changed, 302 insertions(+), 224 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperObjectProperty.java b/src/main/java/edu/isi/oba/MapperObjectProperty.java index 9ddc74c..814b438 100644 --- a/src/main/java/edu/isi/oba/MapperObjectProperty.java +++ b/src/main/java/edu/isi/oba/MapperObjectProperty.java @@ -4,8 +4,10 @@ import static edu.isi.oba.Oba.logger; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; class MapperObjectProperty { final String name; @@ -37,60 +39,60 @@ public MapperObjectProperty(String name, String description, Boolean isFunction this.restrictions = restrictions; } - public Schema getSchemaByObjectProperty(){ - if (this.ref.size() == 0){ - return getComposedSchemaObject(this.ref, array, nullable); + public Schema getSchemaByObjectProperty() { + if (this.ref.isEmpty()){ + return getComposedSchemaObject(this.ref, this.array, this.nullable); } if (this.ref.size() > 1){ - return getComposedSchemaObject(this.ref, array, nullable); - } - else { - return getObjectPropertiesByRef(this.ref.get(0), array, nullable); + return getComposedSchemaObject(this.ref, this.array, this.nullable); + } else { + return getObjectPropertiesByRef(this.ref.get(0), this.array, this.nullable); } } - private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nullable){ + private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nullable) { Schema object = new ObjectSchema(); - object.setDescription(description); + object.setDescription(this.description); if (array) { object.set$ref(ref); ArraySchema objects = new ArraySchema(); - objects.setDescription(description); - if (isFunctional) + objects.setDescription(this.description); + + if (this.isFunctional) { objects.setMaxItems(1); + } - for (String restriction: restrictions.keySet()) { - String value = restrictions.get(restriction); - switch (restriction) { - case "maxCardinality": - objects.setMaxItems(Integer.parseInt(value)); - break ; - case "minCardinality": - objects.setMinItems(Integer.parseInt(value)); - break ; - case "exactCardinality": - objects.setMaxItems(Integer.parseInt(value)); - objects.setMinItems(Integer.parseInt(value)); - break ; - case "someValuesFrom": - nullable=false; - break ; - case "allValuesFrom": - //nothing to do in the Schema - break ; - default: - break ; - } + for (String restriction: this.restrictions.keySet()) { + String value = this.restrictions.get(restriction); + switch (restriction) { + case "maxCardinality": + objects.setMaxItems(Integer.parseInt(value)); + break; + case "minCardinality": + objects.setMinItems(Integer.parseInt(value)); + break; + case "exactCardinality": + objects.setMaxItems(Integer.parseInt(value)); + objects.setMinItems(Integer.parseInt(value)); + break; + case "someValuesFrom": + nullable=false; + break; + case "allValuesFrom": + //nothing to do in the Schema + break; + default: + break; + } } objects.setNullable(nullable); objects.setItems(object); return objects; - } - else { - for (String restriction: restrictions.keySet()) { - String value = restrictions.get(restriction); + } else { + for (String restriction: this.restrictions.keySet()) { + String value = this.restrictions.get(restriction); if (restriction=="objectHasValue") { object.setDefault(value); object.type("string"); @@ -98,72 +100,88 @@ private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nulla return object; } } + return object; } } - private Schema getComposedSchemaObject(List refs, boolean array, boolean nullable){ + private Schema getComposedSchemaObject(List refs, boolean array, boolean nullable) { Schema object = new ObjectSchema(); - ComposedSchema composedSchema = new ComposedSchema() ; + ComposedSchema composedSchema = new ComposedSchema(); object.setType("object"); - object.setDescription(description); + object.setDescription(this.description); if (array) { ArraySchema objects = new ArraySchema(); - objects.setDescription(description); + objects.setDescription(this.description); - if (isFunctional) + if (this.isFunctional) { objects.setMaxItems(1); + } - for (String restriction: restrictions.keySet()) { - String value = restrictions.get(restriction); + for (String restriction: this.restrictions.keySet()) { + String value = this.restrictions.get(restriction); - for (String item:refs) { + // In some cases, the duplicate reference may have been added to the list. We only need to create one $ref item to it. + LinkedHashSet uniqueRefs = refs.stream().collect(Collectors.toCollection(LinkedHashSet::new)); + + for (String item: uniqueRefs) { Schema objectRange = new ObjectSchema(); objectRange.setType("object"); objectRange.set$ref(item); + switch (restriction) { case "unionOf": - if (value=="someValuesFrom") - nullable=false; + if ("someValuesFrom".equals(value)) { + nullable=false; + } + composedSchema.addAnyOfItem(objectRange); objects.setItems(composedSchema); - break ; + break; case "intersectionOf": - if (value=="someValuesFrom") - nullable=false; + if ("someValuesFrom".equals(value)) { + nullable = false; + } + composedSchema.addAllOfItem(objectRange); objects.setItems(composedSchema); - break ; - case "someValuesFrom": + break; + case "someValuesFrom": nullable=false; + composedSchema.addAnyOfItem(objectRange); + objects.setItems(composedSchema); break; - case "allValuesFrom": + case "allValuesFrom": //nothing to do in the Schema - break ; - case "oneOf": - if (value=="someValuesFrom") - nullable=false; - composedSchema.addEnumItemObject(item); - composedSchema.setType("string"); - composedSchema.setFormat("uri"); - objects.setItems(composedSchema); - break; + break; + case "oneOf": + if (value=="someValuesFrom") { + nullable=false; + } + + composedSchema.addEnumItemObject(item); + composedSchema.setType("string"); + composedSchema.setFormat("uri"); + objects.setItems(composedSchema); + break; default: //if the property range is complex it will be omitted - logger.warning("omitted complex restriction"); - objects.setItems(object); + logger.warning("omitted complex restriction"); + objects.setItems(object); } } - } - if (refs.size() == 0) - objects.setItems(object); - objects.setNullable(nullable); + } + + if (refs.isEmpty()) { + objects.setItems(object); + } + objects.setNullable(nullable); + return objects; - } - else { + } else { return object; } } diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 75d784f..8a6c107 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -1,9 +1,13 @@ package edu.isi.oba; +import static edu.isi.oba.Oba.logger; import io.swagger.v3.oas.models.examples.Example; import io.swagger.v3.oas.models.media.ObjectSchema; import io.swagger.v3.oas.models.media.Schema; + +import java.util.*; + import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.OWLReasoner; @@ -12,10 +16,6 @@ import org.semanticweb.owlapi.util.IRIShortFormProvider; import org.semanticweb.owlapi.util.SimpleIRIShortFormProvider; -import java.util.*; - -import static edu.isi.oba.Oba.logger; - class MapperSchema { private final OWLReasoner reasoner; @@ -27,6 +27,7 @@ class MapperSchema { private Map dataProperties; private Map objectProperties; private Map properties; + private List enumInstances; final String name; private final Map schemaNames; private final Schema schema; @@ -80,9 +81,15 @@ public MapperSchema(List ontologies, OWLClass cls, String clsDescri } private Map setProperties() { - dataProperties = this.getDataProperties(); - objectProperties = this.getObjectProperties(); - return properties; + this.dataProperties = this.getDataProperties(); + this.objectProperties = this.getObjectProperties(); + return this.properties; + } + + private List setEnums() { + this.enumInstances = this.getEnumInstances(); + + return this.enumInstances; } private Schema setSchema() { @@ -97,12 +104,24 @@ private Schema setSchema() { schema.not(complement); } - schema.setProperties(this.getProperties()); - HashMap exampleMap = new HashMap<>(); - exampleMap.put("id", "some_id"); - Example example = new Example(); - example.setValue(exampleMap); - schema.setExample(example); + if (this.getEnums() != null && !this.enumInstances.isEmpty()) { + // Only string enums allowed in RDF/OWL ?? + schema.setType("string"); + schema.setEnum(this.enumInstances); + } else { + schema.setType(this.type); + schema.setProperties(this.getProperties()); + + HashMap exampleMap = new HashMap<>(); + exampleMap.put("id", "some_id"); + Example example = new Example(); + example.setValue(exampleMap); + schema.setExample(example); + ArrayList examples = new ArrayList(); + examples.add(example); + schema.setExamples(examples); + } + return schema; } @@ -130,7 +149,28 @@ private boolean checkDomainClass(OWLClass cls, OWLPropertyDomainAxiom dp) { return false; } + /** + * Obtain a list of enumerations (enums) of a OWLClass. + * + * @return A List string: enum name/title + */ + private List getEnumInstances() { + List enums = new ArrayList(); + + for (OWLOntology ontology: this.ontologies) { + ontology.getEquivalentClassesAxioms(this.cls).forEach((ax) -> { + ax.classExpressions().filter((ce) -> ce instanceof OWLObjectOneOf).forEach((oneOfObj) -> { + oneOfObj.getIndividualsInSignature().forEach((OWLNamedIndividual indv) -> { + logger.info("\tclass has following item as an ENUM: " + this.sfp.getShortForm(indv.getIRI())); + enums.add(this.sfp.getShortForm(indv.getIRI())); + }); + }); + }); + } + return enums; + } + /** * Obtain a list of Codegenproperty of a OWLClass * @@ -145,11 +185,12 @@ private Map getDataProperties() { Set properties_class = new HashSet<>(); Set functional; - for (OWLOntology ontology : ontologies) + for (OWLOntology ontology: this.ontologies) { properties_class.addAll(ontology.getAxioms(AxiomType.DATA_PROPERTY_DOMAIN)); + } for (OWLDataPropertyDomainAxiom dp : properties_class) { - if (checkDomainClass(cls, dp)) { + if (checkDomainClass(this.cls, dp)) { for (OWLDataProperty odp : dp.getDataPropertiesInSignature()) { Boolean array = true; Boolean nullable = true; @@ -160,14 +201,15 @@ private Map getDataProperties() { // the data property has been previously analyzed on the getClassRestrictions function. // If the property was analyzed, we will change the value of inspect to false, otherwise // the property will be inspected. - if (propertiesFromDataRestrictions.size() != 0) { + if (!propertiesFromDataRestrictions.isEmpty()) { if (propertiesFromDataRestrictions.contains(odp)) { inspect=false; } - } + } + if (inspect) { Boolean isFunctional=false; - for (OWLOntology ontology : ontologies) { + for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getDataPropertyRangeAxioms(odp)); functional = ontology.getAxioms(AxiomType.FUNCTIONAL_DATA_PROPERTY); for (OWLFunctionalDataPropertyAxiom functionalAxiom:functional) { @@ -175,21 +217,21 @@ private Map getDataProperties() { isFunctional = true; } } - if (ranges.size() == 0) + + if (ranges.isEmpty()) { logger.warning("Property " + odp.getIRI() + " has range equals zero"); + } String propertyName = this.sfp.getShortForm(odp.getIRI()); String propertyURI = odp.getIRI().toString(); propertyNameURI.put(propertyURI, propertyName); //obtain type using the range - List propertyRanges = getCodeGenTypesByRangeData(ranges, odp); - String propertyDescription = ObaUtils.getDescription(odp, ontology_cls); List valuesFromDataRestrictions_ranges = new ArrayList(); Map restrictionValues = new HashMap() ; - for (OWLOntology ontology : ontologies) { - RestrictionVisitor restrictionVisitor = new RestrictionVisitor(cls,ontology,owlThing,propertyName); + for (OWLOntology ontology: this.ontologies) { + RestrictionVisitor restrictionVisitor = new RestrictionVisitor(this.cls, ontology, owlThing, propertyName); for (OWLDataPropertyRangeAxiom propertyRangeAxiom : ranges) { OWLDataRange ce = propertyRangeAxiom.getRange(); ce.accept(restrictionVisitor); @@ -205,6 +247,8 @@ private Map getDataProperties() { } } + List propertyRanges = getCodeGenTypesByRangeData(ranges, odp); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls); MapperDataProperty mapperProperty = new MapperDataProperty(propertyName, propertyDescription, isFunctional, restrictionValues,valuesFromDataRestrictions_ranges,propertyRanges, array, nullable); try { this.properties.put(mapperProperty.name, mapperProperty.getSchemaByDataProperty()); @@ -254,15 +298,16 @@ private Map getObjectProperties() { Set properties_class = new HashSet<>(); Set functional; - for (OWLOntology ontology : ontologies) + for (OWLOntology ontology: this.ontologies) { properties_class.addAll(ontology.getAxioms(AxiomType.OBJECT_PROPERTY_DOMAIN)); + } HashMap propertyNameURI = new HashMap<>(); Map properties = new HashMap<>(); - logger.info("Parsing class " + cls.toString()); + logger.info("Parsing class " + this.cls.toString()); for (OWLObjectPropertyDomainAxiom dp : properties_class) { - if (checkDomainClass(cls, dp)) { + if (checkDomainClass(this.cls, dp)) { logger.info( "Parsing property " + dp.toString()); for (OWLObjectProperty odp : dp.getObjectPropertiesInSignature()) { String propertyName = this.sfp.getShortForm(odp.getIRI()); @@ -272,17 +317,17 @@ private Map getObjectProperties() { // the object property has been previously analyzed on the getClassRestrictions method. // If the property was analyzed, we will change the value of inspect to false, otherwise // the property will be inspected. - if (propertiesFromObjectRestrictions.size() != 0) { + if (!propertiesFromObjectRestrictions.isEmpty()) { if (propertiesFromObjectRestrictions.contains(odp)) { inspect=false; } } - if (inspect) { + if (inspect) { Boolean isFunctional=false; Set ranges = new HashSet<>(); - for (OWLOntology ontology : ontologies) { + for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getObjectPropertyRangeAxioms(odp)); functional = ontology.getAxioms(AxiomType.FUNCTIONAL_OBJECT_PROPERTY); @@ -292,16 +337,17 @@ private Map getObjectProperties() { } } } - if (ranges.size() == 0) + if (ranges.isEmpty()) { logger.warning("Property " + odp.getIRI() + " has range equals zero"); + } String propertyURI = odp.getIRI().toString(); propertyNameURI.put(propertyURI, propertyName); List propertyRanges = getCodeGenTypesByRangeObject(ranges, odp, owlThing, follow_references); Map restrictionValues = new HashMap() ; - for (OWLOntology ontology : ontologies) { - RestrictionVisitor restrictionVisitor = new RestrictionVisitor(cls,ontology,owlThing,propertyName); + for (OWLOntology ontology: this.ontologies) { + RestrictionVisitor restrictionVisitor = new RestrictionVisitor(this.cls, ontology, owlThing, propertyName); for (OWLObjectPropertyRangeAxiom propertyRangeAxiom : ranges) { OWLClassExpression ce = propertyRangeAxiom.getRange(); ce.accept(restrictionVisitor); @@ -312,11 +358,11 @@ private Map getObjectProperties() { restrictionValues=restrictionsValuesFromClass.get(j); } } - if (restrictionsValuesFromClass.isEmpty() && propertyRanges.size()>1) + if (restrictionsValuesFromClass.isEmpty() && propertyRanges.size() > 1) propertyRanges.clear(); } - String propertyDescription = ObaUtils.getDescription(odp, ontology_cls); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls); MapperObjectProperty mapperObjectProperty = new MapperObjectProperty(propertyName, propertyDescription, isFunctional, restrictionValues, propertyRanges); try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); @@ -386,52 +432,51 @@ private List getCodeGenTypesByRangeObject(Set> restrictionsValuesFromClass = restrictionVisitor.getRestrictionsValuesFromClass(); - if (restrictionsValuesFromClass.size()!=0) { + if (!restrictionsValuesFromClass.isEmpty()) { // When the restriction is a ObjectComplementOf it doesn't have a object property, // thus we need to set its value at the setSchema function if (restrictionsValuesFromClass.containsKey("complementOf") && restrictionsValuesFromClass.size() == 1) { - for (String j : restrictionsValuesFromClass.keySet()) { - Map restrictionValues=restrictionsValuesFromClass.get(j); + for (String j: restrictionsValuesFromClass.keySet()) { + Map restrictionValues = restrictionsValuesFromClass.get(j); for (String restriction: restrictionValues.keySet()) { - complementOf = restrictionValues.get(restriction); + this.complementOf = restrictionValues.get(restriction); } } - } else { - - for (OWLObjectProperty op : propertiesFromObjectRestrictions) { + for (OWLObjectProperty op: this.propertiesFromObjectRestrictions) { MapperObjectProperty mapperObjectProperty; - String propertyDescription = ObaUtils.getDescription(op, ontology_cls); - if (propertiesFromObjectRestrictions_ranges.size() != 0) { - List rangesOP = propertiesFromObjectRestrictions_ranges.get(sfp.getShortForm(op.getIRI())); + String propertyDescription = ObaUtils.getDescription(op, this.ontology_cls); + if (!this.propertiesFromObjectRestrictions_ranges.isEmpty()) { + List rangesOP = this.propertiesFromObjectRestrictions_ranges.get(this.sfp.getShortForm(op.getIRI())); for (String j : restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); if (j.equals(sfp.getShortForm(op.getIRI()))) { if (rangesOP.get(0).equals("defaultValue")) - mapperObjectProperty = new MapperObjectProperty(sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, false, true); + mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, false, true); else - mapperObjectProperty = new MapperObjectProperty(sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP); + mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP); try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); } catch (Exception e) { @@ -441,15 +486,16 @@ private void getClassRestrictions(OWLClass analyzedClass){ } } } - for (OWLDataProperty dp : propertiesFromDataRestrictions) { + + for (OWLDataProperty dp: this.propertiesFromDataRestrictions) { List valuesFromDataRestrictions_ranges = new ArrayList<>(); - String propertyDescription = ObaUtils.getDescription(dp, ontology_cls); - if (propertiesFromDataRestrictions_ranges.size() != 0) { - List rangesDP = propertiesFromDataRestrictions_ranges.get(sfp.getShortForm(dp.getIRI())); - for (String j : restrictionsValuesFromClass.keySet()) { + String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls); + if (!this.propertiesFromDataRestrictions_ranges.isEmpty()) { + List rangesDP = this.propertiesFromDataRestrictions_ranges.get(this.sfp.getShortForm(dp.getIRI())); + for (String j: restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); - if (j.equals(sfp.getShortForm(dp.getIRI()))) { - MapperDataProperty mapperDataProperty = new MapperDataProperty(sfp.getShortForm(dp.getIRI()), propertyDescription, false, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, true, true); + if (j.equals(this.sfp.getShortForm(dp.getIRI()))) { + MapperDataProperty mapperDataProperty = new MapperDataProperty(this.sfp.getShortForm(dp.getIRI()), propertyDescription, false, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, true, true); try { this.properties.put(mapperDataProperty.name, mapperDataProperty.getSchemaByDataProperty()); } catch (Exception e) { @@ -464,21 +510,26 @@ private void getClassRestrictions(OWLClass analyzedClass){ } else { this.properties = setProperties(); + this.enumInstances = this.setEnums(); } } addDefaultProperties(this.properties); } + private List getEnums() { + return this.enumInstances; + } + private Map getProperties() { - return properties; + return this.properties; } private String getSchemaName(OWLClass cls) { - return schemaNames.get(cls.getIRI()); + return this.schemaNames.get(cls.getIRI()); } public OWLClass getCls() { - return cls; + return this.cls; } diff --git a/src/main/java/edu/isi/oba/RestrictionVisitor.java b/src/main/java/edu/isi/oba/RestrictionVisitor.java index 7b6543c..dfd9e41 100644 --- a/src/main/java/edu/isi/oba/RestrictionVisitor.java +++ b/src/main/java/edu/isi/oba/RestrictionVisitor.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Stream; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.util.IRIShortFormProvider; @@ -52,13 +51,12 @@ public class RestrictionVisitor implements OWLObjectVisitor { public Map> propertiesFromDataRestrictions_ranges; public List valuesFromDataRestrictions_ranges; - RestrictionVisitor(OWLClass visitedClass, OWLOntology onto, OWLClass owlThing, String propertyName ) { processedClasses = new HashSet(); - this.cls=visitedClass; - this.onto=onto; - this.property_name=propertyName; - this.owlThing=owlThing; + this.cls = visitedClass; + this.onto = onto; + this.property_name = propertyName; + this.owlThing = owlThing; this.propertiesFromObjectRestrictions_ranges= new HashMap<>(); this.propertiesFromObjectRestrictions = new ArrayList<>(); this.restrictionsValuesFromClass = new HashMap<>(); @@ -69,11 +67,11 @@ public class RestrictionVisitor implements OWLObjectVisitor { @Override public void visit(OWLClass ce) { - if (!processedClasses.contains(ce)) { + if (!this.processedClasses.contains(ce)) { // If we are processing inherited restrictions then we recursively visit named supers. - processedClasses.add(ce); - for (OWLSubClassOfAxiom ax : onto.getSubClassAxiomsForSubClass(ce)) { - ax.getSuperClass().accept(this); + this.processedClasses.add(ce); + for (OWLSubClassOfAxiom ax: this.onto.getSubClassAxiomsForSubClass(ce)) { + ax.getSuperClass().accept(this); } } } @@ -85,26 +83,33 @@ public void visit(OWLClass ce) { @Override public void visit(OWLObjectSomeValuesFrom ce) { Map restrictionsValues = new HashMap<>(); - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); - for(OWLObjectProperty property:ce.getObjectPropertiesInSignature()) { - propertiesFromObjectRestrictions.add(property); - property_name = sfp.getShortForm(property.getIRI()); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); + + for(OWLObjectProperty property: ce.getObjectPropertiesInSignature()) { + this.propertiesFromObjectRestrictions.add(property); + this.property_name = this.sfp.getShortForm(property.getIRI()); } - if (ce.getFiller() instanceof OWLObjectUnionOf || ce.getFiller() instanceof OWLObjectIntersectionOf || ce.getFiller() instanceof OWLObjectOneOf) { - restrictionsValues.put("someValuesFrom", ""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); + + OWLClassExpression ceFiller = ce.getFiller(); + if (ceFiller instanceof OWLObjectUnionOf || ceFiller instanceof OWLObjectIntersectionOf || ceFiller instanceof OWLObjectOneOf) { + restrictionsValues.put("someValuesFrom", ""); + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); ce.getFiller().accept(this); - } else { - List ranges = new ArrayList<>(); - ranges.add(sfp.getShortForm(ce.getFiller().asOWLClass().getIRI())); - if (ce.getFiller().asOWLClass().equals(owlThing)) { - logger.info("Ignoring owl:Thing range" + property_name); + } else { + if (ceFiller.asOWLClass().equals(owlThing)) { + logger.info("Ignoring owl:Thing range" + this.property_name); + } else { + if (this.propertiesFromObjectRestrictions_ranges.containsKey(this.property_name)) { + this.propertiesFromObjectRestrictions_ranges.get(this.property_name).add(this.sfp.getShortForm(ceFiller.asOWLClass().getIRI())); + } else { + List ranges = new ArrayList<>(); + ranges.add(this.sfp.getShortForm(ceFiller.asOWLClass().getIRI())); + this.propertiesFromObjectRestrictions_ranges.put(this.property_name, ranges); + } } - else - propertiesFromObjectRestrictions_ranges.put(property_name,ranges); - restrictionsValues.put("someValuesFrom", ""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); + restrictionsValues.put("someValuesFrom", ""); + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); } } @@ -179,32 +184,33 @@ public void visit( OWLObjectComplementOf ce ) { @Override public void visit(OWLObjectHasValue ce) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); List ranges = new ArrayList(); Map restrictionsValues = new HashMap(); - for(OWLObjectProperty property:ce.getObjectPropertiesInSignature()) { - property_name = sfp.getShortForm(property.getIRI()); - restrictionsValues.put("objectHasValue",ce.getValue().toString()); - restrictionsValuesFromClass.put(property_name, restrictionsValues); - propertiesFromObjectRestrictions.add(property); + for(OWLObjectProperty property: ce.getObjectPropertiesInSignature()) { + this.property_name = this.sfp.getShortForm(property.getIRI()); + restrictionsValues.put("objectHasValue", ce.getFiller().toString()); + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); + this.propertiesFromObjectRestrictions.add(property); ranges.add("defaultValue"); - propertiesFromObjectRestrictions_ranges.put(property_name,ranges); + this.propertiesFromObjectRestrictions_ranges.put(this.property_name, ranges); } } @Override public void visit( OWLObjectOneOf ce ) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); List ranges = new ArrayList(); Map restrictionsValues = new HashMap(); - Stream valores=ce.objectPropertiesInSignature(); + if (!property_name.isEmpty()) { - for (OWLIndividual individual : ce.getIndividuals()) { + for (OWLIndividual individual: ce.getIndividuals()) { ranges.add(individual.toString()); } - restrictionsValues.put("oneOf","someValuesFrom"); - restrictionsValuesFromClass.put(property_name, restrictionsValues); - propertiesFromObjectRestrictions_ranges.put(property_name,ranges); + + restrictionsValues.put("oneOf", "someValuesFrom"); + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); + this.propertiesFromObjectRestrictions_ranges.put(this.property_name, ranges); } } @@ -214,7 +220,7 @@ public void visit( OWLObjectOneOf ce ) { */ @Override public void visit( OWLDataAllValuesFrom ce ) { - logger.info( "\n Analized Class: " + this.cls+ " with axiom: "+ce); + logger.info( "\n Analyzed Class: " + this.cls+ " with axiom: "+ce); Map restrictionsValues = new HashMap(); for(OWLDataProperty property:ce.getDataPropertiesInSignature()) { propertiesFromDataRestrictions.add(property); @@ -242,28 +248,30 @@ public void visit( OWLDataAllValuesFrom ce ) { */ @Override public void visit( OWLDataSomeValuesFrom ce ) { - - logger.info( "\n Analized Class: " + this.cls+ " with axiom: "+ce); + logger.info( "\n Analyzed Class: " + this.cls + " with axiom: " + ce); Map restrictionsValues = new HashMap(); - for(OWLDataProperty property:ce.getDataPropertiesInSignature()) { - propertiesFromDataRestrictions.add(property); - property_name = sfp.getShortForm(property.getIRI()); + for(OWLDataProperty property: ce.getDataPropertiesInSignature()) { + this.propertiesFromDataRestrictions.add(property); + this.property_name = this.sfp.getShortForm(property.getIRI()); } - if (ce.getFiller() instanceof OWLDataUnionOf || ce.getFiller() instanceof OWLDataIntersectionOf) { + + OWLDataRange ceFiller = ce.getFiller(); + if (ceFiller instanceof OWLDataUnionOf || ceFiller instanceof OWLDataIntersectionOf) { restrictionsValues.put("someValuesFrom", ""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); + this.restrictionsValuesFromClass.put(property_name, restrictionsValues); ce.getFiller().accept(this); } else { List ranges = new ArrayList(); - ranges.add(sfp.getShortForm(ce.getFiller().asOWLDatatype().getIRI())); - if (ce.getFiller().asOWLDatatype().equals(owlThing)) { + ranges.add(this.sfp.getShortForm(ceFiller.asOWLDatatype().getIRI())); + + if (ceFiller.asOWLDatatype().equals(owlThing)) { logger.info("Ignoring owl:Thing range" + property_name); - } - else - propertiesFromDataRestrictions_ranges.put(property_name,ranges); + } else { + propertiesFromDataRestrictions_ranges.put(property_name, ranges); + } - restrictionsValues.put("someValuesFrom", ""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); + restrictionsValues.put("someValuesFrom", ""); + this.restrictionsValuesFromClass.put(property_name, restrictionsValues); } } @@ -303,44 +311,46 @@ public void visit( OWLDataExactCardinality ce ) { @Override public void visit( OWLDataOneOf ce ) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); List ranges = new ArrayList(); Map restrictionsValues = new HashMap(); - for (OWLLiteral value : ce.getValues()) { - ranges.add(sfp.getShortForm(value.getDatatype().getIRI())); - valuesFromDataRestrictions_ranges.add(value.getLiteral()); + + for (OWLLiteral value: ce.getValues()) { + ranges.add(this.sfp.getShortForm(value.getDatatype().getIRI())); + this.valuesFromDataRestrictions_ranges.add(value.getLiteral()); + restrictionsValues.put("oneOf", ""); + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); + this.propertiesFromDataRestrictions_ranges.put(this.property_name, ranges); } - restrictionsValues.put("oneOf",""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); - propertiesFromDataRestrictions_ranges.put(property_name,ranges); } @Override public void visit( OWLDataComplementOf ce ) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); List ranges = new ArrayList(); Map restrictionsValues = new HashMap(); - for (OWLDatatype value:ce.getDatatypesInSignature()){ - ranges.add(sfp.getShortForm(value.getIRI())); - restrictionsValues.put("complementOf", ""); - restrictionsValuesFromClass.put(property_name, restrictionsValues); - propertiesFromDataRestrictions_ranges.put(property_name,ranges); + for (OWLDatatype value: ce.getDatatypesInSignature()) { + ranges.add(this.sfp.getShortForm(value.getIRI())); + restrictionsValues.put("complementOf", ""); + restrictionsValuesFromClass.put(this.property_name, restrictionsValues); + propertiesFromDataRestrictions_ranges.put(this.property_name, ranges); } } @Override public void visit( OWLDataHasValue ce ) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); List ranges = new ArrayList(); Map restrictionsValues = new HashMap(); - for(OWLDataProperty property:ce.getDataPropertiesInSignature()) { - property_name = sfp.getShortForm(property.getIRI()); + for(OWLDataProperty property: ce.getDataPropertiesInSignature()) { + property_name = this.sfp.getShortForm(property.getIRI()); propertiesFromDataRestrictions.add(property); - restrictionsValues.put("dataHasValue",ce.getValue().getLiteral()); + restrictionsValues.put("dataHasValue", ce.getFiller().getLiteral()); restrictionsValuesFromClass.put(property_name, restrictionsValues); - for (OWLDatatype value:ce.getDatatypesInSignature()){ - ranges.add(sfp.getShortForm(value.getIRI())); - propertiesFromDataRestrictions_ranges.put(property_name,ranges); + + for (OWLDatatype value: ce.getDatatypesInSignature()) { + ranges.add(this.sfp.getShortForm(value.getIRI())); + propertiesFromDataRestrictions_ranges.put(this.property_name, ranges); } } } @@ -410,7 +420,7 @@ public void setBooleanCombinationProperties( Set ranges, Set } } - if (restrictionsValuesFromClass.size()!=0) { + if (!restrictionsValuesFromClass.isEmpty()) { for (String j : restrictionsValuesFromClass.keySet()) { if (j.equals(property_name)) { Map value = restrictionsValuesFromClass.get(property_name); @@ -420,8 +430,7 @@ public void setBooleanCombinationProperties( Set ranges, Set restrictionsValuesFromClass.put(property_name, restrictionsValues); } } - } - else { + } else { restrictionsValues.put(restriction, ""); restrictionsValuesFromClass.put(property_name, restrictionsValues); } @@ -472,11 +481,11 @@ public void setBooleanCombinationDataProperties( Set ranges, Set value = restrictionsValuesFromClass.get(property_name); - for (String i : value.keySet() ) { + for (String i : value.keySet()) { restrictionsValues.put(restriction, i); } restrictionsValuesFromClass.put(property_name, restrictionsValues); @@ -509,28 +518,28 @@ public void setDataPropertiesWithCardinality(OWLDataCardinalityRestriction ce, S restrictionsValuesFromClass.put(property_name, restrictionsValues); } - public Map> getRestrictionsValuesFromClass(){ - return restrictionsValuesFromClass; + public Map> getRestrictionsValuesFromClass() { + return this.restrictionsValuesFromClass; } - public List getPropertiesFromObjectRestrictions(){ - return propertiesFromObjectRestrictions; + public List getPropertiesFromObjectRestrictions() { + return this.propertiesFromObjectRestrictions; } - public Map> getPropertiesFromObjectRestrictions_ranges(){ - return propertiesFromObjectRestrictions_ranges; + public Map> getPropertiesFromObjectRestrictions_ranges() { + return this.propertiesFromObjectRestrictions_ranges; } - public List getPropertiesFromDataRestrictions(){ - return propertiesFromDataRestrictions; + public List getPropertiesFromDataRestrictions() { + return this.propertiesFromDataRestrictions; } - public List getValuesFromDataRestrictions_ranges(){ - return valuesFromDataRestrictions_ranges; + public List getValuesFromDataRestrictions_ranges() { + return this.valuesFromDataRestrictions_ranges; } - public Map> getPropertiesFromDataRestrictions_ranges(){ - return propertiesFromDataRestrictions_ranges; + public Map> getPropertiesFromDataRestrictions_ranges() { + return this.propertiesFromDataRestrictions_ranges; } } From 3f604d173f48cec999bd3770d4960eb20cb0f867 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:23:32 -0500 Subject: [PATCH 08/36] bump the version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 19d55bb..846bf31 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ jar edu.isi.oba oba - 3.7.0 + 3.7.1 core https://github.com/KnowledgeCaptureAndDiscovery/OBA From 03b96d052092ce1d854fe3899dcf96ed64a50d04 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:58:17 -0500 Subject: [PATCH 09/36] add config default desc/props flags --- docs/configuration_file.md | 219 ++++++++++-------- docs/filtering.md | 118 ++++++++-- src/main/java/edu/isi/oba/Mapper.java | 57 +++-- .../java/edu/isi/oba/MapperDataProperty.java | 178 +++++++------- .../edu/isi/oba/MapperObjectProperty.java | 4 +- src/main/java/edu/isi/oba/MapperSchema.java | 120 ++++++---- src/main/java/edu/isi/oba/Oba.java | 22 +- src/main/java/edu/isi/oba/ObaUtils.java | 44 ++-- .../java/edu/isi/oba/config/YamlConfig.java | 19 +- src/test/java/edu/isi/oba/MapperTest.java | 4 +- src/test/java/edu/isi/oba/ObaUtilsTest.java | 2 +- .../java/edu/isi/oba/RestrictionsTest.java | 92 ++++---- 12 files changed, 520 insertions(+), 359 deletions(-) diff --git a/docs/configuration_file.md b/docs/configuration_file.md index ec27bb2..35346bb 100644 --- a/docs/configuration_file.md +++ b/docs/configuration_file.md @@ -7,8 +7,7 @@ Below is an example YAML file which may require some changes for your project's You can find examples in [GitHub](https://github.com/KnowledgeCaptureAndDiscovery/OBA/tree/master/examples) !!! info - If you experience any issues when using OBA, or if you would like us to support additional exciting features, please open an issue on our [GitHub repository](https://github.com/KnowledgeCaptureAndDiscovery/OBA/issues). - +If you experience any issues when using OBA, or if you would like us to support additional exciting features, please open an issue on our [GitHub repository](https://github.com/KnowledgeCaptureAndDiscovery/OBA/issues). ```yaml #Name of the project @@ -25,7 +24,7 @@ openapi: version: v1.3.0 externalDocs: description: DBpedia - url: http://dbpedia.org/ + url: http://dbpedia.org/ servers: - url: https://dbpedia.dbpedia.oba.isi.edu/v1.3.0 - url: http://localhost:8080/v1.3.0 @@ -50,9 +49,15 @@ enable_put_paths: false classes: - http://dbpedia.org/ontology/Genre - http://dbpedia.org/ontology/Band + follow_references: false -``` +## Enable/disable generation of a default description for each schema +default_descriptions: true + +## Enable/disable generation of default properties (description, id, label, and type) for each schema +default_properties: true +``` ## Supported settings @@ -60,9 +65,9 @@ follow_references: false The name of OpenAPI -| Field | Value | -|---|---| -| **Required:** | ``true`` | +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | Example: @@ -70,16 +75,14 @@ Example: name: dbpedia_music ``` - ### output_dir The output directory of the OpenApi specification files, relative to the root of the project. -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Default:** | ``outputs`` | - +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Default:** | `outputs` | Example: @@ -87,17 +90,15 @@ Example: output_dir: outputs ``` - ### OpenAPI Basic information of API using OpenAPI Spec. More info: [OpenAPI Base file](https://swagger.io/docs/specification/basic-structure/) -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``OpenAPI`` | - +| Field | Value | +| ------------- | --------- | +| **Required:** | `true` | +| **Type:** | `OpenAPI` | Example: @@ -110,56 +111,51 @@ openapi: version: v1.3.0 externalDocs: description: DBpedia - url: http://dbpedia.org/ + url: http://dbpedia.org/ servers: - url: https://dbpedia.dbpedia.oba.isi.edu/v1.3.0 - url: http://localhost:8080/v1.3.0 ``` - - ### enable_get_paths Enable the GET method for the paths -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``boolean`` | -| **Default:** | ``true`` | +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `boolean` | +| **Default:** | `true` | -### enable_post_paths: +### enable_post_paths: Enable the POST method for the paths -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``boolean`` | -| **Default:** | ``false`` | - +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `boolean` | +| **Default:** | `false` | ### enable_delete_paths Enable the DELETE method for the paths -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``boolean`` | -| **Default:** | ``false`` | +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `boolean` | +| **Default:** | `false` | ### enable_put_paths Enable the PUT method for the paths -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``boolean`` | -| **Default:** | ``false`` | - - +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `boolean` | +| **Default:** | `false` | ### endpoint @@ -170,64 +166,57 @@ endpoint: url: http://dbpedia.org/sparql prefix: http://dbpedia.org/resource # Add the GRAPH clause. Enable it when you are using authentication. - # OBA uses a graph to store the user contents on a personal namespace. + # OBA uses a graph to store the user contents on a personal namespace. # For DBpedia, dont use it. - graph: http://endpoint.mint.isi.edu/modelCatalog-1.4.0/data/ + graph: http://endpoint.mint.isi.edu/modelCatalog-1.4.0/data/ ``` ### endpoint.url -The url of the SPARQL Endpoint - -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``url`` | +The url of the SPARQL Endpoint +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | +| **Type:** | `url` | Example: ```yaml - url: http://dbpedia.org/sparql +url: http://dbpedia.org/sparql ``` - ### endpoint.prefix - The prefix of the SPARQL Endpoint. This is useful when you create a new resource. -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``url`` | - +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | +| **Type:** | `url` | Example: ```yaml - prefix: http://dbpedia.org/resource +prefix: http://dbpedia.org/resource ``` - ### endpoint.graph_base -OBA uses a graph to store the user contents on a personal namespace. - -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``url`` | +OBA uses a graph to store the user contents on a personal namespace. +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | +| **Type:** | `url` | Example: ```yaml - graph_base: http://ontosoft.isi.edu:3030/modelCatalog-1.2.0/data/ +graph_base: http://ontosoft.isi.edu:3030/modelCatalog-1.2.0/data/ ``` - ## ontologies Example: @@ -236,17 +225,18 @@ Example: ontologies: - https://tinyurl.com/dbpediaoba ``` -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``List[string]`` | + +| Field | Value | +| ------------- | -------------- | +| **Required:** | `true` | +| **Type:** | `List[string]` | ## custom_queries_directory -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``List[Path]`` | +| Field | Value | +| ------------- | ------------ | +| **Required:** | `false` | +| **Type:** | `List[Path]` | [Go to how to add custom queries](adding_custom_queries.md) for more information @@ -256,10 +246,10 @@ Some ontologies contain numerous classes. However, you can be interested in a su ### classes -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``List[URI]`` | +| Field | Value | +| ------------- | ----------- | +| **Required:** | `false` | +| **Type:** | `List[URI]` | ```yaml classes: @@ -269,12 +259,11 @@ classes: ### follow_references -| Field | Value | -|---|---| -| **Required:** | ``false`` | -| **Type:** | ``Boolean`` | -| **Default:** | ``True`` | - +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `Boolean` | +| **Default:** | `True` | For more information, go to [filtering classes](filtering.md#following-references) @@ -282,18 +271,48 @@ For more information, go to [filtering classes](filtering.md#following-reference follow_references: false ``` +### default_descriptions + +Enable/disable generation of a default description for each schema. + +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `Boolean` | +| **Default:** | `True` | + +For more information, go to [filtering classes](filtering.md#default_descriptions) + +```yaml +default_descriptions: false +``` + +### default_properties + +Enable/disable generation of default properties (description, id, label, and type) for each schema. + +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `Boolean` | +| **Default:** | `True` | + +For more information, go to [filtering classes](filtering.md#default_properties) + +```yaml +default_properties: false +``` ## auth Add login to the API and add security to the following methods: `POST`, `PUT` and `DELETE` - ### provider -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``str`` | +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | +| **Type:** | `str` | The providers supported: @@ -314,12 +333,10 @@ firebase: To authenticate a service account and authorize it to access Firebase services, you must generate a private key file. - - -| Field | Value | -|---|---| -| **Required:** | ``true`` | -| **Type:** | ``str`` | +| Field | Value | +| ------------- | ------ | +| **Required:** | `true` | +| **Type:** | `str` | ``` firebase: diff --git a/docs/filtering.md b/docs/filtering.md index 06b97e4..3971d95 100644 --- a/docs/filtering.md +++ b/docs/filtering.md @@ -3,8 +3,8 @@ OBA can filter the classes. The following example is selecting two classes: - - http://dbpedia.org/ontology/Genre - - http://dbpedia.org/ontology/Band +- http://dbpedia.org/ontology/Genre +- http://dbpedia.org/ontology/Band ```yaml ### For more information about the section. Go to the official documentation @@ -42,12 +42,18 @@ enable_put_paths: false classes: - http://dbpedia.org/ontology/Genre - http://dbpedia.org/ontology/Band + follow_references: false + +## Enable/disable generation of a default description for each schema +default_descriptions: true + +## Enable/disable generation of default properties (description, id, label, and type) for each schema +default_properties: true ``` The result is available at: [DBPedia Music](https://app.swaggerhub.com/apis/mosoriob/dbpedia-music/v1.3.0) - ### Following references If you inspect the properties of a Band, you can see the a Band has one or more locationCity. However, a locationCity is a object then you don't have information about the object. @@ -68,24 +74,23 @@ The option `follow_references` enables to follow the references. Let's enable the option for the previous example. Now, you have the whole information: -- A city has 423 properties. -- One property is the leaderName and a leaderName is Person. -- A person has 285. +- A city has 423 properties. +- One property is the leaderName and a leaderName is Person. +- A person has 285. !!! warning - For large ontologies, we don't recommend use the option because the result can be too heavy. - +For large ontologies, we don't recommend use the option because the result can be too heavy. ```yaml components: schemas: Band: - locationCity: - items: - $ref: '#/components/schemas/City' - nullable: true - type: array + locationCity: + items: + $ref: "#/components/schemas/City" + nullable: true + type: array City: properties: cityType: @@ -100,7 +105,7 @@ components: type: array reffBourgmestre: items: - $ref: '#/components/schemas/Person' + $ref: "#/components/schemas/Person" nullable: true type: array communityIsoCode: @@ -110,14 +115,14 @@ components: type: array leaderName: items: - $ref: '#/components/schemas/Person' + $ref: "#/components/schemas/Person" nullable: true type: array Person: properties: parent: items: - $ref: '#/components/schemas/Person' + $ref: "#/components/schemas/Person" nullable: true type: array viafId: @@ -127,17 +132,92 @@ components: type: array competitionTitle: items: - $ref: '#/components/schemas/SportsEvent' + $ref: "#/components/schemas/SportsEvent" nullable: true type: array artPatron: items: - $ref: '#/components/schemas/Artist' + $ref: "#/components/schemas/Artist" nullable: true type: array hairColour: items: type: string nullable: true - type: array + type: array +``` + +### Including default schema descriptions + +It is generally good practice to include a high-level description for a schema. By default, a placeholder description is included with the text `Description not available`. For example: + +```yaml +components: + schemas: + YourClass: + description: Description not available + properties: {} + type: object +``` + +The option `default_descriptions` allows you to disable the default description for a schema (i.e. if there is no description/comment defined for an entity/class in the ontology). By setting the `default_descriptions` value to `false`, the above example becomes: + +```yaml +components: + schemas: + YourClass: + properties: {} + type: object +``` + +### Including default schema properties + +You may wish to include common properties for each even if not defined for the entity/class. Currently, the default properites that are added to each schema are `description`, `id`, `label`, and `type`. For example: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + type: string + propertyB: + type: integer + description: + description: small description + items: + type: string + nullable: true + type: array + id: + description: identifier + nullable: false + type: string + label: + description: short description of the resource + items: + type: string + nullable: true + type: array + type: + description: type of the resource + items: + type: string + nullable: true + type: array + type: object +``` + +The option `default_properties` allows you to disable the default properties for a schema. If one or more of the properties are defined for the class, however, the property will still be included in the OpenAPI YAML specification. By setting the `default_properties` value to `false`, the above example becomes: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + type: string + propertyB: + type: integer + type: object ``` diff --git a/src/main/java/edu/isi/oba/Mapper.java b/src/main/java/edu/isi/oba/Mapper.java index 1c3fcf1..9d931a2 100644 --- a/src/main/java/edu/isi/oba/Mapper.java +++ b/src/main/java/edu/isi/oba/Mapper.java @@ -1,14 +1,11 @@ package edu.isi.oba; import edu.isi.oba.config.YamlConfig; +import static edu.isi.oba.Oba.logger; + import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.io.FileDocumentSource; -import org.semanticweb.owlapi.model.*; - -import static edu.isi.oba.Oba.logger; import java.io.File; import java.io.IOException; @@ -19,6 +16,10 @@ import java.util.logging.Logger; import java.util.stream.Collectors; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.io.FileDocumentSource; +import org.semanticweb.owlapi.model.*; + class Mapper { public static final String DEFAULT_DIR_QUERY = "_default_"; public final Map schemaNames = new HashMap<>(); //URI-names of the schemas @@ -33,19 +34,24 @@ class Mapper { public OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); private Boolean follow_references; + private Boolean default_descriptions; + private Boolean default_properties; public Mapper(YamlConfig config_data) throws OWLOntologyCreationException, IOException { this.config_data = config_data; this.selected_paths = config_data.getPaths(); this.mappedClasses = new ArrayList<>(); this.follow_references = config_data.getFollow_references(); + this.default_descriptions = config_data.getDefault_descriptions(); + this.default_properties = config_data.getDefault_properties(); List config_ontologies = config_data.getOntologies(); String destination_dir = config_data.getOutput_dir() + File.separator + config_data.getName(); File outputDir = new File(destination_dir); - if (!outputDir.exists()){ + if (!outputDir.exists()) { outputDir.mkdirs(); } + //Load the ontology into the manager int i = 0; List ontologyPaths = new ArrayList<>(); @@ -60,8 +66,10 @@ public Mapper(YamlConfig config_data) throws OWLOntologyCreationException, IOExc setSchemaNames(classes); setSchemaDrescriptions(classes,ontology); } - if (config_data.getClasses() != null) + + if (config_data.getClasses() != null) { this.selected_classes = filter_classes(); + } } private void download_ontologies(List config_ontologies, String destination_dir, int i, List ontologyPaths) throws OWLOntologyCreationException, IOException { @@ -100,19 +108,21 @@ private void download_ontologies(List config_ontologies, String destinat * @param destination_dir directory to write the final results * @param config_data yaml configuration */ - public void createSchemas(String destination_dir, YamlConfig config_data) { + public void createSchemas(String destination_dir) { Query query = new Query(destination_dir); - Path pathGenerator = new Path(config_data.getEnable_get_paths(), - config_data.getEnable_post_paths(), - config_data.getEnable_put_paths(), - config_data.getEnable_delete_paths(), - config_data.getAuth().getEnable() + Path pathGenerator = new Path(this.config_data.getEnable_get_paths(), + this.config_data.getEnable_post_paths(), + this.config_data.getEnable_put_paths(), + this.config_data.getEnable_delete_paths(), + this.config_data.getAuth().getEnable() ); + try { query.get_all(DEFAULT_DIR_QUERY); } catch (Exception e) { logger.severe("Unable write the queries"); } + for (OWLOntology ontology : this.ontologies) { OWLDocumentFormat format = ontology.getFormat(); @@ -121,19 +131,21 @@ public void createSchemas(String destination_dir, YamlConfig config_data) { logger.severe("Unable to find the default prefix for the ontology"); System.exit(1); } - Set classes = ontology.getClassesInSignature(); + Set classes = ontology.getClassesInSignature(); for (OWLClass cls : classes) { //filter if the class prefix does not have the default ontology prefix if (cls.getIRI() != null) { - if (selected_classes == null || selected_classes.contains(cls)){ + if (selected_classes == null || selected_classes.contains(cls)) { add_owlclass_to_openapi(query, pathGenerator, ontology, defaultOntologyPrefixIRI, cls, true); } } } } - if (this.config_data.getAuth().getEnable()) + + if (this.config_data.getAuth().getEnable()) { add_user_path(pathGenerator); + } } private void add_user_path(Path pathGenerator) { @@ -207,7 +219,7 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass cls, String cls_description) { //Convert from OWL Class to OpenAPI Schema. - MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, schemaNames, ontology, follow_references); + MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, schemaNames, ontology, this.follow_references, this.default_descriptions, this.default_properties); //Write queries query.write_readme(mapperSchema.name); //Create the OpenAPI schema @@ -217,10 +229,11 @@ private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass } private void addOpenAPIPaths(Path pathGenerator, MapperSchema mapperSchema, OWLClass cls) { - if (selected_classes != null && !selected_classes.contains(cls)) + if (selected_classes != null && !selected_classes.contains(cls)) { logger.info("Ignoring class " + cls.toString()); - else + } else { add_path(pathGenerator, mapperSchema); + } } private void setSchemaNames(Set classes) { @@ -235,10 +248,10 @@ private void setSchemaNames(Set classes) { * @param classes the classes you want the description for * @param ontology the ontology from where we will extract the descriptions */ - private void setSchemaDrescriptions(Set classes,OWLOntology ontology){ - for (OWLClass cls : classes) { + private void setSchemaDrescriptions(Set classes, OWLOntology ontology){ + for (OWLClass cls: classes) { System.out.println(cls); - schemaDescriptions.put(cls.getIRI(), ObaUtils.getDescription(cls, ontology)); + schemaDescriptions.put(cls.getIRI(), ObaUtils.getDescription(cls, ontology, this.default_descriptions)); } } diff --git a/src/main/java/edu/isi/oba/MapperDataProperty.java b/src/main/java/edu/isi/oba/MapperDataProperty.java index d0ff814..73cf860 100644 --- a/src/main/java/edu/isi/oba/MapperDataProperty.java +++ b/src/main/java/edu/isi/oba/MapperDataProperty.java @@ -1,68 +1,64 @@ package edu.isi.oba; +import static edu.isi.oba.Oba.logger; + import io.swagger.v3.oas.models.media.*; -import java.util.HashMap; import java.util.List; import java.util.Map; -import static edu.isi.oba.Oba.logger; - class MapperDataProperty { - private final HashMap dataTypes; - - private void setDataTypes() { - this.dataTypes.put("ENTITIES", "string"); - this.dataTypes.put("ENTITY", "string"); - this.dataTypes.put("ID", "string"); - this.dataTypes.put("IDREF", "string"); - this.dataTypes.put("IDREFS", "string"); - this.dataTypes.put("NCName", "string"); - this.dataTypes.put("NMTOKEN", "string"); - this.dataTypes.put("NMTOKENS", "string"); - this.dataTypes.put("NOTATION", "string"); - this.dataTypes.put("Name", "string"); - this.dataTypes.put("QName", "string"); - this.dataTypes.put("anySimpleType", "string"); - this.dataTypes.put("anyType", "string"); - this.dataTypes.put("anyURI", "string"); - this.dataTypes.put("base64Binary", "string"); - this.dataTypes.put("boolean", "boolean"); - this.dataTypes.put("byte", "integer"); - this.dataTypes.put("date", "string"); - this.dataTypes.put("dateTime", "dateTime"); - this.dataTypes.put("dateTimeStamp", "dateTime"); - this.dataTypes.put("decimal", "number"); - this.dataTypes.put("double", "number"); - this.dataTypes.put("duration", "string"); - this.dataTypes.put("float", "number"); - this.dataTypes.put("gDay", "string"); - this.dataTypes.put("gMonth", "string"); - this.dataTypes.put("gMonthYear", "string"); - this.dataTypes.put("gYear", "string"); - this.dataTypes.put("gYearMonth", "string"); - this.dataTypes.put("hexBinary", "string"); - this.dataTypes.put("int", "integer"); - this.dataTypes.put("integer", "integer"); - this.dataTypes.put("language", "string"); - this.dataTypes.put("long", "integer"); - this.dataTypes.put("negativeInteger", "integer"); - this.dataTypes.put("nonNegativeInteger", "integer"); - this.dataTypes.put("nonPositiveInteger", "integer"); - this.dataTypes.put("normalizedString", "string"); - this.dataTypes.put("positiveInteger", "integer"); - this.dataTypes.put("short", "integer"); - this.dataTypes.put("string", "string"); - this.dataTypes.put("time", "string"); - this.dataTypes.put("token", "string"); - this.dataTypes.put("unsignedByte", "integer"); - this.dataTypes.put("unsignedInt", "integer"); - this.dataTypes.put("unsignedLong", "integer"); - this.dataTypes.put("unsignedShort", "integer"); - this.dataTypes.put("langString", "string"); - this.dataTypes.put("Literal", "string"); - - } + private final Map dataTypes = Map.ofEntries( + Map.entry("ENTITIES", "string"), + Map.entry("ENTITY", "string"), + Map.entry("ID", "string"), + Map.entry("IDREF", "string"), + Map.entry("IDREFS", "string"), + Map.entry("NCName", "string"), + Map.entry("NMTOKEN", "string"), + Map.entry("NMTOKENS", "string"), + Map.entry("NOTATION", "string"), + Map.entry("Name", "string"), + Map.entry("QName", "string"), + Map.entry("anySimpleType", "string"), + Map.entry("anyType", "string"), + Map.entry("anyURI", "string"), + Map.entry("base64Binary", "string"), + Map.entry("boolean", "boolean"), + Map.entry("byte", "integer"), + Map.entry("date", "string"), + Map.entry("dateTime", "dateTime"), + Map.entry("dateTimeStamp", "dateTime"), + Map.entry("decimal", "number"), + Map.entry("double", "number"), + Map.entry("duration", "string"), + Map.entry("float", "number"), + Map.entry("gDay", "string"), + Map.entry("gMonth", "string"), + Map.entry("gMonthYear", "string"), + Map.entry("gYear", "string"), + Map.entry("gYearMonth", "string"), + Map.entry("hexBinary", "string"), + Map.entry("int", "integer"), + Map.entry("integer", "integer"), + Map.entry("language", "string"), + Map.entry("long", "integer"), + Map.entry("negativeInteger", "integer"), + Map.entry("nonNegativeInteger", "integer"), + Map.entry("nonPositiveInteger", "integer"), + Map.entry("normalizedString", "string"), + Map.entry("positiveInteger", "integer"), + Map.entry("short", "integer"), + Map.entry("string", "string"), + Map.entry("time", "string"), + Map.entry("token", "string"), + Map.entry("unsignedByte", "integer"), + Map.entry("unsignedInt", "integer"), + Map.entry("unsignedLong", "integer"), + Map.entry("unsignedShort", "integer"), + Map.entry("langString", "string"), + Map.entry("Literal", "string") + ); private String getDataType(String key){ return this.dataTypes.get(key); @@ -83,10 +79,7 @@ private String getDataType(String key){ private Map restrictions; private List valuesFromDataRestrictions_ranges; - - public MapperDataProperty(String name, String description, Boolean isFunctional,Map restrictions,List valuesFromDataRestrictions_ranges, List type, Boolean array, Boolean nullable) { - this.dataTypes = new HashMap<>(); - this.setDataTypes(); + public MapperDataProperty(String name, String description, Boolean isFunctional, Map restrictions, List valuesFromDataRestrictions_ranges, List type, Boolean array, Boolean nullable) { this.name = name; this.description = description; this.type = type; @@ -135,40 +128,52 @@ else if (this.type.size() > 1) { */ private ArraySchema composedSchema(List base, boolean nullable){ ArraySchema array = new ArraySchema(); - Schema schema ; - ComposedSchema composedSchema = new ComposedSchema() ; + Schema schema; + ComposedSchema composedSchema = new ComposedSchema(); array.setDescription(description); - array.setNullable(nullable); + array.setNullable(nullable); + // Operations for managing boolean combinations for (String restriction: restrictions.keySet()) { String value = restrictions.get(restriction); - for (String item:base) { + for (String item: base) { switch (getDataType(item)) { case STRING_TYPE: schema = new StringSchema(); - if (item.equals("anyURI")) - schema.format("uri"); - else if (item.equals("byte")) - schema.format("byte"); - break ; + + if (item.equals("anyURI")) { + schema.format("uri"); + } else if (item.equals("byte")) { + schema.format("byte"); + } + + break; case NUMBER_TYPE: schema = new NumberSchema(); - if (item.equals("float")) - schema.format("float"); - else if (item.equals("double")) - schema.format("double"); - break ; + + if (item.equals("float")) { + schema.format("double"); + } else if (item.equals("double")) { + schema.format("double"); + } else { + schema.format("number"); + } + + break; case INTEGER_TYPE: schema = new IntegerSchema(); - if (item.equals("long")) - schema.format("int64"); - break ; + + if (item.equals("long")) { + schema.format("int64"); + } + + break; case BOOLEAN_TYPE: schema = new BooleanSchema(); - break ; + break; case DATETIME_TYPE: schema = new DateTimeSchema(); - break ; + break; default: logger.warning("datatype mapping failed " + this.type.get(0)); schema = new Schema(); @@ -190,12 +195,15 @@ else if (item.equals("double")) } } } - array.setItems(composedSchema); - if (isFunctional) - array.setMaxItems(1); - array.setNullable(nullable); - return array ; + array.setItems(composedSchema); + array.setNullable(nullable); + + if (isFunctional) { + array.setMaxItems(1); + } + + return array; } private ArraySchema arraySchema(Schema base, boolean nullable) { diff --git a/src/main/java/edu/isi/oba/MapperObjectProperty.java b/src/main/java/edu/isi/oba/MapperObjectProperty.java index 814b438..e3d903b 100644 --- a/src/main/java/edu/isi/oba/MapperObjectProperty.java +++ b/src/main/java/edu/isi/oba/MapperObjectProperty.java @@ -1,9 +1,9 @@ package edu.isi.oba; -import io.swagger.v3.oas.models.media.*; - import static edu.isi.oba.Oba.logger; +import io.swagger.v3.oas.models.media.*; + import java.util.LinkedHashSet; import java.util.List; import java.util.Map; diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 8a6c107..20c4447 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -8,6 +8,7 @@ import java.util.*; +import org.openapitools.codegen.examples.ExampleGenerator; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.OWLReasoner; @@ -35,6 +36,8 @@ class MapperSchema { private OWLReasonerFactory reasonerFactory; public List properties_range; private boolean follow_references; + private Boolean default_descriptions; + private Boolean default_properties; public List propertiesFromObjectRestrictions; public Map> propertiesFromObjectRestrictions_ranges; @@ -43,24 +46,27 @@ class MapperSchema { public Map> propertiesFromDataRestrictions_ranges; public List getProperties_range() { - return properties_range; + return this.properties_range; } - public List getPropertiesFromObjectRestrictions_ranges(){ + public List getPropertiesFromObjectRestrictions_ranges() { List aggregatedClasses = new ArrayList<>(); - for (List l : propertiesFromObjectRestrictions_ranges.values()){ + for (List l: this.propertiesFromObjectRestrictions_ranges.values()) { aggregatedClasses.addAll(l); } + return aggregatedClasses; } public Schema getSchema() { - return schema; + return this.schema; } - public MapperSchema(List ontologies, OWLClass cls, String clsDescription, Map schemaNames, OWLOntology class_ontology, Boolean follow_references) { + public MapperSchema(List ontologies, OWLClass cls, String clsDescription, Map schemaNames, OWLOntology class_ontology, Boolean follow_references, Boolean default_descriptions, Boolean default_properties) { this.schemaNames = schemaNames; this.follow_references = follow_references; + this.default_descriptions = default_descriptions; + this.default_properties = default_properties; this.cls = cls; this.cls_description = clsDescription; this.type = "object"; @@ -133,11 +139,12 @@ private Schema setSchema() { * @return true or false */ private boolean checkDomainClass(OWLClass cls, OWLPropertyDomainAxiom dp) { - Set superDomainClasses = reasoner.getSuperClasses(cls, false).getFlattened(); + Set superDomainClasses = this.reasoner.getSuperClasses(cls, false).getFlattened(); Set domainClasses = dp.getDomain().getClassesInSignature(); for (OWLClass domainClass : domainClasses) { - if (domainClass.equals(cls)) - return true; + if (domainClass.equals(cls)) { + return true; + } //check super classes for (OWLClass superClass : superDomainClasses) { @@ -208,13 +215,14 @@ private Map getDataProperties() { } if (inspect) { - Boolean isFunctional=false; + Boolean isFunctional = false; for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getDataPropertyRangeAxioms(odp)); functional = ontology.getAxioms(AxiomType.FUNCTIONAL_DATA_PROPERTY); for (OWLFunctionalDataPropertyAxiom functionalAxiom:functional) { - if (functionalAxiom.getProperty().equals(odp)) - isFunctional = true; + if (functionalAxiom.getProperty().equals(odp)) { + isFunctional = true; + } } } @@ -228,8 +236,7 @@ private Map getDataProperties() { //obtain type using the range List valuesFromDataRestrictions_ranges = new ArrayList(); - - Map restrictionValues = new HashMap() ; + Map restrictionValues = new HashMap(); for (OWLOntology ontology: this.ontologies) { RestrictionVisitor restrictionVisitor = new RestrictionVisitor(this.cls, ontology, owlThing, propertyName); for (OWLDataPropertyRangeAxiom propertyRangeAxiom : ranges) { @@ -248,8 +255,8 @@ private Map getDataProperties() { } List propertyRanges = getCodeGenTypesByRangeData(ranges, odp); - String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls); - MapperDataProperty mapperProperty = new MapperDataProperty(propertyName, propertyDescription, isFunctional, restrictionValues,valuesFromDataRestrictions_ranges,propertyRanges, array, nullable); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.default_descriptions); + MapperDataProperty mapperProperty = new MapperDataProperty(propertyName, propertyDescription, isFunctional, restrictionValues, valuesFromDataRestrictions_ranges, propertyRanges, array, nullable); try { this.properties.put(mapperProperty.name, mapperProperty.getSchemaByDataProperty()); } catch (Exception e) { @@ -259,32 +266,45 @@ private Map getDataProperties() { } } } - addDefaultProperties(properties); + + if (this.default_properties) { + properties.putAll(this.getDefaultProperties()); + } + return properties; } /** - * Add DefaultProperties - * @param properties HashMap + * Get default schema properties. + * + * These can be disabled by setting `default_properties` to `false` in the `config.yaml` file. + * + * @return A HashMap key: propertyName, value: Schema of data property */ - private void addDefaultProperties(Map properties) { - List defaultProperties = new ArrayList(){ - { - add("string"); - } - }; + private Map getDefaultProperties() { Map defaultRestrictionValues = new HashMap(); List valuesFromDataRestrictions_ranges = new ArrayList(); - MapperDataProperty idProperty = new MapperDataProperty("id", "identifier", true, defaultRestrictionValues,valuesFromDataRestrictions_ranges,defaultProperties, false, false); - MapperDataProperty labelProperty = new MapperDataProperty("label", "short description of the resource", false,defaultRestrictionValues,valuesFromDataRestrictions_ranges, defaultProperties, true, true); - MapperDataProperty typeProperty = new MapperDataProperty("type", "type of the resource", false, defaultRestrictionValues,valuesFromDataRestrictions_ranges, defaultProperties, true, true); - MapperDataProperty descriptionProperty = new MapperDataProperty("description", "small description", false, defaultRestrictionValues,valuesFromDataRestrictions_ranges, defaultProperties, true, true); - - properties.put(idProperty.name, idProperty.getSchemaByDataProperty()); - properties.put(labelProperty.name, labelProperty.getSchemaByDataProperty()); - properties.put(typeProperty.name, typeProperty.getSchemaByDataProperty()); - properties.put(descriptionProperty.name, descriptionProperty.getSchemaByDataProperty()); + // Add some typical default properties (e.g. id, lable, type, and description) + MapperDataProperty idProperty = new MapperDataProperty("id", "identifier", true, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("integer");}}, false, false); + MapperDataProperty labelProperty = new MapperDataProperty("label", "short description of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); + MapperDataProperty typeProperty = new MapperDataProperty("type", "type of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); + MapperDataProperty descriptionProperty = new MapperDataProperty("description", "small description", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); + + // Also add some default property examples of different types (e.g. a date/time, a boolean, and a float) + MapperDataProperty eventDateTimeProperty = new MapperDataProperty("eventDateTime", "a date time of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("dateTime");}}, false, true); + MapperDataProperty isBoolProperty = new MapperDataProperty("isGood", "a boolean indicator of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("boolean");}}, false, true); + MapperDataProperty quantityProperty = new MapperDataProperty("quantity", "a number quantity of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("float");}}, false, true); + + return Map.ofEntries( + Map.entry(idProperty.name, idProperty.getSchemaByDataProperty()), + Map.entry(labelProperty.name, labelProperty.getSchemaByDataProperty()), + Map.entry(typeProperty.name, typeProperty.getSchemaByDataProperty()), + Map.entry(descriptionProperty.name, descriptionProperty.getSchemaByDataProperty()), + Map.entry(eventDateTimeProperty.name, eventDateTimeProperty.getSchemaByDataProperty()), + Map.entry(isBoolProperty.name, isBoolProperty.getSchemaByDataProperty()), + Map.entry(quantityProperty.name, quantityProperty.getSchemaByDataProperty()) + ); } /** @@ -319,13 +339,13 @@ private Map getObjectProperties() { // the property will be inspected. if (!propertiesFromObjectRestrictions.isEmpty()) { if (propertiesFromObjectRestrictions.contains(odp)) { - inspect=false; + inspect = false; } } if (inspect) { - Boolean isFunctional=false; + Boolean isFunctional = false; Set ranges = new HashSet<>(); for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getObjectPropertyRangeAxioms(odp)); @@ -337,13 +357,14 @@ private Map getObjectProperties() { } } } + if (ranges.isEmpty()) { logger.warning("Property " + odp.getIRI() + " has range equals zero"); } String propertyURI = odp.getIRI().toString(); propertyNameURI.put(propertyURI, propertyName); - List propertyRanges = getCodeGenTypesByRangeObject(ranges, odp, owlThing, follow_references); + List propertyRanges = getCodeGenTypesByRangeObject(ranges, odp, owlThing, this.follow_references); Map restrictionValues = new HashMap() ; for (OWLOntology ontology: this.ontologies) { @@ -362,7 +383,7 @@ private Map getObjectProperties() { propertyRanges.clear(); } - String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.default_descriptions); MapperObjectProperty mapperObjectProperty = new MapperObjectProperty(propertyName, propertyDescription, isFunctional, restrictionValues, propertyRanges); try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); @@ -458,7 +479,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { // When the restriction is a ObjectComplementOf it doesn't have a object property, // thus we need to set its value at the setSchema function if (restrictionsValuesFromClass.containsKey("complementOf") && restrictionsValuesFromClass.size() == 1) { - for (String j: restrictionsValuesFromClass.keySet()) { + for (String j: restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); for (String restriction: restrictionValues.keySet()) { this.complementOf = restrictionValues.get(restriction); @@ -467,16 +488,18 @@ private void getClassRestrictions(OWLClass analyzedClass) { } else { for (OWLObjectProperty op: this.propertiesFromObjectRestrictions) { MapperObjectProperty mapperObjectProperty; - String propertyDescription = ObaUtils.getDescription(op, this.ontology_cls); + String propertyDescription = ObaUtils.getDescription(op, this.ontology_cls, this.default_descriptions); if (!this.propertiesFromObjectRestrictions_ranges.isEmpty()) { List rangesOP = this.propertiesFromObjectRestrictions_ranges.get(this.sfp.getShortForm(op.getIRI())); for (String j : restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); - if (j.equals(sfp.getShortForm(op.getIRI()))) { - if (rangesOP.get(0).equals("defaultValue")) + if (j.equals(this.sfp.getShortForm(op.getIRI()))) { + if (rangesOP.get(0).equals("defaultValue")) { mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, false, true); - else + } else { mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP); + } + try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); } catch (Exception e) { @@ -489,7 +512,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { for (OWLDataProperty dp: this.propertiesFromDataRestrictions) { List valuesFromDataRestrictions_ranges = new ArrayList<>(); - String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls); + String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls, this.default_descriptions); if (!this.propertiesFromDataRestrictions_ranges.isEmpty()) { List rangesDP = this.propertiesFromDataRestrictions_ranges.get(this.sfp.getShortForm(dp.getIRI())); for (String j: restrictionsValuesFromClass.keySet()) { @@ -506,14 +529,17 @@ private void getClassRestrictions(OWLClass analyzedClass) { } } } + this.properties = setProperties(); - } - else { + } else { this.properties = setProperties(); this.enumInstances = this.setEnums(); } } - addDefaultProperties(this.properties); + + if (this.default_properties) { + this.properties.putAll(this.getDefaultProperties()); + } } private List getEnums() { @@ -531,6 +557,4 @@ private String getSchemaName(OWLClass cls) { public OWLClass getCls() { return this.cls; } - - } diff --git a/src/main/java/edu/isi/oba/Oba.java b/src/main/java/edu/isi/oba/Oba.java index f99fcc2..b3b3c17 100644 --- a/src/main/java/edu/isi/oba/Oba.java +++ b/src/main/java/edu/isi/oba/Oba.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.PathItem; import org.json.JSONObject; +import org.openapitools.codegen.examples.ExampleGenerator; import java.io.*; import java.nio.file.Path; @@ -66,30 +67,29 @@ public static void main(String[] args) throws Exception { } else { config_data.setAuth(new AuthConfig()); } + try { Mapper mapper = new Mapper(config_data); - mapper.createSchemas(destination_dir, config_data); + mapper.createSchemas(destination_dir); LinkedHashMap custom_paths = config_data.getCustom_paths(); OpenAPI openapi_base = config_data.getOpenapi(); String custom_queries_dir = config_data.getCustom_queries_directory(); //copy base project - ObaUtils.unZipIt(SERVERS_ZIP, destination_dir); + ObaUtils.unZipIt(Oba.SERVERS_ZIP, destination_dir); //get schema and paths generate_openapi_spec(openapi_base, mapper, destination_dir, custom_paths); generate_openapi_template(mapper, destination_dir, config_data, selected_language); generate_context(config_data, destination_dir); copy_custom_queries(custom_queries_dir, destination_dir); - logger.info("OBA finished successfully. Output can be found at: "+destination_dir); - }catch (Exception e){ - logger.severe("Error while creating the API specification: "+e.getLocalizedMessage()); + logger.info("OBA finished successfully. Output can be found at: " + destination_dir); + } catch (Exception e) { + logger.severe("Error while creating the API specification: " + e.getLocalizedMessage()); e.printStackTrace(); System.exit(1); } } - - private static void generate_context(YamlConfig config_data, String destination_dir) { List ontologies = config_data.getOntologies(); @@ -106,12 +106,12 @@ private static void generate_context(YamlConfig config_data, String destination_ try { ObaUtils.write_file(file_path, context_json_object.toString(4)); ObaUtils.write_file(file_path_class, context_json_object_class.toString(4)); - }catch(Exception e){ + } catch(Exception e) { logger.severe("Could not generate the context files: "+e.getMessage()); } } - private static void copy_custom_queries(String source, String destination){ + private static void copy_custom_queries(String source, String destination) { if (source != null) { try { ObaUtils.copyFolder(new File(source), new File(destination + File.separator + "queries" + File.separator + "custom")); @@ -140,10 +140,8 @@ private static void generate_openapi_spec(OpenAPI openapi_base, String dir, LinkedHashMap custom_paths ) throws Exception { - String destinationProjectDirectory = dir + File.separator + SERVERS_DIRECTORY; + String destinationProjectDirectory = dir + File.separator + Oba.SERVERS_DIRECTORY; Path destinationProject = Paths.get(destinationProjectDirectory); new Serializer(mapper, destinationProject, openapi_base, custom_paths); } - - } diff --git a/src/main/java/edu/isi/oba/ObaUtils.java b/src/main/java/edu/isi/oba/ObaUtils.java index 06793b3..0e55940 100644 --- a/src/main/java/edu/isi/oba/ObaUtils.java +++ b/src/main/java/edu/isi/oba/ObaUtils.java @@ -36,6 +36,7 @@ import uk.ac.manchester.cs.owl.owlapi.OWLAnnotationPropertyImpl; public class ObaUtils { + public static final String DEFAULT_DESCRIPTION = "Description not available"; public static final String[] POSSIBLE_VOCAB_SERIALIZATIONS = { "application/rdf+xml", "text/turtle", "text/n3", "application/ld+json" }; private static final String RDFS_NS = "http://www.w3.org/2000/01/rdf-schema#"; @@ -377,28 +378,31 @@ public static void downloadOntology(String uri, String downloadPath) { * Method that given a class, property or data property, searches for the best description. * @param entity entity to search. * @param ontology ontology to be used to search descriptions. + * @param default_descriptions flag indicating whether default descriptions should or should not be included. * @return Description String (prioritizes English language) */ - public static String getDescription(OWLEntity entity, OWLOntology ontology){ - String descriptionValue = "Description not available"; - for(String description:ObaUtils.DESCRIPTION_PROPERTIES){ - Object[] annotationsObjects = EntitySearcher.getAnnotationObjects(entity, ontology, new OWLAnnotationPropertyImpl(new IRI(description) { - })).toArray(); - if(annotationsObjects.length!=0){ - Optional descriptionLiteral; - for(Object annotation: annotationsObjects){ - descriptionLiteral = ((OWLAnnotation) annotation).getValue().asLiteral(); - if(descriptionLiteral.isPresent()){ - if(annotationsObjects.length == 1 || descriptionLiteral.get().getLang().equals("en")){ - descriptionValue = descriptionLiteral.get().getLiteral(); - } - } - } - break; - } - } - return descriptionValue; + public static String getDescription(OWLEntity entity, OWLOntology ontology, Boolean default_descriptions) { + String descriptionValue = ObaUtils.DEFAULT_DESCRIPTION; + for (String description: ObaUtils.DESCRIPTION_PROPERTIES) { + Object[] annotationsObjects = EntitySearcher.getAnnotationObjects(entity, ontology, new OWLAnnotationPropertyImpl(new IRI(description){})).toArray(); + + if (annotationsObjects.length != 0) { + Optional descriptionLiteral; + for (Object annotation: annotationsObjects) { + descriptionLiteral = ((OWLAnnotation) annotation).getValue().asLiteral(); + + if (descriptionLiteral.isPresent()) { + if (annotationsObjects.length == 1 || descriptionLiteral.get().getLang().equals("en")) { + descriptionValue = descriptionLiteral.get().getLiteral(); + } + } + } + + break; + } + } + + return !Optional.ofNullable(default_descriptions).orElse(false) && ObaUtils.DEFAULT_DESCRIPTION.equals(descriptionValue) ? null : descriptionValue; } - } diff --git a/src/main/java/edu/isi/oba/config/YamlConfig.java b/src/main/java/edu/isi/oba/config/YamlConfig.java index 4573950..97f4dbc 100644 --- a/src/main/java/edu/isi/oba/config/YamlConfig.java +++ b/src/main/java/edu/isi/oba/config/YamlConfig.java @@ -7,7 +7,6 @@ import java.util.List; import java.util.Map; - public class YamlConfig { String DEFAULT_OUTPUT_DIRECTORY = "outputs"; String DEFAULT_PROJECT_NAME = "default_project"; @@ -28,6 +27,8 @@ public class YamlConfig { private LinkedHashMap custom_paths = null; public List classes; public Boolean follow_references = false; + public Boolean default_descriptions = true; + public Boolean default_properties = true; public Boolean getEnable_get_paths() { return enable_get_paths; @@ -160,6 +161,22 @@ public void setFollow_references(Boolean follow_references) { this.follow_references = follow_references; } + public Boolean getDefault_descriptions() { + return this.default_descriptions; + } + + public void setDefault_descriptions(Boolean default_descriptions) { + this.default_descriptions = default_descriptions; + } + + public Boolean getDefault_properties() { + return this.default_properties; + } + + public void setDefault_properties(Boolean default_properties) { + this.default_properties = default_properties; + } + public AuthConfig getAuth() { return auth; } diff --git a/src/test/java/edu/isi/oba/MapperTest.java b/src/test/java/edu/isi/oba/MapperTest.java index e3071a7..2236ada 100644 --- a/src/test/java/edu/isi/oba/MapperTest.java +++ b/src/test/java/edu/isi/oba/MapperTest.java @@ -112,8 +112,8 @@ public void testComplexOntology() throws Exception{ config_data.setAuth(new AuthConfig()); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://businessontology.com/ontology/Person"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); // The person schema must not be null. Assertions.assertNotNull(schema); diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index afc1624..ccb34ea 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -53,7 +53,7 @@ public void getDescription () throws OWLOntologyCreationException{ try { Mapper mapper = new Mapper(config_data); OWLClass planClass = mapper.manager.getOWLDataFactory().getOWLClass("http://purl.org/net/p-plan#Plan"); - String desc = ObaUtils.getDescription(planClass, mapper.ontologies.get(0)); + String desc = ObaUtils.getDescription(planClass, mapper.ontologies.get(0), true); Assertions.assertNotEquals(desc, ""); }catch(Exception e){ Assertions.fail("Failed to get description.", e); diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 2450394..0ce6dc6 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -55,8 +55,8 @@ public void testFunctionalObjectProperty() throws OWLOntologyCreationException, YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasRector"); if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { @@ -81,8 +81,8 @@ public void testObjectUnionOf() throws OWLOntologyCreationException, Exception { YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyMaterial"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("author"); if (property instanceof ArraySchema) { @@ -115,8 +115,8 @@ public void testObjectIntersectionOf() throws OWLOntologyCreationException, Exce YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasEvaluationMethod"); if (property instanceof ArraySchema) { @@ -147,8 +147,8 @@ public void testSimpleObjectSomeValuesFrom() throws OWLOntologyCreationException YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasDepartment"); if (property instanceof ArraySchema) { @@ -175,8 +175,8 @@ public void testObjectSomeValuesFrom_ComposedByRestriction() throws OWLOntologyC YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Student"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("enrolledIn"); if (property instanceof ArraySchema) { @@ -207,8 +207,8 @@ public void testObjectExactCardinality() throws OWLOntologyCreationException, Ex YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasRecord"); if (property instanceof ArraySchema) { @@ -239,8 +239,8 @@ public void testObjectMinCardinality() throws OWLOntologyCreationException, Exce YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("takesCourse"); if (property instanceof ArraySchema) { @@ -268,8 +268,8 @@ public void testObjectMaxCardinality() throws OWLOntologyCreationException, Exce YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasStudentEnrolled"); if (property instanceof ArraySchema) { @@ -299,8 +299,8 @@ public void testObjectComplementOf() throws OWLOntologyCreationException, Except YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInOtherDepartment"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); if (schema.getNot()!=null) Assertions.assertEquals(schema.getNot().get$ref(),expectedResult); @@ -323,8 +323,8 @@ public void testObjectHasValue() throws OWLOntologyCreationException, Exception YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("belongsTo"); if (((ObjectSchema) property).getDefault()!=null) @@ -350,8 +350,8 @@ public void testObjectOneOf() throws OWLOntologyCreationException, Exception { YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Professor"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasDegree"); @@ -384,8 +384,8 @@ public void testFunctionalDataProperty() throws OWLOntologyCreationException, Ex YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("birthDate"); if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { @@ -411,8 +411,8 @@ public void testDataUnionOf() throws OWLOntologyCreationException, Exception { YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("ects"); if (property instanceof ArraySchema) { @@ -445,8 +445,8 @@ public void testDataIntersectionOf() throws OWLOntologyCreationException, Except YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("memberOfOtherDepartments"); if (property instanceof ArraySchema) { @@ -477,8 +477,8 @@ public void testDataSomeValuesFrom() throws OWLOntologyCreationException, Except YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyProgram"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("studyProgramName"); if (property instanceof ArraySchema) { @@ -505,8 +505,8 @@ public void testDataSomeValuesFrom_ComposedByRestriction() throws OWLOntologyCre YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("memberOfOtherDepartments"); if (property instanceof ArraySchema) { @@ -537,8 +537,8 @@ public void testDataAllValuesFrom() throws OWLOntologyCreationException, Excepti YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyProgram"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("studyProgramName"); if (property instanceof ArraySchema) { @@ -562,8 +562,8 @@ public void testDataOneOf() throws OWLOntologyCreationException, Exception { YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Person"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("gender"); if (property instanceof ArraySchema) { @@ -595,8 +595,8 @@ public void testDataHasValue() throws OWLOntologyCreationException, Exception { YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("nationality"); @@ -620,8 +620,8 @@ public void testDataExactCardinality() throws OWLOntologyCreationException,Excep YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("universityName"); Integer maxItems = ((ArraySchema) property).getItems().getMaxItems(); @@ -649,8 +649,8 @@ public void testDataMinCardinality() throws OWLOntologyCreationException, Except YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Professor"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("researchField"); Integer minItems = ((ArraySchema) property).getItems().getMinItems(); @@ -675,8 +675,8 @@ public void testDataMaxCardinality() throws OWLOntologyCreationException, Except YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Person"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("address"); Integer maxItems = ((ArraySchema) property).getItems().getMaxItems(); @@ -701,8 +701,8 @@ public void testDataComplementOf() throws OWLOntologyCreationException,Exception YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Department"); - String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0)); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("numberOfProfessors"); if (((ArraySchema) property).getItems().getNot()!=null) From 4c220542773da93c81a43f29fc78cd7e943bef0c Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:04:04 -0500 Subject: [PATCH 10/36] bump version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 846bf31..0098c2e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ jar edu.isi.oba oba - 3.7.1 + 3.8.0 core https://github.com/KnowledgeCaptureAndDiscovery/OBA From b54f742aa032a4f7047f1bacb08aec5cf6c5660a Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:04:15 -0500 Subject: [PATCH 11/36] fix data property name --- src/main/java/edu/isi/oba/MapperSchema.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 20c4447..3402f3d 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -293,7 +293,7 @@ private Map getDefaultProperties() { // Also add some default property examples of different types (e.g. a date/time, a boolean, and a float) MapperDataProperty eventDateTimeProperty = new MapperDataProperty("eventDateTime", "a date time of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("dateTime");}}, false, true); - MapperDataProperty isBoolProperty = new MapperDataProperty("isGood", "a boolean indicator of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("boolean");}}, false, true); + MapperDataProperty isBoolProperty = new MapperDataProperty("isBool", "a boolean indicator of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("boolean");}}, false, true); MapperDataProperty quantityProperty = new MapperDataProperty("quantity", "a number quantity of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("float");}}, false, true); return Map.ofEntries( From f7d4e671a1f49266c42479543f13921164bc68d0 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:06:46 -0500 Subject: [PATCH 12/36] default description for date/time --- src/main/java/edu/isi/oba/MapperSchema.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 3402f3d..fd43661 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -292,7 +292,7 @@ private Map getDefaultProperties() { MapperDataProperty descriptionProperty = new MapperDataProperty("description", "small description", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); // Also add some default property examples of different types (e.g. a date/time, a boolean, and a float) - MapperDataProperty eventDateTimeProperty = new MapperDataProperty("eventDateTime", "a date time of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("dateTime");}}, false, true); + MapperDataProperty eventDateTimeProperty = new MapperDataProperty("eventDateTime", "a date/time of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("dateTime");}}, false, true); MapperDataProperty isBoolProperty = new MapperDataProperty("isBool", "a boolean indicator of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("boolean");}}, false, true); MapperDataProperty quantityProperty = new MapperDataProperty("quantity", "a number quantity of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("float");}}, false, true); From 9e5c4c4ee52f24dcb3646df09eb91dee75237c9c Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 17 Apr 2024 12:14:42 -0500 Subject: [PATCH 13/36] use array for type prop; update doc --- docs/filtering.md | 32 ++++++++++++++------- src/main/java/edu/isi/oba/MapperSchema.java | 4 +-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/filtering.md b/docs/filtering.md index 3971d95..0889055 100644 --- a/docs/filtering.md +++ b/docs/filtering.md @@ -172,7 +172,7 @@ components: ### Including default schema properties -You may wish to include common properties for each even if not defined for the entity/class. Currently, the default properites that are added to each schema are `description`, `id`, `label`, and `type`. For example: +You may wish to include common properties for each even if not defined for the entity/class. Currently, the default properites that are added to each schema are `description`, `id`, `label`, and `type`. Additional default properties are included (`eventDateTime`, `quantity`, `isBool`) which are meant to provide examples are other common data types. For example: ```yaml components: @@ -183,24 +183,34 @@ components: type: string propertyB: type: integer + eventDateTime: + description: a date/time of the resource + format: date-time + nullable: true + type: string + quantity: + description: a number quantity of the resource + nullable: true + type: number + isBool: + description: a boolean indicator of the resource + nullable: true + type: boolean description: description: small description - items: - type: string nullable: true - type: array - id: - description: identifier - nullable: false type: string label: description: short description of the resource - items: - type: string nullable: true - type: array + type: string + id: + description: identifier + format: int32 + nullable: false + type: integer type: - description: type of the resource + description: type(s) of the resource items: type: string nullable: true diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index fd43661..3684f1e 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -288,8 +288,8 @@ private Map getDefaultProperties() { // Add some typical default properties (e.g. id, lable, type, and description) MapperDataProperty idProperty = new MapperDataProperty("id", "identifier", true, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("integer");}}, false, false); MapperDataProperty labelProperty = new MapperDataProperty("label", "short description of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); - MapperDataProperty typeProperty = new MapperDataProperty("type", "type of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); - MapperDataProperty descriptionProperty = new MapperDataProperty("description", "small description", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); + MapperDataProperty typeProperty = new MapperDataProperty("type", "type(s) of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, true, true); + MapperDataProperty descriptionProperty = new MapperDataProperty("description", "small description", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("string");}}, false, true); // Also add some default property examples of different types (e.g. a date/time, a boolean, and a float) MapperDataProperty eventDateTimeProperty = new MapperDataProperty("eventDateTime", "a date/time of the resource", false, defaultRestrictionValues, valuesFromDataRestrictions_ranges, new ArrayList(){{add("dateTime");}}, false, true); From 02b842c3f77c5cdd0db0eebf0de784e846ec2af0 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:04:04 -0500 Subject: [PATCH 14/36] add this's; fix selected_classes null --- src/main/java/edu/isi/oba/Mapper.java | 44 ++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/main/java/edu/isi/oba/Mapper.java b/src/main/java/edu/isi/oba/Mapper.java index 9d931a2..e190990 100644 --- a/src/main/java/edu/isi/oba/Mapper.java +++ b/src/main/java/edu/isi/oba/Mapper.java @@ -55,7 +55,7 @@ public Mapper(YamlConfig config_data) throws OWLOntologyCreationException, IOExc //Load the ontology into the manager int i = 0; List ontologyPaths = new ArrayList<>(); - download_ontologies(config_ontologies, destination_dir, i, ontologyPaths); + this.download_ontologies(config_ontologies, destination_dir, i, ontologyPaths); //set ontology paths in YAML to the ones we have downloaded (for later reference by owl2jsonld) this.config_data.setOntologies(ontologyPaths); ontologies = this.manager.ontologies().collect(Collectors.toList()); @@ -63,12 +63,12 @@ public Mapper(YamlConfig config_data) throws OWLOntologyCreationException, IOExc //Create a temporal Map schemaNames with the classes for (OWLOntology ontology : ontologies) { Set classes = ontology.getClassesInSignature(); - setSchemaNames(classes); - setSchemaDrescriptions(classes,ontology); + this.setSchemaNames(classes); + this.setSchemaDrescriptions(classes,ontology); } if (config_data.getClasses() != null) { - this.selected_classes = filter_classes(); + this.selected_classes = this.filter_classes(); } } @@ -136,15 +136,15 @@ public void createSchemas(String destination_dir) { for (OWLClass cls : classes) { //filter if the class prefix does not have the default ontology prefix if (cls.getIRI() != null) { - if (selected_classes == null || selected_classes.contains(cls)) { - add_owlclass_to_openapi(query, pathGenerator, ontology, defaultOntologyPrefixIRI, cls, true); + if (this.selected_classes == null || this.selected_classes.contains(cls)) { + this.add_owlclass_to_openapi(query, pathGenerator, ontology, defaultOntologyPrefixIRI, cls, true); } } } } if (this.config_data.getAuth().getEnable()) { - add_user_path(pathGenerator); + this.add_user_path(pathGenerator); } } @@ -172,44 +172,46 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, if (defaultOntologyPrefixIRI.equals(classPrefixIRI)) { try{ MapperSchema mapperSchema = getMapperSchema(query, ontology, cls, this.schemaDescriptions.get(cls.getIRI())); + // add references to schemas in class restrictions (check selected classes to avoid conflicts) for (String classToCheck : mapperSchema.getPropertiesFromObjectRestrictions_ranges()) { OWLClass clsToCheck = manager.getOWLDataFactory().getOWLClass(IRI.create(classPrefixIRI + classToCheck)); - if (this.mappedClasses.contains(clsToCheck) || this.selected_classes.contains(clsToCheck)){ + if (this.mappedClasses.contains(clsToCheck) || (this.selected_classes != null && this.selected_classes.contains(clsToCheck))){ logger.info("The class " + clsToCheck + " exists "); } else { //rare cases have instances, so we filter them out and recheck that the target is a class. if(ontology.containsClassInSignature(clsToCheck.getIRI())) { System.out.println("ADD "+ clsToCheck); for (OWLOntology temp_ontology : this.ontologies) { - if (follow_references) { + if (this.follow_references) { this.mappedClasses.add(clsToCheck); - getMapperSchema(query, temp_ontology, clsToCheck, this.schemaDescriptions.get(clsToCheck.getIRI())); - add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, clsToCheck, false); + this.getMapperSchema(query, temp_ontology, clsToCheck, this.schemaDescriptions.get(clsToCheck.getIRI())); + this.add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, clsToCheck, false); } } } } } + // add references to schemas in property ranges for (OWLClass ref_class : mapperSchema.getProperties_range()) { if (this.mappedClasses.contains(ref_class)){ logger.info("The class " + ref_class + " exists "); } else { for (OWLOntology temp_ontology : this.ontologies) { - if ( follow_references ) { + if (this.follow_references) { this.mappedClasses.add(ref_class); - getMapperSchema(query, temp_ontology, ref_class,this.schemaDescriptions.get(ref_class.getIRI())); -// OWLDocumentFormat format = ontology.getFormat(); -// String temp_defaultOntologyPrefixIRI = format.asPrefixOWLDocumentFormat().getDefaultPrefix(); - add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, ref_class, false); + this.getMapperSchema(query, temp_ontology, ref_class,this.schemaDescriptions.get(ref_class.getIRI())); + this.add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, ref_class, false); } } } } + //Add the OpenAPI paths - if (topLevel) + if (topLevel) { addOpenAPIPaths(pathGenerator, mapperSchema, cls); + } }catch(Exception e){ logger.log(Level.SEVERE,"Could not parse class "+cls.getIRI().toString()); } @@ -219,7 +221,7 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass cls, String cls_description) { //Convert from OWL Class to OpenAPI Schema. - MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, schemaNames, ontology, this.follow_references, this.default_descriptions, this.default_properties); + MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, this.schemaNames, ontology, this.follow_references, this.default_descriptions, this.default_properties); //Write queries query.write_readme(mapperSchema.name); //Create the OpenAPI schema @@ -229,16 +231,16 @@ private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass } private void addOpenAPIPaths(Path pathGenerator, MapperSchema mapperSchema, OWLClass cls) { - if (selected_classes != null && !selected_classes.contains(cls)) { + if (this.selected_classes != null && !this.selected_classes.contains(cls)) { logger.info("Ignoring class " + cls.toString()); } else { - add_path(pathGenerator, mapperSchema); + this.add_path(pathGenerator, mapperSchema); } } private void setSchemaNames(Set classes) { for (OWLClass cls : classes) { - schemaNames.put(cls.getIRI(), cls.getIRI().getShortForm()); + this.schemaNames.put(cls.getIRI(), cls.getIRI().getShortForm()); } } From bf5cc3ff5b6198e5538e201b013377ef0fb323d7 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:05:23 -0500 Subject: [PATCH 15/36] cleanup --- src/main/java/edu/isi/oba/Oba.java | 4 ++-- src/test/java/edu/isi/oba/MapperTest.java | 1 - src/test/java/edu/isi/oba/ObaUtilsTest.java | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/edu/isi/oba/Oba.java b/src/main/java/edu/isi/oba/Oba.java index b3b3c17..4dcd052 100644 --- a/src/main/java/edu/isi/oba/Oba.java +++ b/src/main/java/edu/isi/oba/Oba.java @@ -3,8 +3,6 @@ import edu.isi.oba.config.*; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.PathItem; -import org.json.JSONObject; -import org.openapitools.codegen.examples.ExampleGenerator; import java.io.*; import java.nio.file.Path; @@ -15,6 +13,8 @@ import java.util.logging.LogManager; import java.util.logging.Logger; +import org.json.JSONObject; + class Oba { public static final String SERVERS_ZIP = "/servers.zip"; public static final String SERVERS_DIRECTORY = "servers"; diff --git a/src/test/java/edu/isi/oba/MapperTest.java b/src/test/java/edu/isi/oba/MapperTest.java index 2236ada..e1b9562 100644 --- a/src/test/java/edu/isi/oba/MapperTest.java +++ b/src/test/java/edu/isi/oba/MapperTest.java @@ -18,7 +18,6 @@ import io.swagger.v3.oas.models.media.Schema; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.OWLClass; diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index ccb34ea..c32f380 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -9,13 +9,11 @@ import org.json.JSONObject; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLOntologyCreationException; -@Disabled public class ObaUtilsTest { @Test From ffd0e7f606a621cd87ddac7920696850edd1a9f6 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:26:05 -0500 Subject: [PATCH 16/36] complex relations; improve enums; cardinality --- .../java/edu/isi/oba/MapperDataProperty.java | 164 +++++++----- .../edu/isi/oba/MapperObjectProperty.java | 69 +++-- src/main/java/edu/isi/oba/MapperSchema.java | 242 +++++++++++------- .../java/edu/isi/oba/RestrictionVisitor.java | 137 +++++----- 4 files changed, 365 insertions(+), 247 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperDataProperty.java b/src/main/java/edu/isi/oba/MapperDataProperty.java index 73cf860..c5cb8f8 100644 --- a/src/main/java/edu/isi/oba/MapperDataProperty.java +++ b/src/main/java/edu/isi/oba/MapperDataProperty.java @@ -60,7 +60,7 @@ class MapperDataProperty { Map.entry("Literal", "string") ); - private String getDataType(String key){ + private String getDataType(String key) { return this.dataTypes.get(key); } @@ -90,34 +90,33 @@ public MapperDataProperty(String name, String description, Boolean isFunctional, this.valuesFromDataRestrictions_ranges=valuesFromDataRestrictions_ranges; } - public Schema getSchemaByDataProperty(){ + public Schema getSchemaByDataProperty() { if (this.type.isEmpty()) { - return (array) ? arraySchema(new StringSchema(), nullable) : new StringSchema().nullable(nullable).description(description); - } - else if (this.type.size() > 1) { - return (array) ? composedSchema(this.type, nullable) : new Schema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new StringSchema()) : this.nonArraySchema(new StringSchema()); + } else if (this.type.size() > 1) { + return (this.array) ? this.composedSchema() : this.nonArraySchema(new Schema()); } String schemaType = getDataType(this.type.get(0)); - if (schemaType == null){ + if (schemaType == null) { logger.severe("property " + this.name + " type " + this.type); } switch (schemaType) { case STRING_TYPE: - return (array) ? arraySchema(new StringSchema(), nullable) : new StringSchema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new StringSchema()) : this.nonArraySchema(new StringSchema()); case NUMBER_TYPE: - return (array) ? arraySchema(new NumberSchema(), nullable) : new NumberSchema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new NumberSchema()) : this.nonArraySchema(new NumberSchema()); case INTEGER_TYPE: - return (array) ? arraySchema(new IntegerSchema(), nullable) : new IntegerSchema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new IntegerSchema()) : this.nonArraySchema(new IntegerSchema()); case BOOLEAN_TYPE: - return (array) ? arraySchema(new BooleanSchema(), nullable) : new BooleanSchema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new BooleanSchema()) : this.nonArraySchema(new BooleanSchema()); case DATETIME_TYPE: - return (array) ? arraySchema(new DateTimeSchema() , nullable) : new DateTimeSchema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new DateTimeSchema()) : this.nonArraySchema(new DateTimeSchema()); default: logger.warning("datatype mapping failed " + this.type.get(0)); - return (array) ? arraySchema(new Schema(), nullable) : new Schema().nullable(nullable).description(description); + return (this.array) ? this.arraySchema(new Schema()) : this.nonArraySchema(new Schema()); } } @@ -126,18 +125,18 @@ else if (this.type.size() > 1) { * * @return An ArraySchema: including a composedSchema with a list of items for anyOf, allOf restrictions. */ - private ArraySchema composedSchema(List base, boolean nullable){ + private ArraySchema composedSchema() { ArraySchema array = new ArraySchema(); Schema schema; ComposedSchema composedSchema = new ComposedSchema(); array.setDescription(description); - array.setNullable(nullable); + array.setNullable(this.nullable); // Operations for managing boolean combinations - for (String restriction: restrictions.keySet()) { - String value = restrictions.get(restriction); - for (String item: base) { - switch (getDataType(item)) { + for (String restriction: this.restrictions.keySet()) { + String value = this.restrictions.get(restriction); + for (String item: this.type) { + switch (this.getDataType(item)) { case STRING_TYPE: schema = new StringSchema(); @@ -181,13 +180,17 @@ private ArraySchema composedSchema(List base, boolean nullable){ switch (restriction) { case "unionOf": - if (value=="someValuesFrom") - nullable=false; + if (value == "someValuesFrom") { + this.nullable = false; + } + composedSchema.addAnyOfItem(schema); break; case "intersectionOf": - if (value=="someValuesFrom") - nullable=false; + if (value == "someValuesFrom") { + this.nullable = false; + } + composedSchema.addAllOfItem(schema); break; default: @@ -197,7 +200,7 @@ private ArraySchema composedSchema(List base, boolean nullable){ } array.setItems(composedSchema); - array.setNullable(nullable); + array.setNullable(this.nullable); if (isFunctional) { array.setMaxItems(1); @@ -206,58 +209,77 @@ private ArraySchema composedSchema(List base, boolean nullable){ return array; } - private ArraySchema arraySchema(Schema base, boolean nullable) { + private Schema nonArraySchema(Schema base) { + base.setDescription(this.description); + base.setNullable(this.nullable); + + return this.getSchemaRestrictions(base); + } + + private ArraySchema arraySchema(Schema base) { ArraySchema array = new ArraySchema(); - array.setDescription(description); + array.setDescription(this.description); + + if (this.isFunctional) { + array.setMaxItems(1); + } + + if (this.restrictions.containsKey("complementOf")) { + Schema schema = new Schema(); + Schema complementOf = new Schema(); + complementOf.setType(this.getDataType(this.type.get(0))); + complementOf.setFormat(this.type.get(0)); + schema.setNot(complementOf); + array.setNullable(this.nullable); + array.setItems(schema); + return array; + } - if (isFunctional) - array.setMaxItems(1); - - for (String restriction: restrictions.keySet()) { - String value = restrictions.get(restriction); - switch (restriction) { - case "dataHasValue": - base.setDefault(value); - break; - case "maxCardinality": - base.setMaxItems(Integer.parseInt(value)); - break ; - case "minCardinality": - base.setMinItems(Integer.parseInt(value)); - break ; - case "exactCardinality": - base.setMaxItems(Integer.parseInt(value)); - base.setMinItems(Integer.parseInt(value)); - break ; - case "someValuesFrom": - nullable=false; - break ; - case "allValuesFrom": - //nothing to do - break ; - case "oneOf": - if (value=="someValuesFrom") - nullable=false; - for (String rangeValue:valuesFromDataRestrictions_ranges) - base.addEnumItemObject(rangeValue); - break; - case "complementOf": - Schema schema = new Schema(); - Schema complementOf = new Schema(); - complementOf.setType(getDataType(type.get(0))); - complementOf.setFormat(type.get(0)); - schema.setNot(complementOf); - array.setNullable(nullable); - array.setItems(schema); - return array; - default: - } - } - - array.setNullable(nullable); + base = this.getSchemaRestrictions(base); + + array.setNullable(this.nullable); array.setItems(base); return array; } + private Schema getSchemaRestrictions(Schema base) { + for (String restriction: this.restrictions.keySet()) { + String value = restrictions.get(restriction); + switch (restriction) { + case "dataHasValue": + base.setDefault(value); + break; + case "maxCardinality": + base.setMaxItems(Integer.parseInt(value)); + break; + case "minCardinality": + base.setMinItems(Integer.parseInt(value)); + break; + case "exactCardinality": + base.setMaxItems(Integer.parseInt(value)); + base.setMinItems(Integer.parseInt(value)); + break; + case "someValuesFrom": + this.nullable = false; + break; + case "allValuesFrom": + //nothing to do + break; + case "oneOf": + if (value == "someValuesFrom") { + this.nullable = false; + } + + for (String rangeValue: this.valuesFromDataRestrictions_ranges) { + base.addEnumItemObject(rangeValue); + } + + break; + default: + } + } + + return base; + } } diff --git a/src/main/java/edu/isi/oba/MapperObjectProperty.java b/src/main/java/edu/isi/oba/MapperObjectProperty.java index e3d903b..264aeec 100644 --- a/src/main/java/edu/isi/oba/MapperObjectProperty.java +++ b/src/main/java/edu/isi/oba/MapperObjectProperty.java @@ -52,13 +52,13 @@ public Schema getSchemaByObjectProperty() { } private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nullable) { - Schema object = new ObjectSchema(); - object.setDescription(this.description); + ArraySchema objects = new ArraySchema(); + objects.setDescription(this.description); if (array) { + Schema object = new ObjectSchema(); + object.setDescription(this.description); object.set$ref(ref); - ArraySchema objects = new ArraySchema(); - objects.setDescription(this.description); if (this.isFunctional) { objects.setMaxItems(1); @@ -91,21 +91,45 @@ private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nulla objects.setItems(object); return objects; } else { - for (String restriction: this.restrictions.keySet()) { - String value = this.restrictions.get(restriction); - if (restriction=="objectHasValue") { - object.setDefault(value); - object.type("string"); - object.format("uri"); - return object; - } - } + if (this.restrictions.isEmpty()) { + Schema object = new ObjectSchema(); + object.setDescription(this.description); + object.setType("object"); + return object; + } else { + // For OpenAPI v3.0, "$ref" cannot be used as a sibling with "default". + // see: https://swagger.io/docs/specification/using-ref/ + // see: https://stackoverflow.com/a/77189463 + // A workaround is to include both within "items" and as separate entries under "allOf". + // TODO: version check here (and elsewhere?) to differentiate the schema structure. For v3.1+, it can support "$ref" and "default" as siblings. + ArraySchema tempObjects = new ArraySchema(); + tempObjects.setType(null); + + for (String restriction: this.restrictions.keySet()) { + Schema object = new ObjectSchema(); + String value = this.restrictions.get(restriction); + + if ("objectHasReference".equals(restriction)) { + object.set$ref(value); + object.setType(null); + } + + if ("objectHasValue".equals(restriction)) { + object.setDefault(value); + object.setType("string"); + } + + tempObjects.addAllOfItem(object); + } - return object; - } + objects.items(tempObjects); + objects.setType("array"); - + return objects; + } + } } + private Schema getComposedSchemaObject(List refs, boolean array, boolean nullable) { Schema object = new ObjectSchema(); ComposedSchema composedSchema = new ComposedSchema(); @@ -113,7 +137,7 @@ private Schema getComposedSchemaObject(List refs, boolean array, boolean object.setType("object"); object.setDescription(this.description); - if (array) { + if (array && !this.restrictions.isEmpty()) { ArraySchema objects = new ArraySchema(); objects.setDescription(this.description); @@ -182,17 +206,8 @@ private Schema getComposedSchemaObject(List refs, boolean array, boolean return objects; } else { + object.setNullable(nullable); return object; } } - - private ArraySchema arraySchema(Schema base, boolean nullable) { - ArraySchema array = new ArraySchema(); - array.setNullable(nullable); - array.setItems(base); - if (isFunctional) - array.setMaxItems(1); - return array; - } - } diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 3684f1e..16b461c 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -8,7 +8,6 @@ import java.util.*; -import org.openapitools.codegen.examples.ExampleGenerator; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.OWLReasoner; @@ -28,7 +27,8 @@ class MapperSchema { private Map dataProperties; private Map objectProperties; private Map properties; - private List enumInstances; + private List required_properties; + private Map> enums; final String name; private final Map schemaNames; private final Schema schema; @@ -72,15 +72,16 @@ public MapperSchema(List ontologies, OWLClass cls, String clsDescri this.type = "object"; this.ontologies = ontologies; this.ontology_cls = class_ontology; - reasonerFactory = new StructuralReasonerFactory(); + this.reasonerFactory = new StructuralReasonerFactory(); this.reasoner = reasonerFactory.createReasoner(this.ontology_cls); - properties_range = new ArrayList<>(); - propertiesFromObjectRestrictions_ranges= new HashMap<>(); - propertiesFromObjectRestrictions = new ArrayList<>(); - propertiesFromDataRestrictions_ranges= new HashMap<>(); - propertiesFromDataRestrictions = new ArrayList<>(); - properties = new HashMap<>(); - this.complementOf=""; + this.properties_range = new ArrayList<>(); + this.propertiesFromObjectRestrictions_ranges= new HashMap<>(); + this.propertiesFromObjectRestrictions = new ArrayList<>(); + this.propertiesFromDataRestrictions_ranges= new HashMap<>(); + this.propertiesFromDataRestrictions = new ArrayList<>(); + this.properties = new HashMap<>(); + this.required_properties = new ArrayList<>(); + this.complementOf = ""; this.getClassRestrictions(cls); this.name = getSchemaName(cls); this.schema = setSchema(); @@ -92,32 +93,27 @@ private Map setProperties() { return this.properties; } - private List setEnums() { - this.enumInstances = this.getEnumInstances(); - - return this.enumInstances; - } - private Schema setSchema() { Schema schema = new Schema(); schema.setName(this.name); schema.setDescription(this.cls_description); - schema.setType(this.type); - // if the Schema is the complement of other Schema - if (complementOf!="") { - Schema complement = new ObjectSchema(); - complement.set$ref(complementOf); - schema.not(complement); - } - if (this.getEnums() != null && !this.enumInstances.isEmpty()) { + if (this.enums.containsKey(this.cls.getIRI())) { // Only string enums allowed in RDF/OWL ?? schema.setType("string"); - schema.setEnum(this.enumInstances); + schema.setEnum(this.enums.get(this.cls.getIRI())); } else { + // if the Schema is the complement of other Schema + if (complementOf!="") { + Schema complement = new ObjectSchema(); + complement.set$ref(complementOf); + schema.not(complement); + } schema.setType(this.type); schema.setProperties(this.getProperties()); + schema.setRequired(this.required_properties); + HashMap exampleMap = new HashMap<>(); exampleMap.put("id", "some_id"); Example example = new Example(); @@ -153,29 +149,8 @@ private boolean checkDomainClass(OWLClass cls, OWLPropertyDomainAxiom dp) { } } } - return false; - } - - /** - * Obtain a list of enumerations (enums) of a OWLClass. - * - * @return A List string: enum name/title - */ - private List getEnumInstances() { - List enums = new ArrayList(); - - for (OWLOntology ontology: this.ontologies) { - ontology.getEquivalentClassesAxioms(this.cls).forEach((ax) -> { - ax.classExpressions().filter((ce) -> ce instanceof OWLObjectOneOf).forEach((oneOfObj) -> { - oneOfObj.getIndividualsInSignature().forEach((OWLNamedIndividual indv) -> { - logger.info("\tclass has following item as an ENUM: " + this.sfp.getShortForm(indv.getIRI())); - enums.add(this.sfp.getShortForm(indv.getIRI())); - }); - }); - }); - } - return enums; + return false; } /** @@ -341,7 +316,6 @@ private Map getObjectProperties() { if (propertiesFromObjectRestrictions.contains(odp)) { inspect = false; } - } if (inspect) { @@ -379,8 +353,9 @@ private Map getObjectProperties() { restrictionValues=restrictionsValuesFromClass.get(j); } } - if (restrictionsValuesFromClass.isEmpty() && propertyRanges.size() > 1) - propertyRanges.clear(); + if (restrictionsValuesFromClass.isEmpty() && propertyRanges.size() > 1) { + propertyRanges.clear(); + } } String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.default_descriptions); @@ -394,6 +369,7 @@ private Map getObjectProperties() { } } } + return properties; } @@ -413,6 +389,7 @@ private List getCodeGenTypesByRangeData(Set r } } } + return dataProperties; } @@ -433,18 +410,17 @@ private List getCodeGenTypesByRangeObject(Set> restrictionsValuesFromClass = restrictionVisitor.getRestrictionsValuesFromClass(); - - if (!restrictionsValuesFromClass.isEmpty()) { - // When the restriction is a ObjectComplementOf it doesn't have a object property, - // thus we need to set its value at the setSchema function - if (restrictionsValuesFromClass.containsKey("complementOf") && restrictionsValuesFromClass.size() == 1) { - for (String j: restrictionsValuesFromClass.keySet()) { - Map restrictionValues = restrictionsValuesFromClass.get(j); - for (String restriction: restrictionValues.keySet()) { - this.complementOf = restrictionValues.get(restriction); - } - } - } else { + + // For equivalent (to) classes (e.g. Defined classes) we need to accept the visit to navigate it. + ontology.equivalentClassesAxioms(analyzedClass).forEach((eqClsAx) -> { + eqClsAx.accept(restrictionVisitor); + }); + + this.enums = restrictionVisitor.getAllEnums(); + this.propertiesFromObjectRestrictions = restrictionVisitor.getPropertiesFromObjectRestrictions(); + this.propertiesFromObjectRestrictions_ranges = restrictionVisitor.getPropertiesFromObjectRestrictions_ranges(); + this.propertiesFromDataRestrictions = restrictionVisitor.getPropertiesFromDataRestrictions(); + this.propertiesFromDataRestrictions_ranges = restrictionVisitor.getPropertiesFromDataRestrictions_ranges(); + Map> restrictionsValuesFromClass = restrictionVisitor.getRestrictionsValuesFromClass(); + + if (!restrictionsValuesFromClass.isEmpty()) { + // When the restriction is a ObjectComplementOf it doesn't have a object property, + // thus we need to set its value at the setSchema function + if (restrictionsValuesFromClass.containsKey("complementOf") && restrictionsValuesFromClass.size() == 1) { + for (String j: restrictionsValuesFromClass.keySet()) { + Map restrictionValues = restrictionsValuesFromClass.get(j); + for (String restriction: restrictionValues.keySet()) { + this.complementOf = restrictionValues.get(restriction); + } + } + } else { for (OWLObjectProperty op: this.propertiesFromObjectRestrictions) { MapperObjectProperty mapperObjectProperty; String propertyDescription = ObaUtils.getDescription(op, this.ontology_cls, this.default_descriptions); @@ -494,14 +475,57 @@ private void getClassRestrictions(OWLClass analyzedClass) { for (String j : restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); if (j.equals(this.sfp.getShortForm(op.getIRI()))) { - if (rangesOP.get(0).equals("defaultValue")) { + int exactCardinality = -1; + int minCardinality = -1; + int maxCardinality = -1; + + if (rangesOP != null && rangesOP.get(0).equals("defaultValue")) { mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, false, true); } else { - mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP); + String exactCardinalityStr = restrictionValues.get("exactCardinality"); + exactCardinalityStr = ((exactCardinalityStr == null || exactCardinalityStr.isBlank()) ? "-1" : exactCardinalityStr); + exactCardinality = Integer.parseInt(exactCardinalityStr); + + String minCardinalityStr = restrictionValues.get("minCardinality"); + minCardinalityStr = ((minCardinalityStr == null || minCardinalityStr.isBlank()) ? "-1" : minCardinalityStr); + minCardinality = Integer.parseInt(minCardinalityStr); + + String maxCardinalityStr = restrictionValues.get("maxCardinality"); + maxCardinalityStr = ((maxCardinalityStr == null || maxCardinalityStr.isBlank()) ? "-1" : maxCardinalityStr); + maxCardinality = Integer.parseInt(maxCardinalityStr); + + // If cardinality is exactly 1 OR a minimum of 1, then not nullable. + boolean isNullable = (exactCardinality == -1 && minCardinality == -1) ? true : exactCardinality != 1 && minCardinality < 1; + + // References always need to be included as an array of items. + mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, true, isNullable); } try { - this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); + Schema opSchema = mapperObjectProperty.getSchemaByObjectProperty(); + + boolean is_required = false; + + // If cardinality is exactly 1, then we can remove the min/max property constraints + // and set the property to be required for the class. + if (exactCardinality == 1 || (minCardinality == 1 && maxCardinality == 1)) { + opSchema.setMinItems(null); + opSchema.setMaxItems(null); + is_required = true; + } + + // If cardinality minimum is 1, keep the min/max property constraints + // and set the property to be required for the class. + if (minCardinality > 0) { + is_required = true; + } + + + if (is_required) { + this.required_properties.add(mapperObjectProperty.name); + } + + this.properties.put(mapperObjectProperty.name, opSchema); } catch (Exception e) { logger.warning("Error when parsing object property "+mapperObjectProperty.name); } @@ -518,9 +542,52 @@ private void getClassRestrictions(OWLClass analyzedClass) { for (String j: restrictionsValuesFromClass.keySet()) { Map restrictionValues = restrictionsValuesFromClass.get(j); if (j.equals(this.sfp.getShortForm(dp.getIRI()))) { - MapperDataProperty mapperDataProperty = new MapperDataProperty(this.sfp.getShortForm(dp.getIRI()), propertyDescription, false, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, true, true); + String exactCardinalityStr = restrictionValues.get("exactCardinality"); + exactCardinalityStr = ((exactCardinalityStr == null || exactCardinalityStr.isBlank()) ? "-1" : exactCardinalityStr); + int exactCardinality = Integer.parseInt(exactCardinalityStr); + + String minCardinalityStr = restrictionValues.get("minCardinality"); + minCardinalityStr = ((minCardinalityStr == null || minCardinalityStr.isBlank()) ? "-1" : minCardinalityStr); + int minCardinality = Integer.parseInt(minCardinalityStr); + + String maxCardinalityStr = restrictionValues.get("maxCardinality"); + maxCardinalityStr = ((maxCardinalityStr == null || maxCardinalityStr.isBlank()) ? "-1" : maxCardinalityStr); + int maxCardinality = Integer.parseInt(maxCardinalityStr); + + // If cardinality is present and allows for multiple values, then this is an array. + boolean isArray = exactCardinality > 1 + || minCardinality > 0 + || maxCardinality > 1; + + // If cardinality is exactly 1 OR a minimum of 1, then not nullable. + boolean isNullable = (exactCardinality == -1 && minCardinality == -1) ? true : exactCardinality != 1 && minCardinality < 1; + + MapperDataProperty mapperDataProperty = new MapperDataProperty(this.sfp.getShortForm(dp.getIRI()), propertyDescription, false, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, isArray, isNullable); try { - this.properties.put(mapperDataProperty.name, mapperDataProperty.getSchemaByDataProperty()); + Schema dpSchema = mapperDataProperty.getSchemaByDataProperty(); + + boolean is_required = false; + + // If cardinality is exactly 1, then we can remove the min/max property constraints + // and set the property to be required for the class. + if (exactCardinality == 1 || (minCardinality == 1 && maxCardinality == 1)) { + dpSchema.setMinItems(null); + dpSchema.setMaxItems(null); + is_required = true; + } + + // If cardinality minimum is 1, keep the min/max property constraints + // and set the property to be required for the class. + if (minCardinality > 0) { + is_required = true; + } + + + if (is_required) { + this.required_properties.add(mapperDataProperty.name); + } + + this.properties.put(mapperDataProperty.name, dpSchema); } catch (Exception e) { logger.warning("Error when processing data property " + mapperDataProperty.name); } @@ -528,13 +595,10 @@ private void getClassRestrictions(OWLClass analyzedClass) { } } } - } + } + } - this.properties = setProperties(); - } else { - this.properties = setProperties(); - this.enumInstances = this.setEnums(); - } + this.properties = setProperties(); } if (this.default_properties) { @@ -542,10 +606,6 @@ private void getClassRestrictions(OWLClass analyzedClass) { } } - private List getEnums() { - return this.enumInstances; - } - private Map getProperties() { return this.properties; } diff --git a/src/main/java/edu/isi/oba/RestrictionVisitor.java b/src/main/java/edu/isi/oba/RestrictionVisitor.java index dfd9e41..406dd6d 100644 --- a/src/main/java/edu/isi/oba/RestrictionVisitor.java +++ b/src/main/java/edu/isi/oba/RestrictionVisitor.java @@ -41,7 +41,7 @@ public class RestrictionVisitor implements OWLObjectVisitor { private final OWLClass cls; private final OWLOntology onto; String property_name; - OWLClass owlThing; + OWLClass owlThing; public Map> restrictionsValuesFromClass; @@ -50,6 +50,7 @@ public class RestrictionVisitor implements OWLObjectVisitor { public List propertiesFromDataRestrictions; public Map> propertiesFromDataRestrictions_ranges; public List valuesFromDataRestrictions_ranges; + public Map> enums; RestrictionVisitor(OWLClass visitedClass, OWLOntology onto, OWLClass owlThing, String propertyName ) { processedClasses = new HashSet(); @@ -63,6 +64,7 @@ public class RestrictionVisitor implements OWLObjectVisitor { this.propertiesFromDataRestrictions = new ArrayList<>(); this.propertiesFromDataRestrictions_ranges= new HashMap<>(); this.valuesFromDataRestrictions_ranges = new ArrayList<>(); + this.enums = new HashMap<>(); } @Override @@ -76,6 +78,28 @@ public void visit(OWLClass ce) { } } + @Override + public void visit( OWLEquivalentClassesAxiom ce ) { + logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + + // If equivalent class axiom AND contains owl:oneOf, then we're looking at an ENUM class. + ce.classExpressions().filter((e) -> e instanceof OWLObjectOneOf).forEach((oneOfObj) -> { + var enumValues = new ArrayList(); + ((OWLObjectOneOf) oneOfObj).getOperandsAsList().forEach((indv) -> { + enumValues.add(this.sfp.getShortForm(((OWLNamedIndividual) indv).getIRI())); + }); + + if (!enumValues.isEmpty()) { + this.enums.put(this.cls.getIRI(), enumValues); + } + }); + + // Loop through each expression in the equivalent classes axiom and accept visits from everything else. + ce.classExpressions().filter((e) -> !(e instanceof OWLObjectOneOf)).forEach((e) -> { + e.accept(this); + }); + } + /** * This method gets called when a class expression is an existential * (someValuesFrom) restriction and it asks us to visit it @@ -132,9 +156,9 @@ public void visit(OWLObjectAllValuesFrom ce) { ranges.add(sfp.getShortForm(ce.getFiller().asOWLClass().getIRI())); if (ce.getFiller().asOWLClass().equals(owlThing)) { logger.info("Ignoring owl:Thing range" + property_name); + } else { + propertiesFromObjectRestrictions_ranges.put(property_name, ranges); } - else - propertiesFromObjectRestrictions_ranges.put(property_name,ranges); restrictionsValues.put("allValuesFrom", ""); restrictionsValuesFromClass.put(property_name, restrictionsValues); @@ -144,16 +168,20 @@ public void visit(OWLObjectAllValuesFrom ce) { @Override public void visit( OWLObjectUnionOf ce ) { logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); - Set ranges = ce.getOperands(); - Set properties = ce.getObjectPropertiesInSignature(); - setBooleanCombinationProperties(ranges, properties, "unionOf"); + + // Loop through each item in the union and accept visits. + for (OWLClassExpression e : ce.getOperands()) { + e.accept(this); + } } @Override public void visit( OWLObjectIntersectionOf ce ) { - logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); - Set ranges = ce.getOperands(); - Set properties = ce.getObjectPropertiesInSignature(); - setBooleanCombinationProperties(ranges, properties, "intersectionOf"); + logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); + + // Loop through each item in the intersection and accept visits. + for (OWLClassExpression e : ce.getOperands()) { + e.accept(this); + } } @Override @@ -185,11 +213,27 @@ public void visit( OWLObjectComplementOf ce ) { @Override public void visit(OWLObjectHasValue ce) { logger.info("Analyzing restrictions of Class: " + this.cls + " with axiom: " + ce); - List ranges = new ArrayList(); - Map restrictionsValues = new HashMap(); + for(OWLObjectProperty property: ce.getObjectPropertiesInSignature()) { - this.property_name = this.sfp.getShortForm(property.getIRI()); - restrictionsValues.put("objectHasValue", ce.getFiller().toString()); + List ranges = new ArrayList(); + Map restrictionsValues = new HashMap(); + + this.property_name = this.sfp.getShortForm(property.getIRI()); + + restrictionsValues.put("objectHasValue", this.sfp.getShortForm(((OWLNamedIndividual)ce.getFiller()).getIRI())); + + // If object property has object(s) in its range, we want to set references to the object class. + var obRangeAxioms = this.onto.getObjectPropertyRangeAxioms(property); + if (obRangeAxioms.isEmpty()) { + logger.warning("\tObject has value (named individual) but there is no associated class/reference for the value. Ontology may have errors."); + } else { + obRangeAxioms.forEach((obRangeAxiom) -> { + obRangeAxiom.getRange().classesInSignature().forEach((owlClass) -> { + restrictionsValues.put("objectHasReference", this.sfp.getShortForm(owlClass.getIRI())); + }); + }); + } + this.restrictionsValuesFromClass.put(this.property_name, restrictionsValues); this.propertiesFromObjectRestrictions.add(property); ranges.add("defaultValue"); @@ -278,17 +322,21 @@ public void visit( OWLDataSomeValuesFrom ce ) { @Override public void visit( OWLDataUnionOf ce ) { logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); - Set ranges = ce.getOperands(); - Set properties = ce.getDataPropertiesInSignature(); - setBooleanCombinationDataProperties(ranges, properties, "unionOf"); + + // Loop through each item in the union and accept visits. + for (OWLDataRange e : ce.getOperands()) { + e.accept(this); + } } @Override public void visit( OWLDataIntersectionOf ce ) { logger.info("Analyzing restrictions of Class: " + this.cls+ " with axiom: "+ce); - Set ranges = ce.getOperands(); - Set properties = ce.getDataPropertiesInSignature(); - setBooleanCombinationDataProperties(ranges, properties, "intersectionOf"); + + // Loop through each item in the intersection and accept visits. + for (OWLDataRange e : ce.getOperands()) { + e.accept(this); + } } @Override @@ -383,24 +431,8 @@ public void setPropertiesWithCardinality(OWLObjectCardinalityRestriction ce, Str * @param restriction string value of restriction e.g. "unionOf" */ public void setBooleanCombinationProperties( Set ranges, Set properties, String restriction) { - Boolean inspect=true; Map restrictionsValues = new HashMap(); - for (OWLClassExpression value :ranges) { - //if operands from boolean restriction contain complex combinations the restriction on this property - // will be ignored - if (value instanceof OWLObjectIntersectionOf || value instanceof OWLObjectComplementOf || value instanceof OWLObjectSomeValuesFrom || value instanceof OWLObjectAllValuesFrom - || value instanceof OWLObjectHasValue) { - logger.warning("Ignoring complex range restriction of property "+ property_name); - if (property_name!="") { - propertiesFromObjectRestrictions.remove(property_name); - restrictionsValuesFromClass.remove(property_name); - } - inspect=false; - } - } - // if there are not complex range restrictions inspect ce - if (inspect) { - //if the expression ce is not part of a composed expression (existencial or universal) + //if the expression ce is not part of a composed expression (existential or universal) if (property_name.isEmpty()) { for(OWLObjectProperty property:properties) { propertiesFromObjectRestrictions.add(property); @@ -434,8 +466,7 @@ public void setBooleanCombinationProperties( Set ranges, Set restrictionsValues.put(restriction, ""); restrictionsValuesFromClass.put(property_name, restrictionsValues); } - } - } + } } /** @@ -445,24 +476,8 @@ public void setBooleanCombinationProperties( Set ranges, Set * @param restriction string value of restriction e.g. "unionOf" */ public void setBooleanCombinationDataProperties( Set ranges, Set properties, String restriction) { - Boolean inspect=true; Map restrictionsValues = new HashMap(); - for (OWLDataRange value :ranges) { - //if operands from boolean restriction contain complex combinations the restriction on this property - // will be ignored - if (value instanceof OWLDataIntersectionOf || value instanceof OWLDataComplementOf || value instanceof OWLDataSomeValuesFrom || value instanceof OWLDataAllValuesFrom - || value instanceof OWLDataHasValue) { - logger.warning("Ignoring complex range restriction of property "+ property_name); - if (!property_name.equals("")) { - propertiesFromDataRestrictions.remove(property_name); - restrictionsValuesFromClass.remove(property_name); - } - inspect=false; - } - } - // if there are not complex range restrictions inspect ce - if (inspect) { - //if the expression ce is not part of a composed expression (existencial or universal) + //if the expression ce is not part of a composed expression (existential or universal) if (property_name.equals("")) { for(OWLDataProperty property:properties) { propertiesFromDataRestrictions.add(property); @@ -497,8 +512,7 @@ public void setBooleanCombinationDataProperties( Set ranges, Set> getPropertiesFromDataRestrictions_ranges() { return this.propertiesFromDataRestrictions_ranges; } + public List getEnums(IRI classIRI) { + return this.enums.get(classIRI); + } + + public Map> getAllEnums() { + return this.enums; + } } From 1ca238dda886e7b87a62cbe4347324d062f56f45 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:27:45 -0500 Subject: [PATCH 17/36] support updated cardinality + object value/ref --- .../java/edu/isi/oba/RestrictionsTest.java | 160 +++++++++++++----- 1 file changed, 119 insertions(+), 41 deletions(-) diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 0ce6dc6..7f205e3 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -209,20 +209,35 @@ public void testObjectExactCardinality() throws OWLOntologyCreationException, Ex OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("hasRecord"); - if (property instanceof ArraySchema) { - Integer maxItems = ((ArraySchema) property).getMaxItems(); - Integer minItems = ((ArraySchema) property).getMinItems(); - if (maxItems!=null && minItems!=null) { - if (maxItems == minItems) - // "Exact cardinality configured" -- does this really need to be output for the test? - return; - else - Assertions.fail("Error in exact cardinality restriction."); - } else - Assertions.fail("Null values in exact cardinality restriction."); - } + Schema schema = mapperSchema.getSchema(); + + boolean isRequired = schema.getRequired().contains("hasRecord"); + + // For exact cardinality, the class schema should have it marked as required. + if (isRequired) { + Object property= schema.getProperties().get("hasRecord"); + Integer maxItems = null; + Integer minItems = null; + + // If the property is an array, it is an object property (i.e. has a "$ref" value). Otherwise, it is a data property. + if (property instanceof ArraySchema) { + maxItems = ((ArraySchema) property).getMaxItems(); + minItems = ((ArraySchema) property).getMinItems(); + //return; + } else if (property instanceof ObjectSchema) { + maxItems = ((ObjectSchema) property).getMaxItems(); + minItems = ((ObjectSchema) property).getMinItems(); + } + + // Property is known to be required. And cardinality restrictions should have also been removed, so min/max items should be null. + if (minItems == null && maxItems == null) { + return; + } else { + Assertions.fail("Error in exact cardinality restriction."); + } + } else { + Assertions.fail("Error in exact cardinality restriction."); + } } catch (OWLOntologyCreationException e) { Assertions.fail("Error in ontology creation: ", e); } @@ -314,24 +329,45 @@ public void testObjectComplementOf() throws OWLOntologyCreationException, Except /** * This test attempts to get the OAS representation of the hasValue of an ObjectProperty. + * + * This corresponds to a named individual (of a particular class). Before version 3.1.0, OpenAPI does not support + * the "$ref" at the same level of a default value. For this reason, they are treated as separate items + * under the "allOf" key (which is an array type). The "$ref" value is the named individual's class and the "default" value is + * the named individual's name. */ @Test public void testObjectHasValue() throws OWLOntologyCreationException, Exception { try { this.initializeLogger(); - String expectedResult = ""; + // The short form of: "" + // resolves to the default value of: "ArtificialIntelligenceDepartment". + String expectedResult = "ArtificialIntelligenceDepartment"; YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("belongsTo"); - if (((ObjectSchema) property).getDefault()!=null) - Assertions.assertEquals(((ObjectSchema) property).getDefault(),expectedResult); - else + Object property = schema.getProperties().get("belongsTo"); + + if (property instanceof ArraySchema) { + Schema items = ((ArraySchema) property).getItems(); + if (items != null && (items.getAllOf() != null && !items.getAllOf().isEmpty())) { + for (var item: items.getAllOf()) { + if (((ObjectSchema) item).getDefault() != null) { + Assertions.assertEquals(((ObjectSchema) item).getDefault(), expectedResult); + return; + } + } + + // If we reach here, then none of the items had a default value, so fail. + Assertions.fail("Wrong configuration of ObjectHasValue restriction."); + } else { + Assertions.fail("Wrong configuration of ObjectHasValue restriction."); + } + } else { Assertions.fail("Wrong configuration of ObjectHasValue restriction."); - + } } catch (OWLOntologyCreationException e) { Assertions.fail("Error in ontology creation: ", e); } @@ -419,11 +455,13 @@ public void testDataUnionOf() throws OWLOntologyCreationException, Exception { Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAnyOf(); - for (int i=0; i Date: Mon, 29 Apr 2024 13:31:57 -0500 Subject: [PATCH 18/36] bump version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0098c2e..d050342 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ jar edu.isi.oba oba - 3.8.0 + 3.9.0 core https://github.com/KnowledgeCaptureAndDiscovery/OBA From 5d645955fdf44eb6d8bc4f79d529e386ed5c334a Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:37:20 -0500 Subject: [PATCH 19/36] enum for configuration flags --- src/main/java/edu/isi/oba/config/CONFIG_FLAG.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/edu/isi/oba/config/CONFIG_FLAG.java diff --git a/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java b/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java new file mode 100644 index 0000000..b9622be --- /dev/null +++ b/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java @@ -0,0 +1,13 @@ +package edu.isi.oba.config; + +public enum CONFIG_FLAG { + ALWAYS_GENERATE_ARRAYS, + DEFAULT_DESCRIPTIONS, + DEFAULT_PROPERTIES, + FOLLOW_REFERENCES, + PATH_DELETE, + PATH_GET, + PATH_PATCH, + PATH_POST, + PATH_PUT +} From 8faf2b209ba3257be4d85cbd3e15436cb671c5d0 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:38:28 -0500 Subject: [PATCH 20/36] use map for configuration flags; getters for map --- .../java/edu/isi/oba/config/YamlConfig.java | 87 ++++++++++++------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/src/main/java/edu/isi/oba/config/YamlConfig.java b/src/main/java/edu/isi/oba/config/YamlConfig.java index 97f4dbc..98530a4 100644 --- a/src/main/java/edu/isi/oba/config/YamlConfig.java +++ b/src/main/java/edu/isi/oba/config/YamlConfig.java @@ -3,67 +3,71 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.PathItem; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class YamlConfig { + private final Map configFlags = new HashMap<>(){{ + put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, true); + put(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true); + put(CONFIG_FLAG.DEFAULT_PROPERTIES, true); + put(CONFIG_FLAG.FOLLOW_REFERENCES, true); + put(CONFIG_FLAG.PATH_DELETE, false); + put(CONFIG_FLAG.PATH_GET, true); + put(CONFIG_FLAG.PATH_PATCH, false); + put(CONFIG_FLAG.PATH_POST, false); + put(CONFIG_FLAG.PATH_PUT, false); + }}; + String DEFAULT_OUTPUT_DIRECTORY = "outputs"; String DEFAULT_PROJECT_NAME = "default_project"; public OpenAPI openapi; public String output_dir = DEFAULT_OUTPUT_DIRECTORY; public String name = DEFAULT_PROJECT_NAME; public List paths; - public Boolean enable_get_paths = true; - public Boolean enable_post_paths = false; - public Boolean enable_put_paths = false; - public Boolean enable_delete_paths = false; public List ontologies; private EndpointConfig endpoint; - public AuthConfig auth; public FirebaseConfig firebase; public Map> relations; private LinkedHashMap custom_paths = null; public List classes; - public Boolean follow_references = false; - public Boolean default_descriptions = true; - public Boolean default_properties = true; + public String custom_queries_directory; public Boolean getEnable_get_paths() { - return enable_get_paths; + return this.configFlags.get(CONFIG_FLAG.PATH_GET); } public void setEnable_get_paths(Boolean enable_get_paths) { - this.enable_get_paths = enable_get_paths; + this.configFlags.put(CONFIG_FLAG.PATH_GET, enable_get_paths); } public Boolean getEnable_post_paths() { - return enable_post_paths; + return this.configFlags.get(CONFIG_FLAG.PATH_POST); } public void setEnable_post_paths(Boolean enable_post_paths) { - this.enable_post_paths = enable_post_paths; + this.configFlags.put(CONFIG_FLAG.PATH_POST, enable_post_paths); } public Boolean getEnable_put_paths() { - return enable_put_paths; + return this.configFlags.get(CONFIG_FLAG.PATH_PUT); } public void setEnable_put_paths(Boolean enable_put_paths) { - this.enable_put_paths = enable_put_paths; + this.configFlags.put(CONFIG_FLAG.PATH_PUT, enable_put_paths); } public Boolean getEnable_delete_paths() { - return enable_delete_paths; + return this.configFlags.get(CONFIG_FLAG.PATH_DELETE); } public void setEnable_delete_paths(Boolean enable_delete_paths) { - this.enable_delete_paths = enable_delete_paths; + this.configFlags.put(CONFIG_FLAG.PATH_DELETE, enable_delete_paths); } - public String custom_queries_directory; - public String getCustom_queries_directory() { return custom_queries_directory; } @@ -128,7 +132,6 @@ public void setRelations(Map> relations) { this.relations = relations; } - public LinkedHashMap getCustom_paths() { return custom_paths; } @@ -145,36 +148,44 @@ public void setOpenapi(OpenAPI openapi) { this.openapi = openapi; } - public List getClasses() { - return this.classes; - } + public List getClasses() { + return this.classes; + } public void setClasses(List classes) { this.classes = classes; } + public Boolean getAlways_generate_arrays() { + return this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS); + } + + public void setAlways_generate_arrays(Boolean always_generate_arrays) { + this.configFlags.put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, always_generate_arrays); + } + public Boolean getFollow_references() { - return follow_references; + return this.configFlags.get(CONFIG_FLAG.FOLLOW_REFERENCES); } public void setFollow_references(Boolean follow_references) { - this.follow_references = follow_references; + this.configFlags.put(CONFIG_FLAG.FOLLOW_REFERENCES, follow_references); } public Boolean getDefault_descriptions() { - return this.default_descriptions; + return this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS); } public void setDefault_descriptions(Boolean default_descriptions) { - this.default_descriptions = default_descriptions; + this.configFlags.put(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, default_descriptions); } public Boolean getDefault_properties() { - return this.default_properties; + return this.configFlags.get(CONFIG_FLAG.DEFAULT_PROPERTIES); } public void setDefault_properties(Boolean default_properties) { - this.default_properties = default_properties; + this.configFlags.put(CONFIG_FLAG.DEFAULT_PROPERTIES, default_properties); } public AuthConfig getAuth() { @@ -184,5 +195,23 @@ public AuthConfig getAuth() { public void setAuth(AuthConfig auth) { this.auth = auth; } -} + /** + * Get the value of a particular configuration flag. + * + * @param {flag} the configuration flag name + * @return The flag's value (true/false/null). + */ + public Boolean getConfigFlagValue(CONFIG_FLAG flag) { + return this.configFlags.get(flag); + } + + /** + * Get map of all config flags and their values. + * + * @return Map of CONFIG_FLAGs and their Boolean value (true/false/null). + */ + public Map getConfigFlags() { + return this.configFlags; + } +} \ No newline at end of file From 89bbf1f5a247602db9636d1518cdd20e66c913a6 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:46:39 -0500 Subject: [PATCH 21/36] add PATCH placeholder; minor cleanup --- .../java/edu/isi/oba/MapperOperation.java | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperOperation.java b/src/main/java/edu/isi/oba/MapperOperation.java index 7b9d7a5..584f806 100644 --- a/src/main/java/edu/isi/oba/MapperOperation.java +++ b/src/main/java/edu/isi/oba/MapperOperation.java @@ -2,7 +2,6 @@ import io.swagger.models.Method; import io.swagger.v3.oas.models.Operation; -import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.media.*; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.PathParameter; @@ -30,14 +29,12 @@ class MapperOperation { private final ApiResponses apiResponses = new ApiResponses(); private final Cardinality cardinality; private final Schema schema; + private final Operation operation; public Operation getOperation() { return operation; } - private final Operation operation; - - public MapperOperation(String schemaName, String schemaURI, Method method, Cardinality cardinality, Boolean auth) { this.auth = auth; this.cardinality = cardinality; @@ -50,6 +47,9 @@ public MapperOperation(String schemaName, String schemaURI, Method method, Cardi case GET: setOperationGet(); break; + case PATCH: + setOperationPatch(); + break; case PUT: setOperationPut(); break; @@ -59,7 +59,8 @@ public MapperOperation(String schemaName, String schemaURI, Method method, Cardi case DELETE: setOperationDelete(); break; - + default: + break; } if (cardinality == Cardinality.SINGULAR){ @@ -70,13 +71,14 @@ public MapperOperation(String schemaName, String schemaURI, Method method, Cardi .schema(new StringSchema())); } - if (auth && (method == Method.PUT || method == Method.POST || method == Method.DELETE )) { + if (auth && Set.of(Method.PATCH, Method.PUT, Method.POST, Method.DELETE).contains(method)) { parameters.add(new QueryParameter() .description("Username") .name("user") .required(false) .schema(new StringSchema())); } + operation = new Operation() .description(description) .summary(summary) @@ -84,18 +86,15 @@ public MapperOperation(String schemaName, String schemaURI, Method method, Cardi .parameters(parameters) .responses(apiResponses); - - if (method == Method.PUT || method == Method.POST ){ + if (Set.of(Method.PATCH, Method.PUT, Method.POST).contains(method)) { operation.setRequestBody(requestBody); } - - if (method == Method.PUT || method == Method.POST || method == Method.DELETE ){ + if (Set.of(Method.PATCH, Method.PUT, Method.POST, Method.DELETE).contains(method)) { SecurityRequirement securityRequirement = new SecurityRequirement(); securityRequirement.addList("BearerAuth"); operation.addSecurityItem(securityRequirement); } - } private void setOperationGet() { @@ -113,7 +112,7 @@ private void setOperationGet() { case PLURAL: summary = "List all instances of " + this.schemaName; description = "Gets a list of all instances of " + this.schemaName + - " (more information in " +this.schemaURI+")"; + " (more information in " + this.schemaURI + ")"; responseDescriptionOk = "Successful response - returns an array with the instances of " + schemaName + "."; //Set response @@ -140,9 +139,9 @@ private void setOperationGet() { .schema(new IntegerSchema()._default(100).maximum(BigDecimal.valueOf(200)).minimum(BigDecimal.valueOf(1)))); break; case SINGULAR: - summary = "Get a single " + this.schemaName +" by its id"; - description = "Gets the details of a given " + this.schemaName+ - " (more information in " +this.schemaURI+")"; + summary = "Get a single " + this.schemaName + " by its id"; + description = "Gets the details of a given " + this.schemaName + + " (more information in " + this.schemaURI + ")"; responseDescriptionOk = "Gets the details of a given " + schemaName; //Set request @@ -153,7 +152,10 @@ private void setOperationGet() { break; } + } + private void setOperationPatch() { + // TODO: implement } private void setOperationPost() { @@ -177,13 +179,12 @@ private void setOperationPost() { ); } - private void setOperationPut() { String requestDescription = "An old " + this.schemaName + "to be updated"; summary = "Update an existing " + this.schemaName; - description = "Updates an existing " + this.schemaName+ - " (more information in " +this.schemaURI+")"; + description = "Updates an existing " + this.schemaName + + " (more information in " + this.schemaURI + ")"; //Set request MediaType mediaType = new MediaType().schema(schema); @@ -199,14 +200,12 @@ private void setOperationPut() { ) .addApiResponse("404", new ApiResponse() .description("Not Found")); - } - private void setOperationDelete() { summary = "Delete an existing " + this.schemaName; - description = "Delete an existing " + this.schemaName+ - " (more information in " +this.schemaURI+")"; + description = "Delete an existing " + this.schemaName + + " (more information in " + this.schemaURI + ")"; //Set the response apiResponses @@ -214,7 +213,5 @@ private void setOperationDelete() { .description("Deleted")) .addApiResponse("404", new ApiResponse() .description("Not Found")); - } - } From 123ca03ca34e26d49f615fbaebf671f6b7985e0b Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:51:38 -0500 Subject: [PATCH 22/36] cleanup --- src/main/java/edu/isi/oba/Oba.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/edu/isi/oba/Oba.java b/src/main/java/edu/isi/oba/Oba.java index b3b3c17..2b6f33a 100644 --- a/src/main/java/edu/isi/oba/Oba.java +++ b/src/main/java/edu/isi/oba/Oba.java @@ -4,7 +4,6 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.PathItem; import org.json.JSONObject; -import org.openapitools.codegen.examples.ExampleGenerator; import java.io.*; import java.nio.file.Path; From cd5a22aeac4f7def9f8acef669deaa41235a5fb3 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:54:04 -0500 Subject: [PATCH 23/36] rename to PathGenerator; use configuration flags Map The reason for renaming this is because 1) all the variables referred to is as "path generator" anyway and 2) to avoid confusion with java.nio.file.Path --- .../isi/oba/{Path.java => PathGenerator.java} | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) rename src/main/java/edu/isi/oba/{Path.java => PathGenerator.java} (78%) diff --git a/src/main/java/edu/isi/oba/Path.java b/src/main/java/edu/isi/oba/PathGenerator.java similarity index 78% rename from src/main/java/edu/isi/oba/Path.java rename to src/main/java/edu/isi/oba/PathGenerator.java index 72023c8..6afb52c 100644 --- a/src/main/java/edu/isi/oba/Path.java +++ b/src/main/java/edu/isi/oba/PathGenerator.java @@ -1,62 +1,65 @@ package edu.isi.oba; +import edu.isi.oba.config.CONFIG_FLAG; + import io.swagger.models.Method; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.media.*; -import io.swagger.v3.oas.models.parameters.Parameter; -import io.swagger.v3.oas.models.parameters.PathParameter; import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -class Path { - public Boolean enable_get_paths; - public Boolean enable_post_paths; - public Boolean enable_put_paths; - public Boolean enable_delete_paths; +class PathGenerator { + private final Map configFlags = new HashMap<>(); private Boolean auth; - public Path(Boolean enable_get_paths, Boolean enable_post_paths, Boolean enable_put_paths, Boolean enable_delete_paths, Boolean auth) { + public PathGenerator(Map configFlags, Boolean auth) { this.auth = auth; - this.enable_get_paths = enable_get_paths; - this.enable_post_paths = enable_post_paths; - this.enable_put_paths = enable_put_paths; - this.enable_delete_paths = enable_delete_paths; + this.configFlags.putAll(configFlags); } - public PathItem generate_singular(String schemaName, String schemaURI){ + public PathItem generate_singular(String schemaName, String schemaURI) { PathItem path_item = new PathItem(); - if (enable_get_paths) + if (this.configFlags.get(CONFIG_FLAG.PATH_GET)) { path_item.get(new MapperOperation(schemaName, schemaURI, Method.GET, Cardinality.SINGULAR, auth).getOperation()); + } - if (enable_delete_paths) + if (this.configFlags.get(CONFIG_FLAG.PATH_DELETE)) { path_item.delete(new MapperOperation(schemaName, schemaURI, Method.DELETE, Cardinality.SINGULAR, auth).getOperation()); + } + + if (this.configFlags.get(CONFIG_FLAG.PATH_POST)) { + path_item.put(new MapperOperation(schemaName, schemaURI, Method.POST, Cardinality.SINGULAR, auth).getOperation()); + } - if (enable_put_paths) + if (this.configFlags.get(CONFIG_FLAG.PATH_PUT)) { path_item.put(new MapperOperation(schemaName, schemaURI, Method.PUT, Cardinality.SINGULAR, auth).getOperation()); + } return path_item; } - public PathItem generate_plural(String schemaName, String schemaURI){ + public PathItem generate_plural(String schemaName, String schemaURI) { PathItem path_item = new PathItem(); - if (enable_get_paths) + if (this.configFlags.get(CONFIG_FLAG.PATH_GET)) { path_item.get(new MapperOperation(schemaName, schemaURI, Method.GET, Cardinality.PLURAL, auth).getOperation()); - if (enable_post_paths) + } + + if (this.configFlags.get(CONFIG_FLAG.PATH_POST)) { path_item.post(new MapperOperation(schemaName,schemaURI, Method.POST, Cardinality.PLURAL, auth).getOperation()); + } + return path_item; } - public PathItem user_login(String schema_name) { + public static PathItem user_login(String schema_name) { ApiResponses apiResponses = new ApiResponses(); final RequestBody requestBody = new RequestBody(); From e3d7f65ba2da99b731375e7ced199fa93e5fe9ac Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:55:00 -0500 Subject: [PATCH 24/36] use configuration flags / map throughout --- src/main/java/edu/isi/oba/Mapper.java | 31 ++++------- src/main/java/edu/isi/oba/MapperSchema.java | 32 +++++------ src/test/java/edu/isi/oba/MapperTest.java | 5 +- src/test/java/edu/isi/oba/ObaUtilsTest.java | 2 - .../java/edu/isi/oba/RestrictionsTest.java | 54 +++++++++++-------- 5 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/main/java/edu/isi/oba/Mapper.java b/src/main/java/edu/isi/oba/Mapper.java index 9d931a2..9a3195c 100644 --- a/src/main/java/edu/isi/oba/Mapper.java +++ b/src/main/java/edu/isi/oba/Mapper.java @@ -1,5 +1,6 @@ package edu.isi.oba; +import edu.isi.oba.config.CONFIG_FLAG; import edu.isi.oba.config.YamlConfig; import static edu.isi.oba.Oba.logger; @@ -33,17 +34,11 @@ class Mapper { YamlConfig config_data; public OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); - private Boolean follow_references; - private Boolean default_descriptions; - private Boolean default_properties; public Mapper(YamlConfig config_data) throws OWLOntologyCreationException, IOException { this.config_data = config_data; this.selected_paths = config_data.getPaths(); this.mappedClasses = new ArrayList<>(); - this.follow_references = config_data.getFollow_references(); - this.default_descriptions = config_data.getDefault_descriptions(); - this.default_properties = config_data.getDefault_properties(); List config_ontologies = config_data.getOntologies(); String destination_dir = config_data.getOutput_dir() + File.separator + config_data.getName(); @@ -106,14 +101,10 @@ private void download_ontologies(List config_ontologies, String destinat * The schemas includes the properties * * @param destination_dir directory to write the final results - * @param config_data yaml configuration */ public void createSchemas(String destination_dir) { Query query = new Query(destination_dir); - Path pathGenerator = new Path(this.config_data.getEnable_get_paths(), - this.config_data.getEnable_post_paths(), - this.config_data.getEnable_put_paths(), - this.config_data.getEnable_delete_paths(), + PathGenerator pathGenerator = new PathGenerator(this.config_data.getConfigFlags(), this.config_data.getAuth().getEnable() ); @@ -148,7 +139,7 @@ public void createSchemas(String destination_dir) { } } - private void add_user_path(Path pathGenerator) { + private void add_user_path(PathGenerator pathGenerator) { //User schema Map userProperties = new HashMap<>(); StringSchema username = new StringSchema(); @@ -165,7 +156,7 @@ private void add_user_path(Path pathGenerator) { this.paths.addPathItem("/user/login", pathGenerator.user_login(userSchema.getName())); } - private List add_owlclass_to_openapi(Query query, Path pathGenerator, OWLOntology ontology, + private List add_owlclass_to_openapi(Query query, PathGenerator pathGenerator, OWLOntology ontology, String defaultOntologyPrefixIRI, OWLClass cls, Boolean topLevel) { List ref = new ArrayList<>(); String classPrefixIRI = cls.getIRI().getNamespace(); @@ -182,7 +173,7 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, if(ontology.containsClassInSignature(clsToCheck.getIRI())) { System.out.println("ADD "+ clsToCheck); for (OWLOntology temp_ontology : this.ontologies) { - if (follow_references) { + if (this.config_data.getConfigFlagValue(CONFIG_FLAG.FOLLOW_REFERENCES)) { this.mappedClasses.add(clsToCheck); getMapperSchema(query, temp_ontology, clsToCheck, this.schemaDescriptions.get(clsToCheck.getIRI())); add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, clsToCheck, false); @@ -197,11 +188,9 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, logger.info("The class " + ref_class + " exists "); } else { for (OWLOntology temp_ontology : this.ontologies) { - if ( follow_references ) { + if (this.config_data.getConfigFlagValue(CONFIG_FLAG.FOLLOW_REFERENCES)) { this.mappedClasses.add(ref_class); getMapperSchema(query, temp_ontology, ref_class,this.schemaDescriptions.get(ref_class.getIRI())); -// OWLDocumentFormat format = ontology.getFormat(); -// String temp_defaultOntologyPrefixIRI = format.asPrefixOWLDocumentFormat().getDefaultPrefix(); add_owlclass_to_openapi(query, pathGenerator, temp_ontology, classPrefixIRI, ref_class, false); } } @@ -219,7 +208,7 @@ private List add_owlclass_to_openapi(Query query, Path pathGenerator, private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass cls, String cls_description) { //Convert from OWL Class to OpenAPI Schema. - MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, schemaNames, ontology, this.follow_references, this.default_descriptions, this.default_properties); + MapperSchema mapperSchema = new MapperSchema(this.ontologies, cls, cls_description, schemaNames, ontology, this.config_data.getConfigFlags()); //Write queries query.write_readme(mapperSchema.name); //Create the OpenAPI schema @@ -228,7 +217,7 @@ private MapperSchema getMapperSchema(Query query, OWLOntology ontology, OWLClass return mapperSchema; } - private void addOpenAPIPaths(Path pathGenerator, MapperSchema mapperSchema, OWLClass cls) { + private void addOpenAPIPaths(PathGenerator pathGenerator, MapperSchema mapperSchema, OWLClass cls) { if (selected_classes != null && !selected_classes.contains(cls)) { logger.info("Ignoring class " + cls.toString()); } else { @@ -251,11 +240,11 @@ private void setSchemaNames(Set classes) { private void setSchemaDrescriptions(Set classes, OWLOntology ontology){ for (OWLClass cls: classes) { System.out.println(cls); - schemaDescriptions.put(cls.getIRI(), ObaUtils.getDescription(cls, ontology, this.default_descriptions)); + schemaDescriptions.put(cls.getIRI(), ObaUtils.getDescription(cls, ontology, this.config_data.getConfigFlagValue(CONFIG_FLAG.DEFAULT_DESCRIPTIONS))); } } - private void add_path(Path pathGenerator, MapperSchema mapperSchema) { + private void add_path(PathGenerator pathGenerator, MapperSchema mapperSchema) { String singular_name = "/" + mapperSchema.name.toLowerCase() + "s/{id}"; String plural_name = "/" + mapperSchema.name.toLowerCase() + "s"; //Create the plural paths: for example: /models/ diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 3684f1e..42d1bfe 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -1,5 +1,6 @@ package edu.isi.oba; +import edu.isi.oba.config.CONFIG_FLAG; import static edu.isi.oba.Oba.logger; import io.swagger.v3.oas.models.examples.Example; @@ -8,7 +9,6 @@ import java.util.*; -import org.openapitools.codegen.examples.ExampleGenerator; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.OWLReasoner; @@ -35,9 +35,8 @@ class MapperSchema { private OWLOntology ontology_cls; private OWLReasonerFactory reasonerFactory; public List properties_range; - private boolean follow_references; - private Boolean default_descriptions; - private Boolean default_properties; + + private final Map configFlags = new HashMap<>(); public List propertiesFromObjectRestrictions; public Map> propertiesFromObjectRestrictions_ranges; @@ -62,11 +61,9 @@ public Schema getSchema() { return this.schema; } - public MapperSchema(List ontologies, OWLClass cls, String clsDescription, Map schemaNames, OWLOntology class_ontology, Boolean follow_references, Boolean default_descriptions, Boolean default_properties) { + public MapperSchema(List ontologies, OWLClass cls, String clsDescription, Map schemaNames, OWLOntology class_ontology, Map configFlags) { this.schemaNames = schemaNames; - this.follow_references = follow_references; - this.default_descriptions = default_descriptions; - this.default_properties = default_properties; + this.configFlags.putAll(configFlags); this.cls = cls; this.cls_description = clsDescription; this.type = "object"; @@ -255,7 +252,7 @@ private Map getDataProperties() { } List propertyRanges = getCodeGenTypesByRangeData(ranges, odp); - String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.default_descriptions); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); MapperDataProperty mapperProperty = new MapperDataProperty(propertyName, propertyDescription, isFunctional, restrictionValues, valuesFromDataRestrictions_ranges, propertyRanges, array, nullable); try { this.properties.put(mapperProperty.name, mapperProperty.getSchemaByDataProperty()); @@ -267,7 +264,7 @@ private Map getDataProperties() { } } - if (this.default_properties) { + if (this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)) { properties.putAll(this.getDefaultProperties()); } @@ -364,7 +361,7 @@ private Map getObjectProperties() { String propertyURI = odp.getIRI().toString(); propertyNameURI.put(propertyURI, propertyName); - List propertyRanges = getCodeGenTypesByRangeObject(ranges, odp, owlThing, this.follow_references); + List propertyRanges = getCodeGenTypesByRangeObject(ranges, odp, owlThing); Map restrictionValues = new HashMap() ; for (OWLOntology ontology: this.ontologies) { @@ -383,7 +380,7 @@ private Map getObjectProperties() { propertyRanges.clear(); } - String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.default_descriptions); + String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); MapperObjectProperty mapperObjectProperty = new MapperObjectProperty(propertyName, propertyDescription, isFunctional, restrictionValues, propertyRanges); try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); @@ -421,10 +418,9 @@ private List getCodeGenTypesByRangeData(Set r * @param ranges Represents a ObjectPropertyRange * @param odp Represents a OWLObjectProperty * @param owlThing - * @param follow_references * @return A list with the properties */ - private List getCodeGenTypesByRangeObject(Set ranges, OWLObjectProperty odp, OWLClass owlThing, boolean follow_references) { + private List getCodeGenTypesByRangeObject(Set ranges, OWLObjectProperty odp, OWLClass owlThing) { List objectProperty = new ArrayList<>(); for (OWLObjectPropertyRangeAxiom propertyRangeAxiom : ranges) { @@ -436,7 +432,7 @@ private List getCodeGenTypesByRangeObject(Set rangesOP = this.propertiesFromObjectRestrictions_ranges.get(this.sfp.getShortForm(op.getIRI())); for (String j : restrictionsValuesFromClass.keySet()) { @@ -512,7 +508,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { for (OWLDataProperty dp: this.propertiesFromDataRestrictions) { List valuesFromDataRestrictions_ranges = new ArrayList<>(); - String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls, this.default_descriptions); + String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); if (!this.propertiesFromDataRestrictions_ranges.isEmpty()) { List rangesDP = this.propertiesFromDataRestrictions_ranges.get(this.sfp.getShortForm(dp.getIRI())); for (String j: restrictionsValuesFromClass.keySet()) { @@ -537,7 +533,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { } } - if (this.default_properties) { + if (this.configFlags.get(CONFIG_FLAG.DEFAULT_PROPERTIES)) { this.properties.putAll(this.getDefaultProperties()); } } diff --git a/src/test/java/edu/isi/oba/MapperTest.java b/src/test/java/edu/isi/oba/MapperTest.java index 2236ada..62c01e7 100644 --- a/src/test/java/edu/isi/oba/MapperTest.java +++ b/src/test/java/edu/isi/oba/MapperTest.java @@ -2,6 +2,7 @@ import static edu.isi.oba.ObaUtils.get_yaml_data; import edu.isi.oba.config.AuthConfig; +import edu.isi.oba.config.CONFIG_FLAG; import edu.isi.oba.config.YamlConfig; import java.io.File; @@ -10,6 +11,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.LogManager; @@ -18,7 +20,6 @@ import io.swagger.v3.oas.models.media.Schema; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.OWLClass; @@ -113,7 +114,7 @@ public void testComplexOntology() throws Exception{ Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://businessontology.com/ontology/Person"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), Map.ofEntries(Map.entry(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true), Map.entry(CONFIG_FLAG.DEFAULT_PROPERTIES, true), Map.entry(CONFIG_FLAG.FOLLOW_REFERENCES, true))); Schema schema = mapperSchema.getSchema(); // The person schema must not be null. Assertions.assertNotNull(schema); diff --git a/src/test/java/edu/isi/oba/ObaUtilsTest.java b/src/test/java/edu/isi/oba/ObaUtilsTest.java index ccb34ea..c32f380 100644 --- a/src/test/java/edu/isi/oba/ObaUtilsTest.java +++ b/src/test/java/edu/isi/oba/ObaUtilsTest.java @@ -9,13 +9,11 @@ import org.json.JSONObject; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.semanticweb.owlapi.model.OWLClass; import org.semanticweb.owlapi.model.OWLOntologyCreationException; -@Disabled public class ObaUtilsTest { @Test diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 0ce6dc6..ee63783 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -1,12 +1,14 @@ package edu.isi.oba; import static edu.isi.oba.ObaUtils.get_yaml_data; +import edu.isi.oba.config.CONFIG_FLAG; import edu.isi.oba.config.YamlConfig; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.LogManager; @@ -26,6 +28,12 @@ public class RestrictionsTest { static Logger logger = null; + + // Convenience variable so we don't need to retype this for each MapperSchema constructor. + private final Map configFlags = Map.ofEntries( + Map.entry(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true), + Map.entry(CONFIG_FLAG.DEFAULT_PROPERTIES, true), + Map.entry(CONFIG_FLAG.FOLLOW_REFERENCES, true)); /** * This method allows you to configure the logger variable that is required to print several @@ -56,7 +64,7 @@ public void testFunctionalObjectProperty() throws OWLOntologyCreationException, Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasRector"); if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { @@ -82,7 +90,7 @@ public void testObjectUnionOf() throws OWLOntologyCreationException, Exception { Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyMaterial"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("author"); if (property instanceof ArraySchema) { @@ -116,7 +124,7 @@ public void testObjectIntersectionOf() throws OWLOntologyCreationException, Exce Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasEvaluationMethod"); if (property instanceof ArraySchema) { @@ -148,7 +156,7 @@ public void testSimpleObjectSomeValuesFrom() throws OWLOntologyCreationException Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasDepartment"); if (property instanceof ArraySchema) { @@ -176,7 +184,7 @@ public void testObjectSomeValuesFrom_ComposedByRestriction() throws OWLOntologyC Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Student"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("enrolledIn"); if (property instanceof ArraySchema) { @@ -208,7 +216,7 @@ public void testObjectExactCardinality() throws OWLOntologyCreationException, Ex Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasRecord"); if (property instanceof ArraySchema) { @@ -240,7 +248,7 @@ public void testObjectMinCardinality() throws OWLOntologyCreationException, Exce Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("takesCourse"); if (property instanceof ArraySchema) { @@ -269,7 +277,7 @@ public void testObjectMaxCardinality() throws OWLOntologyCreationException, Exce Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasStudentEnrolled"); if (property instanceof ArraySchema) { @@ -300,7 +308,7 @@ public void testObjectComplementOf() throws OWLOntologyCreationException, Except Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInOtherDepartment"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); if (schema.getNot()!=null) Assertions.assertEquals(schema.getNot().get$ref(),expectedResult); @@ -324,7 +332,7 @@ public void testObjectHasValue() throws OWLOntologyCreationException, Exception Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("belongsTo"); if (((ObjectSchema) property).getDefault()!=null) @@ -351,7 +359,7 @@ public void testObjectOneOf() throws OWLOntologyCreationException, Exception { Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Professor"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("hasDegree"); @@ -385,7 +393,7 @@ public void testFunctionalDataProperty() throws OWLOntologyCreationException, Ex Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("birthDate"); if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { @@ -412,7 +420,7 @@ public void testDataUnionOf() throws OWLOntologyCreationException, Exception { Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("ects"); if (property instanceof ArraySchema) { @@ -446,7 +454,7 @@ public void testDataIntersectionOf() throws OWLOntologyCreationException, Except Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("memberOfOtherDepartments"); if (property instanceof ArraySchema) { @@ -478,7 +486,7 @@ public void testDataSomeValuesFrom() throws OWLOntologyCreationException, Except Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyProgram"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("studyProgramName"); if (property instanceof ArraySchema) { @@ -506,7 +514,7 @@ public void testDataSomeValuesFrom_ComposedByRestriction() throws OWLOntologyCre Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("memberOfOtherDepartments"); if (property instanceof ArraySchema) { @@ -538,7 +546,7 @@ public void testDataAllValuesFrom() throws OWLOntologyCreationException, Excepti Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyProgram"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("studyProgramName"); if (property instanceof ArraySchema) { @@ -563,7 +571,7 @@ public void testDataOneOf() throws OWLOntologyCreationException, Exception { Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Person"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("gender"); if (property instanceof ArraySchema) { @@ -596,7 +604,7 @@ public void testDataHasValue() throws OWLOntologyCreationException, Exception { Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("nationality"); @@ -621,7 +629,7 @@ public void testDataExactCardinality() throws OWLOntologyCreationException,Excep Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("universityName"); Integer maxItems = ((ArraySchema) property).getItems().getMaxItems(); @@ -650,7 +658,7 @@ public void testDataMinCardinality() throws OWLOntologyCreationException, Except Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Professor"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("researchField"); Integer minItems = ((ArraySchema) property).getItems().getMinItems(); @@ -676,7 +684,7 @@ public void testDataMaxCardinality() throws OWLOntologyCreationException, Except Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Person"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("address"); Integer maxItems = ((ArraySchema) property).getItems().getMaxItems(); @@ -702,7 +710,7 @@ public void testDataComplementOf() throws OWLOntologyCreationException,Exception Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Department"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); - MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), true, true, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); Object property= schema.getProperties().get("numberOfProfessors"); if (((ArraySchema) property).getItems().getNot()!=null) From d54e3cd871f65625c6b16be2c59e813ca5b56faf Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 12:58:28 -0500 Subject: [PATCH 25/36] bump as patch version Mostly refactoring. Added PATCH placeholder and a new ALWAYS_GENERATE_ARRAYS flag to be used soon. This is basically a patch without any functionality changes. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0098c2e..2975a76 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ jar edu.isi.oba oba - 3.8.0 + 3.8.1 core https://github.com/KnowledgeCaptureAndDiscovery/OBA From 8b0da604e3aba48d051386fac99af8c0835c2d0c Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Wed, 1 May 2024 13:24:51 -0500 Subject: [PATCH 26/36] add PATCH getter/setter --- src/main/java/edu/isi/oba/config/YamlConfig.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/edu/isi/oba/config/YamlConfig.java b/src/main/java/edu/isi/oba/config/YamlConfig.java index 98530a4..56052d6 100644 --- a/src/main/java/edu/isi/oba/config/YamlConfig.java +++ b/src/main/java/edu/isi/oba/config/YamlConfig.java @@ -44,6 +44,14 @@ public void setEnable_get_paths(Boolean enable_get_paths) { this.configFlags.put(CONFIG_FLAG.PATH_GET, enable_get_paths); } + public Boolean getEnable_patch_paths() { + return this.configFlags.get(CONFIG_FLAG.PATH_PATCH); + } + + public void setEnable_patch_paths(Boolean enable_patch_paths) { + this.configFlags.put(CONFIG_FLAG.PATH_PATCH, enable_patch_paths); + } + public Boolean getEnable_post_paths() { return this.configFlags.get(CONFIG_FLAG.PATH_POST); } From 27531a163a30cb2ca0d3d6f238e4ffb7da37d47f Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 6 May 2024 10:09:51 -0500 Subject: [PATCH 27/36] missing space --- src/main/java/edu/isi/oba/MapperOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/isi/oba/MapperOperation.java b/src/main/java/edu/isi/oba/MapperOperation.java index 584f806..4cc4b89 100644 --- a/src/main/java/edu/isi/oba/MapperOperation.java +++ b/src/main/java/edu/isi/oba/MapperOperation.java @@ -180,7 +180,7 @@ private void setOperationPost() { } private void setOperationPut() { - String requestDescription = "An old " + this.schemaName + "to be updated"; + String requestDescription = "An old " + this.schemaName + " to be updated"; summary = "Update an existing " + this.schemaName; description = "Updates an existing " + this.schemaName + From fb0c34a3571a6192f4dbf115f2046b8e2f1cf28c Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 6 May 2024 10:25:59 -0500 Subject: [PATCH 28/36] add flag for generating required properties list --- src/main/java/edu/isi/oba/config/CONFIG_FLAG.java | 3 ++- src/main/java/edu/isi/oba/config/YamlConfig.java | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java b/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java index b9622be..f85e99e 100644 --- a/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java +++ b/src/main/java/edu/isi/oba/config/CONFIG_FLAG.java @@ -9,5 +9,6 @@ public enum CONFIG_FLAG { PATH_GET, PATH_PATCH, PATH_POST, - PATH_PUT + PATH_PUT, + REQUIRED_PROPERTIES_FROM_CARDINALITY, } diff --git a/src/main/java/edu/isi/oba/config/YamlConfig.java b/src/main/java/edu/isi/oba/config/YamlConfig.java index 56052d6..d0e9b31 100644 --- a/src/main/java/edu/isi/oba/config/YamlConfig.java +++ b/src/main/java/edu/isi/oba/config/YamlConfig.java @@ -19,6 +19,7 @@ public class YamlConfig { put(CONFIG_FLAG.PATH_PATCH, false); put(CONFIG_FLAG.PATH_POST, false); put(CONFIG_FLAG.PATH_PUT, false); + put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, false); }}; String DEFAULT_OUTPUT_DIRECTORY = "outputs"; @@ -196,6 +197,14 @@ public void setDefault_properties(Boolean default_properties) { this.configFlags.put(CONFIG_FLAG.DEFAULT_PROPERTIES, default_properties); } + public Boolean getRequired_properties_from_cardinality() { + return this.configFlags.get(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY); + } + + public void setRequired_properties_from_cardinality(Boolean required_properties_from_cardinality) { + this.configFlags.put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, required_properties_from_cardinality); + } + public AuthConfig getAuth() { return auth; } From e654474f85313439c9e2684e909f5e5f2d6fa23f Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 6 May 2024 10:32:42 -0500 Subject: [PATCH 29/36] use flags for (non-)arrays + required props --- src/main/java/edu/isi/oba/MapperSchema.java | 15 ++++- .../java/edu/isi/oba/RestrictionsTest.java | 55 ++++++++++++++++--- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index fa23274..5858eac 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -110,7 +110,10 @@ private Schema setSchema() { schema.setType(this.type); schema.setProperties(this.getProperties()); - schema.setRequired(this.required_properties); + if (this.configFlags.containsKey(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY) + && this.configFlags.get(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY)) { + schema.setRequired(this.required_properties); + } HashMap exampleMap = new HashMap<>(); exampleMap.put("id", "some_id"); @@ -505,8 +508,11 @@ private void getClassRestrictions(OWLClass analyzedClass) { // If cardinality is exactly 1, then we can remove the min/max property constraints // and set the property to be required for the class. if (exactCardinality == 1 || (minCardinality == 1 && maxCardinality == 1)) { - opSchema.setMinItems(null); - opSchema.setMaxItems(null); + if (!this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) || !this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)) { + opSchema.setMinItems(null); + opSchema.setMaxItems(null); + } + is_required = true; } @@ -555,6 +561,9 @@ private void getClassRestrictions(OWLClass analyzedClass) { || minCardinality > 0 || maxCardinality > 1; + // If config flag to generate arrays is set, use it to override current setting. + isArray |= (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)); + // If cardinality is exactly 1 OR a minimum of 1, then not nullable. boolean isNullable = (exactCardinality == -1 && minCardinality == -1) ? true : exactCardinality != 1 && minCardinality < 1; diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 41f9c05..4ecbefd 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.ConsoleHandler; @@ -30,10 +31,13 @@ public class RestrictionsTest { static Logger logger = null; // Convenience variable so we don't need to retype this for each MapperSchema constructor. - private final Map configFlags = Map.ofEntries( - Map.entry(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true), - Map.entry(CONFIG_FLAG.DEFAULT_PROPERTIES, true), - Map.entry(CONFIG_FLAG.FOLLOW_REFERENCES, true)); + private Map configFlags = new HashMap<>(){{ + put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, true); + put(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true); + put(CONFIG_FLAG.DEFAULT_PROPERTIES, true); + put(CONFIG_FLAG.FOLLOW_REFERENCES, true); + put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, true); + }}; /** * This method allows you to configure the logger variable that is required to print several @@ -204,22 +208,59 @@ public void testObjectSomeValuesFrom_ComposedByRestriction() throws OWLOntologyC } } + + /** + * This test attempts to get the OAS representation of the exact cardinality of an ObjectProperty, + * when arrays are set to always be generated for properties. + */ + @Test + public void testObjectExactCardinalityWithArraysGenerated() throws OWLOntologyCreationException, Exception { + try { + this.initializeLogger(); + YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); + Mapper mapper = new Mapper(config_data); + OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); + String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + + this.configFlags.put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, true); + MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); + Schema schema = mapperSchema.getSchema(); + Object property= schema.getProperties().get("hasRecord"); + if (property instanceof ArraySchema) { + Integer maxItems = ((ArraySchema) property).getMaxItems(); + Integer minItems = ((ArraySchema) property).getMinItems(); + if (maxItems != null && minItems != null) { + if (maxItems == minItems) + // "Exact cardinality configured" -- does this really need to be output for the test? + return; + else + Assertions.fail("Error in exact cardinality restriction."); + } else + Assertions.fail("Null values in exact cardinality restriction."); + } + } catch (OWLOntologyCreationException e) { + Assertions.fail("Error in ontology creation: ", e); + } + } /** - * This test attempts to get the OAS representation of the exact cardinality of an ObjectProperty. + * This test attempts to get the OAS representation of the exact cardinality of an ObjectProperty, + * when properties may or may not be arrays, depending on cardinality. */ @Test - public void testObjectExactCardinality() throws OWLOntologyCreationException, Exception { + public void testObjectExactCardinalityWithoutArraysGenerated() throws OWLOntologyCreationException, Exception { try { this.initializeLogger(); YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#AmericanStudent"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); + + this.configFlags.put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, false); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); - boolean isRequired = schema.getRequired().contains("hasRecord"); + boolean isRequired = schema.getRequired() != null && schema.getRequired().contains("hasRecord"); // For exact cardinality, the class schema should have it marked as required. if (isRequired) { From 2e20268bd87e4e903356f94011f7cff1a3f68c11 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 6 May 2024 10:44:58 -0500 Subject: [PATCH 30/36] required props default change --- src/test/java/edu/isi/oba/RestrictionsTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index 4ecbefd..f15e54d 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -36,7 +36,7 @@ public class RestrictionsTest { put(CONFIG_FLAG.DEFAULT_DESCRIPTIONS, true); put(CONFIG_FLAG.DEFAULT_PROPERTIES, true); put(CONFIG_FLAG.FOLLOW_REFERENCES, true); - put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, true); + put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, false); }}; /** @@ -245,10 +245,10 @@ public void testObjectExactCardinalityWithArraysGenerated() throws OWLOntologyCr /** * This test attempts to get the OAS representation of the exact cardinality of an ObjectProperty, - * when properties may or may not be arrays, depending on cardinality. + * when properties may or may not be arrays, depending on cardinality. Plus, list of required properties are set to be generated for schemas. */ @Test - public void testObjectExactCardinalityWithoutArraysGenerated() throws OWLOntologyCreationException, Exception { + public void testObjectExactCardinalityWithRequiredPropertiesAndWithoutArraysGenerated() throws OWLOntologyCreationException, Exception { try { this.initializeLogger(); YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); @@ -257,6 +257,7 @@ public void testObjectExactCardinalityWithoutArraysGenerated() throws OWLOntolog String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); this.configFlags.put(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS, false); + this.configFlags.put(CONFIG_FLAG.REQUIRED_PROPERTIES_FROM_CARDINALITY, true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); Schema schema = mapperSchema.getSchema(); From a13681423040d06c80fd807e26e9fc1fcf33282e Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Mon, 6 May 2024 11:44:52 -0500 Subject: [PATCH 31/36] update documentation for new config flags --- docs/configuration_file.md | 38 +++++++++++++++ docs/filtering.md | 94 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/docs/configuration_file.md b/docs/configuration_file.md index 35346bb..ee777de 100644 --- a/docs/configuration_file.md +++ b/docs/configuration_file.md @@ -57,6 +57,12 @@ default_descriptions: true ## Enable/disable generation of default properties (description, id, label, and type) for each schema default_properties: true + +## Enable/disable generation of arrays for property type(s) all the time, regardless of cardinality / restrictions +always_generate_arrays: true + +## Enable/disable generation of list of required properties for a schema, if the the cardinality indicates it is required (e.g. exactly 1) +required_properties_from_cardinality: false ``` ## Supported settings @@ -303,6 +309,38 @@ For more information, go to [filtering classes](filtering.md#default_properties) default_properties: false ``` +### always_generate_arrays + +Enable/disable generation of arrays for property type(s) all the time, regardless of cardinality / restrictions. + +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `Boolean` | +| **Default:** | `True` | + +For more information, go to [filtering classes](filtering.md#always_generate_arrays) + +```yaml +always_generate_arrays: true +``` + +### required_properties_from_cardinality + +Enable/disable generation of list of required properties for a schema, if the the cardinality indicates it is required (e.g. exactly 1). + +| Field | Value | +| ------------- | --------- | +| **Required:** | `false` | +| **Type:** | `Boolean` | +| **Default:** | `False` | + +For more information, go to [filtering classes](filtering.md#required_properties_from_cardinality) + +```yaml +required_properties_from_cardinality: true +``` + ## auth Add login to the API and add security to the following methods: `POST`, `PUT` and `DELETE` diff --git a/docs/filtering.md b/docs/filtering.md index 0889055..aa3130b 100644 --- a/docs/filtering.md +++ b/docs/filtering.md @@ -50,6 +50,12 @@ default_descriptions: true ## Enable/disable generation of default properties (description, id, label, and type) for each schema default_properties: true + +## Enable/disable generation of arrays for property type(s) all the time, regardless of cardinality / restrictions +always_generate_arrays: true + +## Enable/disable generation of list of required properties for a schema, if the the cardinality indicates it is required (e.g. exactly 1) +required_properties_from_cardinality: false ``` The result is available at: [DBPedia Music](https://app.swaggerhub.com/apis/mosoriob/dbpedia-music/v1.3.0) @@ -231,3 +237,91 @@ components: type: integer type: object ``` + +### Generating property types as array of items uniformly vs. non-array when cardinality/restrictions warrant it + +When a property can have multiple items (e.g. a list of names), the property schema will always generate `type: array` with an `items:` key and sub-item types (e.g. `type: string`). However, in cases where the property is restricted by cardinality, the API spec can be generated so that the property is not an array but a single type (e.g. `type: string`). These cases include cardinality where the property is exactly 1 or is a maximum of 1. + +The default is to treat everything as an array, such as: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + items: + maxItems: 1 + minItems: 1 + type: string + type: array + propertyB: + items: + maxItems: 3 + type: string + type: array + type: object +``` + +The option `always_generate_arrays` allows you to disable the generating all properties with an array of items, if the class restrictions warrant it (e.g. there is exactly one property value allowed). By setting the `always_generate_arrays` value to `false`, the above example becomes: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + type: array + propertyB: + items: + maxItems: 3 + type: string + type: array + type: object +``` + +### Generating list of required property/properties for a class, when cardinality/restrictions warrant it + +When a property is known to be required based on class restrictions (e.g. exactly 1 or a minimum >= 1), OpenAPI specification supports a `required` key directly under the property. By default, OBA does not generate this required list of properties (for each class), for example: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + items: + maxItems: 1 + minItems: 1 + type: string + type: array + propertyB: + items: + maxItems: 3 + type: string + type: array + type: object +``` + +The option `required_properties_from_cardinality` allows you to generate this list based on class restrictions (e.g. there is exactly one property value or there is a minimum of 1 or more of the property value). By setting the `required_properties_from_cardinality` value to `true`, the above example becomes: + +```yaml +components: + schemas: + YourClass: + properties: + propertyA: + items: + maxItems: 1 + minItems: 1 + type: string + type: array + propertyB: + items: + maxItems: 3 + type: string + type: array + type: object + required: + - propertyA +``` From 7ea5482b264b3b4f76e6f23c3966ac1de689f53f Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Tue, 7 May 2024 13:16:55 -0500 Subject: [PATCH 32/36] arrays flag; correctly set functional --- src/main/java/edu/isi/oba/MapperSchema.java | 52 ++++++++++++++------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index 5858eac..bb97f71 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -14,6 +14,7 @@ import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory; +import org.semanticweb.owlapi.search.EntitySearcher; import org.semanticweb.owlapi.util.IRIShortFormProvider; import org.semanticweb.owlapi.util.SimpleIRIShortFormProvider; @@ -73,9 +74,9 @@ public MapperSchema(List ontologies, OWLClass cls, String clsDescri this.reasonerFactory = new StructuralReasonerFactory(); this.reasoner = reasonerFactory.createReasoner(this.ontology_cls); this.properties_range = new ArrayList<>(); - this.propertiesFromObjectRestrictions_ranges= new HashMap<>(); + this.propertiesFromObjectRestrictions_ranges = new HashMap<>(); this.propertiesFromObjectRestrictions = new ArrayList<>(); - this.propertiesFromDataRestrictions_ranges= new HashMap<>(); + this.propertiesFromDataRestrictions_ranges = new HashMap<>(); this.propertiesFromDataRestrictions = new ArrayList<>(); this.properties = new HashMap<>(); this.required_properties = new ArrayList<>(); @@ -186,7 +187,7 @@ private Map getDataProperties() { // the property will be inspected. if (!propertiesFromDataRestrictions.isEmpty()) { if (propertiesFromDataRestrictions.contains(odp)) { - inspect=false; + inspect = false; } } @@ -360,6 +361,7 @@ private Map getObjectProperties() { } String propertyDescription = ObaUtils.getDescription(odp, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); + MapperObjectProperty mapperObjectProperty = new MapperObjectProperty(propertyName, propertyDescription, isFunctional, restrictionValues, propertyRanges); try { this.properties.put(mapperObjectProperty.name, mapperObjectProperty.getSchemaByObjectProperty()); @@ -467,6 +469,8 @@ private void getClassRestrictions(OWLClass analyzedClass) { } } else { for (OWLObjectProperty op: this.propertiesFromObjectRestrictions) { + boolean isFunctional = EntitySearcher.isFunctional(op, this.ontologies.stream()); + MapperObjectProperty mapperObjectProperty; String propertyDescription = ObaUtils.getDescription(op, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); if (!this.propertiesFromObjectRestrictions_ranges.isEmpty()) { @@ -479,7 +483,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { int maxCardinality = -1; if (rangesOP != null && rangesOP.get(0).equals("defaultValue")) { - mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, false, true); + mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, isFunctional, restrictionValues, rangesOP, false, true); } else { String exactCardinalityStr = restrictionValues.get("exactCardinality"); exactCardinalityStr = ((exactCardinalityStr == null || exactCardinalityStr.isBlank()) ? "-1" : exactCardinalityStr); @@ -493,11 +497,20 @@ private void getClassRestrictions(OWLClass analyzedClass) { maxCardinalityStr = ((maxCardinalityStr == null || maxCardinalityStr.isBlank()) ? "-1" : maxCardinalityStr); maxCardinality = Integer.parseInt(maxCardinalityStr); + // If cardinality is present and allows for multiple values and it is not functional, + // then this is an array. + boolean isArray = !isFunctional + && (exactCardinality > 1 + || minCardinality > 1 + || maxCardinality > 1); + + // If config flag to generate arrays is set, use it to override current setting. + isArray |= (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)); + // If cardinality is exactly 1 OR a minimum of 1, then not nullable. boolean isNullable = (exactCardinality == -1 && minCardinality == -1) ? true : exactCardinality != 1 && minCardinality < 1; - // References always need to be included as an array of items. - mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, false, restrictionValues, rangesOP, true, isNullable); + mapperObjectProperty = new MapperObjectProperty(this.sfp.getShortForm(op.getIRI()), propertyDescription, isFunctional, restrictionValues, rangesOP, isArray, isNullable); } try { @@ -508,7 +521,7 @@ private void getClassRestrictions(OWLClass analyzedClass) { // If cardinality is exactly 1, then we can remove the min/max property constraints // and set the property to be required for the class. if (exactCardinality == 1 || (minCardinality == 1 && maxCardinality == 1)) { - if (!this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) || !this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)) { + if (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && !this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)) { opSchema.setMinItems(null); opSchema.setMaxItems(null); } @@ -522,7 +535,6 @@ private void getClassRestrictions(OWLClass analyzedClass) { is_required = true; } - if (is_required) { this.required_properties.add(mapperObjectProperty.name); } @@ -537,6 +549,8 @@ private void getClassRestrictions(OWLClass analyzedClass) { } for (OWLDataProperty dp: this.propertiesFromDataRestrictions) { + boolean isFunctional = EntitySearcher.isFunctional(dp, this.ontologies.stream()); + List valuesFromDataRestrictions_ranges = new ArrayList<>(); String propertyDescription = ObaUtils.getDescription(dp, this.ontology_cls, this.configFlags.get(CONFIG_FLAG.DEFAULT_DESCRIPTIONS)); if (!this.propertiesFromDataRestrictions_ranges.isEmpty()) { @@ -556,18 +570,20 @@ private void getClassRestrictions(OWLClass analyzedClass) { maxCardinalityStr = ((maxCardinalityStr == null || maxCardinalityStr.isBlank()) ? "-1" : maxCardinalityStr); int maxCardinality = Integer.parseInt(maxCardinalityStr); - // If cardinality is present and allows for multiple values, then this is an array. - boolean isArray = exactCardinality > 1 - || minCardinality > 0 - || maxCardinality > 1; + // If cardinality is present and allows for multiple values and it is not functional, + // then this is an array. + boolean isArray = !isFunctional + && (exactCardinality > 1 + || minCardinality > 1 + || maxCardinality > 1); // If config flag to generate arrays is set, use it to override current setting. - isArray |= (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)); + isArray |= (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)); // If cardinality is exactly 1 OR a minimum of 1, then not nullable. boolean isNullable = (exactCardinality == -1 && minCardinality == -1) ? true : exactCardinality != 1 && minCardinality < 1; - MapperDataProperty mapperDataProperty = new MapperDataProperty(this.sfp.getShortForm(dp.getIRI()), propertyDescription, false, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, isArray, isNullable); + MapperDataProperty mapperDataProperty = new MapperDataProperty(this.sfp.getShortForm(dp.getIRI()), propertyDescription, isFunctional, restrictionValues, valuesFromDataRestrictions_ranges, rangesDP, isArray, isNullable); try { Schema dpSchema = mapperDataProperty.getSchemaByDataProperty(); @@ -576,8 +592,11 @@ private void getClassRestrictions(OWLClass analyzedClass) { // If cardinality is exactly 1, then we can remove the min/max property constraints // and set the property to be required for the class. if (exactCardinality == 1 || (minCardinality == 1 && maxCardinality == 1)) { - dpSchema.setMinItems(null); - dpSchema.setMaxItems(null); + if (this.configFlags.containsKey(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS) && !this.configFlags.get(CONFIG_FLAG.ALWAYS_GENERATE_ARRAYS)) { + dpSchema.setMinItems(null); + dpSchema.setMaxItems(null); + } + is_required = true; } @@ -587,7 +606,6 @@ private void getClassRestrictions(OWLClass analyzedClass) { is_required = true; } - if (is_required) { this.required_properties.add(mapperDataProperty.name); } From 8b546846a9c2aacd08e22ecf7a3c494cfb3091eb Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Tue, 7 May 2024 13:17:33 -0500 Subject: [PATCH 33/36] transfer cardinality to property from items array --- src/main/java/edu/isi/oba/MapperDataProperty.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/edu/isi/oba/MapperDataProperty.java b/src/main/java/edu/isi/oba/MapperDataProperty.java index c5cb8f8..38ca8d0 100644 --- a/src/main/java/edu/isi/oba/MapperDataProperty.java +++ b/src/main/java/edu/isi/oba/MapperDataProperty.java @@ -237,6 +237,20 @@ private ArraySchema arraySchema(Schema base) { base = this.getSchemaRestrictions(base); + // Can this be done in a better way? + Integer minItemsInteger = base.getMinItems(); + if (minItemsInteger != null) { + base.setMinItems(null); + array.setMinItems(minItemsInteger); + } + + // Can this be done in a better way? + Integer maxItemsInteger = base.getMaxItems(); + if (maxItemsInteger != null) { + base.setMaxItems(null); + array.setMaxItems(maxItemsInteger); + } + array.setNullable(this.nullable); array.setItems(base); From ebc10f2494204bceedeb4df28636a36f86924b10 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Tue, 7 May 2024 13:19:07 -0500 Subject: [PATCH 34/36] fix issues with object ref schema generation --- .../edu/isi/oba/MapperObjectProperty.java | 125 ++++++++++-------- 1 file changed, 71 insertions(+), 54 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperObjectProperty.java b/src/main/java/edu/isi/oba/MapperObjectProperty.java index 264aeec..52bbaf5 100644 --- a/src/main/java/edu/isi/oba/MapperObjectProperty.java +++ b/src/main/java/edu/isi/oba/MapperObjectProperty.java @@ -25,7 +25,7 @@ public MapperObjectProperty(String name, String description, Boolean isFunctiona this.ref = ref; this.array = true; this.nullable = true; - this.isFunctional=isFunctional; + this.isFunctional = isFunctional; this.restrictions = restrictions; } @@ -35,7 +35,7 @@ public MapperObjectProperty(String name, String description, Boolean isFunction this.ref = ref; this.array = array; this.nullable = nullable; - this.isFunctional=isFunctional; + this.isFunctional = isFunctional; this.restrictions = restrictions; } @@ -51,24 +51,52 @@ public Schema getSchemaByObjectProperty() { } } - private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nullable) { - ArraySchema objects = new ArraySchema(); - objects.setDescription(this.description); - - if (array) { + private Schema getObjectPropertiesByRef(String ref, boolean isArray, boolean isNullable) { + if (this.restrictions.isEmpty()) { Schema object = new ObjectSchema(); - object.setDescription(this.description); object.set$ref(ref); - if (this.isFunctional) { + if (isArray) { + ArraySchema objects = new ArraySchema(); + objects.setDescription(this.description); + objects.setNullable(isNullable); + objects.setItems(object); + + if (this.isFunctional) { objects.setMaxItems(1); + } + + return objects; + } else { + object.setDescription(this.description); + object.setNullable(isNullable); + object.setType("object"); + + if (this.isFunctional) { + object.setMaxItems(1); + } + + return object; } - - for (String restriction: this.restrictions.keySet()) { - String value = this.restrictions.get(restriction); - switch (restriction) { + } + + ArraySchema objects = new ArraySchema(); + objects.setType("array"); + + // For OpenAPI v3.0, "$ref" cannot be used as a sibling with "default". + // see: https://swagger.io/docs/specification/using-ref/ + // see: https://stackoverflow.com/a/77189463 + // A workaround is to include both within "items" and as separate entries under "allOf". + // TODO: version check here (and elsewhere?) to differentiate the schema structure. For v3.1+, it can support "$ref" and "default" as siblings. + ArraySchema allOfItems = new ArraySchema(); + allOfItems.setType(null); + + for (String restriction: this.restrictions.keySet()) { + String value = this.restrictions.get(restriction); + + switch (restriction) { case "maxCardinality": - objects.setMaxItems(Integer.parseInt(value)); + objects.setMaxItems(Integer.parseInt(value)); break; case "minCardinality": objects.setMinItems(Integer.parseInt(value)); @@ -78,56 +106,45 @@ private Schema getObjectPropertiesByRef(String ref, boolean array, boolean nulla objects.setMinItems(Integer.parseInt(value)); break; case "someValuesFrom": - nullable=false; + isNullable = false; break; case "allValuesFrom": //nothing to do in the Schema break; - default: + case "objectHasReference": { + Schema object = new ObjectSchema(); + object.set$ref(value); + object.setType(null); + allOfItems.addAllOfItem(object); break; } - } - objects.setNullable(nullable); - objects.setItems(object); - return objects; - } else { - if (this.restrictions.isEmpty()) { - Schema object = new ObjectSchema(); - object.setDescription(this.description); - object.setType("object"); - return object; - } else { - // For OpenAPI v3.0, "$ref" cannot be used as a sibling with "default". - // see: https://swagger.io/docs/specification/using-ref/ - // see: https://stackoverflow.com/a/77189463 - // A workaround is to include both within "items" and as separate entries under "allOf". - // TODO: version check here (and elsewhere?) to differentiate the schema structure. For v3.1+, it can support "$ref" and "default" as siblings. - ArraySchema tempObjects = new ArraySchema(); - tempObjects.setType(null); - - for (String restriction: this.restrictions.keySet()) { + case "objectHasValue": { Schema object = new ObjectSchema(); - String value = this.restrictions.get(restriction); - - if ("objectHasReference".equals(restriction)) { - object.set$ref(value); - object.setType(null); - } - - if ("objectHasValue".equals(restriction)) { - object.setDefault(value); - object.setType("string"); - } - - tempObjects.addAllOfItem(object); + object.setDefault(value); + object.setType("string"); + allOfItems.addAllOfItem(object); + break; } + default: + break; + } + } - objects.items(tempObjects); - objects.setType("array"); + if (allOfItems.getAllOf() == null || allOfItems.getAllOf().isEmpty()) { + Schema object = new ObjectSchema(); + object.set$ref(ref); + objects.items(object); + } else { + objects.items(allOfItems); + } - return objects; - } + if (this.isFunctional) { + objects.setMaxItems(1); } + + objects.setNullable(isNullable); + + return objects; } private Schema getComposedSchemaObject(List refs, boolean array, boolean nullable) { @@ -195,7 +212,7 @@ private Schema getComposedSchemaObject(List refs, boolean array, boolean //if the property range is complex it will be omitted logger.warning("omitted complex restriction"); objects.setItems(object); - } + } } } From 7e5b8cdc7dfce786099f19a64673bc9c5eab72d1 Mon Sep 17 00:00:00 2001 From: Christopher Weedall <5010253+cweedall@users.noreply.github.com> Date: Tue, 7 May 2024 13:20:30 -0500 Subject: [PATCH 35/36] cleanup spacing; use expected value first in assertions --- .../java/edu/isi/oba/RestrictionsTest.java | 448 +++++++++--------- 1 file changed, 211 insertions(+), 237 deletions(-) diff --git a/src/test/java/edu/isi/oba/RestrictionsTest.java b/src/test/java/edu/isi/oba/RestrictionsTest.java index f15e54d..ed575ea 100644 --- a/src/test/java/edu/isi/oba/RestrictionsTest.java +++ b/src/test/java/edu/isi/oba/RestrictionsTest.java @@ -69,13 +69,13 @@ public void testFunctionalObjectProperty() throws OWLOntologyCreationException, OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#University"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("hasRector"); - if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("hasRector"); + if (property instanceof io.swagger.v3.oas.models.media.ArraySchema) { Integer maxItems = ((ArraySchema) property).getMaxItems(); Assertions.assertEquals(expectedResult, maxItems); - } - } catch (OWLOntologyCreationException e) { + } + } catch (OWLOntologyCreationException e) { Assertions.fail("Error in ontology creation: ", e); } } @@ -84,31 +84,31 @@ public void testFunctionalObjectProperty() throws OWLOntologyCreationException, * This test attempts to get the OAS representation of a ObjectUnionOf restriction. */ @Test - public void testObjectUnionOf() throws OWLOntologyCreationException, Exception { + public void testObjectUnionOf() throws OWLOntologyCreationException, Exception { List expectedResult = new ArrayList(); expectedResult.add("#/components/schemas/Organization"); expectedResult.add("#/components/schemas/Person"); - try { + try { this.initializeLogger(); YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); Mapper mapper = new Mapper(config_data); OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#StudyMaterial"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("author"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("author"); + if (property instanceof ArraySchema) { Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAnyOf(); - for (int i=0; i expectedResult = new ArrayList(); + List expectedResult = new ArrayList(); expectedResult.add("#/components/schemas/Assignment"); expectedResult.add("#/components/schemas/Exam"); @@ -129,20 +129,20 @@ public void testObjectIntersectionOf() throws OWLOntologyCreationException, Exce OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Course"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("hasEvaluationMethod"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("hasEvaluationMethod"); + if (property instanceof ArraySchema) { Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAllOf(); - for (int i=0; i expectedResult = new ArrayList(); + List expectedResult = new ArrayList(); expectedResult.add("#/components/schemas/BachelorProgram"); expectedResult.add("#/components/schemas/MasterProgram"); expectedResult.add("#/components/schemas/PhDProgram"); @@ -189,24 +190,22 @@ public void testObjectSomeValuesFrom_ComposedByRestriction() throws OWLOntologyC OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Student"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("enrolledIn"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("enrolledIn"); + if (property instanceof ArraySchema) { Boolean nullable = ((ArraySchema) property).getNullable(); Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAnyOf(); - for (int i=0; i itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getEnum(); - for (int i=0; i itemsValue; if (items instanceof ComposedSchema) { @@ -509,12 +503,12 @@ public void testDataUnionOf() throws OWLOntologyCreationException, Exception { if (itemsValue != null) { for (int i = 0; i < itemsValue.size(); i++) { String ref = itemsValue.get(i).getType(); - Assertions.assertEquals(ref,expectedResult.get(i)); + Assertions.assertEquals(expectedResult.get(i), ref); } } - } - } - } catch (OWLOntologyCreationException e) { + } + } + } catch (OWLOntologyCreationException e) { Assertions.fail("error in ontology creation: ", e); } } @@ -535,20 +529,20 @@ public void testDataIntersectionOf() throws OWLOntologyCreationException, Except OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("memberOfOtherDepartments"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("memberOfOtherDepartments"); + if (property instanceof ArraySchema) { Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAllOf(); - for (int i=0; i expectedResult = new ArrayList(); + List expectedResult = new ArrayList(); expectedResult.add("integer"); expectedResult.add("integer"); YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); @@ -595,23 +589,24 @@ public void testDataSomeValuesFrom_ComposedByRestriction() throws OWLOntologyCre OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#ProfessorInArtificialIntelligence"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("memberOfOtherDepartments"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("memberOfOtherDepartments"); + if (property instanceof ArraySchema) { Boolean nullable = ((ArraySchema) property).getNullable(); Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getAllOf(); - for (int i=0; i expectedResult = new ArrayList(); + List expectedResult = new ArrayList(); expectedResult.add("female"); expectedResult.add("male"); YamlConfig config_data = get_yaml_data("examples/restrictions/config.yaml"); @@ -652,24 +647,23 @@ public void testDataOneOf() throws OWLOntologyCreationException, Exception { OWLClass cls = mapper.manager.getOWLDataFactory().getOWLClass("https://w3id.org/example#Person"); String desc = ObaUtils.getDescription(cls, mapper.ontologies.get(0), true); MapperSchema mapperSchema = new MapperSchema(mapper.ontologies, cls, desc, mapper.schemaNames, mapper.ontologies.get(0), this.configFlags); - Schema schema = mapperSchema.getSchema(); - Object property= schema.getProperties().get("gender"); - if (property instanceof ArraySchema) { + Schema schema = mapperSchema.getSchema(); + Object property = schema.getProperties().get("gender"); + if (property instanceof ArraySchema) { Schema items = ((ArraySchema) property).getItems(); List itemsValue; if (items instanceof ComposedSchema) { - itemsValue =((ComposedSchema) items).getEnum(); - for (int i=0; i Date: Tue, 7 May 2024 14:32:30 -0500 Subject: [PATCH 36/36] remove functional check; done via EntitySearcher.isFunctional() instead --- src/main/java/edu/isi/oba/MapperSchema.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/main/java/edu/isi/oba/MapperSchema.java b/src/main/java/edu/isi/oba/MapperSchema.java index bb97f71..681e774 100644 --- a/src/main/java/edu/isi/oba/MapperSchema.java +++ b/src/main/java/edu/isi/oba/MapperSchema.java @@ -192,15 +192,10 @@ private Map getDataProperties() { } if (inspect) { - Boolean isFunctional = false; + boolean isFunctional = EntitySearcher.isFunctional(odp, this.ontologies.stream()); + for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getDataPropertyRangeAxioms(odp)); - functional = ontology.getAxioms(AxiomType.FUNCTIONAL_DATA_PROPERTY); - for (OWLFunctionalDataPropertyAxiom functionalAxiom:functional) { - if (functionalAxiom.getProperty().equals(odp)) { - isFunctional = true; - } - } } if (ranges.isEmpty()) { @@ -321,17 +316,11 @@ private Map getObjectProperties() { } if (inspect) { - Boolean isFunctional = false; + boolean isFunctional = EntitySearcher.isFunctional(odp, this.ontologies.stream()); + Set ranges = new HashSet<>(); for (OWLOntology ontology: this.ontologies) { ranges.addAll(ontology.getObjectPropertyRangeAxioms(odp)); - - functional = ontology.getAxioms(AxiomType.FUNCTIONAL_OBJECT_PROPERTY); - for (OWLFunctionalObjectPropertyAxiom functionalAxiom:functional) { - if (functionalAxiom.getProperty().equals(odp)) { - isFunctional = true; - } - } } if (ranges.isEmpty()) {