Skip to content

Commit

Permalink
Fix mapping with multiple sources linked to another mapping with mult…
Browse files Browse the repository at this point in the history
…iple sources

Without this fix, only half of the Referencing Objects Maps were generated.
  • Loading branch information
pheyvaer authored and DylanVanAssche committed Sep 12, 2023
1 parent d6710dc commit 6050c5a
Show file tree
Hide file tree
Showing 15 changed files with 345 additions and 183 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

### Fixed
- Mapping with multiple sources linked to another mapping with multiple sources only resulted in half of
Referencing Objects Maps.

## [1.6.0] - 2023-08-22

### Added
Expand Down
145 changes: 88 additions & 57 deletions lib/abstract-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class AbstractGenerator {
}

generateMapping(tmSubject, mapping, mappingName, sourceSubject, targetsIRIMap) {
this.targetsIRIMap = targetsIRIMap;
this.quads.push(quad(
tmSubject,
namedNode(namespaces.rdfs + 'label'),
Expand Down Expand Up @@ -187,7 +188,7 @@ class AbstractGenerator {

if (mapping.graphs) {
mapping.graphs.forEach(graph => {
this.generateGraphMap(smSubject, graph, sourceSubject, targetsIRIMap);
this.generateGraphMap(smSubject, graph, sourceSubject);
});
}

Expand All @@ -196,7 +197,7 @@ class AbstractGenerator {
this.quads.push(quad(
smSubject,
namedNode(namespaces.rml + 'logicalTarget'),
targetsIRIMap[target]
this.targetsIRIMap[target]
));
});
}
Expand Down Expand Up @@ -284,55 +285,57 @@ class AbstractGenerator {
this.quads.push(quad(
pmSubject,
namedNode(namespaces.rml + 'logicalTarget'),
targetsIRIMap[target]
this.targetsIRIMap[target]
));
});
}
});

po.objects.forEach(o => {
const omSubject = namedNode(this.baseIRI + this.getUniqueID('om'));
if (o.mapping) {
// We are dealing with a Parent Triples Map.
this.saveReferencingObjectMapDetails(mappingName, pomSubject, o);
} else {
const omSubject = namedNode(this.baseIRI + this.getUniqueID('om'));

this.quads.push(quad(
pomSubject,
namedNode(namespaces.rr + 'objectMap'),
omSubject
));
this.quads.push(quad(
pomSubject,
namedNode(namespaces.rr + 'objectMap'),
omSubject
));

if (o.function) {
if (isPredicateRDFTYPE) {
o.type = 'iri';
}
if (o.function) {
if (isPredicateRDFTYPE) {
o.type = 'iri';
}

this.generateFunctionTermMap(omSubject, o, sourceSubject, 'Literal');
} else if (o.mapping) {
//we are dealing with a parenttriplesmap
this.saveReferencingObjectMapDetails(mappingName, omSubject, o);
} else {
this.generateNormalObjectMap(omSubject, o, targetsIRIMap);
}
this.generateFunctionTermMap(omSubject, o, sourceSubject, 'Literal');
} else {
this.generateNormalObjectMap(omSubject, o);
}

if (o.targets) {
o.targets.forEach(target => {
this.quads.push(quad(
omSubject,
namedNode(namespaces.rml + 'logicalTarget'),
targetsIRIMap[target]
));
});
if (o.targets) {
o.targets.forEach(target => {
this.quads.push(quad(
omSubject,
namedNode(namespaces.rml + 'logicalTarget'),
this.targetsIRIMap[target]
));
});
}
}
});

if (po.graphs) {
po.graphs.forEach(graph => {
this.generateGraphMap(pomSubject, graph, sourceSubject, targetsIRIMap);
this.generateGraphMap(pomSubject, graph, sourceSubject);
});
}
});
}
}

