@base		<https://w3id.org/atomgraph/linkeddatahub> .

@prefix :	<#> .
@prefix ac:	<https://w3id.org/atomgraph/client#> .
@prefix a:	<https://w3id.org/atomgraph/core#> .
@prefix rdf:	<http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:	<http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:	<http://www.w3.org/2001/XMLSchema#> .
@prefix owl:	<http://www.w3.org/2002/07/owl#> .
@prefix dh:	<https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#> .
@prefix sd:	<http://www.w3.org/ns/sparql-service-description#> .
@prefix sp:	<http://spinrdf.org/sp#> .
@prefix spin:	<http://spinrdf.org/spin#> .
@prefix spl:	<http://spinrdf.org/spl#> .
@prefix foaf:	<http://xmlns.com/foaf/0.1/> .
@prefix nfo:	<http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#> .
@prefix sioc:	<http://rdfs.org/sioc/ns#> .
@prefix dct:	<http://purl.org/dc/terms/> .

: a owl:Ontology ;
    owl:imports dh:, ac:, <http://spinrdf.org/spin>, foaf:, sd:, nfo:, owl: ;
    rdfs:label "LinkedDataHub ontology" ;
    rdfs:comment "Should be imported and reused by all extending applications" ;
    owl:versionInfo "1.1.7" .

# PROPERTIES

:count a owl:DatatypeProperty ;
    rdfs:domain dh:Container ;
    rdfs:range xsd:integer ;
    rdfs:label "Children count" ;
    rdfs:isDefinedBy : .

:file a owl:ObjectProperty ;
    rdfs:domain :Import ;
    rdfs:range nfo:FileDataObject ;
    rdfs:label "File" ;
    rdfs:isDefinedBy : .

:delimiter a owl:DatatypeProperty ;
    rdfs:domain :CSVImport ;
    rdfs:range xsd:string ;
    rdfs:label "Delimiter" ;
    rdfs:isDefinedBy : .

:violation a owl:ObjectProperty ;
    rdfs:domain :Import ;
    rdfs:range spin:ConstraintViolation ;
    rdfs:label "Constraint violation" ;
    rdfs:isDefinedBy : .

:violationValue a owl:DatatypeProperty ;
    rdfs:domain :URISyntaxViolation ;
    rdfs:range xsd:string ;
    rdfs:label "Violation value" ;
    rdfs:isDefinedBy : .

:chartType a owl:ObjectProperty ;
    rdfs:domain :Chart ;
    rdfs:range ac:Chart ;
    rdfs:label "Chart type" ;
    rdfs:isDefinedBy : .

:service a owl:ObjectProperty ;
    rdfs:label "Service" ;
    rdfs:range sd:Service ;
    rdfs:isDefinedBy : .

:categoryProperty a owl:ObjectProperty ;
    rdfs:domain :GraphChart ;
    rdfs:range rdf:Property ;
    rdfs:label "Category property" ;
    rdfs:isDefinedBy : .

:seriesProperty a owl:ObjectProperty ;
    rdfs:domain :GraphChart ;
    rdfs:range rdf:Property ;
    rdfs:label "Series property" ;
    rdfs:isDefinedBy : .

:categoryVarName a owl:ObjectProperty ;
    rdfs:domain :ResultSetChart ;
    rdfs:range xsd:string ;
    rdfs:label "Category variable name" ;
    rdfs:isDefinedBy : .

:seriesVarName a owl:ObjectProperty ;
    rdfs:domain :ResultSetChart ;
    rdfs:range xsd:string ;
    rdfs:label "Series variable name" ;
    rdfs:isDefinedBy : .

:view a owl:ObjectProperty ;
    rdfs:domain rdf:Property ;
    rdfs:range :View ;
    rdfs:label "Property view" ;
    rdfs:comment "Attaches a view to a property for forward relationships ($about property ?value)" ;
    rdfs:isDefinedBy : .

