- From: Martynas Jusevičius <martynas@graphity.org>
- Date: Fri, 2 Jan 2015 14:51:41 +0000
- To: public-declarative-apps@w3.org
- Cc: Holger Knublauch <holger@topquadrant.com>
Happy 2015 everyone! We decided to kick off the year by finally posting more about the current status of Graphity, as the implementation has matured and is pretty stable. We want to start with showing an example of the core notion of the declarative LD application approach -- the sitemap, which is an ontology consisting of resource templates that define the application structure. The following is the sitemap of a simple blogging application with 2 main concepts: posts and categories. Both have collection (container) and item pages, and categories can be attached to posts. <#> a owl:Ontology ; owl:imports gcs:, void:, foaf:, dqc: ; rdfs:label "Blog sitemap" ; dct:created "2014-10-21T01:53:00+01:00"^^xsd:dateTime . # RESOURCE CLASSES (GRAPHITY TEMPLATES) <#Site> a owl:Class, gp:Template ; rdfs:subClassOf gp:Space, foaf:Document, sioc:Space ; gp:uriTemplate "/" ; spin:query gp:DescribeWithChildren ; gp:limit 20 ; gc:defaultMode gc:ListMode ; # gc:mode gc:ReadMode, gc:ListMode, gc:TableMode, gc:ThumbnailMode ; rdfs:label "Homepage" ; rdfs:isDefinedBy <#> . # posts <#Forum> a owl:Class, gp:Template ; rdfs:subClassOf foaf:Document, gp:Container, sioc:Forum ; gp:uriTemplate "/posts" ; gp:limit 20 ; gp:orderBy "title"^^xsd:string ; gc:defaultMode gc:ReadMode ; gc:mode gc:ReadMode, gc:ListMode, gc:TableMode, gc:ThumbnailMode, gc:CreateMode ; spin:query gp:DescribeWithChildren ; rdfs:label "Post container" ; rdfs:isDefinedBy <#> . <#Post> a rdfs:Class, owl:Class, gp:Template ; rdfs:subClassOf foaf:Document, gp:Item, sioc:Post , [ a owl:Restriction ; owl:onProperty sioc:has_container ; owl:allValuesFrom <#Forum> ] ; gp:uriTemplate "/posts/{slug}" ; gp:skolemTemplate "/{slug}" ; gc:mode gc:ReadMode, gc:EditMode ; gc:defaultMode gc:ReadMode ; gp:cacheControl "public, max-age=3600" ; spin:query gp:Describe ; spin:update gp:Delete ; spin:constructor [ a sp:Construct ; sp:text """ PREFIX blog: <http://graphity.org/blog#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX sioc: <http://rdfs.org/sioc/ns#> PREFIX gp: <http://graphity.org/gp#> PREFIX gc: <http://graphity.org/gc#> PREFIX dct: <http://purl.org/dc/terms/> CONSTRUCT { ?this a foaf:Document, blog:Post, sioc:Post, gp:Item, sioc:Item ; dct:title " " ; sioc:content " " ; dct:subject _:category ; gp:slug " "^^xsd:string . } WHERE {}""" ] ; spin:constraint [ a dqc:MissingProperties ; sp:arg1 <#Post> ; sp:arg2 gp:slug ] , [ a dqc:MissingProperties ; sp:arg1 <#Post> ; sp:arg2 dct:title ] , [ a dqc:MissingProperties ; sp:arg1 <#Post> ; sp:arg2 sioc:content ] ; rdfs:label "Post document" ; rdfs:isDefinedBy <#> . # categories <#CategoryContainer> a owl:Class, gp:Template ; rdfs:subClassOf foaf:Document, gp:Container, sioc:Container ; gp:uriTemplate "/categories" ; gp:limit 20 ; gp:orderBy "prefLabel"^^xsd:string ; gc:defaultMode gc:ReadMode ; gc:mode gc:ReadMode, gc:ListMode, gc:TableMode, gc:ThumbnailMode, gc:CreateMode ; spin:query gp:DescribeWithChildren ; rdfs:label "Category container" ; rdfs:isDefinedBy <#> . <#CategoryItem> a rdfs:Class, owl:Class, gp:Template ; rdfs:subClassOf foaf:Document, gp:Item, sioc:Item , [ a owl:Restriction ; owl:onProperty sioc:has_container ; owl:allValuesFrom <#CategoryContainer> ] ; gp:uriTemplate "/categories/{slug}" ; gp:skolemTemplate "/{slug}" ; gc:mode gc:ReadMode, gc:EditMode ; gc:defaultMode gc:ReadMode ; gp:cacheControl "public, max-age=3600" ; spin:query [ a sp:Describe ; sp:text """ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dct: <http://purl.org/dc/terms/> DESCRIBE ?this ?category ?post { ?category foaf:isPrimaryTopicOf ?this OPTIONAL { SELECT ?post ?category { ?post dct:subject ?category } } }""" ] ; spin:update gp:DeleteWithTopic ; spin:constructor [ a sp:Construct ; sp:text """ PREFIX blog: <http://graphity.org/blog#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX sioc: <http://rdfs.org/sioc/ns#> PREFIX gp: <http://graphity.org/gp#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> CONSTRUCT { ?this a foaf:Document, blog:CategoryItem, gp:Item, sioc:Item ; foaf:primaryTopic _:category ; gp:slug " "^^xsd:string . _:category a blog:Category, skos:Concept ; foaf:isPrimaryTopicOf ?this ; skos:prefLabel " " . } WHERE {}""" ] ; spin:constraint [ a dqc:MissingProperties ; sp:arg1 <#CategoryItem> ; sp:arg2 gp:slug ] ; rdfs:label "Category document" ; rdfs:isDefinedBy <#> . <#Category> a rdfs:Class, owl:Class ; rdfs:subClassOf skos:Concept, [ a owl:Restriction ; owl:onProperty foaf:isPrimaryTopicOf ; owl:allValuesFrom <#CategoryItem> ] ; gp:skolemTemplate "/{isPrimaryTopicOf.slug}" ; spin:constraint [ a dqc:MissingProperties ; sp:arg1 <#Category> ; sp:arg2 skos:prefLabel ] ; rdfs:label "Category" ; rdfs:isDefinedBy <#> . I have skipped the namespaces here, but you can find the full file on GitHub: https://github.com/Graphity/blog-app/blob/master/src/main/resources/org/graphity/blog/vocabulary/blog.ttl If you check the source code in the repository, you will see that there are only 2 Java classes intended as extension points. Those could also be removed, making the application fully declarative, consisting only of the sitemap and the XSLT stylesheet (about which we will post separately). Processing model embedded in Graphity makes this possible. We have also implemented access control declaratively, but it is not included for this application. To see for yourself that the application works and is read-write, you can visit a demo deployed at http://linkeddatahub.com/blog-app. Looking at the sitemap, you can see a number of components: - each container and and item gets its own class, as they have their own URI templates, as indicated by gp:uriTemplate - spin:query is used for resource description retrieval, spin:update for removal - OWL restrictions indicate the structural relationships between classes, which are based on SIOC vocabulary - container classes have offset/limit/orderBy/desc modifiers that are used for pagination - item classes have skolemization URI templates, which are used to build URIs from blank nodes in request RDF payload - constraints indicate mandatory properties of class instances - constructors define a template of a class instance - cache control and layout modes can be specified per resource class We plan to post in more detail about the more important aspects. If you think some parts are unclear or interesting, or simply have questions, please let us know and we will focus on that. Martynas graphityhq.com
Received on Friday, 2 January 2015 14:52:09 UTC