This wiki is locked. Future workgroup activity and specification development must take place at our new wiki. For more information, see this blog post about the new governance model and this post about changes to the website.

Example OSLC Query Capability discussion

This examples is intended to illustrate an OSLC Query Capability works from the point-of-view of an OSLC Workgroup charged with specifying a facility for querying over blog entries and associated comments by title.

This text is based on the OSLC Core Spec DRAFT as of May 4, 2010.

Define shapes of resources to be queried

If you want people to be able to query your resources, then not only must you define your resources in OSLC terms but you must also provide an OSLC Resource Shape for each of the resources you wish to return in query results. In this section we define two resources, one for blog entry and one for blog comment.

Blog Entry resource shape

We define a blog entry as follows:

  • Name: Entry
  • Namespace URI: http://open-services.net/xmlns/bogus#
  • Type URI: http://open-services.net/xmlns/bogus#Entry
  • Properties:
    • dc:title (XML Literal, exactly-one) title of Podcast
    • dc:modified (DateTime, exactly-one) - date/time that comment was created
    • dc:creator (Local In-Line Resource of type foaf:Person, exactly-one) - name of comment author
    • dc:content (XML Literal, exactly-one) - content of the comment

Here is the corresponding Resource Shape representation, at http://example.com/blogs/entryshape

<oslc:Shape
     rdf:about="http://example.com/shapes/entryshape"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

     <dc:title>Blog Entry Shape</dc:title>
     <rdf:type resource="http://open-services.net/xmlns/oslc#Shape" />

     <oslc:name>Entry</oslc:name>
     <oslc:namespace rdf:resource="http://open-services.net/xmlns/bogus#" />
     <oslc:describes rdf:resource="http://open-services.net/xmlns/bogus#Entry" />

     <oslc:property>
         <oslc:Property>
             <oslc:name>title</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#title" />
             <oslc:valueType rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>modified</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#modified" />
             <oslc:valueType rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>creator</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#creator" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#LocalInlineResource" />
             <oslc:shape rdf:resource="http://example.com/blogs/personshape" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>content</oslc:name>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#content" />
             <oslc:valueType rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" />
             <oslc:occurs>exactly-one</oslc:occurs>
         </oslc:Property>
     </oslc:property>

</oslc:Shape>

Comment Resource shape

We define a blog comment, which points to one blog entry, as follows:

  • Name: Comment
  • Namespace URI: =http://open-services.net/xmlns/bogus=
  • Type URI: http://open-services.net/xmlns/bogus#Comment
  • Properties:
    • dc:modified (DateTime, exactly-one) - date/time that comment was created
    • dc:creator (In-Line Resource of type foaf:Person, exactly-one) - name of comment author
    • dc:content (XML Literal, exactly-one) - content of the comment
    • blog:entry (Resource, exactly-one of type blog:Entry) - link to the Blog Entry

Here is the corresponding Resource Shape representation, at http://example.com/blogs/commentshape

<oslc:Shape
     rdf:about="http://example.com/shapes/entryshape"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

     <dc:title>Blog Comment Shape</dc:title>
     <rdf:type resource="http://open-services.net/xmlns/oslc#Shape" />

     <oslc:name>Comment</oslc:name>
     <oslc:namespace rdf:resource="http://open-services.net/xmlns/bogus#" />
     <oslc:describes rdf:resource="http://open-services.net/xmlns/bogus#Comment" />

     <oslc:property>
         <oslc:Property>
             <oslc:name>modified</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#" />
             <rdf:type resource="http://purl.org/dc/terms#modified" />
             <oslc:valueType rdf:resource="http://www.w3.org/2001/XMLSchema#dateTime" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>creator</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#creator" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#LocalInlineResource" />
             <oslc:shape rdf:resource="http://example.com/blogs/personshape" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>content</oslc:name>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#" />
             <rdf:type resource="http://purl.org/dc/terms#content" />
             <oslc:valueType rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" />
             <oslc:occurs>exactly-one</oslc:occurs>
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>entry</oslc:name>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#" />
             <rdf:type resource="http://purl.org/dc/terms#content" />
             <oslc:valueType rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" />
             <oslc:occurs>exactly-one</oslc:occurs>
         </oslc:Property>
     </oslc:property>

</oslc:Shape>

Person resource shape

