@prefix schema: <http://schema.org/> .
@prefix volipi: <http://data.sparna.fr/ontologies/volipi#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix skosthes: <http://purl.org/iso25964/skos-thes#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
@prefix qb: <http://purl.org/linked-data/cube#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix dcat: <http://www.w3.org/ns/dcat#> .
@prefix euvoc: <http://publications.europa.eu/ontology/euvoc#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix adms: <http://www.w3.org/ns/adms#> .
@prefix org: <http://www.w3.org/ns/org#> .
@prefix xls2rdf: <https://xls2rdf.sparna.fr/vocabulary#> .
@prefix this: <https://data.example.com/ontologies/sparnatural-config/> .
@prefix dbpedia: <http://dbpedia.org/ontology/> .
@prefix odb: <http://example.com/ontology/odb#> .
@prefix core: <http://data.sparna.fr/ontologies/sparnatural-config-core#> .
@prefix datasources: <http://data.sparna.fr/ontologies/sparnatural-config-datasources#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .

<https://data.mydomain.com/ontologies/sparnatural-config> a owl:Ontology .

this:Vehicle a sh:NodeShape;
  sh:order "1"^^xsd:integer;
  volipi:iconName "fa-solid fa-car";
  sh:targetClass odb:Vehicle;
  rdfs:label "Vehicle"@en, "Véhicule"@fr;
  sh:description "A vehicle is a car model for a specific brand."@en, "Un véhicule est un modèle de voiture pour une marque spécifique."@fr;
  sh:property this:Vehicle_VIN, this:Vehicle_hasManufacturer .

this:Museum a sh:NodeShape;
  sh:order "1"^^xsd:integer;
  volipi:iconName "fad fa-university";
  sh:targetClass dbpedia:Museum;
  rdfs:label "Museum"@en, "Musée"@fr;
  sh:description "A DBPedia Museum"@en, "Un Musée DBPedia"@fr;
  sh:property this:Museum_country .

this:Country a sh:NodeShape;
  sh:order "2"^^xsd:integer;
  volipi:iconName "fad fa-globe-africa";
  sh:targetClass dbpedia:Country;
  rdfs:label "Country"@en, "Pays"@fr;
  sh:description "A DBPedia Country"@en, "Un Pays DBPedia"@fr;
  sh:property this:Country_countryOf, this:country_label .

this:Vehicle_VIN sh:path odb:VIN;
  sh:order "1";
  sh:name "has VIN"@en, "a pour VIN"@fr;
  sh:description "Specifies the Vehicle Identification Number (VIN) of the vehicle."@en,
    "Spécifie le numéro d'identification du véhicule (VIN)."@fr;
  sh:minCount "1"^^xsd:integer;
  sh:maxCount "1"^^xsd:integer;
  sh:nodeKind sh:Literal;
  sh:datatype xsd:string;
  dash:searchWidget core:AutocompleteProperty;
  dash:propertyRole dash:LabelRole .

this:Vehicle_hasManufacturer sh:path odb:hasManufacturer;
  sh:order "2";
  sh:name "has manufacturer"@en, "a pour constructeur"@fr;
  sh:description "Specifies the manufacturer of the vehicle."@en, "Spécifie le constructeur d'un véhicule."@fr;
  sh:minCount "1"^^xsd:integer;
  sh:maxCount "1"^^xsd:integer;
  sh:nodeKind sh:IRI;
  sh:class odb:Manufacturer;
  dash:searchWidget core:ListProperty;
  core:enableNegation "true"^^xsd:boolean .

this:Museum_country sh:path dbpedia:country;
  sh:order "1";
  sh:name "country"@en, "pays"@fr;
  sh:description "Specifies the country where the museum is located."@en, "Spécifie le pays où se trouve le musée."@fr;
  sh:minCount "1"^^xsd:integer;
  sh:nodeKind sh:IRI;
  sh:class dbpedia:Country;
  dash:searchWidget core:ListProperty;
  core:enableOptional "true"^^xsd:boolean;
  core:enableNegation "true"^^xsd:boolean .