:inverseView a owl:ObjectProperty ;
    rdfs:domain rdf:Property ;
    rdfs:range :View ;
    rdfs:label "Inverse property view" ;
    rdfs:comment "Attaches a view to a property for inverse relationships (?value property $about)" ;
    rdfs:isDefinedBy : .

:showWhenEmpty a owl:DatatypeProperty ;
    rdfs:domain :View ;
    rdfs:range xsd:boolean ;
    rdfs:label "Show when empty" ;
    rdfs:comment "Whether the view block is shown when its query returns no results. Defaults to true" ;
    rdfs:isDefinedBy : .

# CLASSES

# constructor

:Constructor a rdfs:Class, owl:Class ;
    rdfs:subClassOf sp:Construct, sp:Query ;
    rdfs:label "Constructor" ;
    rdfs:isDefinedBy : .

# imports

:Import a rdfs:Class, owl:Class ;
    # rdfs:subClassOf prov:Activity ;
    spin:constructor :ImportConstructor ;
    spin:constraint :MissingFile ;
    rdfs:label "Import" ;
    rdfs:isDefinedBy : .

:CSVImport a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Import ; # restriction on media type?
    rdfs:label "CSV import" ;
    spin:constructor :CSVImportConstructor ;
    spin:constraint :MissingQuery, :MissingDelimiter ;
    rdfs:isDefinedBy : .

:RDFImport a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Import ; # restriction on media type?
    rdfs:label "RDF import" ;
    spin:constructor :RDFImportConstructor ;
    # TO-DO: spin:constraint that checks that either spin:query or sd:name is provided
    rdfs:isDefinedBy : .

#:XMLImport a rdfs:Class, owl:Class ;
#    rdfs:subClassOf :Import ; # restriction on media type?
#    rdfs:label "XML import" ;
#    rdfs:isDefinedBy : .

:ImportConstructor a :Constructor ;
    sp:text """PREFIX ldh:      <https://w3id.org/atomgraph/linkeddatahub#>
        PREFIX nfo:   <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#>

        CONSTRUCT {
            $this ldh:file [ a nfo:FileDataObject ] .
        }
        WHERE {}""" ;
    rdfs:label "Import constructor" ;
    rdfs:isDefinedBy : .

:CSVImportConstructor a :Constructor ;
    sp:text """PREFIX ldh:        <https://w3id.org/atomgraph/linkeddatahub#>
        PREFIX sp:      <http://spinrdf.org/sp#>
        PREFIX spin:    <http://spinrdf.org/spin#>

        CONSTRUCT {
            $this spin:query [ a sp:Construct ] ;
                ldh:delimiter "," .
        }
        WHERE {}""" ;
    rdfs:label "CSV import constructor" ;
    rdfs:isDefinedBy : .

:RDFImportConstructor a :Constructor ;
    sp:text """PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
        PREFIX sd:    <http://www.w3.org/ns/sparql-service-description#>
        PREFIX sp:      <http://spinrdf.org/sp#>
        PREFIX spin:    <http://spinrdf.org/spin#>

        CONSTRUCT {
            $this sd:name [ a rdfs:Resource ] ;
                spin:query [ a sp:Construct ] .
        }
        WHERE {}""" ;
    rdfs:label "RDF import constructor" ;
    rdfs:isDefinedBy : .

# content block

:Block a rdfs:Class, owl:Class ;
    rdfs:label "Block" ;
    # spin:constructor :BlockInstanceConstructor ;
    # spin:constraint :MissingValue ;
    rdfs:isDefinedBy : .

:BlockInstanceConstructor a :Constructor ;
  sp:text """
      PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
      PREFIX dct:   <http://purl.org/dc/terms/>

      CONSTRUCT {
          $this dct:title [ a xsd:string ] .
      }
      WHERE {}""" ;
    rdfs:label "Block constructor" ;
    rdfs:isDefinedBy : .

# charts

:Chart a rdfs:Class, owl:Class ;
    rdfs:label "Chart" ;
    spin:constructor :ChartConstructor ;
    spin:constraint :MissingQuery, :MissingChartType ;
    rdfs:isDefinedBy : .