In the examples above we refer to a shape for a FOAF Person at the URL http://example.com/blogs/personshape so we must provide a shape at that URL. Here's the RDF/XML shape for FOAF Person:

<oslc:Shape
     rdf:about="http://example.com/shapes/entryshape"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

     <dc:title>FOAF Person Shape</dc:title>
     <rdf:type resource="http://open-services.net/xmlns/oslc#Shape" />

     <oslc:name>Person</oslc:name>
     <oslc:namespace rdf:resource="http://xmlns.com/foaf/spec/#" />
     <oslc:describes rdf:resource="http://xmlns.com/foaf/spec/#term_Person" />

     <oslc:property>
         <oslc:Property>
             <oslc:name>name</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://xmlns.com/foaf/spec/#" />
             <rdf:type resource="http://xmlns.com/foaf/spec/#name" />
             <oslc:valueType rdf:resource="http://www.w3.org/2001/XMLSchema#string" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>givenName</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://xmlns.com/foaf/spec/#" />
             <rdf:type resource="http://xmlns.com/foaf/spec/#givenName" />
             <oslc:valueType rdf:resource="http://www.w3.org/2001/XMLSchema#string" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>familyName</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://xmlns.com/foaf/spec/#" />
             <rdf:type resource="http://xmlns.com/foaf/spec/#familyName" />
             <oslc:valueType rdf:resource="http://www.w3.org/2001/XMLSchema#string" />
         </oslc:Property>
     </oslc:property>

</oslc:Shape>

Define query shape

Now that we have defined shapes for the resources involved in the queries we wish to support, we also need to tie things together by defining a shape for the query resource. You can think of a query resource as a resource that uses mutli-valued properties to link to one or more different types of resources.

Below is a suitable query resource shape for our blog entry and comment example, represented in RDF/XML:


<oslc:Shape
     rdf:about="http://example.com/shapes/blogquery"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

     <dc:title>Blog Query Shape</dc:title>
     <rdf:type resource="http://open-services.net/xmlns/oslc#Shape" />

     <oslc:name>BlogQuery</oslc:name>
     <oslc:namespace rdf:resource="http://open-services.net/xmlns/bogus#" />
     <oslc:describes rdf:resource="http://open-services.net/xmlns/bogus#BlogQuery" />

     <oslc:property>
         <oslc:Property>
             <oslc:name>entry</oslc:name>
             <oslc:namespace rdf:resource="http://open-services.net/xmlns/blog#" />
             <oslc:occurs>zero-or-many</oslc:occurs>
             <oslc:shape rdf:resource="http://example.com/blogs/entryshape" />
             <rdf:type resource="http://open-services.net/xmlns/blog#Entry" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#InlineResource" />
             <oslc:isMemberProperty>true</oslc:isMemberProperty>
         </oslc:Property>
     </oslc:property>

     <oslc:property>
          <oslc:Property>
             <oslc:name>comment</oslc:name>
             <oslc:namespace rdf:resource="http://open-services.net/xmlns/blog#" />
             <oslc:occurs>zero-or-many</oslc:occurs>
             <oslc:shape rdf:resource="http://example.com/blogs/commentshape" />
             <rdf:type resource="http://open-services.net/xmlns/blog#Comment" />
             <oslc:isMemberProperty>true</oslc:isMemberProperty>
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#InlineResource" />
         </oslc:Property>
     </oslc:property>
 
     <oslc:property>
          <oslc:Property>
             <oslc:name>responseInfo</oslc:name>
             <oslc:namespace rdf:resource="http://open-services.net/xmlns/oslc#" />
             <oslc:occurs>zero-or-one</oslc:occurs>
             <oslc:shape rdf:resource="http://example.com/blogs/responseInfoShape" />
             <rdf:type resource="http://open-services.net/xmlns/oslc#ResponseInfo" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#InlineResource" />
         </oslc:Property>
     </oslc:property>
 
  </oslc:Shape>

 

ResponseInfo? resource shape

We referenced the ResponseInfo? resource shape above, so we need to provide that too at http://example.com/blogs/responseInfoShape

