Skip to content

Streamline use cases

Andrea Cimmino Arriaga edited this page Jul 24, 2023 · 12 revisions

This page provides a collection of out of the box mappings for performing common operations.

Freemarker: cast JSON variable to String

In order to print a JSON variable it has to be casted into a String one. For doing that the following macro can be used:

<#assign foo><@objectToJson object=data.myobj /></#assign>
[=foo?html]

The definition of the macro is the following:

<#macro objectToJson object>
    <@compress single_line=true>
        <#if object?is_hash || object?is_hash_ex>
            <#assign first="true">
        {
            <#list object?keys as key>
                <#if first="false">,</#if>
                <#assign foo = key />
                <#assign value><@objectToJson object=object[key]!"" /></#assign>
            "[=key]": [=value?trim]
                <#assign first="false">
            </#list>
        }
        <#elseif object?is_enumerable>
            <#assign first="true">
        [
            <#list object as item>
                <#if first="false">,</#if>
                <#assign value><@objectToJson object=item /></#assign>
            [=value?trim]
                <#assign first="false">
            </#list>
        ]
        <#else>
        "[=object?trim]"
        </#if>
    </@compress>
</#macro>

SIoTRx: provide default value to a variable provided as URL argument

The following excerpt shows a mapping that has a variable arg which value is expected to be injected from a parameter given by a user. However, since it may occur that a user does not provide any value the mapping should initialize it with a default value. The following example show how.

<#assign var = arg!'0'> <#-- If no value is provided then var value is 0 -->

SIoTRx: insert triples into GraphDB with POST

The following excerpt displays how to store a set of triples, stored in the rdf variable, into a named graph which URI is given by the variable namedGraph. The triple store in use is a GraphDB that has a repository within called data-cloud and that is deployed at http://localhost:7200.

<#assign rdf = "..."> <#-- Inject in this variable your RDF in n-triples -->
<#assign namedGraph="..."> <#-- Inject in this variable the URI of your named graph -->
<#assign body="INSERT DATA { GRAPH <"+namedGraph+">  { " +rdf+ " } }">
<#assign url="http://localhost:7200/repositories/data-cloud/statements">
<#assign dataset>
{
            "method": "POST",
            "url": "[=url]",
            "body": "[=body?js_string]",
            "headers" : {  "Content-Type" : "application/sparql-update" }
}
</#assign>

<#assign result = providers("HttpProvider",dataset)>
[=result]

SIoTRx: validate and insert RDF triples into triplestore

In this example we can see the translation of an XML file into RDF, subsequently validated by means of SHACL shapes obtained by means of a GET request. Once validated, if the conforms is True, the triples will be sent by batches to the described triplestore.

<#assign xpath=handlers('XmlHandler')>
<#assign jpath=handlers("JsonHandler")>
<#assign dataset=providers("HttpProvider", {"url" : "https://raw.githubusercontent.com/oeg-upm/cogito_wrapper_module/main/repository/schedule/example/preprocessed.xml", "method" : "GET"})>
<#assign rdf>
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix data: <http://data.cogito.iot.linkeddata.es/resources/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix facility: <https://cogito.iot.linkeddata.es/def/facility#> .
@prefix process: <https://cogito.iot.linkeddata.es/def/process#> .
@prefix resource: <https://cogito.iot.linkeddata.es/def/resource#> .
@prefix const: <https://cogito.iot.linkeddata.es/def/construction#> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix s4city: <https://saref.etsi.org/saref4city#> .
@prefix saref: <https://saref.etsi.org/core#> .
@prefix cost: <http://data.cogito.iot.linkeddata.es/resources/cost/> .
@prefix interval: <http://data.cogito.iot.linkeddata.es/resources/interval/> .

@prefix process_data: <http://data.cogito.iot.linkeddata.es/resources/process/> .
@prefix project: <http://data.cogito.iot.linkeddata.es/resources/project/> .
@prefix task: <http://data.cogito.iot.linkeddata.es/resources/task/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .

data:Project_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]
    a facility:Project ;
    facility:isRelatedToProcess data:[=xpath.filter('./Project/GUID/text()', dataset)] .