:ChartConstructor a :Constructor ;
  sp:text """
      PREFIX ldh:   <https://w3id.org/atomgraph/linkeddatahub#>
      PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>

      CONSTRUCT {
          $this ldh:chartType [ a rdfs:Resource ] .
      }
      WHERE {}""" ;
    rdfs:label "Chart constructor" ;
    rdfs:isDefinedBy : .

:GraphChart a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Chart ;
    rdfs:label "Graph chart" ;
    spin:constructor :GraphChartConstructor ;
    spin:constraint :MissingSeriesProperty ; # - category property not required if URI/ID is used instead
    rdfs:isDefinedBy : .

:GraphChartConstructor a :Constructor ;
  sp:text """
      PREFIX ldh:   <https://w3id.org/atomgraph/linkeddatahub#>
      PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
      PREFIX spin:  <http://spinrdf.org/spin#>
      PREFIX sp:    <http://spinrdf.org/sp#>

      CONSTRUCT {
          $this spin:query [ a sp:Query ] ; # really a union of :Describe and :Construct
            ldh:categoryProperty [ a rdf:Property ] ;
            ldh:seriesProperty [ a rdf:Property ] .
      }
      WHERE {}""" ;
    rdfs:label "Model chart constructor" ;
    rdfs:isDefinedBy : .

:ResultSetChart a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Chart ;
    rdfs:label "Result set chart" ;
    spin:constructor :ResultSetChartConstructor ;
    spin:constraint :MissingCategoryVarName, :MissingSeriesVarName ;
    rdfs:isDefinedBy : .

:ResultSetChartConstructor a :Constructor ;
  sp:text """
      PREFIX ldh:   <https://w3id.org/atomgraph/linkeddatahub#>
      PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
      PREFIX spin:  <http://spinrdf.org/spin#>
      PREFIX sp:    <http://spinrdf.org/sp#>

      CONSTRUCT {
          $this spin:query [ a sp:Select ] ;
            ldh:categoryVarName [ a xsd:string ] ;
            ldh:seriesVarName [ a xsd:string ] .
      }
      WHERE {}""" ;
    rdfs:label "Model chart constructor" ;
    rdfs:isDefinedBy : .

# XHTML

:XHTML a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Block ;
    rdfs:label "XHTML" ;
    spin:constructor :XHTMLConstructor ;
    spin:constraint :MissingValue, :ValueCardinality ;
    rdfs:isDefinedBy : .

:XHTMLConstructor a :Constructor ;
    sp:text """
      PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

      CONSTRUCT {
          $this rdf:value '<div xmlns="http://www.w3.org/1999/xhtml"></div>'^^rdf:XMLLiteral .
      }
      WHERE {}""" ;
    rdfs:label "XHTML constructor" ;
    rdfs:isDefinedBy : .

# object

:Object a rdfs:Class, owl:Class ;
    rdfs:subClassOf :Block ;
    rdfs:label "Object" ;
    spin:constructor :ObjectConstructor ;
    spin:constraint :MissingValue, :ValueCardinality ;
    rdfs:isDefinedBy : .

:ObjectConstructor a :Constructor ;
  sp:text """
      PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
      PREFIX ldh:   <https://w3id.org/atomgraph/linkeddatahub#>
      PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
      PREFIX ac:    <https://w3id.org/atomgraph/client#>

      CONSTRUCT {
          $this rdf:value [ a rdfs:Resource ] ;
              ldh:graph [ a rdfs:Resource ] ;
              ac:mode [ a rdfs:Resource ] .
      }
      WHERE {}""" ;
    rdfs:label "Object constructor" ;
    rdfs:isDefinedBy : .

# view

:View a rdfs:Class, owl:Class ;
    rdfs:label "View" ;
    spin:constructor :ViewConstructor ;
    spin:constraint :MissingQuery ;
    rdfs:isDefinedBy : .

