<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-8989580</atom:id><lastBuildDate>Wed, 21 Mar 2012 07:00:57 +0000</lastBuildDate><category>Personal</category><category>linkedData</category><category>rules</category><category>SPARQL</category><category>RDF</category><category>Sesame Cookbook</category><category>RIO</category><category>SWC</category><category>SMW</category><category>SKOS</category><category>SeRQL</category><category>.Net</category><category>NZ</category><category>Sesame</category><category>OWL</category><category>Rivuli</category><category>Java</category><category>Ontotext</category><category>The Seer</category><category>LOD</category><title>The Seer</title><description>A weblog about semantic web research &amp;amp; development, and anything else that crosses my mind.</description><link>http://jeenbroekstra.blogspot.com/</link><managingEditor>noreply@blogger.com (J1)</managingEditor><generator>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-577532941947346508</guid><pubDate>Mon, 13 Jun 2011 06:45:00 +0000</pubDate><atom:updated>2011-06-13T18:45:34.456+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>The Seer</category><category domain='http://www.blogger.com/atom/ns#'>Rivuli</category><title>Moving my shop to a new site</title><description>I have had nothing but good experiences with Blogger. Nevertheless, I have decided to move and actually start hosting my own (one-man) company website and tech weblog. This means that this is quite likely the last blog-posting here.

My new website is at &lt;a href="http://rivuli-development.com/"&gt;http://rivuli-development.com/&lt;/a&gt;. RSS 1.0 feed available at &lt;a href="http://rivuli-development.com/feed/rdf"&gt;http://rivuli-development.com/feed/rdf&lt;/a&gt;. Please adjust your bookmarks</description><link>http://jeenbroekstra.blogspot.com/2011/06/moving-my-shop-to-new-site.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-7358125685715053720</guid><pubDate>Thu, 19 May 2011 21:45:00 +0000</pubDate><atom:updated>2011-05-20T09:45:44.315+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Sesame 2.4.0 with SPARQL 1.1 Query support</title><description>&lt;p&gt;
    I am very proud to announce the release of &lt;a href="http://www.openrdf.org/"&gt;Sesame 2.4.0&lt;/a&gt;. This
    is a major new release featuring support for SPARQL 1.1 Query. 
   &lt;/p&gt;

   &lt;p&gt;
    Sesame 2.4.0 implements all features of SPARQL 1.1 Query as outlined in the
    &lt;a href="http://www.w3.org/TR/2010/WD-sparql11-query-20101014/"&gt;October 14 W3C Working Draft&lt;/a&gt;,
    with the exception of basic federated query. SPARQL 1.1 for Sesame is developed by
    &lt;a href="http://www.ontotext.com/"&gt;Ontotext&lt;/a&gt; in cooperation with
    &lt;a href="http://www.aduna-software.com/"&gt;Aduna&lt;/a&gt;.
   &lt;/p&gt;
   &lt;p&gt;
    The list of new SPARQL query features includes:
    &lt;ul&gt;

     &lt;li&gt;Use of expressions in the SELECT clause&lt;/li&gt;
     &lt;li&gt;Aggregates (COUNT, MIN, MAX, AVG, SUM, GROUP_CONCAT), HAVING and GROUP BY&lt;/li&gt;
     &lt;li&gt;Property paths &lt;/li&gt;
     &lt;li&gt;Subqueries&lt;/li&gt;
     &lt;li&gt;Negation: (NOT) EXISTS and MINUS&lt;/li&gt;
     &lt;li&gt;Set membership: (NOT) IN&lt;/li&gt;

     &lt;li&gt;Conditionals: IF&lt;/li&gt;
     &lt;li&gt;Various new builtin functions: COALESCE, BNODE, IRI, isNumeric, strLang, strDt&lt;/li&gt;
    &lt;/ul&gt;
   &lt;/p&gt;
   &lt;p&gt;
    Apart from this impressive array of new query language features,
    Sesame 2.4.0 also implements a number of bug fixes and improvements,
    including scalability and performance improvement in the Native store.
    For a full overview, see the
    &lt;a href="http://www.openrdf.org/issues/secure/ReleaseNote.jspa?projectId=10000&amp;amp;styleName=Html&amp;amp;version=10500"&gt;release notes&lt;/a&gt;.
   &lt;/p&gt;</description><link>http://jeenbroekstra.blogspot.com/2011/05/sesame-240-with-sparql-11-query-support.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-8919161797088735668</guid><pubDate>Thu, 28 Apr 2011 00:18:00 +0000</pubDate><atom:updated>2011-04-28T12:45:54.261+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>SPARQL 1.1 Query: negated property sets and the algebra</title><description>I've just finished the implementation of SPARQL 1.1 property paths in Sesame. The major thing still missing was the implementation of negated property sets.
&lt;p&gt;
Negated property sets enable you to formulate a query like, for example: "give me back two resources x and y which are related in any direction via some property, but &lt;i&gt;not&lt;/i&gt; via &lt;code&gt;foaf:knows&lt;/code&gt;". In SPARQL 1.1, this would look like:
&lt;pre&gt;
   SELECT ?x ?y
   WHERE { 
           ?x !(foaf:knows|^foaf:knows) ?y .
   }
&lt;/pre&gt;
The current SPARQL 1.1 draft &lt;a href="http://www.w3.org/2009/sparql/docs/query-1.1/rq25.xml#sparqlTranslatePaths"&gt;defines a new abstract symbol&lt;/a&gt; for supporting negated property sets, called &lt;code&gt;NegatedPropertySet&lt;/code&gt;. The &lt;a href="http://www.w3.org/2009/sparql/docs/query-1.1/rq25.xml#sparqlAlgebra"&gt;SPARQL algebra&lt;/a&gt;, in turn, maps this abstract symbol directly to a new algebraic operator, so the algebra is extended with an additional operator in order to support negated property sets, and it also gives a specific &lt;a href="http://www.w3.org/2009/sparql/docs/query-1.1/rq25.xml#sparqlAlgebraEval"&gt;evaluation semantics&lt;/a&gt; for this new operator.
&lt;p&gt;
However, although perhaps useful in terms of brevity, it is in fact not necessary to thus extend the algebra. Negated property sets do not actually introduce additional expressivity to the language (in contrast to, for example, arbitrary-length property paths): the above query could have been formulated in SPARQL 1.0:
&lt;pre&gt;
   SELECT ?x ?y
   WHERE { 
       { ?x ?p1 ?y . FILTER (?p1 != foaf:knows) }
       UNION
       { ?y ?p2 ?x . FILTER (?p2 != foaf:knows) }
   }
&lt;/pre&gt;
This simple fact makes it possible to implement negated property sets without having to extend Sesame's query model with an additional algebra operator. The advantage of this is that all of Sesame's existing query optimizing/rewriting/evaluation strategies can immediately handle negated property sets, without having to be 'recalibrated' or indeed extended to take a complex additional operator into account.
&lt;p&gt;
So, the SPARQL parser processes a negated property set and translates it to the necessary collection of Joins, Filter comparisons and Unions. The algorithm is roughly as follows:
&lt;pre&gt;
 let NPS be a negated property set with elements e_1...e_n.
 let s be the subject variable of the NPS.
 let ap be the (anonymous) predicate variable of the NPS.
 let O be the set of object variables of the NPS. 
 let F and F_i be two sets of filter conditions.
 let p(e) be the predicate IRI of e.

 for each e in NPS :
    create a filter condition f: p(e) != ap .
    if e is inverted: add f to F_i, otherwise add f to F .
 
 let J be a Join on basic graph patterns. 
 if F is not empty:
    for each o in O :
       add BGP(s, ap, o) to J .

 let I be a Join on basic graph patterns. 
 if F_i is not empty:
    for each o in O :
       add BGP(o, ap, s) to I .
 
 if I and J are both not empty:
    return Union(Filter(J, F), Filter(I, F_i)) .
 else if I is not empty :
    return Filter(I, F_i).
 else if J is not empty :
    return Filter(J, F).
&lt;/pre&gt;
The end result of applying this algorithm to the example SPARQL 1.1 query we saw above would be the following (slightly adapted for readability) Sesame query algebra expression:
&lt;pre&gt;
Projection({x, y}, 
   Union(
      Filter(StatementPattern(y, ap, x), Compare(!=, ap, foaf:knows)),
      Filter(StatementPattern(x, ap, y), Compare(!=, ap, foaf:knows))
   )
)
&lt;/pre&gt;
Short and sweet. Of course, it gets less short and sweet when using more complex property sets, or property sets in combination with other property path features, but the algorithm caters to that. Such more complex expression just result in a larger set of unions and joins.</description><link>http://jeenbroekstra.blogspot.com/2011/04/sparql-11-query-negated-property-sets.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-6208389071824858490</guid><pubDate>Fri, 15 Apr 2011 05:20:00 +0000</pubDate><atom:updated>2011-04-15T17:21:39.338+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Notes on evaluating arbitrary-length property paths</title><description>&lt;p&gt;
I have more or less finished implementing parsing and basic evaluation for SPARQL 1.1 property paths in Sesame. The only thing still missing is negated property sets. Negated sets of properties... Who the heck wants that? Honestly. 
&lt;p&gt;
Anyway. Apart from the fact that the property path syntax is not quite simple to parse, there are some concepts involved which make evaluation of property-paths tricky - especially if arbitrary-length paths are involved.
&lt;p&gt;
Arbitrary-length paths are paths specified with a '+' or '*' modifier. For example, the path &lt;code&gt;?x foaf:knows+/foaf:name ?name&lt;/code&gt; specifies a match where either &lt;code&gt;?x&lt;/code&gt; knows someone with name &lt;code&gt;?name&lt;/code&gt;, or knows someone who knows someone with name &lt;code&gt;?name&lt;/code&gt;, or ... you get the point. The trouble with such queries in 'traditional' evaluation is that there is no a-priori length: you can not simply use the SPARQL parser to build a set of joins. 
&lt;p&gt;
A path of fixed length &lt;code&gt;n&lt;/code&gt; will usually be translated by the parser to &lt;code&gt;n-1&lt;/code&gt; joins on individual statement patterns. In order to allow evaluation of non-fixed length paths, we need something that amounts to graph traversal. Fortunately, Sesame's default evaluation strategy (essentially lazy iteration over bindings) is well suited for this task. What I have done is the following:
&lt;ol&gt;
&lt;li&gt;the SPARQL parser translates an arbitrary-length property path to a new algebra operator, called (rather appropriately I thought) &lt;code&gt;ArbitraryLengthPath&lt;/code&gt;.
&lt;li&gt;the default &lt;code&gt;EvaluationStrategy&lt;/code&gt; for such an operator is based on a dynamically expanding iterator, which creates new joins &lt;i&gt;while being evaluted&lt;/i&gt;.
&lt;/ol&gt;