data:Project_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] owl:sameAs project:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] .
project:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] owl:sameAs data:Project_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] .

data:Process_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]
    a process:Process ;
    process:hasTask
    <#list xpath.filter('./Project/Tasks/Task[*]',dataset)>
    <#items as task>
     data:Task_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] <#if task?is_last> ; <#else> , </#if>
    </#items>
    </#list>
    process:processID '[=xpath.filter('./Project/GUID/text()', dataset)]' ;
    process:hasName '[=xpath.filter('./Project/Name/text()', dataset)]' ;
    process:hasCreationDate '[=xpath.filter('./Project/CreationDate/text()', dataset)]'^^<http://www.w3.org/2001/XMLSchema#dateTime>.

data:Process_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)] owl:sameAs process_data:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)] .

process_data:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)] owl:sameAs data:Process_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)] .

<#list xpath.filter('./Project/Tasks/Task[*]',dataset)>
<#items as task>
data:Task_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] owl:sameAs task:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] .

task:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] owl:sameAs data:Task_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] .

data:Task_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)]
    a process:Task ;
    facility:isRelatedToProject data:Project_[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] ;
    process:taskId '[=xpath.filter('./Task/GUID/text()', task)]' ;
    process:taskUid '[=xpath.filter('./Task/UID/text()', task)]' ;
    process:hasName '[=xpath.filter('./Task/Name/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string> ;
    process:hasCreationDate '[=xpath.filter('./Task/CreationDate/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
    process:hasPriority '[=xpath.filter('./Task/Priority/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#integer> ;
    process:hasProgress '[=xpath.filter('./Task/RemainingWork/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string> ;
    process:hasStatus '[=xpath.filter('./Task/ActualWork/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string>
    <#if xpath.filter('./Task/Childs',task)?trim != '' || xpath.filter('./Task/Parent_WBS',task)?trim != ''>;<#else>.</#if>
    <#if xpath.filter('./Task/Childs',task)?trim != ''>
        process:hasSubTask
        <#assign childs = xpath.filter("./Task/Childs/WBS/text()",task)>
        <#if childs?is_sequence>
            <#list childs as child>
                data:Task_[=child] <#if child?is_last && xpath.filter('./Task/Parent_WBS',task)?trim == ''> . <#elseif child?is_last && xpath.filter('./Task/Parent_WBS',task)?trim != ''> ; <#else> , </#if>
            </#list>
        <#else>
             data:Task_[=childs] <#if xpath.filter('./Task/Parent_WBS',task)?trim == ''> . <#else> ; </#if>
        </#if>
    </#if>
    <#if xpath.filter('./Task/Parent_WBS',task)?trim != ''>
        process:isSubTaskOf data:Task_[=xpath.filter('./Task/Parent_WBS/text()', task)] .
    </#if>
</#items>
</#list>

<#--  Good Pactices -->

project:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]
    a facility:Project ;
    facility:isRelatedToProcess data:[=xpath.filter('./Project/GUID/text()', dataset)] .

process_data:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]
    a process:Process ;
    process:hasTask
    <#list xpath.filter('./Project/Tasks/Task[*]',dataset)>
    <#items as task>
     task:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)] <#if task?is_last> ; <#else> , </#if>
    </#items>
    </#list>
    process:processID '[=xpath.filter('./Project/GUID/text()', dataset)]' ;
    process:hasName '[=xpath.filter('./Project/Name/text()', dataset)]' ;
    process:hasCreationDate '[=xpath.filter('./Project/CreationDate/text()', dataset)]'^^<http://www.w3.org/2001/XMLSchema#dateTime> .