:ViewConstructor a :Constructor ;
  sp:text """
      PREFIX spin:  <http://spinrdf.org/spin#>
      PREFIX sp:    <http://spinrdf.org/sp#>
      PREFIX rdfs:  <http://www.w3.org/2000/01/rdf-schema#>
      PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
      PREFIX ac:    <https://w3id.org/atomgraph/client#>
      PREFIX ldh:   <https://w3id.org/atomgraph/linkeddatahub#>

      CONSTRUCT {
          $this spin:query [ a sp:Select ] ;
              ac:mode [ a rdfs:Resource ] ;
              ldh:showWhenEmpty [ a xsd:boolean ] .
      }
      WHERE {}""" ;
    rdfs:label "View constructor" ;
    rdfs:isDefinedBy : .

# exception

:ResourceExistsException a rdfs:Class, owl:Class ;
    rdfs:label "Resource already exists" ;
    rdfs:isDefinedBy : .

# URI syntax violation

:URISyntaxViolation a rdfs:Class, owl:Class ;
    rdfs:label "URI syntax violation" ;
    rdfs:isDefinedBy : .

:ConstructMissingPropertyValue a sp:Construct ;
      sp:text """PREFIX spin:	<http://spinrdf.org/spin#>
CONSTRUCT {
    _:b0 a spin:ConstraintViolation .
    _:b0 spin:violationRoot ?this .
    _:b0 spin:violationPath ?arg1 .
}
WHERE {
    FILTER NOT EXISTS {
        ?this ?arg1 ?arg2 .
    }
}""" ;
    rdfs:label "Construct missing property value" ;
    rdfs:isDefinedBy : .

:ConstructPropertyCardinality a sp:Construct ;
      sp:text """PREFIX  spin: <http://spinrdf.org/spin#>

CONSTRUCT
  {
    _:c0 a spin:ConstraintViolation .
    _:c0 spin:violationRoot ?this .
    _:c0 spin:violationPath ?arg1 .
  }
WHERE
  { SELECT  ?this ?arg1
    WHERE
      { ?this  ?arg1  ?o }
    GROUP BY ?this ?arg1
    HAVING ( COUNT(DISTINCT ?o) > ?arg2 )
  }""" ;
    rdfs:label "Construct property cardinality" ;
    rdfs:isDefinedBy : .

# match rdf:_N by URI shape (RDFS inference is not enabled in the validation pipeline,
# so ?p a rdfs:ContainerMembershipProperty would never match)
:InvalidContentBlockType a sp:Construct ;
    sp:text """PREFIX rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX spin: <http://spinrdf.org/spin#>
PREFIX ldh:  <https://w3id.org/atomgraph/linkeddatahub#>

CONSTRUCT {
    _:cv a spin:ConstraintViolation .
    _:cv spin:violationRoot ?this .
    _:cv spin:violationPath ?p .
    _:cv spin:violationValue ?block .
}
WHERE {
    ?this ?p ?block .
    FILTER (REGEX(STR(?p), \"^http://www\\\\.w3\\\\.org/1999/02/22-rdf-syntax-ns#_[0-9]+$\"))
    ?block a [] . # only fire when the block is typed in this model; PATCH validation only sees triples of changed resources
    FILTER NOT EXISTS { ?block a ldh:Object }
    FILTER NOT EXISTS { ?block a ldh:XHTML }
}""" ;
    rdfs:label "Invalid content block type" ;
    rdfs:isDefinedBy : .

# SPIN TEMPLATES

:MissingPropertyValue a spin:Template ;
    rdfs:label "Missing property value" ;
    spin:body :ConstructMissingPropertyValue ;
    spin:labelTemplate "Instance does not have a mandatory RDF property {?arg1} with value {?arg2}" ;
    spin:constraint [ a spl:Argument ;
        spl:predicate sp:arg1 ;
        spl:valueType rdf:Property
    ] , [ a spl:Argument ;
        spl:predicate sp:arg2 ;
        spl:optional true
    ] ;
    rdfs:isDefinedBy : .

