From c83288224a0b0df4fcda92fbfda900b1d42f6a61 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 12:04:18 +0100 Subject: [PATCH 01/10] feat (add logical source): improve code structure --- .../java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java index 1a069ca..978ecf1 100644 --- a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java +++ b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java @@ -10,6 +10,7 @@ class RMLGeneratorTest { + Model loadPersonTestData() { Model model = ModelFactory.createDefaultModel(); From f9aeb4cf0328b903881162a1da23b1457ae1d3c0 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 13:57:56 +0100 Subject: [PATCH 02/10] refactor (add logical source): improve code structure --- .../mscr/tranformation/rml/RMLGenerator.java | 28 ++++++++--------- .../tranformation/rml/RMLGeneratorTest.java | 31 +++++++++++-------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java index caa323d..d4e0745 100644 --- a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java +++ b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java @@ -13,6 +13,7 @@ import org.topbraid.shacl.vocabulary.SH; import java.io.InputStream; +import java.util.Optional; //import fi.vm.yti.datamodel.api.v2.dto.MSCR; @@ -29,7 +30,7 @@ public String testMe() { return "test"; } - private String getSourceIteratorForTargetShape(Model model, String targetShapeUri) throws Exception { + private Optional getSourceIteratorForTargetShape(Model model, String targetShapeUri) { String q = String.format(""" PREFIX rdf: @@ -54,14 +55,14 @@ private String getSourceIteratorForTargetShape(Model model, String targetShapeUr if (results.hasNext()) { QuerySolution res = results.next(); - return res.getLiteral("iterator").toString(); + return Optional.of(res.getLiteral("iterator").toString()); } else { - throw new Exception("Source iterator could not be found for " + targetShapeUri); + return Optional.empty(); } } - public Resource addLogicalSource(String logicalSourceURI, Model m) throws Exception { + public Resource addLogicalSource(String logicalSourceURI, Model m, String targetShapeUri) throws Exception { /* You can now get the iterator source for a specific shape by querying along the lines: @@ -75,24 +76,21 @@ public Resource addLogicalSource(String logicalSourceURI, Model m) throws Except String iterator = ""; Resource logicalSource = m.createResource(logicalSourceURI); + + logicalSource.addProperty(RDF.type, m.createResource(nsRML + "BaseSource")); + Resource referenceFormulation = m.createResource(nsQL + "JSONPath"); + logicalSource.addProperty(m.createProperty(nsRML + "referenceFormulation"), referenceFormulation); + logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); + try { - iterator = getSourceIteratorForTargetShape(m, "iterator:https://shacl-play.sparna.fr/shapes/Person"); + iterator = this.getSourceIteratorForTargetShape(m, targetShapeUri).orElseThrow(Exception::new); } catch(Exception e) { - System.out.println(e.toString()); + System.out.println("Iterator could not be found"); throw e; } logicalSource.addProperty(m.createProperty(nsRML + "iterator"), iterator); - /*logicalSource.addProperty(RDF.type, m.createResource(nsRML + "BaseSource")); - Resource referenceFormulation = m.createResource(nsQL + "JSONPath"); - logicalSource.addProperty(m.createProperty(nsRML + "referenceFormulation"), referenceFormulation); - logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); - - Resource sourceProperty = inputModel.getResource(sourcePropertyURI); - Literal iteratorPath = sourceProperty.getProperty(MSCR.instancePath).getLiteral(); - logicalSource.addProperty(m.createProperty(nsRML + "iterator"), iteratorPath);*/ - return logicalSource; } } diff --git a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java index 978ecf1..f274d74 100644 --- a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java +++ b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java @@ -5,22 +5,22 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.StmtIterator; import org.apache.jena.riot.RDFDataMgr; import org.junit.jupiter.api.Test; class RMLGeneratorTest { - - Model loadPersonTestData() { - Model model = ModelFactory.createDefaultModel(); + String [] personJsonTestData = {"src/test/resources/data/person_json2shacl/crosswalk_content.ttl", + "src/test/resources/data/person_json2shacl/crosswalk_metadata.ttl", + "src/test/resources/data/person_json2shacl/source_metadata.ttl", + "src/test/resources/data/person_json2shacl/source_content.ttl", + "src/test/resources/data/person_json2shacl/target_metadata.ttl", + "src/test/resources/data/person_json2shacl/target_content.ttl" + }; - String[] inputFileNames = {"src/test/resources/data/person_json2shacl/crosswalk_content.ttl", - "src/test/resources/data/person_json2shacl/crosswalk_metadata.ttl", - "src/test/resources/data/person_json2shacl/source_metadata.ttl", - "src/test/resources/data/person_json2shacl/source_content.ttl", - "src/test/resources/data/person_json2shacl/target_metadata.ttl", - "src/test/resources/data/person_json2shacl/target_content.ttl" - }; + Model loadPersonTestData(String[] inputFileNames) { + Model model = ModelFactory.createDefaultModel(); for (String inputFileName : inputFileNames) { model.add(RDFDataMgr.loadModel(inputFileName)); @@ -36,10 +36,15 @@ void test() { } @Test - void testAddLogicalSource() throws Exception { - Model model = loadPersonTestData(); + void testAddLogicalSourceForPersonJSON() throws Exception { + Model model = loadPersonTestData(this.personJsonTestData); RMLGenerator r = new RMLGenerator(); - Resource logicalSource = r.addLogicalSource("http://example.com/1", model); + Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person"); + + StmtIterator props = logicalSource.listProperties(); + while (props.hasNext()) { + System.out.println(props.next()); + } assertEquals("http://example.com/1", logicalSource.getURI()); assertEquals("$", logicalSource.getProperty(model.createProperty("http://semweb.mmlab.be/ns/rml#iterator")).getObject().asLiteral().toString()); From 307e54411d481ae086a638a4004f4363d045de26 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 15:49:26 +0100 Subject: [PATCH 03/10] refactor (add logical source): improve code structure --- .github/gradle.yml | 2 + .../tranformation/rml/RMLGeneratorTest.java | 75 ++++++++++--------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/.github/gradle.yml b/.github/gradle.yml index 53d7608..ec57703 100644 --- a/.github/gradle.yml +++ b/.github/gradle.yml @@ -12,3 +12,5 @@ jobs: uses: gradle/actions/setup-gradle@v3 - name: Build with Gradle run: ./gradlew build + - name: Run tests with Gradle + run: ./gradlew test \ No newline at end of file diff --git a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java index f274d74..9ac1499 100644 --- a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java +++ b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java @@ -8,46 +8,47 @@ import org.apache.jena.rdf.model.StmtIterator; import org.apache.jena.riot.RDFDataMgr; import org.junit.jupiter.api.Test; +import java.util.Arrays; +import java.util.List; class RMLGeneratorTest { - String [] personJsonTestData = {"src/test/resources/data/person_json2shacl/crosswalk_content.ttl", - "src/test/resources/data/person_json2shacl/crosswalk_metadata.ttl", - "src/test/resources/data/person_json2shacl/source_metadata.ttl", - "src/test/resources/data/person_json2shacl/source_content.ttl", - "src/test/resources/data/person_json2shacl/target_metadata.ttl", - "src/test/resources/data/person_json2shacl/target_content.ttl" - }; - - Model loadPersonTestData(String[] inputFileNames) { - Model model = ModelFactory.createDefaultModel(); - - for (String inputFileName : inputFileNames) { - model.add(RDFDataMgr.loadModel(inputFileName)); - } - - return model; - } - - @Test - void test() { - RMLGenerator r = new RMLGenerator(); - assertEquals("test", r.testMe()); - } - - @Test - void testAddLogicalSourceForPersonJSON() throws Exception { - Model model = loadPersonTestData(this.personJsonTestData); - RMLGenerator r = new RMLGenerator(); - Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person"); - - StmtIterator props = logicalSource.listProperties(); - while (props.hasNext()) { - System.out.println(props.next()); - } - - assertEquals("http://example.com/1", logicalSource.getURI()); + String[] personJsonTestData = {"src/test/resources/data/person_json2shacl/crosswalk_content.ttl", + "src/test/resources/data/person_json2shacl/crosswalk_metadata.ttl", + "src/test/resources/data/person_json2shacl/source_metadata.ttl", + "src/test/resources/data/person_json2shacl/source_content.ttl", + "src/test/resources/data/person_json2shacl/target_metadata.ttl", + "src/test/resources/data/person_json2shacl/target_content.ttl" + }; + + Model loadPersonTestData(List inputFileNames) { + Model model = ModelFactory.createDefaultModel(); + + inputFileNames.forEach(inputFileName -> model.add(RDFDataMgr.loadModel(inputFileName))); + + return model; + } + + @Test + void test() { + RMLGenerator r = new RMLGenerator(); + assertEquals("test", r.testMe()); + } + + @Test + void testAddLogicalSourceForPersonJSON() throws Exception { + Model model = loadPersonTestData(Arrays.asList(this.personJsonTestData)); + RMLGenerator r = new RMLGenerator(); + Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person"); + + StmtIterator props = logicalSource.listProperties(); + props.forEach( + System.out::println + ); + + assertEquals("http://example.com/1", logicalSource.getURI()); + assertEquals("http://semweb.mmlab.be/ns/rml#BaseSource", logicalSource.getProperty(model.createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")).getObject().toString()); assertEquals("$", logicalSource.getProperty(model.createProperty("http://semweb.mmlab.be/ns/rml#iterator")).getObject().asLiteral().toString()); - } + } } From d5d4634d5fe2747b0f5eddf34819670277475fc1 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 15:51:40 +0100 Subject: [PATCH 04/10] refactor (add logical source): improve code structure --- .github/{ => workflows}/gradle.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/gradle.yml (100%) diff --git a/.github/gradle.yml b/.github/workflows/gradle.yml similarity index 100% rename from .github/gradle.yml rename to .github/workflows/gradle.yml From deeab824fb2aabb7a33a69858a6b17b873cf4a10 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 15:57:19 +0100 Subject: [PATCH 05/10] test (github actions): java version 17 --- .github/workflows/gradle.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index ec57703..2418fa2 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -8,6 +8,11 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v4 + - name: Setup Java + - uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 - name: Build with Gradle From 5d94a6699b6b884d29f2b1b68f573abe4900c9de Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 7 Feb 2025 15:58:42 +0100 Subject: [PATCH 06/10] test (github actions): java version 17 --- .github/workflows/gradle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 2418fa2..07c7f09 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -9,7 +9,7 @@ jobs: - name: Checkout sources uses: actions/checkout@v4 - name: Setup Java - - uses: actions/setup-java@v4 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' From 4770db51d704788fa046e1f28116e93011c17b77 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 14 Feb 2025 08:02:52 +0100 Subject: [PATCH 07/10] adapt test crosswalk subject map creation --- .../resources/data/person_json2shacl/crosswalk_content.ttl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/data/person_json2shacl/crosswalk_content.ttl b/src/test/resources/data/person_json2shacl/crosswalk_content.ttl index 6e577ff..e8fae1a 100644 --- a/src/test/resources/data/person_json2shacl/crosswalk_content.ttl +++ b/src/test/resources/data/person_json2shacl/crosswalk_content.ttl @@ -53,7 +53,7 @@ ; [ - "http://uri.suomi.fi/datamodel/ns/mscr#replace2Func" ; + "http://uri.suomi.fi/datamodel/ns/mscr#template" ; # TODO: adapt in MSCR [ a ; @@ -64,9 +64,9 @@ ] ; [ - "pattern" ; + ; # TODO: adapt in MSCR - "https://example.com/{value_0}{value_1}" + "https://example.com/{firstName}{lastName}" # TODO: adapt in MSCR ] ] ] ; From 1b45d9343e125bd4dca79e1032ef6f2e1551107f Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Thu, 20 Feb 2025 12:10:12 +0100 Subject: [PATCH 08/10] feat (ref formulation): get reference formulation from source schema --- .../mscr/tranformation/rml/RMLGenerator.java | 61 ++++++++++++++++++- .../tranformation/rml/RMLGeneratorTest.java | 3 +- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java index d4e0745..e46717d 100644 --- a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java +++ b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java @@ -26,10 +26,56 @@ public class RMLGenerator { String nsFNML = "http://semweb.mmlab.be/ns/fnml#"; String nsGREL = "http://users.ugent.be/~bjdmeest/function/grel.ttl#"; + enum ReferenceFormulation { + JSONPath, + XPath, + CSV + } + public String testMe() { return "test"; } + private Optional getSourceSchema(Model model, String crosswalkIri) { + + String q = String.format(""" + PREFIX rdf: + PREFIX : + + select ?format where { + <%s> a ; + ?sourceIri . + + ?sourceIri ?format + + + } + """, crosswalkIri); + + QueryExecution qe = QueryExecutionFactory.create(q, model); + ResultSet results = qe.execSelect(); + + + if (results.hasNext()) { + QuerySolution res = results.next(); + var ref = res.getLiteral("format"); + + switch (ref.toString()) { + case "JSONSCHEMA": return Optional.of(ReferenceFormulation.JSONPath); + case "XSD": return Optional.of(ReferenceFormulation.XPath); + case "CSV": return Optional.of(ReferenceFormulation.CSV); + + default: throw new Error("No matching reference formulation found for " + ref); + } + + + + } else { + return Optional.empty(); + } + + } + private Optional getSourceIteratorForTargetShape(Model model, String targetShapeUri) { String q = String.format(""" @@ -62,7 +108,7 @@ private Optional getSourceIteratorForTargetShape(Model model, String tar } - public Resource addLogicalSource(String logicalSourceURI, Model m, String targetShapeUri) throws Exception { + public Resource addLogicalSource(String logicalSourceURI, Model m, String targetShapeUri, String crosswalkIri) throws Exception { /* You can now get the iterator source for a specific shape by querying along the lines: @@ -75,10 +121,21 @@ public Resource addLogicalSource(String logicalSourceURI, Model m, String target */ String iterator = ""; + ReferenceFormulation refFormulation = null; Resource logicalSource = m.createResource(logicalSourceURI); + + try { + var ref = this.getSourceSchema(m, crosswalkIri); + refFormulation = ref.orElseThrow(Exception::new); + } catch(Exception e) { + System.out.println("Format could not be found"); + throw e; + } + + logicalSource.addProperty(RDF.type, m.createResource(nsRML + "BaseSource")); - Resource referenceFormulation = m.createResource(nsQL + "JSONPath"); + Resource referenceFormulation = m.createResource(nsQL + refFormulation); logicalSource.addProperty(m.createProperty(nsRML + "referenceFormulation"), referenceFormulation); logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); diff --git a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java index 9ac1499..fd9c6ee 100644 --- a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java +++ b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java @@ -39,7 +39,7 @@ void test() { void testAddLogicalSourceForPersonJSON() throws Exception { Model model = loadPersonTestData(Arrays.asList(this.personJsonTestData)); RMLGenerator r = new RMLGenerator(); - Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person"); + Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person", "mscr:crosswalk:653b47f8-0bad-4c0e-86e9-f4ff13b5d8e3"); StmtIterator props = logicalSource.listProperties(); props.forEach( @@ -49,6 +49,7 @@ void testAddLogicalSourceForPersonJSON() throws Exception { assertEquals("http://example.com/1", logicalSource.getURI()); assertEquals("http://semweb.mmlab.be/ns/rml#BaseSource", logicalSource.getProperty(model.createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")).getObject().toString()); assertEquals("$", logicalSource.getProperty(model.createProperty("http://semweb.mmlab.be/ns/rml#iterator")).getObject().asLiteral().toString()); + assertEquals("http://semweb.mmlab.be/ns/ql#JSONPath", logicalSource.getProperty(model.createProperty("http://semweb.mmlab.be/ns/rml#referenceFormulation")).getObject().toString()); } } From 35caef14c7578b04db427f47aa04b6d946d2cea8 Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Thu, 20 Feb 2025 15:39:23 +0100 Subject: [PATCH 09/10] refactor (logical source): simplify SPARQL --- .../mscr/tranformation/rml/RMLGenerator.java | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java index e46717d..b34bbfc 100644 --- a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java +++ b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java @@ -43,19 +43,16 @@ private Optional getSourceSchema(Model model, String cross PREFIX : select ?format where { - <%s> a ; - ?sourceIri . - - ?sourceIri ?format - + <%s> a :Crosswalk ; + :sourceSchema ?sourceIri . + ?sourceIri :format ?format } """, crosswalkIri); QueryExecution qe = QueryExecutionFactory.create(q, model); ResultSet results = qe.execSelect(); - if (results.hasNext()) { QuerySolution res = results.next(); var ref = res.getLiteral("format"); @@ -67,9 +64,6 @@ private Optional getSourceSchema(Model model, String cross default: throw new Error("No matching reference formulation found for " + ref); } - - - } else { return Optional.empty(); } @@ -83,15 +77,14 @@ private Optional getSourceIteratorForTargetShape(Model model, String tar PREFIX : select ?iterator where { - ?mappingURI a . + ?mappingURI a :Mapping . ?mappingURI :target/rdf:_1 ?target . ?target :uri <%s> . ?mappingURI :source/rdf:_1 ?source . ?source :uri ?sourceShapeId . - ?sourceShapeId ?iterator . - + ?sourceShapeId :instancePath ?iterator . } """, targetShapeUri); @@ -124,7 +117,6 @@ public Resource addLogicalSource(String logicalSourceURI, Model m, String target ReferenceFormulation refFormulation = null; Resource logicalSource = m.createResource(logicalSourceURI); - try { var ref = this.getSourceSchema(m, crosswalkIri); refFormulation = ref.orElseThrow(Exception::new); @@ -132,12 +124,11 @@ public Resource addLogicalSource(String logicalSourceURI, Model m, String target System.out.println("Format could not be found"); throw e; } - - + logicalSource.addProperty(RDF.type, m.createResource(nsRML + "BaseSource")); Resource referenceFormulation = m.createResource(nsQL + refFormulation); logicalSource.addProperty(m.createProperty(nsRML + "referenceFormulation"), referenceFormulation); - logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); + //logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); try { iterator = this.getSourceIteratorForTargetShape(m, targetShapeUri).orElseThrow(Exception::new); From b226990f9a20510a7283c99493e63f337748700d Mon Sep 17 00:00:00 2001 From: Tobias Schweizer Date: Fri, 21 Feb 2025 07:51:48 +0100 Subject: [PATCH 10/10] feat (subj map): add subj map (ongoing) --- .../mscr/tranformation/rml/RMLGenerator.java | 67 ++++++++++++++++--- .../tranformation/rml/RMLGeneratorTest.java | 15 ++++- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java index b34bbfc..70ad80b 100644 --- a/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java +++ b/src/main/java/fi/csc/mscr/tranformation/rml/RMLGenerator.java @@ -36,6 +36,38 @@ public String testMe() { return "test"; } + private Optional getSubjectMapTemplate(Model model, String mappingIri) { + String q = String.format(""" + PREFIX rdf: + PREFIX : + + select ?template + where { + ?mappingURI a :Mapping . + ?mappingURI :target/rdf:_1 ?target . + ?target :uri . + + ?mappingURI :processing ?proc . + ?proc ?p ?o . + ?o rdf:_2 ?oo. # TODO: is this general? + ?oo :value ?template + + } + + """, mappingIri); + + QueryExecution qe = QueryExecutionFactory.create(q, model); + ResultSet results = qe.execSelect(); + + if (results.hasNext()) { + QuerySolution res = results.next(); + return Optional.of(res.getLiteral("template").toString()); + } else { + return Optional.empty(); + } + + } + private Optional getSourceSchema(Model model, String crosswalkIri) { String q = String.format(""" @@ -101,7 +133,9 @@ private Optional getSourceIteratorForTargetShape(Model model, String tar } - public Resource addLogicalSource(String logicalSourceURI, Model m, String targetShapeUri, String crosswalkIri) throws Exception { + public Resource addLogicalSource(String logicalSourceURI, Model inputModel, String targetShapeUri, String crosswalkIri) throws Exception { + + Model outputModel = ModelFactory.createDefaultModel(); /* You can now get the iterator source for a specific shape by querying along the lines: @@ -115,30 +149,47 @@ public Resource addLogicalSource(String logicalSourceURI, Model m, String target String iterator = ""; ReferenceFormulation refFormulation = null; - Resource logicalSource = m.createResource(logicalSourceURI); + Resource logicalSource = outputModel.createResource(logicalSourceURI); try { - var ref = this.getSourceSchema(m, crosswalkIri); + var ref = this.getSourceSchema(inputModel, crosswalkIri); refFormulation = ref.orElseThrow(Exception::new); } catch(Exception e) { System.out.println("Format could not be found"); throw e; } - logicalSource.addProperty(RDF.type, m.createResource(nsRML + "BaseSource")); - Resource referenceFormulation = m.createResource(nsQL + refFormulation); - logicalSource.addProperty(m.createProperty(nsRML + "referenceFormulation"), referenceFormulation); + logicalSource.addProperty(RDF.type, outputModel.createResource(nsRML + "BaseSource")); + Resource referenceFormulation = outputModel.createResource(nsQL + refFormulation); + logicalSource.addProperty(outputModel.createProperty(nsRML + "referenceFormulation"), referenceFormulation); //logicalSource.addProperty(m.createProperty(nsRML + "source"), m.createLiteral("data/person.json")); try { - iterator = this.getSourceIteratorForTargetShape(m, targetShapeUri).orElseThrow(Exception::new); + iterator = this.getSourceIteratorForTargetShape(inputModel, targetShapeUri).orElseThrow(Exception::new); } catch(Exception e) { System.out.println("Iterator could not be found"); throw e; } - logicalSource.addProperty(m.createProperty(nsRML + "iterator"), iterator); + logicalSource.addProperty(outputModel.createProperty(nsRML + "iterator"), iterator); return logicalSource; } + + public Model addSubjectMap(Model inputModel, String mappingIri) throws Exception { + + Model outputModel = ModelFactory.createDefaultModel(); + + Resource triplesMap = outputModel.createResource("#Mapping"); + + Optional template = getSubjectMapTemplate(inputModel, mappingIri); + + Resource subjMap = outputModel.createResource(); + subjMap.addProperty(outputModel.createProperty(nsRR + "template"), outputModel.createLiteral(template.orElseThrow(Exception::new))); + subjMap.addProperty(outputModel.createProperty(nsRR + "class"), outputModel.createResource("http://schema.org/Person")); // TODO: get this from target + + triplesMap.addProperty(outputModel.createProperty(nsRR + "subjectMap"), subjMap); + + return outputModel; + } } diff --git a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java index fd9c6ee..e4da203 100644 --- a/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java +++ b/src/test/java/fi/csc/mscr/tranformation/rml/RMLGeneratorTest.java @@ -41,10 +41,10 @@ void testAddLogicalSourceForPersonJSON() throws Exception { RMLGenerator r = new RMLGenerator(); Resource logicalSource = r.addLogicalSource("http://example.com/1", model, "iterator:https://shacl-play.sparna.fr/shapes/Person", "mscr:crosswalk:653b47f8-0bad-4c0e-86e9-f4ff13b5d8e3"); - StmtIterator props = logicalSource.listProperties(); + /*StmtIterator props = logicalSource.listProperties(); props.forEach( System.out::println - ); + );*/ assertEquals("http://example.com/1", logicalSource.getURI()); assertEquals("http://semweb.mmlab.be/ns/rml#BaseSource", logicalSource.getProperty(model.createProperty("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")).getObject().toString()); @@ -52,4 +52,15 @@ void testAddLogicalSourceForPersonJSON() throws Exception { assertEquals("http://semweb.mmlab.be/ns/ql#JSONPath", logicalSource.getProperty(model.createProperty("http://semweb.mmlab.be/ns/rml#referenceFormulation")).getObject().toString()); } + @Test + void testAddSubjectMap() throws Exception { + Model model = loadPersonTestData(Arrays.asList(this.personJsonTestData)); + RMLGenerator r = new RMLGenerator(); + + Model subjMap = r.addSubjectMap(model, "subject:https://shacl-play.sparna.fr/shapes/Person"); + + subjMap.write(System.out, "TTL"); + + } + }