<oslc:Shape
     rdf:about="http://example.com/shapes/entryshape"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

     <dc:title>Response Info Shape</dc:title>
     <rdf:type resource="http://open-services.net/xmlns/oslc#Shape" />

     <oslc:name>ResponseInfo</oslc:name>
     <oslc:namespace rdf:resource="http://open-services.net/xmlns/oslc#" />
     <oslc:describes rdf:resource="http://open-services.net/xmlns/oslc#ResponseInfo" />

     <oslc:property>
         <oslc:Property>
             <oslc:name>title</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://purl.org/dc/terms#"/>
             <rdf:type resource="http://purl.org/dc/terms#title" />
             <oslc:valueType rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>type</oslc:name>
             <oslc:occurs>exactly-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#" />
             <rdf:type resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#Resource" />
         </oslc:Property>
     </oslc:property>

     <oslc:property>
         <oslc:Property>
             <oslc:name>nextPage</oslc:name>
             <oslc:occurs>at-most-one</oslc:occurs>
             <oslc:namespace rdf:resource="http://open-service.net/xmlns/oslc-core" />
             <rdf:type resource="http://open-service.net/xmlns/oslc-core#nextPage" />
             <oslc:valueType rdf:resource="http://open-service.net/xmlns/oslc-core/resource-types#Resource" />
         </oslc:Property>
     </oslc:property>

</oslc:Shape>

Define Query Capability

To provide your Query Capability, you'll need to provide a Service Provider resource that does two things: 1) defines your services recommended namespace prefixes (for use in Query Syntax expressions and JSON representations) and 2) defines a Query Capability. Here's an example suitable for our blog example:


<oslc:ServiceProvider 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/terms#" 
   xmlns:oslc="http://open-services.net/xmlns/oslc#"
   rdf:about="http://example.com/bugs/service-descriptor.xml"
   xml:lang="en">

   <dc:title>Blogging Service</dc:title>  
   <dc:description>Example OSLC Blog Service</dc:description>

   <dc:contributor>
      <oslc:Contributor>
         <dc:title>OSLC Core Workgroup documentation department</dc:title>
         <dc:identifier>com.example.oslc.blogservice</dc:identifier>
         <oslc:icon rdf:resource="http://example.com/icons/blogservice.ico" />
      </oslc:Contributor>
   </dc:contributor>
   
   <oslc:namespaceDefinition>
      <oslc:NamepaceDefintion>
         <oslc:prefix>rdf</oslc:prefix>
         <oslc:namespaceURI>http://www.w3.org/1999/02/22-rdf-syntax-ns#</oslc:namespaceURI>
      </oslc:NamepaceDefintion>
   </oslc:namespaceDefinition>

   <oslc:namespaceDefinition>
      <oslc:NamepaceDefintion>
         <oslc:prefix>dc</oslc:prefix>
         <oslc:namespaceURI>http://purl.org/dc/terms#</oslc:namespaceURI>
      </oslc:NamepaceDefintion>
   </oslc:namespaceDefinition>

   <oslc:namespaceDefinition>
      <oslc:NamepaceDefintion>
         <oslc:prefix>oslc</oslc:prefix>
         <oslc:namespaceURI>http://open-services.net/xmlns/oslc#</oslc:namespaceURI>
      </oslc:NamepaceDefintion>
   </oslc:namespaceDefinition>

   <oslc:service>
      <oslc:Service>
         <oslc:domain>http://example.com/xmlns/example-cm#</oslc:domain>

         <oslc:creationFactory>
            <oslc:CreationFactory>
               <dc:title>Location for creation of Blog Entries</dc:title>
               <oslc:label>Blog Entries</oslc:label>
               <oslc:creation rdf:resource="http://example.com/creation/entries" />
               <oslc:shape rdf:resource="http://example.com/shapes/blogentry" />
            </oslc:Factory>
         </oslc:factory>

         <oslc:creationFactory>
            <oslc:CreationFactory>
               <dc:title>Location for creation of Blog Comments</dc:title>
               <oslc:label>Blog Comments</oslc:label>
               <oslc:creation rdf:resource="http://example.com/creation/comments" />
               <oslc:shape rdf:resource="http://example.com/shapes/blogcomment" />
            </oslc:Factory>
         </oslc:creationFactory>

         <oslc:queryCapability>
            <oslc:QueryCapability>
               <dc:title>Blog Entry and Comment Query</dc:title>
               <oslc:label>blogquery</oslc:label>
               <oslc:queryBase rdf:resource="http://example.com/query" />
               <oslc:shape rdf:resource="http://example.com/shapes/blogquery" />
            </oslc:QueryCapability>
         </oslc:queryCapability>

      </oslc:Service>
   </oslc:service>