:PropertyCardinality a spin:Template ;
    rdfs:label "Property cardinality violation" ;
    spin:body :ConstructPropertyCardinality ;
    spin:labelTemplate "Instance violates the cardinality of RDF property {?arg1}: {?arg2}" ;
    spin:constraint [ a spl:Argument ;
        spl:predicate sp:arg1 ;
        spl:valueType rdf:Property
    ] , [ a spl:Argument ;
        spl:predicate sp:arg2 ;
        spl:valueType xsd:integer
    ] ;
    rdfs:isDefinedBy : .

# CONSTRAINTS

:MissingIsDefinedBy a :MissingPropertyValue ;
    rdfs:label "Missing rdfs:isDefinedBy" ;
    sp:arg1 rdfs:isDefinedBy ;
    rdfs:isDefinedBy : .

:MissingFile a :MissingPropertyValue ;
    rdfs:label "Missing file" ;
    rdfs:comment "Requires resources to have a file" ;
    sp:arg1 :file ;
    rdfs:isDefinedBy : .

:MissingQuery a :MissingPropertyValue ;
    rdfs:label "Missing query" ;
    sp:arg1 spin:query ;
    rdfs:isDefinedBy : .

:MissingDelimiter a :MissingPropertyValue ;
    rdfs:label "Missing delimiter" ;
    sp:arg1 :delimiter ;
    rdfs:isDefinedBy : .

:MissingChartType a :MissingPropertyValue ;
    rdfs:label "Missing chart type" ;
    sp:arg1 :chartType ;
    rdfs:isDefinedBy : .

:MissingCategoryProperty a :MissingPropertyValue ;
    rdfs:label "Missing category property" ;
    sp:arg1 :categoryProperty ;
    rdfs:isDefinedBy : .

:MissingSeriesProperty a :MissingPropertyValue ;
    rdfs:label "Missing series property" ;
    sp:arg1 :seriesProperty ;
    rdfs:isDefinedBy : .

:MissingCategoryVarName a :MissingPropertyValue ;
    rdfs:label "Missing category variable name" ;
    sp:arg1 :categoryVarName ;
    rdfs:isDefinedBy : .

:MissingSeriesVarName a :MissingPropertyValue ;
    rdfs:label "Missing series variable name" ;
    sp:arg1 :seriesVarName ;
    rdfs:isDefinedBy : .

:MissingValue a :MissingPropertyValue ;
    rdfs:label "Missing value" ;
    sp:arg1 rdf:value ;
    rdfs:isDefinedBy : .

:ValueCardinality a :PropertyCardinality ;
    rdfs:label "More than one value" ;
    sp:arg1 rdf:value ;
    sp:arg2 1 ;
    rdfs:isDefinedBy : .

# CONTENTS

:SelectChildren a sp:Select ;
    rdfs:label "Select children" ;
    sp:text """
PREFIX  dct:  <http://purl.org/dc/terms/>
PREFIX  foaf: <http://xmlns.com/foaf/0.1/>
PREFIX  sioc: <http://rdfs.org/sioc/ns#>

SELECT DISTINCT  ?child ?thing
WHERE
{ GRAPH ?childGraph
  {   { ?child  sioc:has_parent  $this }
    UNION
      { ?child  sioc:has_container  $this }
    ?child  a                     ?Type
    OPTIONAL
      { ?child  dct:title  ?title }
    OPTIONAL
      { ?child  foaf:primaryTopic  ?thing }
  }
}
ORDER BY ?title
""" ;
    rdfs:isDefinedBy : .

:SelectInstances a sp:Select ;
    rdfs:label "Select instances" ;
    dct:description "Selects instances of type from the default graph" ;
    sp:text """SELECT DISTINCT ?s
WHERE
  { ?s  a   $type ;
        ?p  ?o
  }""" ;
    rdfs:isDefinedBy : .

