Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pseudocode #2

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
265 changes: 238 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
# mscr-rmlgenerator

## Preconditions
1. Iterator mappings must be one-to-one mappings i.e. only only one property is mapped for source and target. (Is this true?)
## Preconditions / limitations
1. Iterator mappings must be one-to-one mappings i.e. only only one property is mapped for source and target AND there can be only one iterator mapping per NodeShape. The reason fro this is that there is currently no way of grouping other mappings under specific iterator mapping. TODO: Add examples (screenshots from MSCR).
2. Subject source mapping must have only one target property (i.e. the generated subject source property)
3. There can only be one pair of iterator/subject source mappings per SHACL shape. How significant restriction is this?
4. If mapping include more than one source properties a mapping function must be specified.

## Function calls

sourceFunc
- default -> passThrough
- input: field to reference
- output: array of values in the order of source properties

mappingFunc
- default -> passThrough
- input: array of values extracted from the source properties
- output: array of values. Exact output depends on the function.
targetFunc
- default -> passThrough
- input: array of values
- output: ?

createArray
- create new array and add the value param
- return array

addToArray
- add value param to the list provides through list param
- return array

Example with two source properties.
```
targetFunc(
mappingFunc(
addToArray(
value:
sourceFunc(valueParam: <raw value2)
list:
createArray(
value:
sourceFunc(valueParam: <raw value1>)
)
)
)
)
```


## Pseudocode
Expand All @@ -18,51 +62,218 @@ def getReferenceFormulationResource(sourceSchemaURI, inputGraph)
JSON
return new Resource(ql:JSONPath)

def getLogicalSourceData(g)
# Returns an ordered list of source propertyURIs that are used to reference of generate subject URIs for the given target shape
def getSubjectSourceMapping(inputGraph, targetShapeURI)
return queryResults(inputGraph,
select ?mappingURI
where
?mappingURI a :Mapping
?mappingURI :target/rdf:_1 ?target
?target :id targetShapeURI
?target :mscrType ?targetType .
filter(?targetType == "subject")
)

# Returns a list of values that represent all the iterator mappings in the crosswalk
def getIteratorData(g)
return queryResults(g,
select ?targetProperty ?sourceProperty
select ?targetShapeURI ?sourcePropertyURI ?mappingURI
where
?mapping a :Mapping .
?mapping :target/rdf:_1 ?target # see precondition 1
?mapping :source/rdf:_1 ?source
?target :id ?targetShape .
?source :id ?sourceProperty .

?mappingURI a :Mapping .
?mappingURI :target/rdf:_1 ?target # see precondition 1
?mappingURI :source/rdf:_1/:id ?sourcePropertyURI
?target :id ?targetShapeURI .
?target :mscrType ?targetType .
filter(?targetType == "iterator")
)

def getLogicalSource(subjectURI, inputGraph, sourceSchemaURI)
def getLogicalSourceModel(subjectURI, inputGraph, sourceSchemaURI, sourcePropertyURI)
logicalSource = new Graph()
referenceFormulation = getReferenceFormulationResource(sourceSchemaURI, inputGraph)
# create triples for RML LogicalSource
# What to add for rml:source?
iteratorPath = inputGraph.getPropertyValue(sourcePropertyURI, :instancePath)

logicalSource.add(rml:referenceFormulation, referenceFormulation)
logicalSource.add(rml:iterator, iteratorPath)
# What to add for rml:source?
logicalSource.add(rml:source, ?????)
return logicalSource


def createFunctionModel(functionValueTargetURI, functionToCallURI, paramDataList)
m = new Graph()
m.addRDF(
functionValueTargetURI,
fnml:functionValue,
[
rr:predicateObjectMap [
rr:predicate fno:executes;
rr:objectMap [
rr:constant {functionToCallURI}
];
];
{for each paramData in paramDataList
rr:predicateObjectMap [
rr:predicate {paramData.paramName};
rr:objectMap {paramData.paramValueModel}

];
}
]
)
return m
def createOuterFunctionModel(functionValueTargetURI, functionToCallURI, valueURI)
m = new Graph()
m.addRDF(
functionValueTargetURI,
fnml:functionValue,
[
rr:predicateObjectMap [
rr:predicate fno:executes;
rr:objectMap [
rr:constant {functionToCallURI}
];
];
{for each paramData in paramDataList
rr:predicateObjectMap [
rr:predicate :valueParameter
rr:objectMap {valueURI}

];
}
]
)
return m

def addSourceFuncModel(sourcePropertyInfoList, m)
latestFunctionURI = null
for(sourcePropertyInfo in sourcePropertyInfoList)
# create function call pair: source function + outer function
sourceFunctionURI = "mscr:func:passthrough"
if(sourcePropertyInfo.processing != null)
sourceFunctionURI = sourcePropertyInfo.processing.functionURI
params = sourcePropertyInfo.processing.params