<#list xpath.filter('./Project/Tasks/Task[*]',dataset)>
<#items as task>
task:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)]_[=xpath.filter('./Project/GUID/text()', dataset)]_[=xpath.filter('./Task/UID/text()', task)]
    a process:Task ;
    facility:isRelatedToProject project:[=xpath.filter('./Project/Final_Project_ID/text()', dataset)] ;
    process:taskId '[=xpath.filter('./Task/GUID/text()', task)]' ;
    process:taskUid '[=xpath.filter('./Task/UID/text()', task)]' ;
    process:hasName '[=xpath.filter('./Task/Name/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string> ;
    process:hasCreationDate '[=xpath.filter('./Task/CreationDate/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
    process:hasPriority '[=xpath.filter('./Task/Priority/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#integer> ;
    process:hasProgress '[=xpath.filter('./Task/RemainingWork/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string> ;
    process:hasStatus '[=xpath.filter('./Task/ActualWork/text()', task)]'^^<http://www.w3.org/2001/XMLSchema#string>
    <#if xpath.filter('./Task/Childs',task)?trim != '' || xpath.filter('./Task/Parent_WBS',task)?trim != ''>;<#else>.</#if>
    <#if xpath.filter('./Task/Childs',task)?trim != ''>
        process:hasSubTask
        <#assign childs = xpath.filter("./Task/Childs/WBS/text()",task)>
        <#if childs?is_sequence>
            <#list childs as child>
                task:[=child] <#if child?is_last && xpath.filter('./Task/Parent_WBS',task)?trim == ''> . <#elseif child?is_last && xpath.filter('./Task/Parent_WBS',task)?trim != ''> ; <#else> , </#if>
            </#list>
        <#else>
             task:[=childs] <#if xpath.filter('./Task/Parent_WBS',task)?trim == ''> . <#else> ; </#if>
        </#if>
    </#if>
    <#if xpath.filter('./Task/Parent_WBS',task)?trim != ''>
        process:isSubTaskOf task:[=xpath.filter('./Task/Parent_WBS/text()', task)] .
    </#if>
</#items>
</#list>
</#assign>

<#assign shape=providers("HttpProvider", {"url" : "https://raw.githubusercontent.com/oeg-upm/cogito_data_repository/main/shapes/all_shapes.ttl", "method" : "GET"})>


<#-- Running the validation -->
<#-- configure the action to output report in NT serialization -->
<#assign config="{\"shape\" : \""+shape?js_string+"\", \"output-format\" : \"turtle\"  }">
<@action type="ShaclValidator" data=rdf conf=config; report>
<#--  aggregate the RDF and the report into a variable-->
<#assign rdf_report = rdf+"\n"+report>
<#assign report = report>
</@action>

<#--  Fetch and cast the RDF into NT serialization -->
<#assign config = {"data-format" : "turtle", "output-format" : "nt"}>
<@action type="RdfCast" data=rdf conf=config; result>
<#assign rdf_nt = result>
</@action>

<#assign query>
SELECT ?o WHERE {
    ?s <http://www.w3.org/ns/shacl#conforms> ?o .
}
</#assign>
<#assign config = '{"query" : "'+query+'" }'>
<@action type="SparqlEngine" data=rdf_report conf=config; result>
<#list jpath.filter("$.*",result) as res>

<#if res?contains("bindings")>
<#if jpath.filter("$.bindings.*.o.value",res)?contains("true")>

<#-- Split in chunks and execute post request -->
<#assign e = rdf_nt?split("\n")>
<#list e?chunk(20) as row>
<#assign f = row?join("\n")>

<#assign graph="INSERT DATA { GRAPH <https://data.cogito.iot.linkeddata.es/test1> { " + f + "} }">

<#assign graph="https://triplestore.cogito.iot.linkeddata.es/repositories/cogito-triplestore/statements?update="+ graph?url('ISO-8859-1')>

<#assign dataset>
{
            "method": "POST",
            "url": "[=graph]",
            "body": ""
}
</#assign>

<#assign dataset=providers("HttpProvider", dataset)>
</#list>

<#else>
<#assign query> 
SELECT (count(distinct ?instance) as ?notConformingInstances) WHERE { 
    ?subject <http://www.w3.org/ns/shacl#focusNode> ?instance . 
    ?subject <http://www.w3.org/ns/shacl#sourceShape> <http://shacl-practice.helio/resource/LocalityShape> . 
} 
</#assign>
<#assign config = '{"query" : "'+query+'" }'>
<@action type="SparqlEngine" data=rdf_report conf=config; result>
[=result]
</@action>
</#if>
</#if>
</#list>
</@action>