:SelectInstancesInGraphs a sp:Select ;
    rdfs:label "Select instances in graphs" ;
    dct:description "Selects instances of type from named graphs" ;
    sp:text """SELECT DISTINCT ?s
WHERE
  { GRAPH ?g
      { ?s  a   $type ;
            ?p  ?o
      }
  }""" ;
    rdfs:isDefinedBy : .

:ChildrenView a :View ;
    rdfs:label "Children view" ;
    spin:query :SelectChildren ;
    rdfs:isDefinedBy : .

# CLIENT TERMS. TO-DO: move to a separate Web-Client ontology?

ac:Chart a rdfs:Class, owl:Class ;
    rdfs:label "Chart" ;
    rdfs:isDefinedBy ac: .

ac:Table a rdfs:Class, owl:Class ;
    rdfs:subClassOf ac:Chart ;
    rdfs:label "Table" ;
    rdfs:isDefinedBy ac: .

ac:ScatterChart a rdfs:Class, owl:Class ;
    rdfs:subClassOf ac:Chart ;
    rdfs:label "Scatter chart" ;
    rdfs:isDefinedBy ac: .

ac:LineChart a rdfs:Class, owl:Class ;
    rdfs:subClassOf ac:Chart ;
    rdfs:label "Line chart" ;
    rdfs:isDefinedBy ac: .

ac:BarChart a rdfs:Class, owl:Class ;
    rdfs:subClassOf ac:Chart ;
    rdfs:label "Bar chart" ;
    rdfs:isDefinedBy ac: .

ac:Timeline a rdfs:Class, owl:Class ;
    rdfs:subClassOf ac:Chart ;
    rdfs:label "Timeline" ;
    rdfs:isDefinedBy ac: .

# individuals

:ContentMode a ac:Mode ;
    rdfs:label "Content" ;
    rdfs:isDefinedBy : .

ac:ChartMode a ac:Mode, ac:ContainerMode ;
    rdfs:label "Chart" ;
    rdfs:isDefinedBy ac: .

### EXTERNAL ASSERTIONS

# https://w3id.org/atomgraph/linkeddatahub/document-hierarchy

dh:Item spin:constructor :TitleConstructor, :DescriptionConstructor, :PrimaryTopicConstructor, :BlockConstructor .

:PrimaryTopicConstructor a :Constructor ;
    rdfs:label "Primary topic constructor" ;
    sp:text """
        PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
        PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>

        CONSTRUCT {
          $this foaf:primaryTopic [ a rdfs:Resource ] .
        }
        WHERE {}""" ;
    rdfs:isDefinedBy : .

:TitleConstructor a :Constructor ;
    rdfs:label "Title constructor" ;
    sp:text """
        PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>
        PREFIX dct:     <http://purl.org/dc/terms/>

        CONSTRUCT {
          $this dct:title [ a xsd:string ] .
        }
        WHERE {}""" ;
    rdfs:isDefinedBy : .

:DescriptionConstructor a :Constructor ;
    rdfs:label "Description constructor" ;
    sp:text """
        PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>
        PREFIX dct:     <http://purl.org/dc/terms/>

        CONSTRUCT {
          $this dct:description [ a xsd:string ] .
        }
        WHERE {}""" ;
    rdfs:isDefinedBy : .

:BlockConstructor a :Constructor ;
    rdfs:label "Content constructor" ;
    sp:text """
        PREFIX ldh:     <https://w3id.org/atomgraph/linkeddatahub#>
        PREFIX rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

        CONSTRUCT {
          $this rdf:_1 [ a ldh:Block ] .
        }
        WHERE {}""" ;
    rdfs:isDefinedBy : .

:ChildrenViewContructor a :Constructor ;
    rdfs:label "Container content constructor" ;
    sp:text """
        PREFIX ldh:     <https://w3id.org/atomgraph/linkeddatahub#>
        PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
        PREFIX spin:    <http://spinrdf.org/spin#>

        CONSTRUCT {
            $this rdf:_1 [
                a ldh:Object ;
                rdf:value ldh:ChildrenView ;
            ] .
        }
        WHERE {}""" ;
    rdfs:isDefinedBy : .