this:Country_countryOf sh:path dbpedia:countryOf;
  sh:order "1";
  sh:name "country of"@en, "pays de"@fr;
  sh:description "Specifies the museums located in this country."@en, "Spécifie les musées situés dans ce pays."@fr;
  sh:minCount "1"^^xsd:integer;
  sh:nodeKind sh:IRI;
  sh:class dbpedia:Museum;
  dash:searchWidget core:AutocompleteProperty;
  core:enableOptional "true"^^xsd:boolean;
  core:enableNegation "true"^^xsd:boolean .

this:country_label sh:path rdfs:label;
  sh:name "label"@en, "libellé"@fr;
  sh:minCount "1"^^xsd:integer;
  sh:nodeKind sh:Literal;
  sh:datatype rdf:langString;
  dash:propertyRole dash:LabelRole .

this:search_VIN_strstarts a datasources:SparqlDatasource;
  datasources:queryTemplate datasources:query_search_label_strstarts;
  datasources:labelProperty odb:VIN .

this:list_componentCode_alpha a datasources:SparqlDatasource;
  datasources:queryString """PREFIX odb: <http://example.com/ontology/odb#>
 SELECT DISTINCT ?uri ?label
 WHERE {
 ?domain $type $domain .
 ?domain $property ?uri .
 # Note how the range criteria is not used in this query
 FILTER(isIRI(?uri))
 ?uri rdfs:label ?libelleComposant .
 FILTER(lang(?libelleComposant) = \"\" || lang(?libelleComposant) = $lang)
 ?uri odb:componentCode ?codeComposant .
 # Concat component code + component label
 BIND(CONCAT(STR(?codeComposant),\" - \",STR(?libelleComposant)) AS ?label)
 }
 ORDER BY UCASE(?label)
 LIMIT 500""" .

this:tree_root_Component a datasources:SparqlDatasource;
  datasources:queryString """PREFIX odb: <http://example.com/ontology/odb#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#label>
SELECT ?uri ?label ?hasChildren (COUNT(?x) AS ?count) WHERE {
 ?uri a odb:Component .
 # Keep only roots, that do not have any parent
 FILTER NOT EXISTS {
 ?uri odb:parentComponent ?parent .
 }
 ?uri rdfs:label ?libelleComposant .
 FILTER(lang(?libelleComposant) = \"\" || lang(?libelleComposant) = $lang)
 ?uri odb:componentCode ?codeComposant .
 # Concat component code + component label
 BIND(CONCAT(STR(?codeComposant),\" - \",STR(?libelleComposant)) AS ?label)
 OPTIONAL { ?uri ^odb:parentComponent ?children }
 BIND(IF(bound(?children),true,false) AS ?hasChildren)
 OPTIONAL {
 ?x a $domain .
 ?x $property ?uri .
 }
}
GROUP BY ?uri ?label ?hasChildren
ORDER BY ?label""" .

this:tree_children_Component a datasources:SparqlDatasource;
  datasources:queryString """PREFIX odb: <http://example.com/ontology/odb#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#label>
SELECT DISTINCT ?uri ?label ?hasChildren (COUNT(?x) AS ?count) WHERE {

 $node ^odb:parentComponent ?uri .

 ?uri rdfs:label ?libelleComposant .
 FILTER(lang(?libelleComposant) = \"\" || lang(?libelleComposant) = $lang)
 ?uri odb:componentCode ?codeComposant .
 # Concat component code + component label
 BIND(CONCAT(STR(?codeComposant),\" - \",STR(?libelleComposant)) AS ?label)
 
 OPTIONAL { ?uri ^odb:parentComponent ?children }
 BIND(IF(bound(?children),true,false) AS ?hasChildren)

 OPTIONAL {
 ?x a $domain .
 ?x $property ?uri .
 }
}
GROUP BY ?uri ?label ?hasChildren
ORDER BY ?label""" .