</oslc:ServiceProvider>

Executing Queries

Given all of the above plus an implementation of the OSLC Query Syntax, we have enabled queries against blog entries and comments.

For example, if we wanted a list of URLs to all comments that link to blog #42 we would use this URL:

http://example.com/query?oslc.from=blog:comment&oslc.where=blog:entry=<http://example.com/blogs/entry/42>

And we would receive in return a query representation like so:

<blog:BlogQuery
     rdf:about="http://example.com/query?oslc.from=blog:comment&oslc.where=blog:entry=&lt;http://example.com/blogs/entry/42&gt;"
     xmlns:blog="http://open-services.net/xmlns/bogus#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:foaf="http://FOAFNAMESPACE_GOES_HERE"
     xmlns:oslc="http://open-services.net/xmlns/oslc#">

    <blog:comment rdf:about="http://example.com/blogs/comment/346" />
    <blog:comment rdf:about="http://example.com/blogs/comment/344" />
    <blog:comment rdf:about="http://example.com/blogs/comment/673" />
    <blog:comment rdf:about="http://example.com/blogs/comment/232" />
    <blog:comment rdf:about="http://example.com/blogs/comment/333" />
    <!-- etc. etc. -->

</blog:BlogQuery>
<font face="Verdana, Arial, Helvetica, sans-serif" color="#FF0000"><font face="'Courier New', courier, monaco, monospace" color="#7A4707" size="4">
</font></font>

Representing results

A query resource is an OSLC Defined Resource, with an OSLC Resource Shape, so we can use standard rules defines in the Core to represent it in RDF/XML, JSON or Turtle. Currently, our rules for Atom representations of feeds are incorrect.

Here's a proposal for how to represent queries in Atom format:

  • Represent a Query Response as an Atom <feed>
  • End result should be a valid Atom feed
  • If the Query resource has an oslc:pageInfo value, then map:
    • dc:title to Atom title
    • oslc:nextPage to Atom link element with rel equal to next
  • For each member property value, represent it as an Atom <entry>
    • Represent property value itself as RDF/XML inside the Atom <content> element
    • If the property value has the following nested values then map them as specified:
      • <dc:title$gt; to Atom <title>
      • <dc:modified> to Atom <updated>
      • etc...
  • Represent any other property values as children of the <feed> element

Here's an example:

<feed 
     xmlns:blog="http://open-services.net/xmlns/bogus#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:dc="http://purl.org/dc/terms#"
     xmlns:foaf="http://FOAFNAMESPACE_GOES_HERE"
     xmlns:oslc="http://open-services.net/xmlns/oslc#>

   <title>BlogQuery</title>

   <link rel="self" href="http://example.com/query?oslc.from=blog:comment&oslc.where=blog:entry=&lt;http://example.com/blogs/entry/42&gt;">
   <link rel="next" href="http://example.com/query?page=2&oslc.from=blog:comment&oslc.where=blog:entry=&lt;http://example.com/blogs/entry/42&gt;">

   <entry>
      <title>BlogQuery Entry</title>
      <content type="application/rdf+xml">
         <blog:comment rdf:about="http://example.com/blogs/comment/346" />
      </content>
   </entry>

   <entry>
      <title>BlogQuery Entry</title>
      <content type="application/rdf+xml">
         <blog:comment rdf:about="http://example.com/blogs/comment/344" />
      </content>
   </entry>

   <entry>
      <title>BlogQuery Entry</title>
      <content type="application/rdf+xml">
         <blog:comment rdf:about="http://example.com/blogs/comment/673" />
      </content>
   </entry>

   <entry>
      <title>BlogQuery Entry</title>
      <content type="application/rdf+xml">
         <blog:comment rdf:about="http://example.com/blogs/comment/232" />
      </content>
   </entry>

   <entry>
      <title>BlogQuery Entry</title>
      <content type="application/rdf+xml">
         <blog:comment rdf:about="http://example.com/blogs/comment/333" />
      </content>
   </entry>

</feed>

Topic revision: r4 - 05 May 2010 - 12:22:57 - DaveJohnson
 
This site is powered by the TWiki collaboration platform Copyright � by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Contributions are governed by our Terms of Use
Ideas, requests, problems regarding this site? Send feedback