if(is first element in the sourcePropertyInfoList) {
outerFunctionURI = "mcsr:createArray"
}
else {
outerFunctionURI = "mcsr:addToArray"
}
sourceFunctionResource = generateFuncURI(sourcePropertyInfo.id, false)
outerFunctionResource = generateFuncURI(sourcePropertyInfo.id, true)
m.addModel(createFunctionModel(sourceFunctionResource, sourceFunctionURI, params))
m.addModel(createOuterFunctionModel(outerFunctionResource, outerFunctionURI, sourceFunctionResource}

latestFunctionURI = outerFunctionResource
return latestFunctionURI

def addMappingFuncModel(mappingInfo, sourceFuncURI, m)
mappingFunctionURI = "mscr:func:passthrough"
if(mappingInfo.processing != null)
mappingFunctionURI = mappingInfo.processing.functionURI
mappingFunctionResource = generateFuncURI(mappingInfo.id)
m.addModel(createOuterFunctionModel(mappingFunctionResource, mappingFunctionURI, sourceFuncURI))
return mappingFunctionResource

def addTargetFuncModel(uri, targetPropertyInfoList, mappingFuncURI, m)

for(targetPropertyInfo in targetPropertyInfoList)
functionURI = "mscr:func:passthrough"
if(targetPropertyInfo.processing != null)
functionURI = targetPropertyInfo.processing.functionURI
params = targetPropertyInfo.processing.params
m.addModel(createOuterFunctionModel(uri, functionURI, mappingFuncURI}

def getSubjectMap(subjectURI):

def getPredicateObjectMap(subjectURI):
def getProcessingModel(uri, inputGraph, mappingURI)
mappingInfo = getMappingInfo(mappingURI)
m = new Graph()
if(mappingInfo.processing == null && mappingInfo.source.filter(x: x.processing != null).isEmpty && mappingInfo.target.filter(x: x.processing != null).isEmpty)
# mapping does not include any kind of processing configuration
return null

sourceFuncURI = addSourceFuncModel(mappingInfo.source, m)
mappingFuncURI = addMappingFuncModel(mappingInfo, sourceFuncURI, m)
addTargetFuncModel(uri, mappingInfo.target, mappingFuncURI, m)
return m


def getSourcePropertyURIs(mappingURI, inputGraph)
return queryResults(inputGraph,
select ?sourcePropertyID
where
mappingURI :source/* ?sourceProperty
?sourceProperty :id ?sourcePropertyID
?sourceProperty :index ?index
order by ASC(?index)
)

# Return a graph that contains all information related to single subjectMap
def getSubjectMapModel(uri, targetShapeURI, inputGraph):
mappingURI = getSubjectSourceMapping(targetShapeURI, inputGraph)
subjectMap = new Graph()

sourcePropertyURIs = getSourcePropertyURIs(mappingURI, inputGraph)
if(sourcePropertyURIs.isEmptyUI)
# case: blank node
else
subjectMap.addTriple(uri, rdf.type, rr:SubjectMap)
processingURI = getProcessingURI(...)

processingModel = getProcessingModel(processingURI, inputGraph, mappingURI)
if(processingModel != null)
subjectMap.addModel(processingModel)
subjectMap.addTriple(uri, fnml:functionValue, processingURI)
else
if(sourcePropertyURIs.size() > 1)
throw new Exception("Subject source mapping without processing functions must have only one source")
sourcePath = inputGraph.getString(sourceProeprtyURIs.get(0) :instancePath)
subjectMap.addTriple(uri, rml:reference, sourcePath)
# add also rr:class ?
subjectMap.addTriple(uri, rr:tempType, rr:IRI)
return subjectMap

# return mappingURIs for that have targets in target shape (excluding mappings to iterator and subject source)
def getPredicateObjectMapppings(targetShapeURI)

def getPredicateObjectMapModel(subjectURI, targetShapeURI, inputGraph):
MappingMapper mapper = new MappingMapper();
g = new Graph()
foreach(mappingURI in getPredicateObjectMapppings(targetShapeURI, inputGraph))
mappingInfo = mapper.mapToMappingDTO(mappingURI, inputModel);
# do processing until mappingFunc
# foreach target doTargetProcessing(mappingFunc, targetIndex)


def generateRMLFromMSCRGraph(inputGraph)
validate(inputGraph) # check if the preconditions hold
sourceSchemaURI = getSourceSchemaURI(inputGraph)
outputGraph = new Graph()
foreach(logicalSourceData in getLogicalSourceData(inputGraph))
triplesMapURI = new Resource(getTriplesMapURI()) # blank node
logicalSourceURI = new Resource(getLogicalSourceURI())
subjectMapURI = new Resource(getSubjectMapURI())
predicateObjecMapURI = new Resource(getPredicateObjectMapURI())
foreach(iteratorData in getIteratorData(inputGraph))

targetShape = logicalSourceData.targetShape
sourceProperty = logicalSourceData.sourceProperty
triplesMapURI = getTriplesMapURI()
logicalSourceURI = getLogicalSourceURI()
subjectMapURI = getSubjectMapURI()
predicateObjecMapURI = getPredicateObjectMapURI()

mappingURI = iteratorData.mappingURI
targetShapeURI = iteratorData.targetShapeURI
sourcePropertyURI = iteratorData.sourcePropertyURI

outputGraph.add(getLogicalSource(logicalSourceResource, inputGraph, sourceSchemaURI))
outputGraph.add(rml:logicalSource, new Resource(logicalSourceURI))
outputGraph.addModel(getLogicalSourceModel(logicalSourceURI, inputGraph, sourceSchemaURI, sourcePropertyURI))
outputGraph.addTriple(triplesMapURI, rml:logicalSource, logicalSourceURI)

outputGraph.add(getSubjectMap(subjectMapURI))
outputGraph.add(rr:subjectMap, new Resource(subjectMapURI))
outputGraph.addModel(
getSubjectMapModel(
subjectMapURI
inputGraph
)
)
outputGraph.addTriple(triplesMapURI, rr:subjectMap, subjectMapURI)

outputGraph.add(getPredicateObjectMap(predicateObjectMapURI))
outputGraph.add(rr:predicateObjectMap, new Resource(predicateObjectMapURI))
outputGraph.addModel(getPredicateObjectMapModel(predicateObjectMapURI))
outputGraph.addTriple(triplesMapURI, rr:predicateObjectMap, predicateObjectMapURI)

return outputGraph
```
Loading