this:query_list_label_alpha_with_count_langfr a datasources:SPARQLQuery;
  datasources:queryString """SELECT DISTINCT ?uri ?count (CONCAT(STR(?theLabel), ' (', STR(?count), ')') AS ?label)
WHERE {
{
 SELECT DISTINCT ?uri (COUNT(?domain) AS ?count)
 WHERE {
 ?domain a $domain .
 ?domain $property ?uri .
 FILTER(isIRI(?uri))
 # Note how the range criteria is not used in this query
 }
 GROUP BY ?uri
}
OPTIONAL { ?uri $labelPath ?theLabelLang . FILTER(lang(?theLabelLang) = $lang) }
OPTIONAL { ?uri $labelPath ?theLabelNone . FILTER(lang(?theLabelNone) = \"\") }
OPTIONAL { ?uri $labelPath ?theLabelFr . FILTER(lang(?theLabelFr) = \"fr\") }
BIND(COALESCE(?theLabelLang, ?theLabelNone, ?theLabelFr, STR(?uri)) AS ?theLabel)
}
ORDER BY UCASE(?label)
LIMIT 500""";
  rdfs:comment "A query that will list entries alphabetically with number of occurrences in parenthesis by fetching first in the user language but will default to French"@en .

this:query_list_label_count_langfr a datasources:SPARQLQuery;
  datasources:queryString """SELECT ?uri ?count (CONCAT(STR(?theLabel), ' (', STR(?count), ')') AS ?label)
WHERE {
{
 SELECT DISTINCT ?uri (COUNT(?domain) AS ?count)
 WHERE {
 ?domain a $domain .
 ?domain $property ?uri .
 FILTER(isIRI(?uri))
 # Note how the range criteria is not used in this query
 }
 GROUP BY ?uri
}
OPTIONAL { ?uri $labelPath ?theLabelLang . FILTER(lang(?theLabelLang) = $lang) }
OPTIONAL { ?uri $labelPath ?theLabelNone . FILTER(lang(?theLabelNone) = \"\") }
OPTIONAL { ?uri $labelPath ?theLabelFr . FILTER(lang(?theLabelFr) = \"fr\") }
BIND(COALESCE(?theLabelLang, ?theLabelNone, ?theLabelFr) AS ?theLabel)
}
ORDER BY DESC(?count) UCASE(?label)
LIMIT 500""";
  rdfs:comment "A query that will list entries by descending number of occurrences by fetching first in the user langauge but will default to French"@en .

this:query_list_label_alpha_langfr a datasources:SPARQLQuery;
  datasources:queryString """SELECT DISTINCT ?uri ?label
WHERE {
 ?domain a $domain .
 ?domain $property ?uri .
 # Note how the range criteria is not used in this query
 FILTER(isIRI(?uri))

 OPTIONAL { ?uri $labelPath ?theLabelLang . FILTER(lang(?theLabelLang) = $lang) }
 OPTIONAL { ?uri $labelPath ?theLabelNone . FILTER(lang(?theLabelNone) = \"\") }
 OPTIONAL { ?uri $labelPath ?theLabelFr . FILTER(lang(?theLabelFr) = \"fr\") }
 BIND(COALESCE(?theLabelLang, ?theLabelNone, ?theLabelFr) AS ?label)
}
ORDER BY UCASE(?label)
LIMIT 500""";
  rdfs:comment "A query that will list entries alphabetically by fetching first in the user language but will default to French"@en .

this:query_search_label_contains_langfr a datasources:SPARQLQuery;
  datasources:queryString """SELECT DISTINCT ?uri ?label
WHERE {
 ?domain a $domain .
 ?domain $property ?uri .
 ?uri a $range .
 ?uri $labelPath ?label .
 FILTER(isIRI(?uri))
 FILTER(CONTAINS(LCASE(STR(?label)), LCASE(\"$key\"))) 
 FILTER(lang(?label) = '' || lang(?label) = \"fr\")
} 
ORDER BY UCASE(?label)
LIMIT 50""";
  rdfs:comment "A query that will search in labels using contains function, first in the user language but will default to French."@en .