generateNormalObjectMap(omSubject, o, targetsIRIMap) {
generateNormalObjectMap(omSubject, o) {
let isIRI = false;
this.quads.push(quad(
omSubject,
Expand Down Expand Up @@ -370,37 +373,59 @@ class AbstractGenerator {
o.type
));

this.processDatatypeAndLanguageOfObject(o, omSubject, targetsIRIMap);
this.processDatatypeAndLanguageOfObject(o, omSubject);
}

generateAllReferencingObjectMap() {
Object.keys(this.referencingObjectMapDetails).forEach(mappingName => {
const allDetails = this.referencingObjectMapDetails[mappingName];

allDetails.forEach(details => {
this.generateReferencingObjectMap(details.om, details.o);
this.generateReferencingObjectMap(details.pom, details.o);
});
});
};

generateReferencingObjectMap(omSubject, o) {
this.quads.push(quad(
omSubject,
namedNode(namespaces.rdf + 'type'),
namedNode(namespaces.rr + 'ObjectMap')
));
generateReferencingObjectMap(pomSubject, o) {
const objectMappings = this.mappingsAndIRIs[o.mapping];

this.quads.push(quad(
omSubject,
namedNode(namespaces.rr + 'parentTriplesMap'),
this.mappingsAndIRIs[o.mapping][0]
));
objectMappings.forEach(objectMappingIri => {
const omSubject = namedNode(this.baseIRI + this.getUniqueID('om'));

if (o.conditions) {
o.conditions.forEach(condition => {
this.generateCondition(condition, omSubject);
});
}
this.quads.push(quad(
pomSubject,
namedNode(namespaces.rr + 'objectMap'),
omSubject
));

this.quads.push(quad(
omSubject,
namedNode(namespaces.rdf + 'type'),
namedNode(namespaces.rr + 'ObjectMap')
));

this.quads.push(quad(
omSubject,
namedNode(namespaces.rr + 'parentTriplesMap'),
objectMappingIri
));

if (o.conditions) {
o.conditions.forEach(condition => {
this.generateCondition(condition, omSubject);
});
}

if (o.targets) {
o.targets.forEach(target => {
this.quads.push(quad(
omSubject,
namedNode(namespaces.rml + 'logicalTarget'),
this.targetsIRIMap[target]
));
});
}
});
}

generateCondition(condition, omSubject) {
Expand Down Expand Up @@ -429,17 +454,23 @@ class AbstractGenerator {
});
}

saveReferencingObjectMapDetails(mappingName, om, o) {
/**
* Save the details of referencing object map to generate later.
* @param mappingName - The mapping that is the subject of the referencing object map.
* @param pom - The IRI of the predicate object map.
* @param o - The YARRRML object of the referencing object map.
*/
saveReferencingObjectMapDetails(mappingName, pom, o) {
if (!this.referencingObjectMapDetails[mappingName]) {
this.referencingObjectMapDetails[mappingName] = [];
}

this.referencingObjectMapDetails[mappingName].push({
om, o
pom, o
});
}

generateFunctionTermMap(omSubject, o, sourceSubject, termType, targetsIRIMap) {
generateFunctionTermMap(omSubject, o, sourceSubject, termType) {
if (o.function === 'equal') {
this.convertEqualToIDLabEqual(o);
}
Expand All @@ -464,7 +495,7 @@ class AbstractGenerator {
));
}

this.processDatatypeAndLanguageOfObject(o, omSubject, targetsIRIMap);
this.processDatatypeAndLanguageOfObject(o, omSubject);

const fnSubject = namedNode(this.baseIRI + this.getUniqueID('fn'));
const pomExecutesSubject = namedNode(this.baseIRI + this.getUniqueID('pomexec'));
Expand Down Expand Up @@ -595,7 +626,7 @@ class AbstractGenerator {
));
}
} else if (pm.from === 'function') {
this.generateFunctionTermMap(omSubject, pm.value, sourceSubject, targetsIRIMap);
this.generateFunctionTermMap(omSubject, pm.value, sourceSubject);
} else {
const parentTermMapSubject = namedNode(this.baseIRI + this.getUniqueID('ptm'));

Expand All @@ -617,7 +648,7 @@ class AbstractGenerator {
}
}

generateGraphMap(subject, graph, sourceSubject, targetsIRIMap) {
generateGraphMap(subject, graph, sourceSubject) {
const graphMapSubject = namedNode(this.baseIRI + this.getUniqueID('gm'));

this.quads.push(quad(
Expand Down Expand Up @@ -658,7 +689,7 @@ class AbstractGenerator {
this.quads.push(quad(
graphMapSubject,
namedNode(namespaces.rml + 'logicalTarget'),
targetsIRIMap[target]
this.targetsIRIMap[target]
));
});
}
Expand Down Expand Up @@ -934,7 +965,7 @@ class AbstractGenerator {
}
}

processDatatypeAndLanguageOfObject(o, omSubject, targetsIRIMap) {
processDatatypeAndLanguageOfObject(o, omSubject) {
this.removeUnusedDatatypes(o);

if (o.datatype) {
Expand All @@ -956,7 +987,7 @@ class AbstractGenerator {
this.quads.push(quad(
languageMapSubject,
namedNode(namespaces.rml + 'logicalTarget'),
targetsIRIMap[target]
this.targetsIRIMap[target]
));
});
}
Expand Down
6 changes: 5 additions & 1 deletion lib/rml-generator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('YARRRML to RML', function () {
doTestCase('spec/mapping-with-database-as-source', options);

doTestCase('spec/graphs-all-triples', options);

});

it.skip('works for dbpedia', function () {
Expand Down Expand Up @@ -341,6 +341,10 @@ describe('YARRRML to RML', function () {
work('multiple-sources/mapping.yarrrml', 'multiple-sources/mapping.rml.ttl', done, {includeMetadata: false});
});

it('multiple sources with linked mappings', function (done) {
work('multiple-sources-with-linked-mappings/mapping.yarrrml', 'multiple-sources-with-linked-mappings/mapping.rml.ttl', done, {includeMetadata: false});
});

it('works when generating a constant iri', function (done) {
work('namednode/mapping.yarrrml.yml', 'namednode/mapping.rml.ttl', done, {includeMetadata: false});
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"author": "Ben De Meester",
"contributors": [
"Pieter Heyvaert <[email protected]>"
"Pieter Heyvaert (https://pieterheyvaert.com/)"
],
"license": "MIT",
"dependencies": {
Expand Down
Loading

0 comments on commit 6050c5a

Please sign in to comment.