@prefix :     <https://w3id.org/atomgraph/linkeddatahub/apps#> .
@prefix a:    <https://w3id.org/atomgraph/core#> .
@prefix dct:  <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ldh:  <https://w3id.org/atomgraph/linkeddatahub#> .
@prefix ldt:  <https://www.w3.org/ns/ldt#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sp:   <http://spinrdf.org/sp#> .
@prefix spin: <http://spinrdf.org/spin#> .
@prefix spl:  <http://spinrdf.org/spl#> .
@prefix void: <http://rdfs.org/ns/void#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

:AdminApplicationConstructor
        rdf:type          ldh:Constructor ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Admin application constructor" ;
        sp:text           "\n      PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>\n      PREFIX dct:     <http://purl.org/dc/terms/>\n\n      CONSTRUCT {\n          $this dct:title [ a xsd:string ] ;\n            dct:description [ a xsd:string ] ;\n      }\n      WHERE {}" .

:origin  rdf:type         owl:InverseFunctionalProperty , owl:FunctionalProperty , owl:ObjectProperty ;
        rdfs:comment      "The origin URI of an application, which serves as the base URI for all resources in the application's dataspace" ;
        rdfs:domain       :Application ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Origin" ;
        rdfs:range        rdfs:Resource .

:backendProxy  rdf:type   owl:ObjectProperty ;
        rdfs:comment      "An intermediary server (such as cache) that proxies backend requests to service" ;
        rdfs:domain       :Dataset ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Backend proxy" ;
        rdfs:range        rdfs:Resource .

:frontendProxy  rdf:type  owl:ObjectProperty ;
        rdfs:comment      "An intermediary server (such as cache) that proxies frontend requests to service" ;
        rdfs:domain       :Dataset ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Frontend proxy" ;
        rdfs:range        rdfs:Resource .

:StartsWithHTTPS  rdf:type  sp:Construct ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "lapp:origin starts with https://" ;
        sp:text           "\nPREFIX  lapp: <https://w3id.org/atomgraph/linkeddatahub/apps#>\nPREFIX  spin: <http://spinrdf.org/spin#>\nPREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n\nCONSTRUCT {\n    _:c0 a spin:ConstraintViolation .\n    _:c0 spin:violationRoot ?this .\n    _:c0 spin:violationPath lapp:origin .\n    _:c0 rdfs:label \"Application origin URI must start with https://\" .\n}\nWHERE {\n  ?this  lapp:origin  ?origin\n  FILTER ( ! strstarts(str(?origin), \"https://\") )\n}" .

:EndUserApplication  rdf:type  owl:Class , rdfs:Class ;
        rdfs:comment      "Application with a dynamic access control and sitemap" ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "End-user application" ;
        spin:constructor  :EndUserApplicationConstructor .

:application  rdf:type    owl:FunctionalProperty , owl:ObjectProperty ;
        rdfs:comment      "Links a resource to an application" ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Application" ;
        rdfs:range        :Application .

:allowRead  rdf:type      owl:DatatypeProperty ;
        rdfs:comment      "If true, this application allows GET an HEAD methods for all request URIs without authorization check" ;
        rdfs:domain       :Application ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Allow read" ;
        rdfs:range        xsd:boolean .

:Application  rdf:type    rdfs:Class , owl:Class ;
        rdfs:comment      "An application represents a data space identified by its origin URI, in which application resource URIs are relative to the origin URI. The only application interface (API) is read-write RESTful Linked data, backed by an RDF dataset accessible as a SPARQL 1.1 service. Application structure is defined in an ontology, which can import other ontologies." ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Application" ;
        rdfs:subClassOf   ldt:Application ;
        spin:constraint   :StartsWithHTTPS , :ValidOrigin ;
        spin:constraint   [ rdf:type    ldh:MissingPropertyValue ;
                            rdfs:label  "Missing origin URI" ;
                            sp:arg1     :origin
                          ] ;
        spin:constructor  :ApplicationConstructor .