Effectively, this new iterator (called &lt;code&gt;PathIteration&lt;/code&gt;, currently located as an inner class in the &lt;code&gt;EvaluationStrategyImpl&lt;/code&gt;) implements a depth-first graph traversal strategy. It reports back results iteratively and expands the path sequence length (using an ever-increasing iterative creation of nested joins) until it reaches a length at which the nested join no longer produces any matches. Cycle-detection is implemented by the simple expedient of adding an boolean comparison operator (NEQ) on top of our join: if the start node of the path has the same value as the end node, we have a cycle.</description><link>http://jeenbroekstra.blogspot.com/2011/04/notes-on-evaluating-arbitrary-length.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-603083770933859678</guid><pubDate>Thu, 31 Mar 2011 20:13:00 +0000</pubDate><atom:updated>2011-04-01T09:13:01.023+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Ontotext</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Sesame 2.4.0-alpha1 released, with SPARQL 1.1 Query support</title><description>I'm very pleased to announce a first test release of Sesame with SPARQL 1.1 support: &lt;a href="http://www.openrdf.org/news.jsp#sesame-2.4.0-alpha1"&gt;Sesame 2.4.0-alpha1&lt;/a&gt;. This first alpha-release of Sesame 2.4 contains support for various SPARQL 1.1 Query features as specified in the current
    &lt;a href="http://www.w3.org/TR/sparql11-query/"&gt;SPARQL 1.1 Query Working Draft&lt;/a&gt;.
    The implementation of SPARQL 1.1 in Sesame is led by
    &lt;a href="http://www.ontotext.com/"&gt;Ontotext&lt;/a&gt;.
   &lt;br /&gt;
&lt;p&gt;
The list of features includes:
   &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use of &lt;a href="http://www.w3.org/TR/sparql11-query/#select_expressions"&gt;expressions in the SELECT clause&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use of &lt;a href="http://www.w3.org/TR/sparql11-query/#aggregates"&gt;aggregates&lt;/a&gt; (COUNT, MIN, MAX, AVG, SUM)&lt;/li&gt;
&lt;li&gt;Use of &lt;a href="http://www.w3.org/TR/sparql11-query/#aggregates"&gt;HAVING and GROUP BY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use of &lt;a href="http://www.w3.org/TR/sparql11-query/#subqueries"&gt;Subqueries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.w3.org/TR/sparql11-query/#negation"&gt;Negation&lt;/a&gt;: (NOT) EXISTS and MINUS&lt;/li&gt;
&lt;li&gt;Set membership: &lt;a href="http://www.w3.org/TR/sparql11-query/#func-in"&gt;(NOT) IN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Various new &lt;a href="http://www.w3.org/TR/sparql11-query/#SparqlOps"&gt;builtin functions&lt;/a&gt;: COALESCE, BNODE, IRI, isNumeric, strLang, strDt&lt;/li&gt;
&lt;li&gt;Partial support for &lt;a href="http://www.w3.org/TR/sparql11-query/#propertypaths"&gt;property paths&lt;/a&gt;.
    Current support includes path sequences (/), path alternatives (|), zero or one matches (?),
    specific numbers of occurrences ({n, m}), and inverted properties (^). Not yet supported are
    arbitrary-length paths (+ and * wildcards) and negated properties (!).&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
As this is an alpha release we advise you to use it for testing and
    evaluation purposes only. We are actively looking for your feedback in
    terms of bug reports and other problems you may encounter. We'd love to
    hear your comments! Please send your feedback to the &lt;a href="https://lists.sourceforge.net/lists/listinfo/sesame-general"&gt;sesame-general&lt;/a&gt; mailinglist.
&lt;/p&gt;
&lt;p&gt;In other news, the &lt;a href="http://www.openrdf.org/"&gt;OpenRDF.org website&lt;/a&gt; has been given a fresh coat of paint and a good update. I'm sure Arjohn will be pleased to hear your feedback. Take a look, and fill in the &lt;a href="http://www.openrdf.org/survey.jsp"&gt;survey&lt;/a&gt;.
&lt;/p&gt;</description><link>http://jeenbroekstra.blogspot.com/2011/04/sesame-240-alpha1-released-with-sparql.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-2786733233160379558</guid><pubDate>Mon, 14 Feb 2011 23:11:00 +0000</pubDate><atom:updated>2011-09-02T11:56:42.303+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>RIO</category><category domain='http://www.blogger.com/atom/ns#'>Sesame Cookbook</category><title>Cooking with Sesame: parsing and writing RDF with Rio</title><description>&lt;div style="background-color: yellow; color: red; border: solid 1px red; width: 100%; padding: 2px; margin-bottom: 10px; "&gt;
&lt;b&gt;The Sesame Cookbook has moved to my new site: &lt;a href="http://rivuli-development.com/"&gt;http://rivuli-development.com/&lt;/a&gt;&lt;/b&gt;
&lt;/div&gt;