:MissingContainer a :MissingPropertyValue ;
    rdfs:label "Missing container" ;
    rdfs:comment "Requires items to have a parent container" ;
    sp:arg1 sioc:has_container ;
    rdfs:isDefinedBy : .

dh:Container spin:constructor :TitleConstructor, :DescriptionConstructor, :PrimaryTopicConstructor, :ChildrenViewContructor .

:MissingParent a :MissingPropertyValue ;
    rdfs:label "Missing parent" ;
    rdfs:comment "Requires containers to have a parent container" ;
    sp:arg1 sioc:has_parent ;
    rdfs:isDefinedBy : .

# http://spinrdf.org/sp

sp:Query spin:constructor [
        a :Constructor ;
        rdfs:label "Query constructor" ;
        sp:text """
          PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
          PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>
          PREFIX sp:      <http://spinrdf.org/sp#>
          PREFIX sd:      <http://www.w3.org/ns/sparql-service-description#>
          PREFIX :        <https://w3id.org/atomgraph/linkeddatahub#>

          CONSTRUCT {
              $this rdfs:label [ a xsd:string ] ;
                  rdfs:comment [ a xsd:string ] ;
                  sp:text [ a xsd:string ] ;
                  :service [ a sd:Service ] .
          }
          WHERE {}"""
    ] ;
    spin:constraint :MissingSPText .

:MissingSPText a :MissingPropertyValue ;
    rdfs:label "Missing sp:text" ;
    sp:arg1 sp:text ;
    rdfs:isDefinedBy : .

# http://www.semanticdesktop.org/ontologies/2007/03/22/nfo

nfo: rdfs:label "NEPOMUK File Ontology" .

nfo:FileDataObject spin:constructor :FileConstructor ;
    spin:constraint [
        a :MissingPropertyValue ;
        rdfs:label "Missing nfo:fileName" ;
        sp:arg1 nfo:fileName
    ] .

:FileConstructor a :Constructor ;
    sp:text """PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>
    PREFIX nfo:     <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#>
    PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX dct:     <http://purl.org/dc/terms/>

    CONSTRUCT {
        $this nfo:fileName [ a xsd:string ] ;
            dct:format [ a rdfs:Resource ] .
    }
    WHERE {}""" ;
    rdfs:label "File constructor" ;
    rdfs:isDefinedBy : .

# http://www.w3.org/ns/sparql-service-description

sd: rdfs:label "SPARQL Service Description" .

sd:name a owl:ObjectProperty . # otherwise causes com.hp.hpl.jena.ontology.ConversionException

sd:Service spin:constructor :ServiceConstructor ;
    spin:constraint [
            a :MissingPropertyValue ;
            rdfs:label "Missing supported language" ;
            sp:arg1 sd:supportedLanguage
        ] , [
            a :MissingPropertyValue ;
            rdfs:label "Missing SPARQL endpoint" ;
            sp:arg1 sd:endpoint
        ] .

:ServiceConstructor a :Constructor ;
    sp:text """
      PREFIX a:       <https://w3id.org/atomgraph/core#>
      PREFIX lds:     <https://w3id.org/atomgraph/linkeddatahub/dataspaces#>
      PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
      PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>
      PREFIX sd:      <http://www.w3.org/ns/sparql-service-description#>

      CONSTRUCT {
          $this sd:supportedLanguage sd:SPARQL11Query, sd:SPARQL11Update ;
              sd:endpoint [ a rdfs:Resource ] ;
              a:graphStore [ a rdfs:Resource ] ;
              a:authUser [ a xsd:string ] ;
              a:authPwd [ a xsd:string ] ;
              lds:proxy [ a rdfs:Resource ] .
      }
      WHERE {}""" ;
    rdfs:label "Service constructor" ;
    rdfs:isDefinedBy : .