:Dataset  rdf:type        owl:Class , rdfs:Class ;
        rdfs:comment      "A dataspace that returns RDF Linked Data" ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Linked Data dataset" ;
        rdfs:subClassOf   void:Dataset .

:public  rdf:type         owl:DatatypeProperty ;
        rdfs:comment      "If true, this application can be listed as public (ACL still applies). If false, it is private and will not be listed" ;
        rdfs:domain       :EndUserApplication ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Public" ;
        rdfs:range        xsd:boolean .

:Package  rdf:type        owl:Class , rdfs:Class ;
        rdfs:comment      "A reusable package containing RDF ontology and optional XSLT stylesheet for vocabulary support" ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Package" .

:       rdf:type         owl:Ontology ;
        rdfs:comment     "Ontology of LinkedDataHub applications" ;
        rdfs:label       "LinkedDataHub application ontology" ;
        owl:imports      spin: , sp: , ldt: , ldh: ;
        owl:versionInfo  "1.1.4" .

:ValidOrigin  rdf:type    sp:Construct ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Origin must not have trailing slash and must have hostname" ;
        sp:text           "\nPREFIX  lapp: <https://w3id.org/atomgraph/linkeddatahub/apps#>\nPREFIX  spin: <http://spinrdf.org/spin#>\nPREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n\nCONSTRUCT \n  { \n    _:c0 a spin:ConstraintViolation .\n    _:c0 spin:violationRoot ?this .\n    _:c0 spin:violationPath lapp:origin .\n    _:c0 rdfs:label ?message .\n  }\nWHERE\n  { \n    ?this lapp:origin ?origin .\n\n    BIND(STRAFTER(str(?origin), \"//\") AS ?afterScheme)\n    BIND(IF(CONTAINS(?afterScheme, \"/\"), \n            STRBEFORE(?afterScheme, \"/\"), \n            ?afterScheme) AS ?hostname)\n    \n    BIND(\n      IF(STRENDS(str(?origin), \"/\"),\n         \"Origin URL must not end with a trailing slash\",\n      IF(?hostname = \"\",\n         \"Origin URL must have a non-empty hostname\",\n         \"\")) AS ?message\n    )\n    \n    FILTER(?message != \"\")\n  }\n" .

:AdminApplication  rdf:type  owl:Class , rdfs:Class ;
        rdfs:comment      "Meta-application that manages the access control and sitemap of the main end-user application" ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Admin application" ;
        spin:constructor  :AdminApplicationConstructor .

:ApplicationConstructor
        rdf:type          ldh:Constructor ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "Application constructor" ;
        sp:text           "\n      PREFIX lapp:    <https://w3id.org/atomgraph/linkeddatahub/apps#>\n      PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>\n\n      CONSTRUCT {\n          $this lapp:origin [ a rdfs:Resource ] .\n      }\n      WHERE {\n    }" .

:EndUserApplicationConstructor
        rdf:type          ldh:Constructor ;
        rdfs:isDefinedBy  : ;
        rdfs:label        "End-user application constructor" ;
        sp:text           "\n      PREFIX lapp:    <https://w3id.org/atomgraph/linkeddatahub/apps#>\n      PREFIX ldh:     <https://w3id.org/atomgraph/linkeddatahub#>\n      PREFIX ac:      <https://w3id.org/atomgraph/client#>\n      PREFIX xsd:     <http://www.w3.org/2001/XMLSchema#>\n      PREFIX ldt:     <https://www.w3.org/ns/ldt#>\n      PREFIX dct:     <http://purl.org/dc/terms/>\n\n      CONSTRUCT {\n          $this dct:title [ a xsd:string ] ;\n            dct:description [ a xsd:string ] ;\n            ac:stylesheet [ a ldh:File ] ;\n            lapp:public [ a xsd:boolean ] .\n      }\n      WHERE {}" .