The Sesame framework includes&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/package-summary.html"&gt; a set of parsers and writers called Rio&lt;/a&gt;. Rio (a rather imaginative acronym for "RDF I/O") is a toolkit that can be used independently from the rest of Sesame. In this recipe, we will take a look at various ways to use Rio to parse from or write to an RDF document. I will show how to do a simple parse and collect the results, how to count the number of triples in a file, how to convert a file from one syntax format to another, and how to dynamically create a parser for the correct syntax format.&lt;br /&gt;
&lt;br /&gt;
If you use Sesame as a triplestore (via the&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/package-summary.html"&gt; Repository API&lt;/a&gt;), then&amp;nbsp; typically you will not need to use the parsers directly: you simply supply the document (either via a URL, or as a File, InputStream or Reader object) to the RepositoryConnection and the parsing is all handled internally. However, sometimes you may want to parse an RDF document without immediately storing it in a triplestore. For those cases, you can use Rio directly.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;The Rio parsers all work with a set of Listener interfaces that they report results to: &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/ParseErrorListener.html"&gt;ParseErrorListener&lt;/a&gt;, &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/ParseLocationListener.html"&gt;ParseLocationListener&lt;/a&gt;, and &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/RDFHandler.html"&gt;RDFHandler&lt;/a&gt;. Of these three, RDFHandler is the most useful one: this is the listener that receives parsed RDF triples. So we will concentrate on this interface here.&lt;br /&gt;
&lt;br /&gt;
The RDFHandler interface is quite simple, it contains just five methods:&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;startRDF&lt;/span&gt;, &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;handleNamespace&lt;/span&gt;&lt;span style="font-size: small;"&gt;, &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;handleComment&lt;/span&gt;&lt;span style="font-size: small;"&gt;, &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;handleStatement&lt;/span&gt;, and &lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;endRDF&lt;/span&gt;. Rio also pr&lt;/span&gt;ovides a number of default implementations of RDFHandler, such as &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/util/RDFInserter.html"&gt;RDFInserter&lt;/a&gt;, which immediately adds any received RDF triples to its supplied RepositoryConnection, and &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/helpers/StatementCollector.html"&gt;StatementCollector&lt;/a&gt;, which stores all received RDF triples in a Java Collection. Depending on what you want to do with parsed statements, you can either reuse one of the existing RDFHandlers, or, if you have a specific task in mind, you can simply write your own implementation of RDFHandler. Here, I will show you some simple examples of things you can do with RDFHandlers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Collecting all parsed triples in a List&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As a simple example of how to use Rio, we parse an RDF document and collect all the parsed statements in a Java List object. For this, we need the following ingredients:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;an RDF file;&lt;/li&gt;
&lt;li&gt;a RDFParser object;&lt;/li&gt;
&lt;li&gt;a RDFHandler object.&lt;/li&gt;
&lt;/ul&gt;
For the RDF file, let's say we have a Turtle file, available at http://example.org/example.ttl:&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;java.net.URL documentUrl&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = new URL("http://example.org/example.ttl");&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;InputStream inputStream = documentUrl.openStream();&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
We now have an open InputStream to our RDF file. Now we need a RDFParser object that reads this InputStream and creates RDF statements out of it. Since we are reading a Turtle file, we create a TurtleParser object:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;&lt;br style="background-color: #cccccc;" /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;RDFParser rdfParser = new TurtleParser();&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
(note: all Rio classes and interfaces are in package org.openrdf.rio&amp;nbsp; or one of its subpackages)&lt;br /&gt;
&lt;br /&gt;
We also need an RDFHandler which can receive RDF statements from the parser. Since we just want to create a Java List of Statements for now, we'll just use Rio's StatementCollector:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;java.util.ArrayList&lt;statement&gt; myList = new ArrayList&lt;statement&gt;();&lt;/statement&gt;&lt;/statement&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;StatementCollector collector = new StatementCollector(myList);&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;rdfParser.setRDFHandler(collector);&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Finally, we need to set the parser to work:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;try { &lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; rdfParser.parse(inputStream, documentURL.toString());&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;}&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;catch (IOException e) {&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; // handle IO problems (e.g. the file could not be read)&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;catch (RDFParseException e) {&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; // handle unrecoverable parse error&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;catch (RDFHandlerException e) {&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; // handle a problem encountered by the RDFHandler&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;/div&gt;
&lt;br /&gt;
After the parse() method has executed (and provided no exception has occurred), the list &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;myList&lt;/span&gt; will be filled by the StatementCollector. As an aside: you do not have to provide the StatementCollector with a list in advance, you can also use an empty constructor and then just get the collection, using StatementCollector.getStatements() .&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Using your own RDFHandler: counting statements&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As a simple example of writing your own RDFHandler, suppose you want to simply count the number of triples in the RDF file. You could of course use the above code for this, adding all triples to a List, and then just checking the size of the List. However, this will get you into trouble when you are parsing very large RDF files: you might run out of memory. And in any case: creating and storing all these Statement objects just to be able to count them seems a bit of a waste. So instead, we will create our own RDFHandler, which just counts the parsed RDF statements and then immediately throws them away. &lt;br /&gt;
&lt;br /&gt;
To create your own RDFHandler implementation, you can of course just create a class that implements the RDFHandler interface, but a useful shortcut is to instead create a subclass of &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/helpers/RDFHandlerBase.html"&gt;RDFHandlerBase&lt;/a&gt;. This is a base class that provides dummy implementations of all interface methods. The advantage is that you only have to override the methods in which you need to do something. Since what we want to do is just count statements, we only need to override the handleStatement method. Additionaly, we of course need a way to get back the total number of statements found by our counter. &lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;class StatementCounter extends RDFHandlerBase {&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; private int countedStatements = 0;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; @Override&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; public void handleStatement(Statement st) {&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; countedStatements++;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;public int getCountedStatements() {&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; return countedStatements; &lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;
&lt;div style="background-color: #cccccc;"&gt;
&lt;span style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;"&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Once we have this, our custom RDFHandler class, we can supply that to the parser instead of the StatementCollector, and we're done.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Converting RDF serialization formats&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A useful trick with Rio is to pipeline parsers and writers. Since all Rio &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/RDFWriter.html"&gt;RDFWriters&lt;/a&gt; are in fact RDFHandler implementations, you can directly supply them to a parser, thus creating a very simple syntax convertor.&lt;br /&gt;
&lt;br /&gt;
Say, you have a file in Turtle format, and you want to convert it to RDF/XML. Simply create a TurtleParser as shown above, and provide it with a &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/rdfxml/RDFXMLWriter.html"&gt;RDFXMLWriter&lt;/a&gt;, which is an RDFHandler implementation that writes the received RDF statements to an outputstream in RDF/XML format. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating the right parser for the right format&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In the examples sofar, we have created a parser by simply using the constructor of the specific format's parser class. In other words: our program code assumes that the input file is a Turtle file, so we just create a new TurtleParser object. However, you may not always know in advance what exact format the RDF file is in. What then? Fortunately, Rio has a couple of useful features to help you.&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/Rio.html"&gt;Rio&lt;/a&gt; class is a factory class which can create a RDFParser object given a specific &lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/rio/RDFFormat.html"&gt;RDFFormat&lt;/a&gt;. RDFFormat is a set of constants defining the available serialization formats. It also has a couple of utility methods for guessing the correct format, given either a filename or a MIME-type. For example, to get back the RDF format for our Turtle file, we could do the following:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;RDFFormat format = RDFFormat.forFileName(documentURL.toString());&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
This will guess, based on the extension of the file (.ttl) that the file is a Turtle file and return the correct format. We can then use that with the Rio factory class to create the correct parser dynamically:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #cccccc; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;RDFParser rdfParser = Rio.createParser(format);&lt;/span&gt;&lt;/div&gt;
&amp;nbsp; &lt;br /&gt;
As you can see, we still have the same result: we have created an RDFParser object which we can use to parse our file, but now we have not made the explicit assumption that the input file is in Turtle format: if we would later use the same code with a different file (say, a .owl file - which is in RDF/XML format), it would still work. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
I have tried to show a couple of useful ways to employ Rio in practice. It is a versatile set of streaming RDF parsers and writers that can be easily used in your own programs, and it can be used separately from the rest of the Sesame framework. Of course, more could be said about it (for example, how to configure its error handling, datatype verification, and so on), but that's for next time and/or the comments. Enjoy! And any feedback on these recipes is of course much appreciated.</description><link>http://jeenbroekstra.blogspot.com/2011/02/cooking-with-sesame-parsing-and-writing.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-7517732275545081726</guid><pubDate>Sat, 05 Feb 2011 04:03:00 +0000</pubDate><atom:updated>2011-02-05T17:03:21.961+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Implementing SPARQL 1.1 Query - first findings</title><description>I am currently in the middle of implementing &lt;a href="http://www.w3.org/TR/sparql11-query/"&gt;SPARQL 1.1 Query Language&lt;/a&gt; into Sesame 2 (code can be found in &lt;a href="http://repo.aduna-software.org/websvn/listing.php?repname=aduna&amp;amp;path=%2Forg.openrdf%2Fsesame%2Fbranches%2F2.4%2F"&gt;Sesame's subversion repository, branch 2.4&lt;/a&gt;). The current working draft specifies a number of new features for SPARQL, and I will briefly make some points about the features I have implemented thus far, noting problems I encountered or where the current working draft was unclear to me.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Expressions in SELECT&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
This new feature was fairly straightforward to implement, mainly as Sesame already had support for it in its query algebra. I only needed to adapt the parser.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Negation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In &lt;a href="http://www.w3.org/TR/sparql11-query/#negation"&gt;section 8&lt;/a&gt; two additional operators are introduced, both of which can be used to express negation. They are (NOT) EXISTS, and MINUS. Implementation of the EXISTS function again was quite straightforward, Sesame already having algebraic support for it.&lt;br /&gt;
&lt;br /&gt;
The definition of MINUS in SPARQL gave me some headaches, however. In Sesame's native query language &lt;a href="http://www.openrdf.org/doc/sesame2/users/ch09.html"&gt;SeRQL&lt;/a&gt;, the MINUS operator is a set operator operating on collections of triples - that is, the result of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{A} MINUS {B}&lt;/span&gt; is the set of all triples matching A, minus all triples matching B. In SPARQL, however, MINUS is defined in terms of&amp;nbsp; compatible solutions. This means that Sesame's own algebra operator for MINUS can not simply be reused for SPARQL. However, it also seems that SPARQL's definition of MINUS makes it, for all practical purposes, exactly equivalent to using a NOT EXISTS filter. To see why this is, we have to take a look at the definitions of both operators.&lt;br /&gt;
&lt;br /&gt;
In &lt;a href="http://www.w3.org/TR/sparql11-query/#neg-notexists-minus"&gt;section 8.3&lt;/a&gt; , the difference between NOT EXISTS and MINUS is explained, with a number of examples. This explanation shows that when the right-hand side pattern shares no variables with the left-hand pattern, the outcome is different. However, what is also apparent from this explanation that when a MINUS operator is used and no shared variables exist between the two patterns, the MINUS operator effectively does nothing.&lt;br /&gt;
&lt;br /&gt;
This also follows if we look at&amp;nbsp; the definition of MINUS in the &lt;a href="http://www.w3.org/TR/sparql11-query/#sparqlAlgebra"&gt;SPARQL algebra&lt;/a&gt; and the definition of compatible solutions in &lt;a href="http://www.w3.org/TR/sparql11-query/#BasicGraphPattern"&gt;section 17.3&lt;/a&gt;: by definition any two solutions µ and µ' which share no variables v are compatible. So the outcome of any such query would be exactly the same as if the MINUS were not there. This leaves us with two scenarios:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;the two patterns share a variable, in this case the MINUS can be replaced with a NOT EXISTS;&lt;/li&gt;
&lt;li&gt;the two patterns do not share a variable, in this case the MINUS can be ignored.&lt;/li&gt;
&lt;/ol&gt;
All in all it seems to me that MINUS as currently defined does not add additional expressivity to the language and is only a syntactic variant. If that is intended, that might be useful to clarify in the working draft.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Subqueries&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Sesame already having basic support for this in the algebra, again this was rather simple to add, as it only required me to tweak the SPARQL parser. I will probably need to test it further though.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Aggregates&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Fortunately for me, it turns out that basic support for aggregate functions had been added to Sesame's algebra earlier, courtesy of David Huynh. It required a bit of tweaking to be compatible with SPARQL's definitions, but the framework was already there, ready for me to extend.&lt;br /&gt;
&lt;br /&gt;
There are a number of things unclear in the working draft however, regarding the expected behaviour of aggregate functions.&lt;br /&gt;
&lt;br /&gt;
The first problem has to do with datatypes. Most examples take it as given that all input to, say, a SUM operator will be numeric values. It is not clearly stated what the expected behaviour is if a particular variable binding turns out to be non-numeric value. As a case in point, SUM is formally defined in terms of the XPath function op:numeric-add. This function explicitly states that it operates only on specific numeric types. No mention is made however, of expected behaviour when one operand is not a numeric type (section 16.3 of the SPARQL WD does mention that a type error results for incompatible operands, but it is not clear if this also applies to aggregate functions). Moreover, it is not clearly stated how a type error in an aggregate function should influence the result. I can see a number of possible scenarios, when a type error occurs during evaluation of an aggregate function:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;the entire query fails with an error;&lt;/li&gt;
&lt;li&gt;the incompatible operand value is ignored and evaluation continues;&lt;/li&gt;
&lt;li&gt;the aggregate operator fails silently, returning 0.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
From a usability perspective, I would probably have a preference for option 2, although I note that in other mathematical operators (+, -, *, etc.) Sesame's interpretation currently is that an incompatible operand results in a failed query.&lt;br /&gt;
&lt;br /&gt;
Another problem with the definition of aggregates, or more in general with aggregates in combination with several other features, is that it is not always clearly defined how they should interact (disclaimer: perhaps it is properly defined in &lt;a href="http://www.w3.org/TR/sparql11-query/#defn_algGroupBy"&gt;section 10.2&lt;/a&gt;, but I'm having a hard time following the definitions there). For example, what happens when we apply an ORDER BY on a graph pattern that already has a GROUP BY and an aggregate function? For example, take the following data set:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
:org1 :affiliates :auth1, :auth2 .&lt;br /&gt;
:auth1 :name "John" .&lt;br /&gt;
:auth2 :name "Paul" .&lt;br /&gt;
:org2 :affiliates :auth3 .&lt;br /&gt;
:auth3 :name "Ringo" .&lt;/div&gt;
&lt;br /&gt;
And the following query:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SELECT (GROUP_CONCAT(?name) AS ?names)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WHERE {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; ?org :affiliates ?auth .&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; ?auth :name ?name.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GROUP BY ?org&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ORDER BY ASC(str(?name))&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;/div&gt;
&lt;br /&gt;
My intuitive understanding would be that the result of this query would be:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;u&gt;?names&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/u&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
"Ringo" &lt;br /&gt;
"John Paul"&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;/div&gt;
&lt;br /&gt;
That is: the ordering is applied to the intermediate result of the grouping, thus supplying the aggregate operator (in this case, GROUP_CONCAT) with an ordered sequence (which makes sure that we get a concatenated string "John Paul" rather than "Paul John"). But it is not completely clear to me from the working draft if the ORDER BY clause should be applied to a grouping in this fashion. &lt;br /&gt;
&lt;br /&gt;
These are my findings thus far. I have not yet started on property paths or federated query. In the mean time, I would welcome any feedback on my notes, including feedback that tells me I should have read section so-and-so and it's all clear as glass if I had just taken the time to study it properly :)&lt;br /&gt;
&lt;br /&gt;
Also, this: in the course of this work I have written several DAWG-Manifest style unit tests to check conformance as I saw it. They can be found in Sesame's SVN repository, and I'd be happy to let them be reused. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://jeenbroekstra.blogspot.com/2011/02/implementing-sparql-11-query-first.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-2467351154045428115</guid><pubDate>Thu, 20 Jan 2011 23:48:00 +0000</pubDate><atom:updated>2011-01-21T12:48:46.775+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Back to working on Sesame</title><description>&lt;a href="http://www.ontotext.com/"&gt;Ontotext&lt;/a&gt;, the Bulgarian Semantic Web company of &lt;a href="http://www.ontotext.com/owlim"&gt;OWLIM&lt;/a&gt; fame, have given me the opportunity to return to working on &lt;a href="http://www.openrdf.org/"&gt;Sesame&lt;/a&gt; as a developer. Specifically, I have been contracted to help implement&lt;a href="http://www.w3.org/TR/sparql11-query/"&gt; SPARQL 1.1 Query&lt;/a&gt; and &lt;a href="http://www.w3.org/TR/sparql11-update/"&gt;Update&lt;/a&gt; into the Sesame framework.&lt;br /&gt;
&lt;br /&gt;
Work has already started and I'm happy to report that various features have already been implemented and tested - the fact that Sesame's query algebra is based on the SeRQL language helps a lot here, as various SPARQL 1.1 features were already available in SeRQL. This includes the use of expressions in the SELECT, as well as negation features and subqueries. More challenging will be the inclusion of aggregates and property paths. More soon.</description><link>http://jeenbroekstra.blogspot.com/2011/01/back-to-working-on-sesame.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-9172374641706004703</guid><pubDate>Sat, 04 Dec 2010 10:47:00 +0000</pubDate><atom:updated>2010-12-04T23:47:18.430+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Personal</category><category domain='http://www.blogger.com/atom/ns#'>NZ</category><title>New personal weblog</title><description>My wife and I have started a new personal weblog, about our emigration to New Zealand: &lt;a href="http://naarnz.blogspot.com/"&gt;http://naarnz.blogspot.com/&lt;/a&gt;. This new weblog will be in Dutch, as its primary purpose is to keep our families and friends back in Holland and Belgium up to date. So, if you understand a bit of Dutch and want to know more about our decision to move to the other side of the world and follow how we fare, have a look!</description><link>http://jeenbroekstra.blogspot.com/2010/12/new-personal-weblog.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-7881179277011612563</guid><pubDate>Mon, 18 Oct 2010 14:17:00 +0000</pubDate><atom:updated>2010-10-19T03:20:11.426+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SWC</category><title>SWC 0.10.1 - bugfix release</title><description>I've just put version 0.10.1 of the &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;SWC&lt;/a&gt; online. This is a bugfix release that addresses a number of annoying problems:
&lt;ul&gt;
&lt;li&gt;several buttons on the construct query tab were not visible due to layout problems;&lt;/li&gt;
&lt;li&gt;the namespaces tab and context comboboxes were not properly updated after uploading new data;&lt;/li&gt;
&lt;li&gt;when adding a file was aborted for any reason, the tool forgot to close the file stream.&lt;/li&gt;
&lt;/ul&gt;
As always, we welcome your feedback. By the way, for anyone interested in discussing the tool with us, there is a &lt;a href="http://lists.sourceforge.net/lists/listinfo/sesamewinclient-devel"&gt;mailinglist for this purpose&lt;/a&gt; at Sourceforge.</description><link>http://jeenbroekstra.blogspot.com/2010/10/swc-0101-bugfix-release.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-5071230394332076175</guid><pubDate>Tue, 12 Oct 2010 11:12:00 +0000</pubDate><atom:updated>2011-09-02T11:57:32.681+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>Sesame Cookbook</category><title>Cooking with Sesame: the RepositoryManager</title><description>&lt;div style="background-color: yellow; color: red; border: solid 1px red; width: 100%; padding: 2px; margin-bottom: 10px; "&gt;
&lt;b&gt;The Sesame Cookbook has moved to my new site: &lt;a href="http://rivuli-development.com/"&gt;http://rivuli-development.com/&lt;/a&gt;&lt;/b&gt;
&lt;/div&gt;

(This is part of series of weblog postings on using the &lt;a href="http://www.openrdf.org/"&gt;Sesame framework&lt;/a&gt; more effectively.)
&lt;br /&gt;
&lt;br /&gt;
As is also explained in the official &lt;a href="http://www.openrdf.org/doc/sesame2/users/"&gt;Sesame user manual&lt;/a&gt;, the &lt;a href="http://www.openrdf.org/doc/sesame2/users/ch08.html"&gt;Repository API&lt;/a&gt; (see also the&lt;a href="http://www.openrdf.org/doc/sesame2/api/"&gt; Sesame Javadoc&lt;/a&gt;) is the starting point for anyone wanting to program against Sesame. While the user manual gives some good examples on getting you started with using that API, however, there are some tips and tricks for more effective use that I thought I might share, in a series of weblog postings I'm planning on &lt;i&gt;"Cooking with Sesame"&lt;/i&gt;. This first episode, I'll go a bit deeper into creation and management of Sesame repositories, specifically using the &lt;b&gt;RepositoryManager&lt;/b&gt; and related classes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating repositories: the basics&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Sesame supports a number of different types of Repository. The two that are most commonly used are the &lt;b&gt;&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/sail/package-summary.html"&gt;SailRepository&lt;/a&gt;&lt;/b&gt;, for local repositories&lt;b&gt;, &lt;/b&gt;and the &lt;b&gt;&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/http/package-summary.html"&gt;HTTPRepository&lt;/a&gt;&lt;/b&gt;, a proxy for repositories on a remote Sesame server. &lt;br /&gt;
&lt;br /&gt;
A SailRepository is an object that represents a local Sesame database. Note that, although we call it a database, this does not automatically mean persistence, or anything "heavy" - it can be a simple in-memory representation of an RDF graph. In fact, the easiest way to load any RDF file into memory using Sesame is by creating a SailRepository using an in-memory database.
&lt;br/&gt;&lt;br/&gt; 
The type of database (main memory, native, relational, ...) is determined by the &lt;b&gt;SAIL stack&lt;/b&gt; provided to the SailRepository (the &lt;a href="http://www.openrdf.org/doc/sesame2/system/ch05.html"&gt;SAIL API&lt;/a&gt; is a Sesame system-internal API that is used to wrap the details of the underlying storage and reasoning mechanism). For example, for creating a simple in-memory repository, we do the following:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import org.openrdf.repository.Repository;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.sail.memory.MemoryStore;

Repository repository = new SailRepository(new MemoryStore());

repository.initialize();
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
The &lt;b&gt;MemoryStore&lt;/b&gt; object referred to here is a SAIL backend that simply stores all RDF in-memory. Sesame provides various different SAIL backends, as well as various options for configuring each SAIL backend. Some further examples of the creation of various types of repositories (including also the use of the HTTPRepository) are shown in chapter 8 of the &lt;a href="http://www.openrdf.org/doc/sesame2/users/ch08.html"&gt;Sesame user manual&lt;/a&gt;.
&lt;br /&gt;&lt;br/&gt;
Once you have created a Repository object like this, you can open a &lt;b&gt;&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/RepositoryConnection.html"&gt;RepositoryConnection&lt;/a&gt;&lt;/b&gt; on it to make further use of the repository: adding or removing data, executing queries, and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The RepositoryManager&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So far so good: we can easily create and use various different types of Sesame repositories. However, when developing an application in which you have to keep track of several repositories, sharing references to these repositories between different parts of your code can quickly become complex. Of course, you could declare some static references for use throughout your application, but if several repositories have to be juggled this way, this too can become cumbersome. Ideal would be one central location where all information on the repositories in use (including id, type, directory for persistent data storage, etc.) is kept. This is the role of the Sesame &lt;b&gt;&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/manager/package-summary.html"&gt;RepositoryManager&lt;/a&gt;&lt;/b&gt;.
&lt;br/&gt;&lt;br/&gt;
Using the RepositoryManager for handling repository creation and administration offers a number of advantages, including:
&lt;ul&gt;
&lt;li&gt;a single RepositoryManager object can be more easily shared throughout your application than a host of static references to individual repositories;&lt;/li&gt;
&lt;li&gt;you can more easily create and manage repositories 'on-the-fly', for example if your application requires creation of new repositories on user input;&lt;/li&gt;
&lt;li&gt;the RepositoryManager stores your configuration, including all repository data, in one central spot on the file system.&lt;/li&gt;
&lt;/ul&gt;
The RepositoryManager comes in two flavours: the LocalRepositoryManager and the RemoteRepositoryManager.&lt;br/&gt;&lt;br/&gt; A &lt;b&gt;LocalRepositoryManager&lt;/b&gt; manages repository handling for you locally, and is always created using a (local) directory. This directory is where all Sesame repositories handled by the manager store their data, and also where the LocalRepositoryManager itself stores its configuration data.&lt;br /&gt;
&lt;br /&gt;
You create a new LocalRepositoryManager as follows:&lt;br /&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import java.io.File;
import org.openrdf.repository.manager.LocalRepositoryManager;

File baseDir = new File("/path/to/storage/dir/");
LocalRepositoryManager manager =
               new LocalRepositoryManager(baseDir);
manager.initialize();
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
To use a LocalRepositoryManager to create and manager repositories works slightly differently from what we've seen above about creating Sesame repositories. The LocalRepositoryManager works by providing it with &lt;b&gt;&lt;a href="http://www.openrdf.org/doc/sesame2/api/org/openrdf/repository/config/RepositoryConfig.html"&gt;RepositoryConfig&lt;/a&gt;&lt;/b&gt; objects, which are declarative specifications of the repository you want. You add a RepositoryConfig object for your new repository, and then request the actual Repository back from the LocalRepositoryManager:&lt;br /&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import org.openrdf.repository.config.RepositoryConfig;

String repositoryId = "test-db";
RepositoryConfig repConfig = 
      new RepositoryConfig(repositoryId, repositoryTypeSpec);

manager.addRepositoryConfig(repConfig);
Repository repository = manager.getRepository(repositoryId);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br/&gt;
In the above bit of code, you may have noticed that I provide an innocuous-looking variable called &lt;b&gt;repositoryTypeSpec&lt;/b&gt; to the constructor of our RepositoryConfig. This variable is an instance of a class called &lt;b&gt;RepositoryImplConfig&lt;/b&gt;, and this specifies the actual configuration of our new repository: what backends to use, whether or not to use inferencing, and so on.&lt;br /&gt;
&lt;br /&gt;
Creating a RepositoryImplConfig object can be done in two ways: programmatically, or by reading a (RDF) config file. Here, I will show the programmatic way (in a future article we may look at the other method, using RDF config files).
&lt;br/&gt;&lt;br/&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import org.openrdf.sail.config.SailImplConfig;
import org.openrdf.sail.memory.config.MemoryStoreConfig;
import org.openrdf.repository.config.RepositoryImplConfig;
import org.openrdf.repository.sail.config.SailRepositoryConfig;

// create a configuration for the SAIL stack
SailImplConfig backendConfig = new MemoryStoreConfig();

// create a configuration for the repository implementation
RepositoryImplConfig repositoryTypeSpec = 
                new SailRepositoryConfig(backendConfig);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br/&gt;
As you can see, we use a class called &lt;b&gt;MemoryStoreConfig&lt;/b&gt; for specifying the type of storage backend we want. This class resides in a &lt;code&gt;config&lt;/code&gt; sub-package of the memory store package (&lt;code&gt;org.openrdf.sail.memory&lt;/code&gt;). Each particular type of SAIL in Sesame has such a config class.
&lt;br/&gt;&lt;br/&gt;
As a second example, we create a slightly more complex type of store: still in-memory, but this time we want it to use the memory store's persistence option, and we also want to add RDFS inferencing. In Sesame, RDFS inferencing is provided by a separate SAIL implementation, which can be 'stacked' on top of another SAIL. We follow that pattern in the creation of our config object:
&lt;br/&gt;&lt;br/&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import org.openrdf.sail.inferencer.fc.config.ForwardChainingRDFSInferencerConfig;

// create a configuration for the SAIL stack
boolean persist = true;
SailImplConfig backendConfig = new MemoryStoreConfig(persist);

// stack an inferencer config on top of our backend-config
backendConfig = 
     new ForwardChainingRDFSInferencerConfig(backendConfig);

// create a configuration for the repository implementation
SailRepositoryConfig repositoryTypeSpec = 
                new SailRepositoryConfig(backendConfig);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;The RemoteRepositoryManager&lt;/b&gt;
&lt;br/&gt;&lt;br/&gt;
A useful feature of Sesame is that most its APIs are transparent with respect to whether you are working locally or remote. This is the case for the Sesame repositories, but also for the RepositoryManager. In the above examples, we have used a &lt;b&gt;Local&lt;/b&gt;RepositoryManager, creating Sesame repositories for local use. However, it is also possible to use a &lt;b&gt;Remote&lt;/b&gt;RepositoryManager, using it to create and manage Sesame repositories residing on a remotely running Sesame server.
&lt;br/&gt;&lt;br/&gt;
A RemoteRepositoryManager is initialized as follows:
&lt;br/&gt;&lt;br/&gt;
&lt;div style="background-color: #f0f0f0;"&gt;
&lt;pre&gt;
import org.openrdf.repository.manager.RemoteRepositoryManager;

// URL of the remote Sesame server we want to access
String serverUrl = "http://localhost:8080/openrdf-sesame";
RemoteRepositoryManager manager = 
              new RemoteRepositoryManager(serverUrl);
manager.initialize();
&lt;/pre&gt;
&lt;/div&gt;
&lt;br/&gt;
Once initialized, the RemoteRepositoryManager can be used in the same fashion as the LocalRepositoryManager: creating new repositories, requesting references to existing repositories, and so on.
&lt;br/&gt;
&lt;br/&gt;
&lt;i&gt;Disclaimer: although I have done my best to check the correctness, I can give no guarantees that any of the provided code examples work as expected. Also I make no claims on whether any of this is the 'official' way of working with Sesame.&lt;/i&gt;</description><link>http://jeenbroekstra.blogspot.com/2010/10/cooking-with-sesame-repositorymanager.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-5549376762911077872</guid><pubDate>Thu, 30 Sep 2010 12:51:00 +0000</pubDate><atom:updated>2010-10-01T02:04:26.015+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>OWL</category><category domain='http://www.blogger.com/atom/ns#'>SWC</category><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>SWC 0.10 - OWL Reasoning support</title><description>Anton and I have just released version 0.10 of SWC, the &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;Sesame Windows Client&lt;/a&gt;. The main new feature of this release is support for OWL reasoning.&lt;br /&gt;
&lt;br /&gt;
The Sesame Windows Client now includes the latest version of &lt;a href="http://ontotext.com/"&gt;Ontotext&lt;/a&gt;'s &lt;a href="http://www.ontotext.com/owlim/"&gt;SwiftOWLIM&lt;/a&gt; store, a high-performance in-memory store and OWL reasoner. SWC allows you to create a local SwiftOWLIM store like any other Sesame repository, with the added advantage that it supports OWL semantics. OWL reasoning made easy!&lt;br /&gt;
&lt;br /&gt;
Also, we have made a number of improvements in the performance of data upload and data export, as well as several minor changes in the UI.&lt;br /&gt;
&lt;br /&gt;
Next steps in the development of SWC are: adding support for other triplestores that have a Sesame API bridge (including&amp;nbsp;&lt;a href="http://virtuoso.openlinksw.com/"&gt;Virtuoso&lt;/a&gt; and &lt;a href="http://www.franz.com/agraph/allegrograph/"&gt;AllegroGraph&lt;/a&gt;), as well as improving the SPARQL endpoint support (by allowing additional parameters to be set). And oh yeah, we're still looking for a good new name for the SWC... &lt;br /&gt;
&lt;br /&gt;</description><link>http://jeenbroekstra.blogspot.com/2010/09/swc-010-owl-reasoning-support.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-5869521420822775314</guid><pubDate>Mon, 20 Sep 2010 14:10:00 +0000</pubDate><atom:updated>2010-09-21T02:10:46.108+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>SMW</category><title>Semantic Mediawiki Conference (SMWCon) Fall 2010</title><description>I just came back from an exhausting but highly inspirational 2 days of talks and demos about &lt;a href="http://semantic-mediawiki.org/wiki/Semantic_MediaWiki"&gt;Semantic Mediawiki&lt;/a&gt; and various extensions and use cases: &lt;a href="http://semantic-mediawiki.org/wiki/SMWCon_Fall_2010"&gt;SMWCon Fall 2010&lt;/a&gt; (hosted at the Open University in Amsterdam).&lt;br /&gt;
&lt;br /&gt;
Some of my personal highlights (in no particular order):&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mediawiki.org/wiki/Extension:Semantic_Maps"&gt;&lt;b&gt;Semantic Maps&lt;/b&gt;&lt;/a&gt; as presented by Jeroen de Dauw. This was a bit of an eye-opener, as I had previously briefly thought about using something like this, but decided it wouldn't be worth the bother if it involved having to type in a lot of coordinates. &lt;br /&gt;Well guess what, you don't have to: it provides full geocoding functionality, effectively allowing you just to type in a street address. It ties in with Google maps as well as Open StreetMaps, Yahoo maps and OpenLayers. Overall it looks just massively useful.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://smwforum.ontoprise.com/smwforum/index.php/Help:WikiTags"&gt;&lt;b&gt;WikiTags&lt;/b&gt; &lt;/a&gt;by Jesse Wang: a very impressive demo on how to link the world of (semantic) wikis to the world of MS Office. Automated annotation of terms in MS Word, live links between Outlook and the wiki, quick and easy adding of e-mail messages to the wiki, etc. etc. The thought behind this effort appeals to me: don't rage against the machine but accept that MS Office tools are the daily working environment for many people and organisations, and cater to that.&lt;/li&gt;
&lt;li&gt;The Suite of &lt;b&gt;&lt;a href="http://www.projecthalo.com/"&gt;Halo&lt;/a&gt;&lt;/b&gt; extensions presented by Daniel Hansch: although I was already aware of the Halo extensions I had not yet completely grokked the full range of features and improvements it encompasses. In particular its support for fine-grained access control is something that captured my attention. On the ToDo list to take for a test drive.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="http://www.mediawiki.org/wiki/Extension:SparqlExtension"&gt;SparqlExtension&lt;/a&gt; &lt;/b&gt;by Alfredas Chmieliauskas and Chris Davis: particularly impressive about this demo was the way in which this extension enables integration of (RDF) data from many different sources and creating all sorts of reportings on that data. Can't wait to tweak this one to talk to a Sesame server and start testing it on our internal group wiki.&lt;/li&gt;
&lt;li&gt;Rudi van Bavel and Michael Cariaso both showed very interesting stuff involving the creation, maintenance and use of &lt;b&gt;&lt;a href="http://www.snpedia.com/"&gt;SNPedia&lt;/a&gt;&lt;/b&gt;, a wiki containing huge amounts of human genetic data.&lt;/li&gt;
&lt;/ul&gt;
To be honest, though, I found all presentations and demos, not just the ones mentioned above, interesting and engaging. The atmosphere throughout the two days was positive and pragmatic, with lots of interesting group discussion going on. It was great to see people from so many different background coming together to share experiences and show new and innovative ways in which the SMW platform can be used and extended. &lt;br /&gt;
&lt;ul&gt;
&lt;/ul&gt;</description><link>http://jeenbroekstra.blogspot.com/2010/09/semantic-mediawiki-conference-smwcon.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-4558279620954624389</guid><pubDate>Tue, 14 Sep 2010 11:44:00 +0000</pubDate><atom:updated>2010-10-01T04:25:37.832+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SWC</category><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>SWC 0.9 released: out-of-the box triplestore and SPARQL query library</title><description>Hot on the heels of the previous SWC release comes another major update of the &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;Sesame Windows Client&lt;/a&gt;. Version 0.9 has a whole range of useful new features and improvements:&amp;nbsp; &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;You can now create and use local repositories (many thanks to the IKVM developers and Enrico Minack for making this possible);&lt;/li&gt;
&lt;li&gt;"My Query Book" allows you to save and reuse your favorite SPARQL queries;&lt;/li&gt;
&lt;li&gt;You can now open the result of a SPARQL SELECT query in a new (paged) window;&lt;/li&gt;
&lt;li&gt;You can now directly save the result of a SPARQL SELECT query as comma-separated values, XML, or JSON;&lt;/li&gt;
&lt;li&gt;Your most recently used server URLs are now remembered;&lt;/li&gt;
&lt;li&gt;Autocompletion when typing in a server URL.&lt;/li&gt;
&lt;/ul&gt;
The use of local repositories means that you can use the SWC as a quick and easy RDF triplestore. Create a new store, add your RDF data, and start querying. No need to install a separate triplestore server.&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Dh28GpBqd14/TI9ExQMmCwI/AAAAAAAAAFg/M9UA8inZ-uA/s1600/querybook-screen.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="220" src="http://1.bp.blogspot.com/_Dh28GpBqd14/TI9ExQMmCwI/AAAAAAAAAFg/M9UA8inZ-uA/s320/querybook-screen.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Query Book screenshot (click to enlarge)&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
The Query Book allows you to not only save your queries, but also to document them. This way, you can quickly create a library of useful SPARQL queries and document not only what they do, but also on which repository or SPARQL endpoint the query is most likely to give a useful result. The Query Book's search feature makes sure that even in a large library you can still easily find back any query.&lt;br /&gt;
&lt;br /&gt;
Another new feature is the opening of a SPARQL SELECT query result in a new (paged) window. What is especially useful about this is that you can now execute one query, keep the result in a separate window, and then execute another query and compare its result with the previous one.&lt;br /&gt;
&lt;br /&gt;
If you want to save the result of a SPARQL query, you can now do so, in a choice of three formats: comma-separated values (CSV), which is useful for import in e.g. Excel, is the default choice, but the official &lt;a href="http://www.w3.org/TR/rdf-sparql-XMLres/"&gt;SPARQL Query Results XML format&lt;/a&gt; and the &lt;a href="http://www.w3.org/TR/rdf-sparql-json-res/"&gt;SPARQL JSON format&lt;/a&gt; are also suppported.&lt;br /&gt;
&lt;br /&gt;
Both Anton and I are quite happy with this new release, and hope you find it useful as well. As always, the new release can be found on the&amp;nbsp;  &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;project homepage on Sourceforge&lt;/a&gt;.</description><link>http://jeenbroekstra.blogspot.com/2010/09/swc-09-released-out-of-box-triplestore.html</link><author>noreply@blogger.com (J1)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Dh28GpBqd14/TI9ExQMmCwI/AAAAAAAAAFg/M9UA8inZ-uA/s72-c/querybook-screen.png' height='72' width='72'/></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-901215915564354070</guid><pubDate>Fri, 03 Sep 2010 08:38:00 +0000</pubDate><atom:updated>2010-09-03T23:26:45.030+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>.Net</category><title>Sesame 2 Windows Client - or is that SPARQL Windows/Linux Client?</title><description>&lt;a href="http://1.bp.blogspot.com/_Dh28GpBqd14/TICxJ6yb5jI/AAAAAAAAAFY/q3nlizqOD3s/s1600/startup-screen.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="249" src="http://1.bp.blogspot.com/_Dh28GpBqd14/TICxJ6yb5jI/AAAAAAAAAFY/q3nlizqOD3s/s320/startup-screen.png" width="320" /&gt;&lt;/a&gt;
I've just released a new version of the &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;Sesame 2 Windows Client&lt;/a&gt;. Thanks to a new co-developer, Anton Andreev (of &lt;a href="http://ontotext.com/"&gt;OntoText&lt;/a&gt;), the SWC tool is now a full-fledged SPARQL client: it can connect to any SPARQL endpoint, not just Sesame servers.&lt;br /&gt;
&lt;br /&gt;
Apart from this new feature, the tool also has a couple of other improvements:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;context information fetching can now be disabled when connecting to large repositories;&lt;/li&gt;
&lt;li&gt;namespace clauses can now be automatically generated, based on the prefixes used in the query.&lt;/li&gt;
&lt;/ul&gt;
The only problem with this new release is that the name of the tool is now even more of a mismatch. Not only is the Sesame 2 Windows Client not just for Windows (it also runs on Linux under Mono), but now it is also not just for Sesame. A free drink to whoever suggests a good new name!&lt;br /&gt;
&lt;br /&gt;
As always, the new release can be found on the&amp;nbsp;  &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;project homepage on Sourceforge&lt;/a&gt;. The source code can from now on be found in the Sourceforge SVN repository.</description><link>http://jeenbroekstra.blogspot.com/2010/09/sesame-2-windows-client-or-is-that.html</link><author>noreply@blogger.com (J1)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Dh28GpBqd14/TICxJ6yb5jI/AAAAAAAAAFY/q3nlizqOD3s/s72-c/startup-screen.png' height='72' width='72'/></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-889888004014328665</guid><pubDate>Mon, 30 Aug 2010 10:11:00 +0000</pubDate><atom:updated>2010-08-30T22:11:51.488+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Personal</category><category domain='http://www.blogger.com/atom/ns#'>NZ</category><title>Moving to New Zealand</title><description>&lt;a href="http://www.flickr.com/photos/jeen/4256988382/" title="Milford Sound from kayak by jeenbroekstra, on Flickr"&gt;&lt;img align="right" alt="Milford Sound from kayak" height="180" src="http://farm5.static.flickr.com/4011/4256988382_8f136ec371_m.jpg" width="240" /&gt;&lt;/a&gt;
Karen and I are taking the plunge together. Well, another plunge: we are emigrating to New Zealand at the end of this year.&lt;br /&gt;
&lt;br /&gt;
This is not, of course, something you decide on a whim. We've both long felt that we might like to make a "big change" for the better, and a long holiday spent getting to know New Zealand and its people convinced us that it is everything we were hoping it would be. New Zealand is an absolutely breathtakingly beautiful place, its people are friendly and easy-going, and for what is basically a predominantly Anglosaxon culture they actually make very good coffee as well.&lt;br /&gt;
&lt;br /&gt;
The plan is quite simple. We have both obtained our permanent residence visa, and will move to New Zealand, to the Wellington area, in December. Although neither of us has secured a job yet, I am actively on the lookout, and confident that something suitable will turn up. NZ and especially Wellington is full of smaller and larger IT firms, and every job vacancy site I check literally posts 2 to 6 positions for (Java) developers a day, at least. However, what I've not been able to find much of yet, is companies or institutes who work in Semantic Web/Ontologies, or who have a need for expertise in that area. If any of you have tips for me (or a job offer ;-)), it would be much appreciated!&lt;br /&gt;
&lt;br /&gt;
I will post updates on developments now and then on this weblog. Oh and yes: we will of course be giving a farewell party later this year ;-)</description><link>http://jeenbroekstra.blogspot.com/2010/08/moving-to-new-zealand.html</link><author>noreply@blogger.com (J1)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4011/4256988382_8f136ec371_t.jpg' height='72' width='72'/></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-1498005454936607288</guid><pubDate>Fri, 11 Jun 2010 09:43:00 +0000</pubDate><atom:updated>2010-06-11T21:43:23.569+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>linkedData</category><category domain='http://www.blogger.com/atom/ns#'>RDF</category><title>wurvoc.org - linked open data for Quality of Life</title><description>&lt;a href="http://www.wurvoc.org/"&gt;&lt;img src="http://www.wurvoc.org/images/logo-wurvoc.png" alt="wurvoc.org" align="right" border="0"/&gt;&lt;/a&gt;
I am proud to announce the official launch of &lt;a href="http://www.wurvoc.org/"&gt;wurvoc.org&lt;/a&gt;. Built by the &lt;a href="http://www.fbresearch.nl/InformationManagement"&gt;Intelligent Systems Group&lt;/a&gt; at &lt;a href="http://www.fbr.wur.nl/"&gt;Wageningen UR Food &amp;amp; Biobased Research&lt;/a&gt;,  the goal of wurvoc.org is to serve as a hub for various vocabularies and semantic web services we have developed and are still developing. Many of these vocabularies (modeled in RDF and OWL) have been built using public funding and we feel it important that this information is also publicly available in a way that is open and reusable.
&lt;br/&gt;
&lt;h4&gt;Vocabularies&lt;/h4&gt;
Currently, wurvoc.org publishes 4 vocabularies:
&lt;ul&gt;
&lt;li&gt;The &lt;a href="http://www.wurvoc.org/vocabularies/OM-MC-1.6/"&gt;Ontology of Units of Measure&lt;/a&gt; models concepts and relations important to quantitative scientific research. It has a strong focus on units and quantities, measurements, and dimensions.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.wurvoc.org/vocabularies/food-additives/"&gt;Food Additives&lt;/a&gt; vocabulary describes substances added to food to improve the flavour, taste, shelf-life, stability et cetera of the food product. Food additives that are approved by EFSA, the European Food Safety Authority are labelled with an E-number.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.wurvoc.org/vocabularies/dairy/"&gt;Dairy&lt;/a&gt;
ontology contains a hierarchy of types of dairy products and provides general information about these products.&lt;/li&gt;
&lt;li&gt;The &lt;a href="http://www.wurvoc.org/vocabularies/drinks"&gt;Drinks&lt;/a&gt; vocabulary contains a classification hierarchy of various types of beverages.&lt;/li&gt;
&lt;/ul&gt; 
&lt;br/&gt;
Our aim is both to publish more vocabularies and data in the near future, and to extend and improve the current vocabularies: although the data is Open, it is not yet truly Linked in the sense that it has very few relations with external datasets. 
&lt;br/&gt;
&lt;h4&gt;Software&lt;/h4&gt;
We've developed the wurvoc publication platform, a set of REST services on top of the &lt;a href="http://www.openrdf.org/"&gt;Sesame&lt;/a&gt; framework. In line with linked data principles, the platform publishes each vocabulary and each vocabulary term on its own URI. For example, an ontology on food additives is available at &lt;a href="http://www.wurvoc.org/vocabularies/food-additives/"&gt;http://www.wurvoc.org/vocabularies/food-additives/&lt;/a&gt;, and the food additive Pectin is reprsented by &lt;a href="http://www.wurvoc.org/vocabularies/food-additives/Pectin"&gt;http://www.wurvoc.org/vocabularies/food-additives/Pectin&lt;/a&gt;.
&lt;br/&gt;&lt;/br&gt;
The platform uses &lt;a href="http://en.wikipedia.org/wiki/Content_negotiation"&gt;HTTP content negotation&lt;/a&gt; to determine the representation format, currently supporting XHTML, RDF/XML, Turtle, N3, NTriples, and TriG (with JSON on the ToDo list).
&lt;br/&gt;
&lt;h4&gt;OUM Web Services&lt;/h4&gt;
Apart from a vocabulary publication platform, wurvoc.org also offers a number of SOAP-based &lt;a href="http://www.wurvoc.org/services/oum.jsp"&gt;web services&lt;/a&gt; on top of the Ontology of Units of Measure (OUM). These web services provide a number of useful functions, including lookup and matching functions as well as more advanced stuff, such as unit conversion or formulaic consistency checking.
&lt;br/&gt;
&lt;h4&gt;Future plans&lt;/h4&gt;
We are aiming to publish the publication platform software as open source as soon as possible. Various improvements are also planned, including a SPARQL endpoint and support for JSON.
&lt;br/&gt;&lt;br/&gt;
I'd very much like to hear your comments on what we've brewed sofar, what you think is good and what you think could be better. I encourage you to reuse our linked data (and would appreciate it if you could let us know if you do).
&lt;br/&gt;
I also plan to keep you up to date on our findings regarding use, performance, and general lessons that we learn after the launch of this project. Watch this space :)</description><link>http://jeenbroekstra.blogspot.com/2010/06/wurvocorg-linked-open-data-for-quality.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-4779951220414401418</guid><pubDate>Fri, 19 Mar 2010 12:53:00 +0000</pubDate><atom:updated>2010-03-20T01:53:20.097+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SPARQL</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>LOD</category><title>Accessing DBpedia's SPARQL endpoint with Sesame</title><description>I'd like to share a tip on using Sesame as a client for SPARQL endpoints. This may be rather trivial to some but perhaps new to others.
&lt;br/&gt;&lt;br/&gt;
We are developing a tool called ROC (Rapid Ontology Construction) (see our &lt;a href="http://www.springerlink.com/content/f265078227m3140p/"&gt;paper@ASWC'08&lt;/a&gt;), which is a tool that allows domain experts to quickly build a basic vocabulary for their domain, re-using existing terminology whenever possible. How this works is that the ROC tool asks the domain expert for a set of keywords that are 'core' terms of the domain, and then queries remote sources for concepts matching those terms. These are then presented to the user, who can select terms from the list, find relations to other terms, and expand the set of terms and relations, iteratively. The resulting vocabulary (or 'proto-ontology', basically a SKOS-like thesaurus) can be used as is, or can be used as input for a knowledge engineer to base a more comprehensive domain ontology on.
&lt;br/&gt;&lt;br/&gt;
ROC is developed on top of Sesame, and up until now we simply supplied the tool with 'remote sources' by adding data to a locally running Sesame repository. In order to act with the LOD cloud, we obviously needed something a bit less awkward, so I started looking into ways to extend the functionality to be able to query linked open data.
&lt;br/&gt;&lt;br/&gt;
Fortunately, I didn't have to look far, because Sesame actually already supports this: &lt;a href="http://www.openrdf.org/doc/sesame2/system/ch08.html"&gt;Sesame's client server protocol is a superset the SPARQL protocol&lt;/a&gt;. This I already knew, but what I hadn't yet tried was to see if that meant you could use Sesame's client libraries to query &lt;i&gt;any&lt;/i&gt; SPARQL endpoint (instead of just connect to a remote Sesame server, which is what it is primarily designed for, after all). And guess what, it turns out that you can! 
&lt;br/&gt;&lt;br/&gt;
Here's a bit of code that connects to &lt;a href="http://dbpedia.org/"&gt;DBPedia&lt;/a&gt;'s SPARQL endpoint and fires a query. The idea is simply to reuse Sesame HTTPRepository class, supply the endpoint URL as the server, and specify no repository:
&lt;pre&gt;
String endpointURL = "http://dbpedia.org/sparql";
HTTPRepository dbpediaEndpoint = 
         new HTTPRepository(endpointURL, "");
dbpediaEndpoint.initialize();

RepositoryConnection conn = 
         dbpediaEndpoint.getConnection();
try {
  String sparqlQuery = 
         " SELECT * WHERE {?X ?P ?Y} LIMIT 10 ";
  TupleQuery query = conn.prepareTupleQuery(SPARQL, query);
  TupleQueryResult result = query.evaluate();

  while (result.hasNext()) {
      ... // do something linked and open
  }
}
finally {
  conn.close();
}
&lt;/pre&gt;
Now, I'm perhaps easily impressed, but to me this was beautifully easy. This makes integrating arbitrary linked open data in most of our Sesame-based tooling (including ROC) completely painless.</description><link>http://jeenbroekstra.blogspot.com/2010/03/accessing-dbpedias-sparql-endpoint-with.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-8590635980763916084</guid><pubDate>Wed, 21 Oct 2009 07:10:00 +0000</pubDate><atom:updated>2009-10-21T20:50:40.206+13:00</atom:updated><title>VU Dies Natalis: Web and Science</title><description>&lt;p&gt;Yesterday, the &lt;a href="http://www.vu.nl/"&gt;VU University Amsterdam&lt;/a&gt; celebrated its &lt;a href="http://www.vu.nl/en/news-agenda/agenda/2009/oct-dec/20-oktober-dies-natalis.asp"&gt;129th birtday&lt;/a&gt; (or Dies Natalis, as universities obviously do not have something as common as a 'birthday'). The theme of this year's celebration was "Web &amp; Science".
&lt;p&gt;The Dies Natalis lecture was delivered by Frank van Harmelen and centered on the question how Web technologies are not just speeding up communication between scientists, but how these new technologies change the way in which we do science itself: is the academic paper, the yardstick of academic achievement, getting out of date, and what other possible yardsticks do we have? Van Harmelen paints a picture of a future landscape of science where data-driven research, empowered by the web, becomes the dominant way of conducting research: the vast amounts of data produced by individual scientists can be shared on the Web and aggregated, integrated, interpreted, and be used to fuel new hypotheses on a scale that was impossible before. In this world, scientific achievement should not just measured by number of published papers or citations, but by number of published data sets or downloads of one's data sets. By using Semantic technologies it may become possible for computers to assist the scientist not just in writing his e-mail and marking up his paper, but in finding relevant data sets, hypotheses, arguments pro and contra, and so on. It would even be possible for the machine to point out contradicting results in two different publications and offer a suggestion for an experiment that shows which result is correct. Science fiction? Perhaps, but van Harmelen argues that at least some of these ideas are closer than we realize.
&lt;p&gt;Highlight of the Dies celebration was the bestowing of an honorary Doctorate to Sir Tim Berners-Lee, not only for his achievement in creating the WWW, but in admiration of his personal commitment to keeping the WWW truly open and universal.&lt;br&gt;
Tim, obviously a bit uncomfortable with the ceremony (which involved him standing in the middle of the podium, wearing a rather peculiar robe, while Guus Schreiber said all sorts of nice things about him), was characteristically humble and gracious in his acceptance, pointing out that all he did was working out a good idea, and that basically the Web came about not just because he had a good idea, but that other people also considered it a good idea and spent tremendous time and effort in making it happen.
&lt;p&gt;The morning session was devoted to the dies symposium, titled "&lt;a href="http://www.vu.nl/nl/nieuws-agenda/agenda/2009/okt-dec/20oktober_symposium_world_wide_web_and_social_development.asp"&gt;The World Wide Web and Social Development&lt;/a&gt;". The focus was very much on how Web technology can be more effectively employed to help developing nations. A highlight was the film and subsequent talk about Yacouba Sawadogo and the efforts in re-greening Africa's drylands, and how more effective communication technology is needed in order to scale up these efforts. Also, a very interesting talk was given about the creation of the &lt;a href="http://www.webfoundation.org/"&gt;WWW Foundation&lt;/a&gt;, which focuses on breaking down barriers to effective access to and use of Web technology in less priviliged countries.
&lt;p&gt;All in all, an inspirational day. The beer (specially brewed for the occasion) was not bad either :)</description><link>http://jeenbroekstra.blogspot.com/2009/10/vu-dies-natalis-web-and-science.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-2192154239350432067</guid><pubDate>Thu, 08 Oct 2009 12:18:00 +0000</pubDate><atom:updated>2010-10-12T21:11:19.855+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>rules</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>SeRQL</category><category domain='http://www.blogger.com/atom/ns#'>RDF</category><title>Simple rules using construct queries in Sesame</title><description>&lt;p&gt;A while ago I put together a simple  rule-based reasoner for Sesame 2 (available in Aduna's &lt;a href="http://repo.aduna-software.org/websvn/listing.php?repname=aduna&amp;amp;path=%2Forg.openrdf%2Fsesame-ext%2Fcustomreasoner%2F"&gt;Sesame extension SVN&lt;/a&gt;). The idea was to have a configurable rule-based reasoner that would reuse Sesame's query engine (in combination with SeRQL/SPARQL CONSTRUCT queries) to perform simple customized entailment.
&lt;p&gt;
The idea is fairly simple: the reasoner works as a stacked SAIL in Sesame's repository configuration (the SAIL is a Sesame internal api that wraps the physical data storage medium). Rules are defined in an RDF format that reuses&lt;a href="http://www.openrdf.org/doc/sesame2/users/ch09.html"&gt; SeRQL&lt;/a&gt; syntax for defining graph patterns. By adding these rules to the Sesame repository the reasoner picks up on them, creates actual SeRQL CONSTRUCT queries out of these rules and then uses Sesame's own query engine to execute the rules, adding the rule result back into the repository.
&lt;p&gt;
For example, a rule defining that an uncle of some person P is the brother of one of the parents of P would look like this (using Turtle syntax):
&lt;pre&gt;
&lt;span style="font-family:courier new;"&gt;ex:defUncle a custom:Rule;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;   rdfs:comment "my parent's brother is my uncle";&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;   custom:head "{X} ex:uncleOf {Y}";&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;   custom:body "{X} ex:brotherOf {} ex:parentOf {Y}" .&lt;/span&gt;
&lt;/pre&gt;
The reasoner would translate this to the following SeRQL query:
&lt;pre&gt;
&lt;span style="font-family:courier new;"&gt; CONSTRUCT {X} ex:uncleOf {Y}&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt; FROM {X} ex:brotherOf {} ex:parentOf {Y} &lt;/span&gt;
&lt;/pre&gt;
For those of you not familiar with SeRQL, the SPARQL equivalent would look like this:
&lt;pre&gt;
&lt;span style="font-family:courier new;"&gt; CONSTRUCT {?X ex:uncleOf ?Y }&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt; WHERE {?X ex:brotherOf ?Z.  ?Z  ex:parentOf  ?Y. } &lt;/span&gt;
&lt;/pre&gt;
I've recently returned to this reasoner, for use in the Tiffany project. In this project, we are developing a Research Management System for researchers in the food industry, and one core concept in this system is a hierarchy of Research Questions and associated activities. Each activity is used by at least one team, and we need to keep a number of things up to date. For example, if a Research Question has an associated activity that is used by team X, the research question itself should also be marked as "used by team X". Moreover, if a research question A has a subquestion B, and that subquestion is used by team X, then research question A should also be marked 'used by team X'.
&lt;p&gt;
Previously we tried to support this from code, by explicitly calculating and asserting RDF triples for the 'isUsedBy' relation whenever an activity is linked to (or unlinked from) a research question, or whenever the research question hierarchy is changed. However, the seemingly simple rules for entailment of isUsedBy quickly become devilishly complex when implemented in an imperative fashion. The function  that deals with this is well over 100 lines of code. Now, compare that to the rule-based approach:
&lt;pre&gt;
&lt;span style="font-family:courier new;"&gt; tifrule:activityUsedBy a custom:Rule ;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;    custom:body "{X} tifn:activity {Y} tifn:isUsedBy {T} " ;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;    custom:head "{X} tifn:isUsedBy {T} " .&lt;/span&gt;
&lt;/pre&gt;
&lt;pre&gt;
 &lt;span style="font-family:courier new;"&gt;tifrule:inheritanceUsedBy a custom:Rule ;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;    custom:body "{X} rdf:type {tifn:ResearchQuestion} ;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;                     tifn:isUsedBy {T} ,&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;             {Y} tifn:hasSubQuestion {X} " ;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;    custom:head "{Y} tifn:isUsedBy {T} "&lt;/span&gt;
&lt;/pre&gt;
Simple.  And from some early tests I ran, remarkably good performance too.
&lt;p&gt;
Next steps are to investigate how the performance of the approach holds up when I add more rules, and when I start doing many updates on the repository (after all, it's nice if querying is quick, but we also expect users to add new data or update existing information, and that requires that we do not have a large performance penalty for updates).</description><link>http://jeenbroekstra.blogspot.com/2009/10/simple-rules-using-construct-queries-in.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-8023806746659463440</guid><pubDate>Wed, 12 Nov 2008 15:03:00 +0000</pubDate><atom:updated>2008-11-13T04:11:44.671+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>SKOS</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>SKOS Browser</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Dh28GpBqd14/SRrwhvaL9hI/AAAAAAAAAA8/RrSGSaJ1CQ4/s1600-h/screen05.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 297px;" src="http://2.bp.blogspot.com/_Dh28GpBqd14/SRrwhvaL9hI/AAAAAAAAAA8/RrSGSaJ1CQ4/s400/screen05.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5267787176615867922" /&gt;&lt;/a&gt;
The latest release of my pet project, the &lt;a href="https://sourceforge.net/projects/sesamewinclient"&gt;Sesame 2 Windows Client&lt;/a&gt; (SWC), has a nice little feature that I though was worth sharing with you: a SKOS hierarchy browser.
&lt;p&gt;
Many ontology editors and viewers have the option of showing a class hierarchy but to my surprise I found very few tools that could display a SKOS broader/narrower hierarchy. So I hacked one together and put it in this client.
&lt;p&gt;
Add your SKOS thesaurus to a Sesame Repository, point the SWC at it, go to the "Browse Hierarchy" tab and choose "SKOS Hierarchy". 
&lt;p&gt;
For now you can only click around in the hierarchy, you can not follow cross-taxonomical links or do any editing.</description><link>http://jeenbroekstra.blogspot.com/2008/11/skos-browser.html</link><author>noreply@blogger.com (J1)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Dh28GpBqd14/SRrwhvaL9hI/AAAAAAAAAA8/RrSGSaJ1CQ4/s72-c/screen05.png' height='72' width='72'/></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-4331173439057228730</guid><pubDate>Thu, 11 Sep 2008 14:21:00 +0000</pubDate><atom:updated>2008-09-12T02:33:11.498+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>.Net</category><title>Sesame 2 Desktop Client</title><description>&lt;p&gt;I recently needed a programming excercise in creating a Windows graphical user interface, and decided to create a simple Sesame 2 client. This has turned out to become quite a useful little tool so I've decided to make it available open source.
&lt;p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Dh28GpBqd14/SMkqytBW7SI/AAAAAAAAAAU/TNG89z4sAj0/s1600-h/screen03.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_Dh28GpBqd14/SMkqytBW7SI/AAAAAAAAAAU/TNG89z4sAj0/s400/screen03.png" alt="" id="BLOGGER_PHOTO_ID_5244770291616771362" border="0" /&gt;&lt;/a&gt; 
The Sesame 2 desktop client is a windows (.Net) application that can communicate with a (remote) Sesame 2 server, perform queries, add/remove data, and so on. It is somewhat similar to the Sesame Workbench application, but it has a couple of nice user-friendly options (such as implicit adding of namespace declarations to your queries, dynamic sorting of the query result, etc).
&lt;p&gt;
You can &lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;downlo&lt;/a&gt;&lt;a href="http://sourceforge.net/projects/sesamewinclient/"&gt;ad it from sourceforge&lt;/a&gt;. Give it a spin, tell me what you think, suggestions most welcome!
&lt;p&gt;
Of and of course my thanks to the &lt;a href="http://sourceforge.net/projects/dotsesame"&gt;dotSesame &lt;/a&gt;people, whose work I've gratefully reused in this
tool.</description><link>http://jeenbroekstra.blogspot.com/2008/09/sesame-2-desktop-client.html</link><author>noreply@blogger.com (J1)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Dh28GpBqd14/SMkqytBW7SI/AAAAAAAAAAU/TNG89z4sAj0/s72-c/screen03.png' height='72' width='72'/></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-8466769707268240924</guid><pubDate>Wed, 02 Jan 2008 09:11:00 +0000</pubDate><atom:updated>2008-01-02T22:12:20.907+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><title>Sesame 2.0 final released (while you weren't looking...)</title><description>&lt;p&gt;While everybody was busy stocking food and drink, the Sesame developers apparently have been at it in overdrive, managing to release the &lt;a href="http://www.openrdf.org/"&gt;final release of Sesame 2.0&lt;/a&gt; just in time for Christmas. From the openRDF.org announcement: 
&lt;blockquote&gt;
&lt;p&gt;
"Thanks to an overwhelming number of people that have tested the previous release candidates and reported any issues that surfaced, we can now proudly present Sesame, version 2.0!
&lt;p&gt;
After the second release candidate, only one serious issue was reported and fixed. We found and fixed some minor, non-critical issues ourselves and made some small improvements here and there, mostly related to HTTP communication and OpenRDF Workbench. All in all, we think the code is now sufficiently tested to call it 2.0-final.
&lt;p&gt;
The development focus will now shift to performance and scalability improvements. An RDBMS-based Sail implementation is currently under development and the first results look very promising. The performance of the native- and memory stores will also be improved. As there hasn't been put a lot of effort into this so far, we expect to achieve good results here."
&lt;/blockquote&gt;
&lt;p&gt;
I just want to take the opportunity to congratulate the people at Aduna with this important milestone! Great job, and thanks!</description><link>http://jeenbroekstra.blogspot.com/2008/01/sesame-20-final-released-while-you.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-4178489872539207057</guid><pubDate>Wed, 12 Dec 2007 09:19:00 +0000</pubDate><atom:updated>2007-12-12T22:47:14.902+13:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Java</category><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>.Net</category><title>.Net is truly like a foreign country...</title><description>...they do things exactly the same there.
&lt;p&gt;
I have recently been involved in a project where an RDF ontology + instance set needs to be exposed through a web UI. Being a Java man myself I was immediately set to start fiddling about with JSP/JSF, Spring MVC and (obviously) a Sesame 2 store. 
&lt;p&gt;
However, in this project my coworkers are .Net developers, so we were left with either me doing all the work myself or somehow figuring out a way of using a Sesame store in a .Net environment. Given that I only have one brain and two arms, and the project has a deadline that falls within the first half of this century, we decided to go for the second option. The web frontent will be in ASP/.Net, the server backend will run Sesame in Java. So, how to get them to talk?
&lt;p&gt;
Our first attempt involved using Spring-WS to write a Web Services wrapper (SOAP messaging, WSDL description, the works) around the Sesame store. However, this wrapper was application-specific (talking in terms of business objects from the application domain rather than being a generic sesame wrapper), and really rather large, clumsy and difficult to maintain, so we decided to try something else.
&lt;p&gt;
Enter &lt;a href="http://ikvm.net/"&gt;IKVM.net&lt;/a&gt;. This is a Java implementation for Mono and .Net that can also be used to do a static porting of Java classes to .Net bytecode (or CIL as they call it in .Net-land). Using a handy little tool called ikvmc I managed (in about half an hour time, mostly spent on trying to figure out which of Sesame 2's impressive collection of jar files to in- and exclude from the process) to create a DLL and he presto! A Sesame 2-compatible HTTP Repository proxy API for .Net Is Born! 
&lt;p&gt;
Using this DLL we can now access, in C#, a remote Sesame server in exactly the same fashion as we would from a Java environment: by simply using Sesame's own Repository API. 
&lt;p&gt;
Perhaps not the most elegant and robust solution - and not nearly as much fun as spending several man-months on painstakingly building a .Net client library from scratch, including the creation of parsers and writers for N3, Turtle, RDFXML, Trig, TriX, SPARQL XML result format, SPARQL, SeRQL, and Sesame 2's transaction serialization format - but in a pinch and on a tight budget quite a satisfactory little workaround.</description><link>http://jeenbroekstra.blogspot.com/2007/12/net-is-truly-like-foreign-country.html</link><author>noreply@blogger.com (J1)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8989580.post-3801679328682321526</guid><pubDate>Fri, 22 Jun 2007 08:25:00 +0000</pubDate><atom:updated>2007-06-22T20:30:04.327+12:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>Sesame</category><category domain='http://www.blogger.com/atom/ns#'>Personal</category><title>Moving on to new things</title><description>Some of you may have heard this already, but I have recently decided to take a new step in my professional career.
&lt;P&gt;
I will be leaving Aduna, effective August 1, and therefore also leave as lead developer of the Sesame framework. I will also leave my position at the Eindhoven University of Technology (TU/e).
&lt;p&gt;
I will take up a position as researcher/developer at the Wageningen UR (the Agrotechnology &amp; Food Science Group, AFSG), where I will take part in projects dealing with the use of SW technology in the agrotechnology and food sector (think biology researchers, or food processing/distribution companies, etc.).
&lt;p&gt;
I have spent a wonderful 8 years at Aduna, working with a great team, and I take enormous personal pride in the fact that I have helped create an RDF framework that is used successfully by so many people. I have every confidence that the Sesame framework will continue to be the success it is today and that all the Sesame developers, both in the Aduna team and outside it, will continue to work on making it even better.</description><link>http://jeenbroekstra.blogspot.com/2007/06/moving-on-to-new-things.html</link><author>noreply@blogger.com (J1)</author></item></channel></rss>