User Guide for Sesame

104
6 User Guide for Sesame Updated for Sesame release 1.2.6 Copyright © 2002-2006 Aduna B.V., Sirma AI Ltd. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in GNU Free Documentation License. Table of Contents Preface: Open, Sesame 1. Introduction: what is Sesame? 1.1. The Sesame library 1.2. The Sesame Server 1.3. Repositories and Inferencing 1.4. An Overview of the Sesame Architecture 2. Installing Sesame 2.1. Library installation 2.2. Server installation 2.2.1. Required software 2.2.2. Installation under Tomcat 4 or 5 2.2.3. Installation under Tomcat 3 2.2.4. Installation under Oracle Container for Java (OC4J) 2.3. Testing Your Installation 2.4. More on the RDBMS 2.4.1. Notes on PostgreSQL 2.4.2. Notes on MySQL 2.4.3. Notes on Oracle 3. Server administration 3.1. Changing the system configuration 3.2. Loading a system configuration 3.3. Storing a system configuration 3.4. Setting the admin password 3.5. Adding and removing user accounts 3.6. Configuring repositories 3.6.1. Editing an existing repository configuration

description

Web semantics and ontology design.

Transcript of User Guide for Sesame

Page 1: User Guide for Sesame

6

User Guide for SesameUpdated for Sesame release 1.2.6

Copyright © 2002-2006 Aduna B.V., Sirma AI Ltd.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in GNU Free Documentation License.

Table of Contents

Preface: Open, Sesame 1. Introduction: what is Sesame?

1.1. The Sesame library 1.2. The Sesame Server 1.3. Repositories and Inferencing 1.4. An Overview of the Sesame Architecture

2. Installing Sesame 2.1. Library installation 2.2. Server installation 2.2.1. Required software 2.2.2. Installation under Tomcat 4 or 5 2.2.3. Installation under Tomcat 3 2.2.4. Installation under Oracle Container for Java (OC4J)2.3. Testing Your Installation 2.4. More on the RDBMS 2.4.1. Notes on PostgreSQL 2.4.2. Notes on MySQL 2.4.3. Notes on Oracle

3. Server administration 3.1. Changing the system configuration 3.2. Loading a system configuration 3.3. Storing a system configuration 3.4. Setting the admin password 3.5. Adding and removing user accounts 3.6. Configuring repositories 3.6.1. Editing an existing repository configuration 3.6.2. Adding new repositories 3.6.3. Removing repositories

4. Advanced repository configuration 4.1. Basic setup 4.1.1. The repository id and title 4.1.2. The Sail stack4.2. Native Sail Indexing 4.3. Custom inferencing 4.3.1. XML syntax

Page 2: User Guide for Sesame

6

4.3.2. Example 4.3.3. Configuration 4.3.4. Notes and Hints4.4. Change Tracking

5. The web interface 5.1. Logging in 5.2. Adding data to a repository

6. The SeRQL query language (revision 1.2) 6.1. Revisions 6.1.1. revision 1.1 6.1.2. revision 1.26.2. Introduction 6.3. URIs, literals and variables 6.3.1. Variables 6.3.2. URIs 6.3.3. Literals 6.3.4. Blank Nodes (R1.2)6.4. Path expressions 6.4.1. Basic path expressions 6.4.2. Path expression short cuts 6.4.3. Optional path expressions6.5. Select- and construct queries 6.6. Select queries 6.7. Construct queries 6.8. The WHERE clause 6.8.1. Boolean constants 6.8.2. Value (in)equality 6.8.3. Numerical comparisons 6.8.4. The LIKE operator (R1.2) 6.8.5. isResource() and isLiteral() 6.8.6. isURI() and isBNode() (R1.2) 6.8.7. AND, OR, NOT 6.8.8. Nested WHERE clauses (R1.2)6.9. Other functions 6.9.1. label(), lang() and datatype() 6.9.2. namespace() and localName() (R1.2)6.10. The LIMIT and OFFSET clauses 6.11. The USING NAMESPACE clause 6.12. Built-in predicates 6.13. Set combinatory operations 6.13.1. UNION (R1.2) 6.13.2. INTERSECT (R1.2) 6.13.3. MINUS (R1.2)6.14. NULL values 6.15. Query Nesting 6.15.1. The IN operator (R1.2) 6.15.2. ANY and ALL (R1.2) 6.15.3. EXISTS (R1.2)6.16. Example SeRQL queries 6.16.1. Query 1 6.16.2. Query 2 6.16.3. Query 36.17. Comments/feedback 6.18. References

Page 3: User Guide for Sesame

6

6.19. SeRQL grammar7. The Sesame API

7.1. An Overview of the Sesame Architecture 7.2. The Repository API 7.2.1. Accessing a repository 7.2.2. Querying a repository 7.2.3. Adding RDF data to a repository7.3. The Graph API 7.3.1. Creating an empty Graph and adding statements to it 7.3.2. Adding/removing a Graph to/from a repository 7.3.3. Creating a Graph for an existing repository 7.3.4. Creating a graph using graph queries 7.3.5. Using graphs and graph queries for updates

8. Communication protocols 8.1. Communicating over HTTP 8.1.1. Logging in 8.1.2. Logging out 8.1.3. Requesting a list of available repositories 8.1.4. Evaluating a SeRQL-select, RQL or RDQL query 8.1.5. Evaluating a SeRQL-construct query 8.1.6. Extracting RDF from a repository 8.1.7. Uploading data to a repository 8.1.8. Adding data from the web to a repository 8.1.9. Clearing a repository 8.1.10. Removing statements

9. Frequently Asked Questions 9.1. General Questions 9.1.1. I've got a Sesame-related question, where can I get an answer? 9.1.2. Something goes wrong when I use Sesame, what do I do? 9.1.3. How do I report a bug? 9.1.4. Why doesn't Sesame support $FEATURE? 9.1.5. I need $FEATURE right now! 9.1.6. Can you keep me informed of any Sesame-related news? 9.1.7. Is this user guide the only documentation for Sesame?9.2. Troubleshooting 9.2.1. I get a "HTTP error 500" message in the toolbar frame 9.2.2. I get a "HTTP error 500" message in the main frame 9.2.3. I get "error while adding new triples: Invalid byte 2 of 3-byte UTF-8 sequence" 9.2.4. I get a warning: "Unable to set namespace prefix 'foo' for namespace ..." 9.2.5. My in-memory repository is very slow and/or runs out of memory 9.2.6. On upload I get an error "java.lang.IllegalStateException: Post too large" 9.2.7. Can not evaluate directSubClassOf on a non-inferencing repository

A. GNU Free Documentation License A.1. PREAMBLE A.2. APPLICABILITY AND DEFINITIONS A.3. VERBATIM COPYING A.4. COPYING IN QUANTITY A.5. MODIFICATIONS A.6. COMBINING DOCUMENTS A.7. COLLECTIONS OF DOCUMENTS A.8. AGGREGATION WITH INDEPENDENT WORKS

Page 4: User Guide for Sesame

6

A.9. TRANSLATION A.10. TERMINATION A.11. FUTURE REVISIONS OF THIS LICENSE A.12. How to use this License for your documents

Preface: Open, SesameWhen they were out of sight Ali Baba came down, and, going up to the rock, said, "Open, Sesame." The door at once opened, and Ali Baba, entering, found himself in a large cave, lighted from a hole in the top, and full of all kinds of treasure--rich silks and carpets, gold and silver ware, and great bags of money. He loaded his three asses with as many of the bags of gold as they could carry; and, after closing the door by saying, "Shut, Sesame," made his way home.

--Tales of 1001 Nights

In February 2000 the European IST project On-To-Knowledge kicked off. The goal of this project was to provide tools and a methodology for “content-driven knowledge management through evolving ontologies”.

In this project, the Dutch company Aduna (then known as Aidministrator Nederland b.v.) developed Sesame. Sesame fullfills the role of storage and retrieval middleware for ontologies and metadata expressed in RDF and RDF Schema. Another tool developed in On-To-Knowledge is OMM, the Ontology Middleware Module, which was developed by OntoText. OMM is an extension of Sesame that adds features such as change tracking and improved security.

Currently, Sesame and OMM are being further developed as an open source software product, by Aduna in cooperation with and partially funded by the NLNet Foundation, and by OntoText. The goal is to provide a stable, efficient and scalable middleware platform for storing, retrieving, manipulating and managing ontologies and metadata stored in RDF, RDF Schema and more expressive languages like OWL.

We aren't there yet, but it's looking good, we hope. This document is here to provide you, the Sesame user, with helpful information on how to deploy Sesame in various contexts, such as a database add-on in a client-server setting, or as a Java library to add functionality to stand-alone applications.

We hope this document will get you started, and of course we hope that you find Sesame easy to use and, well, good. Being an open source product in development also means that we are very keen on receiving feedback from our users. If you have questions, comments, if you think something is wrong with Sesame, or you have a good idea on how to improve it, please let us know. Contact us through the forums and/or issue tracker that are available on the Sesame website: www.openrdf.org.

We wish to conclude with a big thank you to all of you who have been (and indeed still are) supportive of this project, in particular Teus Hagen, Wytze van der Raay, Frank van Harmelen, Andy Seaborne, Peter Mika and Jacco van Ossenbruggen. Special thanks go to Holger Lausen for providing the Oracle implementation of the RDF Sail.

The Sesame and OMM development teams.

Chapter 1. Introduction: what is Sesame?Table of Contents

Page 5: User Guide for Sesame

6

1.1. The Sesame library 1.2. The Sesame Server 1.3. Repositories and Inferencing 1.4. An Overview of the Sesame Architecture

Sesame is an open source Java framework for storing, querying and reasoning with RDF and RDF Schema. It can be used as a database for RDF and RDF Schema, or as a Java library for applications that need to work with RDF internally. For example, suppose you need to read a big RDF file, find the relevant information for your application, and use that information. Sesame provides you with the necessary tools to parse, interpret, query and store all this information, embedded in your own application if you want, or, if you prefer, in a seperate database or even on a remote server. More generally: Sesame provides application developers a toolbox that contains useful hammers, screwdrivers etc. for doing 'Do-It-Yourself' with RDF.

In the next sections, we will take a closer look at Sesame.

1.1. The Sesame libraryThe Sesame library consists of a set of java archives:

sesame.jar. The Sesame core classes. rio.jar. Rio (RDF I/O) is a set of parsers and writers for different RDF

serialization formats (RDF/XML, Turtle, N-Triples).

openrdf-model.jar. Shared interfaces and classes for the RDF model.

openrdf-util.jar. Shared utility classes.

These archives (which are located in the lib/ directory) contain Java classes ready for use in your own application. In Chapter 7, The Sesame API, you can find instructions and examples on how to use Sesame in your own code: how to do queries, how to add and remove data, etc.

1.2. The Sesame ServerSesame can be used as a Server with which client applications (or human users) can communicate over HTTP (see Figure 1.1, “Sesame Server”). Sesame can be deployed as a Java Servlet Application in Apache Tomcat, a webserver that supports Java Servlets and JSP technology.

Figure 1.1. Sesame Server

Page 6: User Guide for Sesame

6

In Chapter 2, Installing Sesame, you will find detailed information on how to install Sesame as a server.

1.3. Repositories and InferencingA central concept in the Sesame framework is the repository. A repository is a storage container for RDF. This can simply mean a Java object (or set of Java objects) in memory, or it can mean a relational database. Whatever way of storage is chosen however, it is important to realize that almost every operation in Sesame happens with respect to a repository: when you add RDF data, you add it to a repository. When you do a query, you query a particular repository.

Sesame, as mentioned, supports RDF Schema inferencing. This means that given a set of RDF and/or RDF Schema, Sesame can find the implicit information in the data. Sesame supports this by simply adding all implicit information to the repository as well when data is being added.

It is important to realize that inferencing in Sesame is associated with the type of repository that you use. Sesame supports several different types of repositories (see Chapter 4, Advanced repository configuration for details). Some of these support inferencing, others do not. Whether you want Sesame to do inferencing for you is a choice that depends very much on your application.

1.4. An Overview of the Sesame ArchitectureIn Figure 1.2, “The Sesame architecture” an overview of Sesame's overall architecture is given.

Figure 1.2. The Sesame architecture

Starting at the bottom, the Storage And Inference Layer, or SAIL API, is an internal Sesame API that abstracts from the storage format used (i.e. whether the data is stored in an RDBMS, in memory, or in files, for example), and provides reasoning support. SAIL implementations can also be stacked on top of each other, to provide functionality such as caching or concurrent access handling. Each Sesame repository has its own SAIL object to represent it.

On top of the SAIL, we find Sesame's functional modules, such as the SeRQL, RQL and RDQL query engines, the admin module, and RDF export. Access to these functional modules is available through Sesame's Access APIs, consisting of two seperate parts: the Repository API and the Graph API. The

Page 7: User Guide for Sesame

6

Repository API provides high-level access to Sesame repositories, such as querying, storing of rdf files, extracting RDF, etc. The Graph API provides more fine-grained support for RDF manipulation, such as adding and removing individual statements, and creation of small RDF models directly from code. The two APIs complement each other in functionality, and are in practice often used together.

The Access APIs provide direct access to Sesame's functional modules, either to a client program (for example, a desktop application that uses Sesame as a library), or to the next component of Sesame's architecture, the Sesame server. This is a component that provides HTTP-based access to Sesame's APIs. Then, on the remote HTTP client side, we again find the access APIs, which can again be used for communicating with Sesame, this time not as a library, but as a server running on a remote location.

While each part of the Sesame code is publicly available and extensible, most developers will be primarily interested in the Access APIs, for communicating with a Sesame RDF model or a Sesame repository from their application. In Chapter 7, The Sesame API, these APIs are described in more detail, through several code examples.

Chapter 2. Installing SesameTable of Contents

2.1. Library installation 2.2. Server installation

2.2.1. Required software 2.2.2. Installation under Tomcat 4 or 5 2.2.3. Installation under Tomcat 3 2.2.4. Installation under Oracle Container for Java (OC4J)

2.3. Testing Your Installation 2.4. More on the RDBMS

2.4.1. Notes on PostgreSQL 2.4.2. Notes on MySQL 2.4.3. Notes on Oracle

Sesame can deployed in several ways. The two most common scenarios include deployment as a java library, or deployment as a server. In this chapter, both installation scenarios are explained.

2.1. Library installationTo use Sesame as a library in a java application, one needs the Sesame jar files. These are:

sesame.jar. The Sesame core classes. rio.jar. Rio (RDF I/O) is a set of parsers and writers for different RDF

serialization formats (RDF/XML, Turtle, N-Triples).

openrdf-model.jar. Shared interfaces and classes for the RDF model.

openrdf-util.jar. Shared utility classes.

These files can be found in the lib directory of the binary download. Simply including them in your classpath will allow you to use the functionality of Sesame in your own Java application.

Sesame requires Java 2, version 1.4 or newer, to function properly.

Page 8: User Guide for Sesame

6

If you intend to use client/server communication over HTTP, then you will additionally need the following third-party libraries:

Jakarta Commons FileUpload, release 1.2. Jakarta Commons IO, release 1.3.

These third-party libraries can be found in the ext/ directory of the source distribution of Sesame, and are also included in the library directory of the Sesame Web Archive (sesame.war). More information about these libraries, including license information, can be found in the file doc/thirdparty.txt.

For more information on how to use Sesame as a library, see Chapter 7, The Sesame API

2.2. Server installation2.2.1. Required software

The Sesame server requires the following software:

Sesame itself A Java servlet container (running Java 2, version 1.4 or newer) for running

the Sesame servlets

Sesame should be able to run on any Java servlet container that supports the Servlet 2.2 and JSP 1.1 specifications, or newer. So far, it has been tested with Tomcat and, in the case of Oracle, with OC4J. It has also been reported to work without problems on BEA WebLogic 8.1 SP2 and Jetty. Please post any reports about compatibility with other servlet containers to our forums.

Sesame has several options for storage of RDF data: it can store data in main-memory (optionally with a dump to file for persistence), it can store data on disk in a dedicated file structure, or it can store data in a relational database. See section More on the RDBMS for more info about the last option.

2.2.2. Installation under Tomcat 4 or 5

The following steps describe the easiest procedure to install Sesame on Tomcat 4.x or 5.x. The described procedure doesn't require any reconfiguration of Tomcat itself, but it might not be the best option for you. Please see the documentation that came with your copy of Tomcat if you want more fine-grained control over where and how Sesame should be installed.

1. Install Tomcat. This usually consists of downloading the binary Tomcat distribution from http://jakarta.apache.org/tomcat and installing it in an appropriate location on your disk (we will refer to this location as [TOMCAT_DIR] here). Please see the Tomcat documentation for more information on how to get it up and running.

2. Go to the web applications directory ([TOMCAT_DIR]/webapps/ by default) and create a directory 'sesame' there.

3. Extract the sesame.war file (which can be found in the lib directory of the binary Sesame distribution) to the newly created 'sesame' directory. You can do this on the command line by changing directories to the new 'sesame' directory and executing the command jar -xf [PATH/TO/]sesame.war. You can also use a program like WinZip or unzip

Page 9: User Guide for Sesame

6

to extract the archive. We will refer to the directory where you have extracted the sesame.war file as [SESAME_DIR] in the rest of this document.

4. In case you are planning to use a database with Sesame, copy the appropriate JDBC-driver file(s) to the directory [SESAME_DIR]/WEB-INF/lib/.

5. Copy the file [SESAME_DIR]/WEB-INF/system.conf.example to [SESAME_DIR]/WEB-INF/system.conf. NOTE: only do this for a fresh install of Sesame, if you are upgrading you will already have a config file, and copying the example over it will destroy your existing configuration. The example file contains some repository entries for different Sails and databases, and one user account. The file may require some modifications in order to work on your machine. Please check out Server administration if you want to learn how to do this.

6. (Re)start your Tomcat server and Sesame should now be up and running. You can access the Sesame web interface at http://[MACHINE_NAME]:8080/sesame.

2.2.3. Installation under Tomcat 3

Installation of Sesame under Tomcat 3 is almost identical to the procedure described above. It requires one additional step:

1. Perform the steps described in Installation under Tomcat 4 or 5. 2. Copy the file [SESAME_DIR]/WEB-INF/lib/web.xml-2.2 over the existing

web.xml file and (re)start your Tomcat server.

2.2.4. Installation under Oracle Container for Java (OC4J)

Sesame has been tested with OC4J v9.0.3.0. The installed procedure differs from the standard installation procedure.

Create a directory [OC4J_HOME]/j2ee/home/applications/sesame and extract the sesame.war file there. We will refer to the directory where you have installed Sesame as [SESAME_DIR] in the rest of this document.

Add the following line to [OC4J_HOME]/j2ee/home/config/application.xml:

<web-module id="sesame" path="../../home/applications/sesame"/> Add the following line to [OC4J_HOME]/j2ee/home/config/http-web-

site.xml:

<web-app application="default" name="sesame" root="/sesame"/>

2.3. Testing Your InstallationIf you have followed the installation instruction described in the previous section, the Sesame server should now be up-and-running. Pointing a browser to the location where you have installed Sesame (e.g. http://[MACHINE_NAME]:8080/sesame/ if you have installed Sesame under Tomcat as described in this document) should now display the Sesame web interface.

You should also test whether the Sesame servlets are running correctly, and whether Sesame can talk to the RDBMS (if applicable). Select one of the repositories that you have configured and press

Page 10: User Guide for Sesame

6

'Go>>'. Click on the 'Add (www)' link in the toolbar at the top of the window, and try to upload the test.rdf file from Sesame's admin directory (e.g. http://[MACHINE_NAME]:8080/sesame/admin/test.rdf). You can do this by typing this URL in the first text field and by clicking on the 'Add data' button after that.

If the data-upload was successful, you should also be able to extract the uploaded data. Click on the 'Extract' link in the toolbar and press the 'Extract' button. This should yield an RDF document describing all classes and properties in the repository.

Sesame has been successfully installed if all of this works. You can remove or reconfigure the test user account and repository if you want. If you haven't done so already, you can take a look at the next chapter for information on how to add and remove user accounts and repositories to/from Sesame.

2.4. More on the RDBMSSesame has an RDBMS-Sail that uses an RDBMS for storing RDF data. Currently, this Sail supports PostgreSQL, MySQL, Microsoft SQL Server and Oracle databases. The first two RDBMS's are open source and are freely available on the Internet. Please check the documentation delivered with these databases for any questions on how to get them installed.

Sesame's RDBMS Sail has been extensively tested in combination with MySQL and PostgreSQL. The RDBMS Sail used to perform much better in combination with MySQL than with PostgreSQL, but recent versions of PostgreSQL have shown major performance increases. These two RDBMS's now have comparable performance, with PostgreSQL having an edge over MySQL where it concerns the evaluation of complex queries. The SQL Server- and Oracle support are third-party contribution and we have no comparitive data on their performance.

2.4.1. Notes on PostgreSQL

Recent versions of PostgreSQL are a lot faster than the 7.1 version that Sesame was originally developed against. The most recents tests have been done using version 8.1.4. If possibly, you should use the newest possible (stable) version of PostgreSQL that is available.

JDBC-drivers for PostgreSQL can be found at http://jdbc.postgresql.org, but these also come bundled with (some of) the PostgreSQL installation packages.

Make sure that the PostgreSQL server is running with the TCP/IP connections enabled. If TCP/IP is not enabled, the JDBC-driver will not be able to talk to the server.

pgAdmin is an excellent tool to administer a PostgreSQL server (for those who don't mind using GUIs).

The RDBMS Sail will need an (empty) database on the PostgreSQL server, as well as a user account that has access to (or owns) that database. You need to create these manually, for example by using the pgAdmin tool mentioned above. In most cases, the encoding of the new database should be set to 'UTF8'. The RDBMS Sail will take care of creating the required tables and indexes when first run. We'll assume that the user account is called 'sesame' in the rest of this document.

Page 11: User Guide for Sesame

6

2.4.2. Notes on MySQL

Sesame tries to use the character set features that were introduced in MySQL 4.1 to properly handle non-ASCII characters. Sesame will automatically detect whether these features are available and will fall back to using BLOBs when an older version of MySQL is used. In that case, Sesame will not be able to properly handle non-ASCII characters in literals and namespace names.

Sesame's RDBMS Sail makes extensive use of the TRUNCATE command. Unfortunately, this command is mapped to the much slower DELETE command for InnoDB tables in pre-MySQL 5.0.3 releases. To achieve reasonable performance one should use MySQL 5.0.3 or newer, or configure MySQL to use the older MyISAM tables instead of InnoDB tables.

Several people have reported problems with 4.x and early 5.0.x version of MySQL, especially with versions that came pre-installed with Linux distributions. So far, all these problems were resolved by installing the most recent stable version of MySQL and its JDBC-driver. Please try this before reporting problems when using unstable/beta releases.

MySQL Administrator is an great tool to administer a MySQL server (for those who don't mind using GUIs).

The RDBMS Sail will need an (empty) database on the MySQL server, as well as a user account that has access to that database. You need to create these manually, for example by using the MySQL Administrator tool mentioned above. In most cases, the encoding of the new database should be set to 'UTF8'. The RDBMS Sail will take care of creating the required tables and indexes when first run. We'll assume that the user account is called 'sesame' in the rest of this document.

2.4.3. Notes on Oracle

Note: We do not have first-hand experience with using the RDBMS Sail on Oracle. The comments below are based on feedback that we have received from users.

The RDBMS Sail has been tested with Oracle 9i and newer, Oracle 8i does not work due to lack of support for left (outer) joins. Oracle 9.2.0.1.0 has a bug affecting ANSI-style left (outer) joins which makes it incompatible with Sesame. This bug has been fixed in version 9.2.0.4.0.

The Oracle JDBC driver can be found at [ORACLE_HOME]/jdbc/lib/classes12.jar or at http://otn.oracle.com/.

You will have to create a user with appropriate rights (resource + connect).

If ORA-0150 (maximum key length (...) exceeded) is raised during creation of your DB-Schema the reason might be in your DB configuration. You have got the following options:

o Increase db_block_size in your init.ora and create a new database to allow larger index columns (refer to Oracle Note:136158.1).

o Edit Oracle.java in package org.openrdf.sesame.sailimpl.rdbms and alter the size of the Datatype NAME and LABEL. The new size can be calculated from the error message, e.g.: "ORA-01450

Page 12: User Guide for Sesame

6

maximum key length (3166) exceeded at varchar(3157)" (length-9 for block overhead).

Chapter 3. Server administrationTable of Contents

3.1. Changing the system configuration 3.2. Loading a system configuration 3.3. Storing a system configuration 3.4. Setting the admin password 3.5. Adding and removing user accounts 3.6. Configuring repositories

3.6.1. Editing an existing repository configuration 3.6.2. Adding new repositories 3.6.3. Removing repositories

3.1. Changing the system configurationSesame's configuration is specified in the file [SESAME_DIR]/WEB-INF/system.conf. You can edit this configuration file locally on your Sesame server using the Configure Sesame! tool available in [SESAME_DIR]/WEB-INF/bin/. You can start the tool with the command configSesame.bat (on Windows) or configSesame.sh (on UNIX. Note that in UNIX you may have to give the file executable permissions first). Alternatively, you can download Configure Sesame! as a standalone tool from the Sesame project website, and install it on a remote client machine to configure your Sesame server over HTTP.

It is possible to edit the system configuration manually with an XML or text editor, but we do not recommend this.

3.2. Loading a system configurationFigure 3.1. Configure Sesame!

Page 13: User Guide for Sesame

6

When you have started Configure Sesame! (Figure 3.1, “Configure Sesame!”), load the file system.conf. If you want to configure a running Sesame server, you can do this by loading the file directly from the server (menu option [File]-->[Load from server...], see Figure 3.2, “Loading the configuration from a running server”). If the server is not running, you can open the file from disk (menu option [File]-->[Open file...]).

Figure 3.2. Loading the configuration from a running server

If this is a fresh installation of Sesame, the admin password is still the default password. In this case, you will need to enter "admin" as the Current admin password to load the configuration. If this is not a fresh installation of Sesame you will need to enter the admin password that you have specified earlier.

3.3. Storing a system configurationWhen you have modified the configuration, you can store it on disk (menu option [File]-->[Save file as...]), or you can send it directly to a running Sesame server (menu option [File]-->[Send to server...], see Figure 3.3, “Send a configuration to a running server”). Notice that if you use the "Send to Server" option, the changes to the configuration will be applied to the running server immediately. You do not need to restart or refresh the server separately.

Figure 3.3. Send a configuration to a running server

Page 14: User Guide for Sesame

6

3.4. Setting the admin passwordIf you have not changed the admin password before, it's probably a good idea to set one right now. To set the admin password, go to the server tab (Figure 3.4, “The Server tab”) and fill in an admin password.

Figure 3.4. The Server tab

3.5. Adding and removing user accountsTo add a user account to Sesame, perform the following steps:

1. Open the Tab "Users" (Figure 3.5, “The "Users" configuration tab”). You see an overview of currently configured users.

Figure 3.5. The "Users" configuration tab

Page 15: User Guide for Sesame

6

2. Click the "Add user" icon on the bottom of the window. A new entry is added to the overview.

3. Enter the credentials for the new user, hitting Enter to go to the next column.

To remove a user account, simply select the user you wish to remove and click the "Remove user" button in the bottom right of the window.

3.6. Configuring repositoriesYou can configure existing repositories, add new ones and of course remove repository configuration using Configure Sesame!.

In this section, we introduce the basic use of Configure Sesame! In Chapter 4, Advanced repository configuration we go into the details of repository config parameters.

3.6.1. Editing an existing repository configuration

1. Open the "Repositories" tab (Figure 3.6, “The "Repository" tab”). Select the repository you wish to configure and click the "Repository details" button on the bottom left.

Figure 3.6. The "Repository" tab

Page 16: User Guide for Sesame

6

2. In the Repository details window (Figure 3.7, “The "Repository details" window”), you can edit several parameters of your repository. The top part of the window shows the Sail stack, the bottom part shows the parameters of the selected Sail in the stack. In most cases, you will only want to edit the parameters of the bottom sail in the stack (for more information about the Sail stack and configuration parameter see Chapter 4, Advanced repository configuration).

Figure 3.7. The "Repository details" window

Page 17: User Guide for Sesame

6

The Repository details window also allows you to change the access rights of users to a repository. To change the access rights, click the "Access rights" tab, where you can edit the rights of existing users or add new users (Figure 3.8, “The "access rights" tab”). The entry anonymous is a special entry that represents users who do not log in. Giving this entry access rights means that anybody can access the repository.

Figure 3.8. The "access rights" tab

3.6.2. Adding new repositories

Page 18: User Guide for Sesame

6

The easiest way to add a new repository is to "clone" an existing repository. Use the "Clone" button on the repository tab (Figure 3.6, “The "Repository" tab”) to do this. This creates a copy of the currently selected repository configuration, which you can then edit. Take special care to change details such as the jdbcUrl or file attributes of the Sail (see Chapter 4, Advanced repository configuration).

Alternatively, you can add a new repository by using the "Add" button and filling in all the information by yourself.

3.6.3. Removing repositories

To remove a repository, simply open the repository tab (Figure 3.6, “The "Repository" tab”), select a repository and click the "Remove" button on the bottom right.

Chapter 4. Advanced repository configurationTable of Contents

4.1. Basic setup 4.1.1. The repository id and title 4.1.2. The Sail stack

4.2. Native Sail Indexing 4.3. Custom inferencing

4.3.1. XML syntax 4.3.2. Example 4.3.3. Configuration 4.3.4. Notes and Hints

4.4. Change Tracking

When setting up a repository in Sesame, you can make a number of choices: should the repository support versioning or security, or should it be as fast as possible? What database will it use, or will it be in-memory?

In this chapter, we look at several of these configuration options in more detail.

4.1. Basic setupThe setup for each Sesame repository is configured using Configure Sesame!. As we have already seen in Server administration, this configuration tool allows tweaking of numerous parameters, which we will discuss in more detail here.

4.1.1. The repository id and title

In the repository tab (Figure 3.6, “The "Repository" tab”), the repository id and title are declared. The id is how the repository will be known by Sesame: all client access will need to use this identifier.

The title is for human convenience and can be used to give a short description of the repository's purpose. Clients such as the web interface use it to represent the repository to the end user.

4.1.2. The Sail stack

Page 19: User Guide for Sesame

6

The most important part of the repository configuration is the sail stack, which can be found in the "repository details" screen (Figure 3.7, “The "Repository details" window”). Here, you configure where the actual repository storage resides, whether or not inferencing, security and versioning, etc. should be used, and what additional options are needed.

The sail stack is represented top-to-bottom. In the example, we see two sail declarations: org.openrdf.sesame.sailimpl.sync.SyncRdfSchemaRepository and org.openrdf.sesame.sailimpl.rdbms.RdfSchemaRepository. The first sail is stacked on top of the second one (which means that it operates by calling methods on the Sail underneath it). The second sail is the base sail: it is the lowest of the stack and does not operate on another sail, but directly on the actual data source. In this example, the base sail is an RDF Schema-aware driver for a relational database that supports (currently) MySQL (3.23.47 and higher), PostgreSQL (7.0.2 and higher) and Oracle 9i.

The SyncRdfSchemaRepository is optional, but we strongly recommend using it. This Sail handles concurrent access issues, without it Sesame would behave unpredictably when several users access the repository simultaneously.

Other base sails to choose from include:

org.openrdf.sesame.sailimpl.rdbms.RdfRepository: an non-inferencing driver for relational database storage.

org.openrdf.sesame.sailimpl.omm.versioning.VersioningRdbmsSail: an inferencing driver for relational database storage that supports change tracking.

org.openrdf.sesame.sailimpl.memory.RdfRepository: a non-inferencing driver for storage in main memory.

org.openrdf.sesame.sailimpl.memory.RdfSchemaRepository: an inferencing driver for storage in main memory that support RDF and RDF Schema entailment.

org.openrdf.sesame.sailimpl.nativerdf.NativeRdfRepository: a non-inferencing driver for storage directly on disk.

All base sails that work on relational databases need a number of parameters to function:

jdbcDriver identifies the JDBC (Java Data Base Connectivity) driver that is to be used to access the database. In the example, com.mysql.jdbc.Driver, the standard MySQL JDBC driver, is used.

jdbcUrl identifies the location of the database through a URL. The precise syntax of this URL is DBMS-dependent. An example URl for a MySQL database would be jdbc:mysql://localhost:3306/testdb. This specifies a database names testdb on a MySQL server running on localhost, which uses port 3306 for communication. The last part of the URL identifies the name of the database (in this case testdb). Note that this is the name of the database as it is known to the DBMS, and that it is not related to the Sesame repository id (though it might be convenient to assign them identical names).

user identifies a username with which Sesame can access the database. This must therefore be a user which is known to the DBMS, and which has been granted access rights (see also Server administration).

Page 20: User Guide for Sesame

6

password identifies a password with which Sesame can access the database. This must therefore be a password that matches the username configured in the user parameter.

The RDBMS-based sails also take some optional parameters:

dependency-inferencing indicates whether the dependency-based truth maintenance should be used (possible values are 'yes' and 'no', the default is 'yes'). Dependency-based truth maintenance speeds up removal operations, but performance of uploads is slowed down.

commitInterval indicates a number of triples to be added before the sail does an in-between commit during upload of large datasets. The default is '1000'. This figure can be tweaked to improve upload performance.

The memory-based sails take four optional parameters:

file specifies a file in which the in-memory repository stores its contents on local disk. This file is automatically saved and reloaded on (re)start of the server.

dataFormat specifies the format of the data in the file. Legal values are 'rdfxml' (the default), 'ntriples' and 'turtle'.

compressFile specifies whether the file used for storage should be compressed with gzip.

syncDelay specifies the time (in milliseconds) to wait after a transaction was commited before writing the changed data to file. Setting this variable to '0' (the default value) will force a file sync immediately after each commit. A negative value will deactivate file synchronization until the Sail is shut down. A positive value will postpone the synchronization for at least that amount of milliseconds. If in the meantime a new transaction is started, the file synchronization will be rescheduled to wait for another syncDelay ms. This way, bursts of transaction events can be combined in one file sync, improving performance.

The native sail has one required parameter:

dir specifies the directory that can be used by the native sail to store its files.

The native sail also has an optional triple-indexes parameter, with which one can specify the indexing strategy the native sail should take. We will explain this in more detail in the next section.

4.2. Native Sail IndexingThe native store uses B-Trees for indexing statements, where the index key consists of three fields: subject (s), predicate (p) and object (o). The order in which each of these fields is used in the key determines the usability of an index on a specify triple query pattern: searching triples with a specific subject in an index that has the subject as the first field is signifantly faster than searching these same triples in an index where the subject field is second or third. In the worst case, the 'wrong' triple pattern will result in a sequential scan over the entire set of triples.

Page 21: User Guide for Sesame

6

By default, the native store only uses a single index, with a subject-predicate-object key pattern. However, it is possible to define different indexes for the native store, using the triple-indexes parameter. This can be used to optimize performance for query patterns that occur frequently.

The subject-, predicate- and object fields are represented by the characters 's', 'p' and 'o', respectively. Indexes can be specified by creating 3-letter words from these three characters. Multiple indexes can be specified by separating these words with comma's, spaces and/or tabs. For example, the string "spo, pos" specifies two indexes; a subject-predicate-object index and a predicate-object-subject index.

Of course, creating multiple indexes speeds up querying, but there is a cost factor to take into account as well: adding and removing data will become more expensive, because each index will have to be updated. Also, each index takes up additional disk space.

The native store automatically creates/drops indexes upon (re)initialization, so the parameter can be adjusted and upon the first refresh of the configuration the native store will change its indexing strategy, without loss of data.

4.3. Custom inferencingThe basic set of RDFS inference rules (as defined in the RDF(S) MT semantics) sometimes can be insufficient to build custom applications. For example, in some applications there is a need for defining one's own transitive, symmetric or inverse properties. Providing an infrastructure to define such custom inference rules helps developers to tune the Sesame inferencer so it can suit better in the application.

Since Sesame release 0.95, we provide an alternative inferencer that works with org.openrdf.sesame.sailimpl.rdbms.RdfSchemaRepository SAIL. This custom inferencer can be initialized with a set of axiomatic triples and inference rules defined in an external file. The format of these definitions is very simple and intuitive and it is explained in greater detail in the next section.

Support for inter-rule dependency is also added to the customizable inferencer. Now we can state explicitly which rules are triggered if a rule infers a new statement. This information is given within an additional tag within the 'rule' one - 'triggers_rule'. It consists of several 'rule' tags with a name attribute specifying the rules affected.

4.3.1. XML syntax

The definition file is in XML and should conform to the following DTD:

<!DOCTYPE InferenceRules [ <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'> <!ENTITY daml 'http://www.daml.org/2001/03/daml+oil#'>

<!ELEMENT InferenceRules (axiom | rule)*>

<!ELEMENT axiom (subject, predicate, object)>

<!ELEMENT rule ((premise+, consequent, triggers_rule?) | EMPTY)> <!ATTLIST rule name CDATA #REQUIRED>

<!ELEMENT premise (subject, predicate, object)> <!ELEMENT consequent (subject, predicate, object)> <!ELEMENT triggers_rule (rule)*>

Page 22: User Guide for Sesame

6

<!ELEMENT subject EMPTY> <!ATTLIST subject var CDATA #IMPLIED uri CDATA #IMPLIED pattern CDATA #IMPLIED escape CDATA #IMPLIED type (resource) #IMPLIED>

<!ELEMENT predicate EMPTY> <!ATTLIST predicate var CDATA #IMPLIED uri CDATA #IMPLIED pattern CDATA #IMPLIED escape CDATA #IMPLIED type (resource) #IMPLIED>

<!ELEMENT object EMPTY> <!ATTLIST object var CDATA #IMPLIED uri CDATA #IMPLIED pattern CDATA #IMPLIED escape CDATA #IMPLIED type (resource) #IMPLIED>]>

If a 'uri' attribute is present within the 'subject', 'predicate' or 'object' tags, its value is assumed to be a name of a resource.

The value of the 'var' attribute of the above tags gives the name of that variable. This attribute cannot be used within an 'axiom' tag.

For example, here are two of the axiomatic triples, as they are defined in the RDF(S) MT semantics. They appear in the configuration file like this:

<axiom><subject uri="&rdfs;subPropertyOf"/> <predicate uri="&rdfs;domain"/> <object uri="&rdf;Property"/>

</axiom><axiom>

<subject uri="&rdfs;subPropertyOf"/><predicate uri="&rdfs;range"/><object uri="&rdf;Property"/>

</axiom>

An example of an inference rule (one stating that - if a resource is used as predicate then it is of 'type' 'Property') looks like:

<rule name="rdfs1"> <premise> <subject var="xxx"/> <predicate var="aaa"/> <object var="yyy"/> </premise>

<consequent> <subject var="aaa"/> <predicate uri="&rdf;type"/> <object uri="&rdf;Property"/> </consequent>

<triggers_rule> <rule name="rdfs2" /> <rule name="rdfs3" />

Page 23: User Guide for Sesame

6

<rule name="rdfs4a" /> <rule name="rdfs5b" /> <rule name="rdfs6" /> <rule name="rdfs9" /> </triggers_rule></rule>

In the above example 'xxx', 'aaa' and 'yyy' are variables and 'rdf:type' and 'rdf:Property' are exact resource URIs.

A 'pattern' attribute with conjunction with an 'escape' attribute is used to define a pattern for matching resource names. They both can appear only in a triple component denoting variables, e.g. with 'var' attribute specified. Use '?' to denote any single character and '*' to match any character combination with length greater than 0.

Use a character declared in 'escape' attribute to escape '?' or '*' characters within pattern. You need to specify 'pattern' and 'escape' attributes for a given variable only once per rule (note that pattern and escape are used only once for variable 'id'.

An example of rule using pattern matching:

<rule name="rdfsXI"> <premise> <subject var="xxx"/> <predicate var="id" pattern="&rdf;_*" escape="\"/> <object var="yyy"/> </premise>

<consequent> <subject var="id"/> <predicate uri="&rdf;type"/> <object uri="&rdfs;ContainerMembershipProperty"/> </consequent>

<triggers_rule> <rule name="rdfs2" /> <rule name="rdfs3" /> <rule name="rdfs6" /> <rule name="rdfs9" /> <rule name="rdfs10" /> </triggers_rule></rule>

Note that you can match these triple templates by the values to the variables used in them and the specified resources used as subjects, predicates or objects of a triple.

4.3.2. Example

Consider the property URI is http://somewhere.org#partOf. In our example domain, we wish to ensure that this resource is always inserted in the repository, so we add the axiomatic triple stating that it is a property:

<axiom> <subject uri="http://somewhere.org#partOf"/> <predicate uri="&rdf;type"/> <object uri="&rdf;Property"/></axiom>

We also wish to define that the property is transitive. To this end, we add a single inference rule:

<rule name="userPartOf">

Page 24: User Guide for Sesame

6

<premise> <subject var="xxx"/> <predicate uri="http://somewhere.org#partOf"/> <object var="yyy"/> </premise> <premise> <subject var="yyy"/> <predicate uri="http://somewhere.org#partOf"/> <object var="zzz"/> </premise>

<consequent> <subject var="xxx"/> <predicate uri="http://somewhere.org#partOf"/> <object var="zzz"/> </consequent>

<triggers_rule> <rule name="rdfs2" /> <rule name="rdfs3" /> <rule name="rdfs6" /> <rule name="userPartOf" /> </triggers_rule></rule>

If the repository has these two triples: T1 - (finger.1, partOf, Hand.Left) and T2 - (Hand.Left, partOf, Human.1) and if they match the condition (since the same 'yyy' variable is used in both 'premise' tags) T1.object = T2.subject, a triple corresponding to the 'consequent' tag is added to the repository, using the current variable bindings and will have the form TInfer = (T1.subject, partOf, T2.object) e.g. Tinfer=(Finger.1, partOf, Human.1).

4.3.3. Configuration

The inferencer used by a repository based on org.openrdf.sesame.sailimpl.rdbms.RdfSchemaRepository sail is defined by a parameter passed to it during the initialization. To start using the custom inferencer on a repository, add the following extra parameter to the configuration of that repository:

use-inferencer specifies the full classname of the inferencer. To use the custom inferencer, use the value org.openrdf.sesame.sailimpl.rdbms.CustomInferenceServices.

rule-file specifies the location of the XML file in which the inference rules for the custom inferencer are specified. Make sure that you specify the full path name.

4.3.4. Notes and Hints

An example rules file, containing the axioms and entailment rules as specified by the January 23 Working Draft of the RDF Model Theory, can be found in the Sesame source tree, specifically in src/org/openrdf/sesame/sailimpl/rdbms/entailment-rdf-mt-20030123.xml. This file is used per default by the custom inferencer if the rule-file parameter is not specified.

Changes to the rules file do not lead to automatic reapplication of the rules over the existing data in the repository. So clean the repository first to avoid inconsistency problems.

The dependency information used by the TMS system is also affected by the rules. The default inferencer uses dependency database table, that can handle cases where up to two triples leads to the inference of a new one. Since there can exist inference rules involving arbitrary number of

Page 25: User Guide for Sesame

6

'premise' tags in the configuration file - the structure of the default dependency table cannot handle them. To avoid loss of data, the structure of that table is not altered and it is created only if it not exist. This check is performed during repository initialization phase. So it is better to apply new/modified inference rules on a completely clean datastorage (database).

4.4. Change Tracking[This section not yet available. See the documentation at http://www.ontotext.com/omm/ for details.]

Chapter 5. The web interfaceTable of Contents

5.1. Logging in 5.2. Adding data to a repository

Sesame comes with a Web interface to allow access to repositories through a normal Web browser. In this chapter, we will briefly describe the user interface.

5.1. Logging inIf you installed Sesame according to the guidelines in Chapter 2, Installing Sesame, the Sesame entry page is located at http://[MACHINE_NAME]:8080/sesame/. If you point your browser to this address, it should display the Sesame entry page shown in Figure 5.1, “The Sesame entry page”.

Figure 5.1. The Sesame entry page

Page 26: User Guide for Sesame

6

The screen provides you with a choice of repositories to work on. Since you are not yet logged in, and no publicly accessible repositories are available, you get a notification that no repositories can be accessed.

To log in to Sesame, click the "log in" link and provide user name and password (see Figure 5.2, “The Sesame login page”).

Figure 5.2. The Sesame login page

After you have logged in, you are returned to the entry page, which now shows that you are logged in and gives you a choice of repositories that you have access on.

Figure 5.3. The Sesame entry page when logged in

Page 27: User Guide for Sesame

6

After selecting a repository, you come to the actual Sesame function interface (see Figure 5.4, “The repository function screen”).

Figure 5.4. The repository function screen

The toolbar at the top of the screen shows user and repository information, and allows the selection of different actions on the repository. The actions are divided in read actions (such as queries) and write actions (adding and removing data).

Page 28: User Guide for Sesame

6

5.2. Adding data to a repositoryThe web interface offers three options for adding data to a Sesame repository: Add file, Add (www) and Add (copy-paste).

The Add file and Add (www) options are fairly straightforward. The first option allows you to select an RDF document from your local disk to add to the Sesame repository. The second option allows you to add RDF documents that are accessible through a URL to the repository.

Optionally, you can supply a base URL. The base URL is used by the RDF parser to disambiguate any relative resource references in the RDF document. By default, Sesame uses foo:bar as a base URL, but this may not always be desirable, for example when the file is being from a temporary location, or when resources defined in the document are referenced by other RDF sources with different URLs.

The Add (copy-paste) option allows you to upload data to Sesame by typing (or copying and pasting) it in the text area. The pasted text should be valid RDF/XML document.

Chapter 6. The SeRQL query language (revision 1.2)Table of Contents

6.1. Revisions 6.1.1. revision 1.1 6.1.2. revision 1.2

6.2. Introduction 6.3. URIs, literals and variables

6.3.1. Variables 6.3.2. URIs 6.3.3. Literals 6.3.4. Blank Nodes (R1.2)

6.4. Path expressions 6.4.1. Basic path expressions 6.4.2. Path expression short cuts 6.4.3. Optional path expressions

6.5. Select- and construct queries 6.6. Select queries 6.7. Construct queries 6.8. The WHERE clause

6.8.1. Boolean constants 6.8.2. Value (in)equality 6.8.3. Numerical comparisons 6.8.4. The LIKE operator (R1.2) 6.8.5. isResource() and isLiteral() 6.8.6. isURI() and isBNode() (R1.2) 6.8.7. AND, OR, NOT 6.8.8. Nested WHERE clauses (R1.2)

6.9. Other functions 6.9.1. label(), lang() and datatype() 6.9.2. namespace() and localName() (R1.2)

6.10. The LIMIT and OFFSET clauses 6.11. The USING NAMESPACE clause

Page 29: User Guide for Sesame

6

6.12. Built-in predicates 6.13. Set combinatory operations

6.13.1. UNION (R1.2) 6.13.2. INTERSECT (R1.2) 6.13.3. MINUS (R1.2)

6.14. NULL values 6.15. Query Nesting

6.15.1. The IN operator (R1.2) 6.15.2. ANY and ALL (R1.2) 6.15.3. EXISTS (R1.2)

6.16. Example SeRQL queries 6.16.1. Query 1 6.16.2. Query 2 6.16.3. Query 3

6.17. Comments/feedback 6.18. References 6.19. SeRQL grammar

6.1. Revisions6.1.1. revision 1.1

SeRQL revision 1.1 is a syntax revision (see issue tracker item SES-75). This document describes the revised syntax. From Sesame release 1.2-RC1 onwards, the old syntax is no longer supported.

6.1.2. revision 1.2

SeRQL revision 1.2 covers a set of new functions and operators:

Specification of blank node identifiers (Section 6.3.4, “Blank Nodes (R1.2)”). Case sensitive string matching (Section 6.8.4, “The LIKE operator (R1.2)”).

New functions isBNode(), isURI() (Section 6.8.6, “isURI() and isBNode() (R1.2)”).

Nested WHERE clause for optional path expressions (Section 6.8.8, “Nested WHERE clauses (R1.2)”).

New functions namespace(), localName() (Section 6.9.2, “namespace() and localName() (R1.2)”).

OWL default namespace (Section 6.11, “The USING NAMESPACE clause”).

Set operations (Section 6.13, “Set combinatory operations”).

Nested queries (Section 6.15, “Query Nesting”).

Set membership operator (Section 6.15.1, “The IN operator (R1.2)”).

ANY and ALL keywords (Section 6.15.2, “ANY and ALL (R1.2)”).

Existential quantification (Section 6.15.3, “EXISTS (R1.2)”).

New operations have been marked with (R1.2) where appropriate in this document.

Page 30: User Guide for Sesame

6

6.2. IntroductionSeRQL ("Sesame RDF Query Language", pronounced "circle") is a new RDF/RDFS query language that is currently being developed by Aduna as part of Sesame. It combines the best features of other (query) languages (RQL, RDQL, N-Triples, N3) and adds some of its own. This document briefly shows all of these features. After reading through this document one should be able to write SeRQL queries.

Some of SeRQL's most important features are:

Graph transformation. RDF Schema support.

XML Schema datatype support.

Expressive path expression syntax.

Optional path matching.

6.3. URIs, literals and variablesURIs and literals are the basic building blocks of RDF. For a query language like SeRQL, variables are added to this list. The following sections will show how to write these down in SeRQL.

6.3.1. Variables

Variables are identified by names. These names must start with a letter or an underscore ('_') and can be followed by zero or more letters, numbers, underscores, dashes ('-') or dots ('.'). Examples variable names are:

Var1 _var2

unwise.var-name_isnt-it

SeRQL keywords are not allowed to be used as variable names. Currently, the following keywords are used or reserved for future use in SeRQL: select, construct, from, where, using, namespace, true, false, not, and, or, like, label, lang, datatype, null, isresource, isliteral, sort, in, union, intersect, minus, exists, forall, distinct, limit, offset.

Keywords in SeRQL are all case-insensitive, this in contrast to variable names; these are case-sensitive.

6.3.2. URIs

There are two ways to write down URIs in SeRQL: either as full URIs or as abbreviated URIs. Full URIs must be surrounded with "<" and ">". Examples of this are:

<http://www.openrdf.org/index.html> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>

<mailto:[email protected]>

<file:///C:\rdffiles\test.rdf>

Page 31: User Guide for Sesame

6

As URIs tend to be long strings with the first part being shared by several of them (i.e. the namespace), SeRQL allows one to use abbreviated URIs (or QNames) by defining (short) names for these namespaces which are called "prefixes". A QName always starts with one of the defined prefixes and a colon (":"). After this colon, the part of the URI that is not part of the namespace follows. The first part, consisting of the prefix and the colon, is replaced by the full namespace by the query engine. Some example QNames are:

sesame:index.html rdf:type

foaf:Person

6.3.3. Literals

RDF literals consist of three parts: a label, a language tag, and a datatype. The language tag and the datatype are optional and at most one of these two can accompany a label (a literal can not have both a language tag and a datatype). The notation of literals in SeRQL has been modelled after their notation in N-Triples; literals start with the label, which is surrounded by double quotes, optionally followed by a language tag with a "@" prefix or by a datatype URI with a "^^" prefix. Example literals are:

"foo" "foo"@en

"<foo/>"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>

The SeRQL notation for abbreviated URIs can also be used. When the prefix rdf is mapped to the namespace http://www.w3.org/1999/02/22-rdf-syntax-ns#, the last example literal could also have been written down like:

"<foo/>"^^rdf:XMLLiteral

SeRQL has also adopted the character escapes from N-Triples; special characters can be escaped by prefixing them with a backslash. One of the special characters is the double quote. Normally, a double quote would signal the end of a literal's label. If the double quote is part of the label, it needs to be escaped. For example, the sentence John said: "Hi!" can be encoded in a SeRQL literals as: "John said: \"Hi!\"".

As the backslash is a special character itself, it also needs to be escaped. To encode a single backslash in a literal's label, two backslashes need to be written in the label. For example, a Windows directory would be encoded as: "C:\\Program Files\\Apache Tomcat\\".

SeRQL has functions for extracting each of the three parts of a literal. These functions are label, lang, and datatype. label("foo"@en) extracts the label "foo", lang("foo"@en) extracts the language tag "en", and datatype("foo"^^rdf:XMLLiteral) extracts the datatype rdf:XMLLiteral. The use of these functions is explained later.

6.3.4. Blank Nodes (R1.2)

RDF has a notion of blank nodes. These are nodes in the RDF graph that are not labeled with a URI or a literal. The interpretation of such blank nodes is as a form of existential quantification: it allows one to assert that "there exists a node such that..." without specifying what that particular node is. Blank nodes do in fact often have identifiers, but these identifiers are assigned internally by whatever

Page 32: User Guide for Sesame

6

processor is processing the graph and they are only valid in the local context, not as global identifiers (unlike URIs).

Strictly speaking blank nodes are only addressable indirectly, by querying for one or more properties of the node. However, SeRQL, as a practical shortcut, allows blank node identifiers to be used in queries. The syntax for blank nodes is adopted from N-Triples, using a QName-like syntax with "_" as the namespace prefix, and the internal blank node identifier as the local name. For example:

_:bnode1

This identifies the blank node with internal identifier "bnode1". These blank node identifiers can be used in the same way that normal URIs or QNames can be used.

Caution: It is important to realize that addressing blank nodes in this way makes SeRQL queries non-portable across repositories. There is no guarantee that in two repositories, even if they contain identical datasets, the blank node identifiers will be identical. It may well be that "bnode1" in repository A is a completely different blank node than "bnode1" in repository B. Even in the same repository, it is not guaranteed that blank node identifiers are stable over updates: if certain statements are added to or removed from a repository, it is not guaranteed "bnode1" still identifies the same blank node that it did before the update operation.

6.4. Path expressionsOne of the most prominent parts of SeRQL are path expressions. Path expressions are expressions that match specific paths through an RDF graph. Most current RDF query languages allow you to define path expressions of length 1, which can be used to find (combinations of) triples in an RDF graph. SeRQL, like RQL, allows you to define path expressions of arbitrary length.

6.4.1. Basic path expressions

Imagine that we want to query an RDF graph for persons who work for companies that are IT companies. Querying for this information comes down to finding the following pattern in the RDF graph (gray nodes denote variables):

Figure 6.1. A basic path expression

The SeRQL notation for path expressions resembles the picture above; it is written down as:

{Person} ex:worksFor {Company} rdf:type {ex:ITCompany}

The parts surrounded by curly brackets represent the nodes in the RDF graph, the parts between these nodes represent the edges in the graph. The direction of the arcs (properties) in SeRQL path expressions is always from left to right.

In SeRQL queries, multiple path expressions can be specified by seperating them with commas. For example, the path expression show before can also be written down as two smaller path expressions:

{Person} ex:worksFor {Company},{Company} rdf:type {ex:ITCompany}

Page 33: User Guide for Sesame

6

The nodes and edges in the path expressions can be variables, URIs and literals. Also, a node can be left empty in case one is not interested in the value of that node. Here are some more example path expressions to illustrate this:

{Person} ex:worksFor {} rdf:type {ex:ITCompany} {Painting} ex:painted_by {} ex:name {"Picasso"}

{comic:RoadRunner} SomeRelation {foo:WillyECoyote}

6.4.2. Path expression short cuts

Each and every path can be constructed using a set of basic path expressions. Sometimes, however, it is nicer to use one of the available short cuts. There are three types of short cuts, all of them are explained below.

6.4.2.1. Multi-value nodes

In situations where one wants to query for two or more triples with identical subject and predicate, the subject and predicate do not have to be repeated over and over again. Instead, a multi-value node can be used:

{subj1} pred1 {obj1, obj2, obj3}

A built-in constraint on this construction is that each value for the variables in the multi-value node is unique (i.e. they are pairwise disjoint). Therefore, this path expression is equivalent to the following combination of path expressions and boolean constraints:

FROM {subj1} pred1 {obj1}, {subj1} pred1 {obj2}, {subj1} pred1 {obj3}WHERE obj1 != obj2 AND obj1 != obj3 AND obj2 != obj3

Or graphically:

Figure 6.2. Multi-value nodes

Multi-value nodes can also be used when statements share the predicate and object, e.g.:

{subj1, subj2, subj3} pred1 {obj1}

When used in a longer path expression, multi-value nodes apply to both the part left of the node and the part right of the node. The following path expression:

{first} pred1 {middle1, middle2} pred2 {last}

matches the following graph:

Page 34: User Guide for Sesame

6

Figure 6.3. Multi-value nodes in a longer path expression

When using variables in multi-value nodes, a constraint on its values is implicitly added: the variable's value is not allowed to be equal to any other value in the multi-value node. So, in the first example, the variables obj1, obj2 and obj3 will not match identical values at the same time. This prevents the path from matching a single triple three times.

6.4.2.2. Branches

One of the shorts cuts that is likely going to be used most, is the notation for branches in path expressions. There are lots of situations where one wants to query multiple properties of a single subject. Instead of repeating the subject over and over again, one can use a semi-colon to attach a predicate-object combination to the subject of the last part of a path expression, e.g.:

{subj1} pred1 {obj1}; pred2 {obj2}

Which is equivalent to:

{subj1} pred1 {obj1},{subj1} pred2 {obj2}

Or graphically:

Figure 6.4. Branches in a path expression

Or a slightly more complicated example:

{first} pred {} pred1 {obj1}; pred2 {obj2} pred3 {obj3}

Which matches the following graph:

Figure 6.5. Branches in a longer path expression

Note that an anonymous variable is used in the middle of the path expressions.

6.4.2.3. Reified statements

Page 35: User Guide for Sesame

6

The last short cut is a short cut for reified statements. A path expression representing a single statement (i.e. {node} edge {node}) can be written between the curly brackets of a node, e.g.:

{ {reifSubj} reifPred {reifObj} } pred {obj}

This would be equivalent to querying (using "rdf:" as a prefix for the RDF namespace, and "_Statement" as a variable for storing the statement's URI):

{_Statement} rdf:type {rdf:Statement},{_Statement} rdf:subject {reifSubj},{_Statement} rdf:predicate {reifPred},{_Statement} rdf:object {reifObj},{_Statement} pred {obj}

Again, graphically:

Figure 6.6. A reification path expression

6.4.3. Optional path expressions

Optional path expressions differ from 'normal' path expressions in that they do not have to be matched to find query results. The SeRQL query engine will try to find paths in the RDF graph matching the path expression, but when it cannot find any paths it will skip the expression and leave any variables in it uninstantiated (they will have the value null).

Consider an RDF graph that contains information about people that have names, ages, and optionally e-mail addresses. This is a situation that is likely to be very common in RDF data. A logical query on this data is a query that yields all names, ages and, when available, e-mail addresses of people, e.g.:

{Person} ex:name {Name}; ex:age {Age}; ex:email {EmailAddress}

However, using normal path expressions like in the query above, people without e-mail address will not be returned by the SeRQL query engine. With optional path expressions, one can indicate that a specific (part of a) path expression is optional. This is done using square brackets, i.e.:

{Person} ex:name {Name}; ex:age {Age}; [ex:email {EmailAddress}]

Or alternatively:

{Person} ex:name {Name}; ex:age {Age},

Page 36: User Guide for Sesame

6

[{Person} ex:email {EmailAddress}]

In contrast to the first path expressions, this expression will also match with people without an e-mail address. For these people, the variable EmailAddress will not be assigned a value.

Optional path expressions can also be nested. This is useful in situations where the existence of a specific path is dependent on the existence of another path. For example, the following path expression queries for the titles of all known documents and, if the author of the document is known, the name of the author (if it is known) and his e-mail address (if it is known):

{Document} ex:title {Title}; [ex:author {Author} [ex:name {Name}]; [ex:email {Email}]]

With this path expression, the SeRQL query engine will not try to find the name and e-mail address of an author when it cannot even find the resource representing the author.

6.5. Select- and construct queriesThe SeRQL query language supports two querying concepts. The first one can be characterized as returning a table of values, or a set of variable-value bindings. The second one returns a true RDF graph, which can be a subgraph of the graph being queried, or a graph containing information that is derived from it. The first type of queries are called "select queries", the second type of queries are called "construct queries".

A SeRQL query is typically built up from one to six clauses. For select queries these clauses are: SELECT, FROM, WHERE, LIMIT, OFFSET and USING NAMESPACE. One might recognize the first five clauses from SQL, but their usage is slightly different. For construct queries the clauses are the same with the exception of the first; construct queries start with a CONSTRUCT clause instead of a SELECT clause.

The first clause (i.e. SELECT or CONSTRUCT) determines what is done with the results that are found. In a SELECT clause, one can specify which variable values should be returned and in what order. In a CONSTRUCT clause, one can specify which triples should be returned.

The FROM clause is optional and always contains path expressions, which were explained in the previous section. It defines the paths in an RDF graph that are relevant to the query. Note that when the FROM clause is not specified, the query will simply return the constants specified in the SELECT or CONSTRUCT clause.

The WHERE clause is optional and can contain additional (Boolean) constraints on the values in the path expressions. These are constraints on the nodes and edges of the paths, which cannot be expressed in the path expressions themselves.

The LIMIT and OFFSET clauses are also optional. These clauses can be used separately or combined in order to get a subset of all query answers. Their usage is very similar to the LIMIT and OFFSET clauses in SQL queries. The LIMIT clause determines the (maximum) amount of query answers that will be returned. The OFFSET clause determines which query answer will be returned as the first result, skipping as many query results as specified in this clause.

Finally, the USING NAMESPACE clause is also optional and it can contain namespace declarations; these are the mappings from prefixes to namespaces that were referred to in one of previous sections about (abbreviated) URIs.

Page 37: User Guide for Sesame

6

The WHERE, LIMIT, OFFSET and USING NAMESPACE clauses will be explained in one of the next sections. The following section will explain the SELECT and FROM clause.

6.6. Select queriesAs said before, select queries return tables of values, or sets of variable-value bindings. Which values are returned can be specified in the select clause. One can specify variables and/or values in the select clause, seperated by commas. The following example query returns all URIs of classes:

SELECT CFROM {C} rdf:type {rdfs:Class}

It is also possible to use a '*' in the SELECT clause. In that case, all variable values will be returned in the order in which they appear in the query, e.g.:

SELECT *FROM {S} rdfs:label {O}

This query will return the values of the variables S and O, in that order. If a different order is preferred, one needs to specify the variables in the select clause, e.g.:

SELECT O, SFROM {S} rdfs:label {O}

By default, the results of a select query are not filtered for duplicate rows. Because of the nature of the above queries, these queries will never return duplicates. However, more complex queries might result in duplicate result rows. These duplicates can be filtered out by the SeRQL query engine. To enable this functionality, one needs to specify the DISTINCT keyword after the select keyword. For example:

SELECT DISTINCT *FROM {Country1} ex:borders {} ex:borders {Country2}USING NAMESPACE ex = <http://example.org/things#>

6.7. Construct queriesConstruct queries return RDF graphs as set of triples. The triples that a query should return can be specified in the construct clause using the previously explained path expressions. The following is an example construct query:

CONSTRUCT {Parent} ex:hasChild {Child}FROM {Child} ex:hasParent {Parent}USING NAMESPACE ex = <http://example.org/things#>

This query defines the inverse of the property foo:hasParent to be foo:hasChild. This is just one example of a query that produces information that is derived from the original information. Here is one more example:

CONSTRUCT {Artist} rdf:type {ex:Painter}; ex:hasPainted {Painting}FROM {Artist} rdf:type {ex:Artist}; ex:hasCreated {Painting} rdf:type {ex:Painting}USING NAMESPACE

Page 38: User Guide for Sesame

6

ex = <http://example.org/things#>

This query derives that an artist who has created a painting, is a painter. The relation between the painter and the painting is modelled to be art:hasPainted.

Instead of specifying a path expression in the CONSTRUCT clause, one can also use a '*'. In that case, the CONSTRUCT clause is identical to the FROM clause. This allows one to extract a subgraph from a larger graph, e.g.:

CONSTRUCT *FROM {SUB} rdfs:subClassOf {SUPER}

This query extracts all rdfs:subClassOf relations from an RDF graph.

Just like with select queries, the results of a construct query are not filtered for duplicate triples by default. Again, these duplicates are filtered out by the SeRQL query engine if the DISTINCT keyword is specified after the construct keyword, for example:

CONSTRUCT DISTINCT {Artist} rdf:type {ex:Painter}FROM {Artist} rdf:type {ex:Artist}; ex:hasCreated {} rdf:type {ex:Painting}USING NAMESPACE ex = <http://example.org/things#>

6.8. The WHERE clauseThe third clause in a query is the WHERE clause. This is an optional clause in which one can specify Boolean constraints on variables.

The following sections will explain the available Boolean expressions for use in the WHERE clause. Section 6.8.8, “Nested WHERE clauses (R1.2)” will explain how WHERE clauses can be nested inside optional path expressions.

6.8.1. Boolean constants

There are two Boolean constants, TRUE and FALSE. The first one is simply always true, the last one is always false. The following query will never produce any results because the constraint in the where clause will never evaluate to true:

SELECT *FROM {X} Y {Z}WHERE FALSE

6.8.2. Value (in)equality

The most common boolean constraint is equality or inequality of values. Values can be compared using the operators "=" (equality) and "!=" (inequality). The expression

Var = <foo:bar>

is true if the variable Var contains the URI <foo:bar>, and the expression

Var1 != Var2

Page 39: User Guide for Sesame

6

checks whether two variables are not equal.

6.8.3. Numerical comparisons

Numbers can be compared to each other using the operators "<" (lower than), "<=" (lower than or equal to), ">" (greater than) and ">=" (greater than or equal to). SeRQL uses a literal's datatype to determine whether its value is numerical. All XML Schema built-in numerical datatypes are supported, i.e.: xsd:float, xsd:double, xsd:decimal and all subtypes of xsd:decimal (xsd:long, xsd:nonPositiveInteger, xsd:byte, etc.), where the prefix xsd is used to reference the XML Schema namespace.

In the following query, a comparison between values of type xsd:positiveInteger is used to retrieve all countries that have a population of less than 1 million:

SELECT CountryFROM {Country} ex:population {Population}WHERE Population < "1000000"^^xsd:positiveIntegerUSING NAMESPACE ex = <http://example.org/things#>

SeRQL is currently restricted to numerical comparisons between values with identical datatypes. This means that e.g. xsd:int values cannot (yet) be compared to xsd:byte values.

If only one of the parameters of a comparison has a datatype, SeRQL will try to assign the other parameter the same datatype. This means that the above query can still be used when the population literals don't have any datatype. SeRQL will try to interpret the literal as a positive integer and compare it to the one million constant.

6.8.4. The LIKE operator (R1.2)

The LIKE operator can check whether a value matches a specified pattern of characters. '*' characters can be used as wildcards, matching with zero or more characters. The rest of the characters are compared lexically. The pattern is surrounded with double quotes, just like a literal's label.

SELECT CountryFROM {Country} ex:name {Name}WHERE Name LIKE "Belgium"USING NAMESPACE ex = <http://example.org/things#>

By default, the LIKE operator does a case-sensitive comparison: in the above query, the operator fails is the variable Name is bound to the value "belgium" instead of "Belgium". Optionally, one can specify that the operator should perform a case-insensitive comparison:

SELECT CountryFROM {Country} ex:name {Name}WHERE Name LIKE "belgium" IGNORE CASEUSING NAMESPACE ex = <http://example.org/things#>

In this query, the operator will succeed for "Belgium", "belgium", "BELGIUM", etc.

The '*' character can be used as a wildcard to indicate substring matches, for example:

SELECT CountryFROM {Country} ex:name {Name}

Page 40: User Guide for Sesame

6

WHERE Name LIKE "*Netherlands"USING NAMESPACE ex = <http://example.org/things#>

This query will match any country names that end with the string "Netherlands", for example "The Netherlands".

6.8.5. isResource() and isLiteral()

The isResource() and isLiteral() boolean functions check whether a variable contains a resource or a literal, respectively. For example:

SELECT *FROM {R} rdfs:label {L}WHERE isLiteral(L)

6.8.6. isURI() and isBNode() (R1.2)

The isURI() and isBNode() boolean functions are more specific versions of isResource(). They check whether a variable is bound to a URI value or a BNode value, respectively. For example, the following query returns only URIs (and filters out all bNodes and literals):

SELECT VFROM {R} prop {V}WHERE isURI(V)

6.8.7. AND, OR, NOT

Boolean constraints and functions can be combined using the AND and OR operators, and negated using the NOT operator. The NOT operator has the highest presedence, then the AND operator, and finally the OR operator. Parentheses can be used to override the default presedence of these operators. The following query is a (kind of artifical) example of this:

SELECT *FROM {X} Prop {Y} rdfs:label {L}WHERE NOT L LIKE "*FooBar*" AND (Y = <foo:bar> OR Y = <bar:foo>) AND isLiteral(L)

6.8.8. Nested WHERE clauses (R1.2)

In order to be able to express boolean constraints on variables in optional path expressions, it is possible to use a nested WHERE clause. The constraints in such a nested WHERE clause restrict the potential matches of the optional path expressions, without causing the entire query to fail if the boolean constraint fails.

To illustrate the difference between a nested WHERE clause and a 'normal' WHERE clause, consider the following two queries on the same data:

Data (using Turtle format):

@prefix foaf: <http://xmlns.com/foaf/0.1/> .@prefix ex: <http://example.org/> .

_:a foaf:name "Michael" .

_:b foaf:name "Rubens" .

Page 41: User Guide for Sesame

6

_:b ex:email "[email protected]".

_:b foaf:name "Giancarlo" ._:b ex:email "[email protected]".

Query 1 (normal WHERE-clause):

SELECT Name, EmailAddressFROM {Person} foaf:name {Name}; [ex:email {EmailAddress}]WHERE EmailAddress LIKE "g*"

Query 2 (nested WHERE-clause):

SELECT Name, EmailAddressFROM {Person} foaf:name {Name}; [ex:email {EmailAddress} WHERE EmailAddress LIKE "g*"]

In query 1, a normal WHERE clause specifies that the EmailAddress found by the optional expression must begin with the letter "g". The result of this query will be:

Name EmailAddressGiancarlo "[email protected]"

Despite the fact that the match on EmailAddress is defined as optional, the persons named "Michael" and "Rubens" are not returned. The reason is that the WHERE clause explicitly says that the value bound to the optional variable must start with the letter "g". For Michael, no value is found, hence the variable is equal to NULL, and the comparison operator fails on this. For Rubens, a value is found, but it does not start with the letter "g".

In query 2, however, a nested WHERE-clause is used. This specifies that any binding the optional expression does must begin with the letter "g", otherwise NULL is returned. The result of this query is:

Name EmailAddressMichael  Rubens  Giancarlo "[email protected]"

The person "Michael" is returned without a result for his email address because there is no email address known for him at all. The person "Rubens" is returned without a result for his email address because, although he does have an email address, it does not start with the letter "g".

A query can contain at most one nested WHERE-clause per optional path expression, and at most one 'normal' WHERE-clause.

6.9. Other functions

Page 42: User Guide for Sesame

6

Apart from the boolean functions and operators introduced in the previous section, SeRQL supports several other functions that return RDF terms rather than non-boolean values. These functions can be used in both the SELECT and the WHERE clause.

6.9.1. label(), lang() and datatype()

The three functions label(), lang() and datatype() all operate on literals. The result of the label() function is the lexical form of the supplied literal. The lang() function returns the language attribute. Both functions return their result as an untyped literal, which can again be compared with other literals using (in)equality-, comparison-, and like operators. The result of the datatype() function is a URI, which can be compared to other URIs. These functions can also be used in SELECT clauses, but not in path expressions.

An example query:

SELECT label(L)FROM {R} rdfs:label {L}WHERE isLiteral(L) AND lang(L) LIKE "en*"

6.9.2. namespace() and localName() (R1.2)

The functions namespace() and localName() operate on URIs. The namespace() function returns the namespace of the supplied URI, as a URI object. The localName() function returns the local name part of the supplied URI, as a literal. These functions can also be used in SELECT clauses, but not in path expressions.

The following query retrieves all properties of foaf:Person instances that are in the FOAF namespace. Notice that as a shorthand for the full URI, we can use a namespace prefix (followed by a colon) as an argument.

Data:

@prefix foaf: <http://xmlns.com/foaf/0.1/> .@prefix ex: <http://example.org/> .

_:a rdf:type foaf:Person ._:a my:nick "Schumi" ._:a foaf:firstName "Michael" ._:a foaf:knows _:b .

_:b rdf:type foaf:Person ._:b foaf:firstName "Rubens" ._:b foaf:nick "Rubinho" .

Query:

SELECT foafProp, ValueFROM {} foafProp {Value}WHERE namespace(foafProp) = foaf:USING NAMESPACE foaf = <http://xmlns.com/foaf/0.1/>

Result:

foafProp Value<http://xmlns.com/foaf/0.1/firstName "Michael"

Page 43: User Guide for Sesame

6

foafProp Value<http://xmlns.com/foaf/0.1/knows _:b<http://xmlns.com/foaf/0.1/firstName "Rubens"<http://xmlns.com/foaf/0.1/nick "Rubinho"

In the following example, the localName() function is used to match two equivalent properties from different namespaces (using the above data).

Query:

SELECT nickFROM {} rdf:type {foaf:Person}; nickProp {nick}WHERE localName(nickProp) LIKE "nick"USING NAMESPACE foaf = <http://xmlns.com/foaf/0.1/>

Result:

nick"Schumi""Rubinho"

6.10. The LIMIT and OFFSET clausesLIMIT and OFFSET allow you to retrieve just a portion of the results that are generated by the query. If a limit count is given, no more than that many results will be returned (but possibly less, if the query itself yields less results).

OFFSET says to skip that many results before beginning to return results. OFFSET 0 is the same as omitting the OFFSET clause. If both OFFSET and LIMIT appear, then OFFSET rows are skipped before starting to count the LIMIT results that are returned.

6.11. The USING NAMESPACE clauseThe USING NAMESPACE clause can be used to define short prefixes for namespaces, which can then be used in abbreviated URIs. Multiple prefixes can be defined, but each declaration must have a unique prefix. The following query shows the use of namespace prefixes:

CONSTRUCT {Artist} rdf:type {art:Painter}; art:hasPainted {Painting}FROM {Artist} rdf:type {art:Artist}; art:hasCreated {Painting} rdf:type {art:Painting}USING NAMESPACE rdf = <http://www.w3.org/1999/02/22-rdf-syntax-ns#>, art = <http://example.org/arts/>

The query engine will replace every occurence of rdf: in an abbreviated URI with http://www.w3.org/1999/02/22-rdf-syntax-ns#, and art: with http://example.org/arts/. So art:hasPainted will be resolved to the URI http://example.org/arts/hasPainted.

Page 44: User Guide for Sesame

6

Four namespaces that are used very frequently have been assigned prefixes by default:

Table 6.1. Default namespaces

Prefix Namespacerdf http://www.w3.org/1999/02/22-rdf-syntax-ns#rdfs http://www.w3.org/2000/01/rdf-schema#xsd http://www.w3.org/2001/XMLSchema#owl http://www.w3.org/2002/07/owl#serql http://www.openrdf.org/schema/serql#

These prefixes can be used without declaring them. If either of these prefixes is declared explicitly in a query, this declaration will override the default mapping.

6.12. Built-in predicatesSeRQL contains a number of built-in predicates. These built-ins can be used like any other predicate, as part of a path expression. The difference with normal predicates is that the built-ins act as operators on the underlying rdf graph: they can be used to query for relations between RDF resources that are not explicitly modeled, nor immediately apparant from the RDF Semantics, but which are nevertheless very useful.

Currently, the following built-in predicates are supported:

{X} serql:directSubClassOf {Y}

This relation holds for every X and Y where:

1. X rdfs:subClassOf Y. 2. X != Y.

3. There is no class Z (Z != Y and Z != X) such that X rdfs:subClassOf Z and Z rdfs:subClassOf Y.

{X} serql:directSubPropertyOf {Y}

This relation holds for every X and Y where:

1. X rdfs:subPropertyOf Y. 2. X != Y.

3. There is no property Z (Z != X and Z != Y) such that X rdfs:subPropertyOf Z and Z rdfs:subPropertyOf Y.

{X} serql:directType {Y}

This relation holds for every X and Y where:

1. X rdf:type Y. 2. There is no class Z (Z != Y) such that X rdf:type Z and Z

rdfs:subClassOf Y.

Page 45: User Guide for Sesame

6

Note: the above definition takes class/property equivalence through cyclic subClassOf/subPropertyOf relations into account. This means that if A rdfs:subClassOf B, and B rdfs:subClassOf A, it holds that A = B.

The namespace prefix 'serql' is built-in and does not have to be defined in the query.

6.13. Set combinatory operationsSeRQL offers three combinatory operations that can be used to combine sets of query results.

6.13.1. UNION (R1.2)

UNION is a combinatory operation the result of which is the set of query answers of both its operands. This allows one to specify alternatives in a query solution.

By default, UNION filters out duplicate answers from its operands. Specifying the ALL keyword ("UNION ALL") disables this filter.

The following example query retrieves the titles of books in the data, where the property used to describe the title can be either from the DC 1.0 or DC 1.1 specification.

Data:

@prefix dc10: <http://purl.org/dc/elements/1.0/> .@prefix dc11: <http://purl.org/dc/elements/1.1/> .

_:a dc10:title "The SeRQL Query Language" ._:b dc11:title "The SeRQL Query Language (revision 1.2)" .

_:c dc10:title "SeRQL" ._:c dc11:title "SeRQL (updated)" .

Query:

SELECT titleFROM {book} dc10:title {title}

UNION

SELECT titleFROM {book} dc11:title {title}

USING NAMESPACE dc10 = <http://purl.org/dc/elements/1.0/>, dc11 = <http://purl.org/dc/elements/1.1/>

Result:

title"The SeRQL Query Language""The SeRQL Query Language (revision 1.2)""SeRQL""SeRQL (updated)"

Page 46: User Guide for Sesame

6

The union operator matches the projection items in order without taking the name of the projection item into account:

SELECT title, "1.0" AS "version"FROM {book} dc10:title {title}

UNION

SELECT y, NULLFROM {x} dc11:title {y}

USING NAMESPACE dc10 = <http://purl.org/dc/elements/1.0/>, dc11 = <http://purl.org/dc/elements/1.1/>

Result:

title version"The SeRQL Query Language" "1.0""The SeRQL Query Language (revision 1.2)"  "SeRQL" "1.0""SeRQL (updated)"  

SeRQL will use the names of the variables in the first operand of the union in the query result.

6.13.2. INTERSECT (R1.2)

The INTERSECT operation retrieves query results that occur in both its operands.

The following query only retrieves those album creators for which the name is specified identically in both DC 1.0 and DC 1.1.

Data:

@prefix dc10: <http://purl.org/dc/elements/1.0/> .@prefix dc11: <http://purl.org/dc/elements/1.1/> .

_:a dc10:creator "George" ._:a dc10:creator "Ringo" .

_:b dc11:creator "George" ._:b dc11:creator "Ringo" .

_:c dc10:creator "Paul" ._:c dc11:creator "Paul C." .

Query:

SELECT creatorFROM {album} dc10:creator {creator}

INTERSECT

SELECT creatorFROM {album} dc11:creator {creator}

USING NAMESPACE dc10 = <http://purl.org/dc/elements/1.0/>, dc11 = <http://purl.org/dc/elements/1.1/>

Page 47: User Guide for Sesame

6

Result:

creator"George""Ringo"

6.13.3. MINUS (R1.2)

The Minus operation returns query results from its first operand which do not occur in the results from its second operand.

The following query returns the titles of all albums of which "Paul" is not a creator.

Data:

@prefix dc10: <http://purl.org/dc/elements/1.0/> .

_:a dc10:creator "George" ._:a dc10:title "Sergeant Pepper" .

_:b dc10:creator "Paul" ._:b dc10:title "Yellow Submarine" .

_:c dc10:creator "Paul" ._:c dc10:creator "Ringo" ._:c dc10:title "Let it Be" .

Query:

SELECT titleFROM {album} dc10:title {title}

MINUS

SELECT titleFROM {album} dc10:title {title}; dc10:creator {creator}WHERE creator like "Paul"

USING NAMESPACE dc10 = <http://purl.org/dc/elements/1.0/>, dc11 = <http://purl.org/dc/elements/1.1/>

Result:

title"Sergeant Pepper"

6.14. NULL valuesJust like SQL and most programming languages, SeRQL also has a NULL value. This value can be used just like any other value in SeRQL. For example, it can be used in the where clause to check that a literal doesn't have a datatype:

SELECT *FROM {X} Y {Z}WHERE isLiteral(Z) AND datatype(L) = NULL

Page 48: User Guide for Sesame

6

6.15. Query NestingSeRQL has several constructs for nested queries. Nested queries can occur as operands for several boolean operators, which are explained in more detail in the following sections.

SeRQL applies variable scoping for nested queries. This means that when a variable is assigned in the outer query, its value will be carried over to the inner query when that variable is reused there.

6.15.1. The IN operator (R1.2)

The IN operator allows set membership checking where the set is defined by a nested SELECT-query.

The following example query uses the IN operator to retrieve all names of Persons, but only those names that also appear as names of Authors.

@prefix ex: <http://example.org/things#> .

_:a rdf:type ex:Person ._:a ex:name "John" .

_:b rdf:type ex:Person ._:b ex:name "Ringo" .

_:c rdf:type ex:Author ._:c ex:name "John" .

_:d rdf:type ex:Author ._:d ex:name "George" .

Query:

SELECT nameFROM {} rdf:type {ex:Person}; ex:name {name}WHERE name IN ( SELECT n FROM {} rdf:type {ex:Author}; ex:name {n} )USING NAMESPACE ex = <http://example.org/things#>

Result:

name"John"

6.15.2. ANY and ALL (R1.2)

The ANY and ALL keywords can be used for existential and universal quantification on the right operand of a boolean operator, if this operand is a set, defined by a nested query. The ALL keyword indicates that for every value of the nested query the boolean condition must hold. The ANY keyword indicates that the boolean condition must hold for at least one value of the nested query.

The following query selects the highest value from a set of values using the ALL keyword and a nested query.

Page 49: User Guide for Sesame

6

Data:

@prefix ex: <http://example.org/things#> .

_:a ex:value "10"^^xsd:int ._:b ex:value "11"^^xsd:int ._:c ex:value "12"^^xsd:int ._:d ex:value "13"^^xsd:int ._:e ex:value "14"^^xsd:int .

Query:

SELECT highestValueFROM {node} ex:value {highestValue}WHERE highestValue >= ALL ( SELECT value FROM {} ex:value {value} )USING NAMESPACE ex = <http://example.org/things#>

Result:

highestValue"14"^^xsd:int

6.15.3. EXISTS (R1.2)

EXISTS is a unary operator that has a nested SELECT-query as its operand. The operator is an existential quantifier that succeeds when the nested query has at least one result.

In the following example, we use EXIST to determine whether any authors are known that share a name with a person, and if so, to retrieve that person's names and hobbies.

Data:

@prefix ex: <http://example.org/things#> .

_:a rdf:type ex:Person ._:a ex:name "John" ._:a ex:hobby "Stamp collecting" .

_:b rdf:type ex:Person ._:b ex:name "Ringo" ._:b ex:hobby "Crossword puzzles" .

_:c rdf:type ex:Author ._:c ex:name "John" ._:c ex:authorOf "Let it be".

Query:

SELECT name, hobbyFROM {} rdf:type {ex:Person}; ex:name {name}; ex:hobby {hobby}WHERE EXISTS ( SELECT n FROM {} rdf:type {ex:Author}; ex:name {n}; ex:authorOf {} WHERE n = name )

Page 50: User Guide for Sesame

6

USING NAMESPACE ex = <http://example.org/things#>

Result:

name hobby"John" "Stamp collecting"

6.16. Example SeRQL queries6.16.1. Query 1

Description: Find all papers that are about "RDF" and about "Querying", and their authors.

SELECT Author, PaperFROM {Paper} rdf:type {foo:Paper}; ex:keyword {"RDF", "Querying"}; dc:author {Author}USING NAMESPACE dc = <http://purl.org/dc/elements/1.0/>, ex = <http://example.org/things#>

Depicted as a graph, this query searches through the RDF graph for all subgraphs matching the following template:

Figure 6.7. Path expression for query 1

6.16.2. Query 2

Description: Find all artefacts whose English title contains the string "night" and the museum where they are exhibited. The artefact must have been created by someone with first name "Rembrandt". The artefact and museum should both be represented by their titles.

SELECT DISTINCT label(ArtefactTitle), MuseumNameFROM {Artefact} arts:created_by {} arts:first_name {"Rembrandt"}, {Artefact} arts:exhibited {} dc:title {MuseumName}, {Artefact} dc:title {ArtefactTitle}WHERE isLiteral(ArtefactTitle) AND lang(ArtefactTitle) = "en" AND label(ArtefactTitle) LIKE "*night*"USING NAMESPACE dc = <http://purl.org/dc/elements/1.0/>, arts = <http://example.org/arts/>

Page 51: User Guide for Sesame

6

Again, depicted as a subgraph template:

Figure 6.8. Path expression for query 2

Note that this figure only shows the path expressions from the from clause. The where clause poses additional constraints on the values of the variables which can't be as easily depicted graphically.

6.16.3. Query 3

Description: Find all siblings of class foo:bar.

SELECT DISTINCT SiblingFROM {Sibling, <foo:bar>} rdfs:subClassOf {ParentClass}

Or graphically:

Figure 6.9. Path expression for query 3

Note that the URI foo:bar is not returned as a result (there is an implicit constraint that doesn't allow Sibling to be equal to values that occur in the same multi-value node).

6.17. Comments/feedbackFeedback on this document and/or the SeRQL language is highly appreciated and can be posted on the forum at www.openrdf.org.

6.18. References RQL RQL tutorial

RDQL

RDF/XML syntax (W3C Recommandation)

Revised RDF/XML syntax (W3C Technical Report)

Page 52: User Guide for Sesame

6

RDF Semantics (W3C Recommandation)

N-Triples

Turtle

N3

URI (RFC 2396)

Namespace in XML (W3C Recommandation)

6.19. SeRQL grammarThe following is the BNF grammar of SeRQL, revision 1.2:

Query ::= Table_query_set (Namespace_list)? | Graph_query_set (Namespace_list)?

Namespace_list ::= "using" "namespace" Namespace ("," Namespace)*Namespace ::= <PREFIX_NAME> "=" <FULL_URI>

Table_query_set ::= Table_query (Set_operator Table_query_set)?Table_query ::= "(" Table_query_set ")" | Select_query

Graph_query_set ::= Graph_query (Set_operator Graph_query_set)?Graph_query ::= "(" Graph_query_set ")" | Construct_query

Set_operator ::= "union" | "minus" | "intersect"

Select_query ::= "select" ("distinct")? Projection ("from" Graph_pattern)? ("limit" <POS_INTEGER>)? ("offset" <POS_INTEGER>)?

Projection ::= "*" | Projection_elem ("," Projection_elem)*

Projection_elem ::= Var_or_value ("as" <STRING>)?

Construct_query ::= "construct" ("distinct")? Construct_clause ("from" Graph_pattern)? ("limit" <POS_INTEGER>)? ("offset" <POS_INTEGER>)?

Construct_clause ::= "*" | Path_expr_list

Graph_pattern ::= Path_expr_list ("where" Boolean_expr)?

Path_expr_list ::= Path_expr ("," Path_expr)*Path_expr ::= Path_expr_head ((";")? Path_expr_tail)? | "[" Graph_pattern "]"Path_expr_head ::= Node Edge NodePath_expr_tail ::= Edge Node ((";")? Path_expr_tail)? | "[" Edge Node ((";")? Path_expr_tail)? ("where" Boolean_expr)? "]" (";" Path_expr_tail)?

Edge ::= Var | UriNode ::= "{" (Node_elem_list)? "}"Node_elem_list ::= Node_elem ("," Node_elem)*Node_elem ::= Var

Page 53: User Guide for Sesame

6

| Uri | BNode | Literal | Reified_statReified_stat ::= Node Edge Node

Boolean_expr ::= And_expr ("or" Boolean_expr)?And_expr ::= Boolean_elem ("and" And_expr)?Boolean_elem ::= "(" Boolean_expr ")" | "true" | "false" | "not" Boolean_elem | Var_or_value Comp_op Var_or_value | Var_or_value Comp_op ("any"|"all") "(" Table_query_set ")" | Var_or_value "like" <STRING> | Var_or_value "in" "(" Table_query_set ")" | "exists" "(" Table_query_set ")" | "isResource" "(" Var ")" | "isURI" "(" Var ")" | "isBNode" "(" Var ")" | "isLiteral" "(" Var ")"

Comp_op ::= "=" | "!=" | "<" | "<=" | ">" | ">="

Var_or_value ::= Var | Value

Var ::= <NC_NAME>Value ::= Uri | BNode | Literal | "null" | "datatype" "(" Var ")" | "lang" "(" Var ")" | "label" "(" Var ")" | "namespace" "(" Var ")" | "localname" "(" Var ")"

Uri ::= <FULL_URI> | <QNAME>

BNode ::= <BNODE>

Literal ::= (* A SeRQL literal, see section on literals *) | <POS_INTEGER> | <NEG_INTEGER> | <DECIMAL>

<FULL_URI> ::= "<" (* a legal URI, see http://www.ietf.org/rfc/rfc2396.txt *) ">"

<QNAME> ::= <PREFIX_NAME> ":" <NC_NAME_CHAR>*

<BNODE> ::= "_:" <NC_NAME>

<POS_INTEGER> ::= "+"? [0-9]+<NEG_INTEGER> ::= "-" [0-9]+<DECIMAL> ::= ("+"|"-")? [0-9]* "." [0-9]+

<STRING> ::= '"' (* zero or more (encoded) characters *) '"'

<PREFIX_NAME> ::= <LETTER> <NC_NAME_CHAR>* | "_" <NC_NAME_CHAR>+

<NC_NAME> ::= (<LETTER>|"_") <NC_NAME_CHAR>*<NC_NAME_CHAR> ::= (* see http://www.w3.org/TR/REC-xml-names/#NT-NCNameChar *)<LETTER> ::= (* see http://www.w3.org/TR/REC-xml/#NT-Letter *)

Page 54: User Guide for Sesame

6

Note: all keywords are assumed to be case-insensitive. Whitespace characters between tokens are not significant other than for separating the tokens. Production rules with a head that is surrounded by angular brackets define tokens (aka "terminals").

Chapter 7. The Sesame APITable of Contents

7.1. An Overview of the Sesame Architecture 7.2. The Repository API

7.2.1. Accessing a repository 7.2.2. Querying a repository 7.2.3. Adding RDF data to a repository

7.3. The Graph API 7.3.1. Creating an empty Graph and adding statements to it 7.3.2. Adding/removing a Graph to/from a repository 7.3.3. Creating a Graph for an existing repository 7.3.4. Creating a graph using graph queries 7.3.5. Using graphs and graph queries for updates

In this chapter, we introduce the Sesame API, and give some brief code examples to show how this API can be used to communicate with Sesame from another program, either remote, or locally, and how it can be used as a library instead of as a server.

The Javadoc reference for the Sesame API is available online.

7.1. An Overview of the Sesame ArchitectureIn Figure 7.1, “The Sesame architecture” an overview of Sesame's overall architecture is given.

Figure 7.1. The Sesame architecture

Starting at the bottom, the Storage And Inference Layer, or SAIL API, is an internal Sesame API that abstracts from the storage format used (i.e. whether the data is stored in an RDBMS, in memory, or

Page 55: User Guide for Sesame

6

in files, for example), and provides reasoning support. SAIL implementations can also be stacked on top of each other, to provide functionality such as caching or concurrent access handling.

On top of the SAIL, we find Sesame's functional modules, such as the SeRQL, RQL and RDQL query engines, the admin module, and RDF export. Access to these functional modules is available through Sesame's Access APIs, consisting of two seperate parts: the Repository API and the Graph API. The Repository API provides high-level access to Sesame repositories, such as querying, storing of rdf files, extracting RDF, etc. The Graph API provides more fine-grained support for RDF manipulation, such as adding and removing individual statements, and creation of small RDF models directly from code. The two APIs complement each other in functionality, and are in practice often used together.

The Access APIs provide direct access to Sesame's functional modules, either to a client program (for example, a desktop application that uses Sesame as a library), or to the next component of Sesame's architecture, the Sesame server. This is a component that provides HTTP- and RMI-based access to Sesame's APIs. Then, on the remote HTTP/RMI client side, we again find the access APIs, which can again be used for communicating with Sesame, this time not as a library, but as a server running on a remote location.

While each part of the Sesame code is publicly available and extensible, most developers will be primarily interested in the Access APIs, for communicating with a Sesame RDF model or a Sesame repository from their application. In the next sections, these APIs are described in more detail, through several code examples.

7.2. The Repository APIThe Repository API is the central access point for Sesame repositories. It can be used to query and update the contents of both local and remote repositories. The Repository API handles all the details of client-server communication, allowing you to handle remote repositories as easily as local ones.

The main interfaces for the repository API can be found in package org.openrdf.sesame.repository. The implementations of these interface for local and remote repositories can be found in subpackages of this package.

In the following sections, the repository API is explained in more detail. We will show how one connects to an existing repository, how to configure a new (local or remote) Sesame repository, and how to perform queries or other actions.

7.2.1. Accessing a repository

The first step in any action that involves Sesame repositories is to get hold of a SesameRepository object representing it. The following sections explain how to do this for a local repository, a remote repository and a server repository.

7.2.1.1. Local repositories

Local repositories are very useful when you have to deal with some RDF in your own application. You can quickly create a local repository directly from your own program (without the use of any configuration files or databases), and store RDF in it, query this RDF and change it if necessary.

To quickly create a non-inferencing main-memory repository, one can use the following code:

LocalService service = Sesame.getService();boolean inferencing = true;

Page 56: User Guide for Sesame

6

LocalRepository myRepository = service.createRepository("myRep", inferencing);

This creates a local repository that uses main memory for storing its data. The boolean parameter inferencing indicates whether the repository should do RDF Schema inferencing. Note that the created repository is volatile: its contents are lost when the object is garbage collected or when the program is shut down.

For many purposes, the above way of creating a repository is convenient and sufficient. Sometimes, however, you may want to have a little more control over the exact configuration of a repository. For example, you may want to have a repository that dumps its contents to file. In such cases, you can create a RepositoryConfig object, configure it to your liking and pass that object to the createRepository() method of class LocalRepository.

In the following example, we again create a local repository, but this time we specify that it should use a file for persistence. First, we need to create a RepositoryConfig object that specifies the configuration of our required repository. In this example, we create a specification for a repository with ID "myCustomRep" that uses a stack of two Sails -- a main-memory Sail with schema support, and a synchronization Sail on top -- and which uses the file C:\TEMP\myCustomRep.rdf as a dump file for persistent storage.

RepositoryConfig repConfig = new RepositoryConfig("myCustomRep");

SailConfig syncSail = new SailConfig("org.openrdf.sesame.sailimpl.sync.SyncRdfSchemaRepository");SailConfig memSail = new org.openrdf.sesame.sailimpl.memory.RdfSchemaRepositoryConfig( "C:\\tmp\\myCustomRep.rdf", RDFFormat.RDFXML);

repConfig.addSail(syncSail);repConfig.addSail(memSail);repConfig.setWorldReadable(true);repConfig.setWorldWriteable(true);

As you can see, by using the SailConfig and RepositoryConfig classes, we can fine-tune the configuration of our repository. We specify the types of Sails that are to be used, any paramaters for those Sails (these are the same parameters as described in Chapter 4, Advanced repository configuration), and read and write permissions. Note that we use the utility class RdfSchemaRepositoryConfig from package org.openrdf.sesame.sailimpl.memory in this example. This class is a subclass of SailConfig with main-memory specific methods for easy configuration. Utility classes like these are available for most Sail implementations.

Now that we have created the repository specification, creating a repository object for it is a snap:

LocalRepository myCustomRepository = service.createRepository(repConfig);

The resulting LocalRepository object can then be used to add RDF data, to query the added data, etc. We will briefly illustrate this in one of the following sections.

7.2.1.2. Remote repositories

When we are using a remote Sesame server, we need to set up a connection with the remote server and identify the repository that we want to use. The code example below sets up a remote connection to a Sesame server over HTTP. The server is running at the location http://HOSTNAME/SESAME_DIR/ and we are authenticating ourselves using the username USERNAME and the password PASSWORD.

Page 57: User Guide for Sesame

6

java.net.URL sesameServerURL = new java.net.URL("http://HOSTNAME/SESAME_DIR/");SesameService service = Sesame.getService(sesameServerURL);service.login("USERNAME", "PASSWORD");

The example for RMI-based communication is nearly identical:

java.net.URI sesameServerURI = new java.net.URI("rmi://HOSTNAME:PORT/");SesameService service = Sesame.getService(sesameServerURI);service.login("USERNAME", "PASSWORD");

Please note that we are using a URL object in the HTTP example and a URI object in the RMI example.

The next step is to connect to a specific repository on this server. Assuming that we want to connect to the repository that is identified by the string remoteRepositoryID:

SesameRepository myRepository = service.getRepository("remoteRepositoryID");

Of course, all of the above may not succeed for a number of reasons, such as the user not being known, having passed an erroneous password, or perhaps the server is not available. You will need to handle the exceptions thrown for all these cases. These exceptions are all documented in the Javadoc documentation. For the sake of keeping the examples simple, we will ignore these exceptions here.

7.2.1.3. Local manipulation of server repositories

In the previous examples, we have seen how to quickly create a local repository on the spot, or how to connect through a remote communication protocol (like HTTP or RMI) to a running Sesame server. In this section, we describe a special use case of the repository API, namely one where we want to extend the functionality of a Sesame server. An example of this is the creation of a new JSP page for the server. Of course, one can communicate with the local server through the remote access method shown earlier, but Sesame also allows us to use the local access method on a running server, which is much more efficient because the data does not need to beserialized and deserialized.

The Sesame server is represented by the class org.openrdf.sesame.server.SesameServer. Among other things, this class allows us to retrieve the LocalService that is used by the server by calling the getLocalService() method:

LocalService service = SesameServer.getLocalService();

Using this object we can get to the available repositories in an identical fashion as in the local repository scenario.

Note: this method of accessing the server locally only works if the code that executes the getLocalService() method is executed within the same Java Virtual Machine as the one on which the server itself runs. For example, this can be used if you wish to add JSP pages to your website, and these JSP pages are hosted on the same server as the Sesame server. It will not work, however, if you are programming a standalone program that happens to be executed on the same machine as the Sesame server.

7.2.2. Querying a repository

Now that we have a connection to a repository (either remote or local), we want to do something with it. As you can see in the Javadoc documentation, there are a number of methods available for SesameRepository objects. We will show an example that performs a SeRQL query on a

Page 58: User Guide for Sesame

6

SesameRepository object called myRepository, retrieve the result as a table, and dumps its values to standard output:

String query = "SELECT * FROM {x} p {y}";QueryResultsTable resultsTable = myRepository.performTableQuery(QueryLanguage.SERQL, query);

int rowCount = resultsTable.getRowCount();int columnCount = resultsTable.getColumnCount();

for (int row = 0; row < rowCount; row++) { for (int column = 0; column < columnCount; column++) { Value value = resultsTable.getValue(row, column);

if (value != null) { System.out.print(value.toString()); } else { System.out.print("null"); }

System.out.print("\t"); }

System.out.println();}

A large variety of operations can be performed on repositories in a similar way as the above example. Of course, all such operations are only allowed if you have sufficient prilileges to perform the operation. This may require you to log in to the SesameService prior to obtaining the repository object. For example, if you do not have read acccess on myRepository, the above example will throw an AccessDeniedException.

7.2.3. Adding RDF data to a repository

Adding RDF to a repository can be done in several ways: the RDF can be in the form of a local file, a location on the Web, or a java String object. Individual RDF statements can not be added through the repository API. For that purpose, use the Graph API (see the next section).

The method in the Repository API for adding data is named addData() and it takes several parameters. The first parameter is the data source. This can be either a java String that contains the actual RDF, a java.net.URL that specifies the location of an RDF file on the Web, a java.io.File, or an java.io.InputStream. We will use a URL in the next example.

The addData() method takes several other parameters. The parameter baseURI specifies the base URI that any relative URIs in the data should be resolved against. format specifies the format of the data (RDF/XML, N-Triples or Turtle). verifyData is a boolean flag that specifies whether the data should be checked for syntactic correctness before attempting upload. Finally, listener specifies an AdminListener object to which status updates during upload, and possible errors and warnings, are reported.

There are several types of AdminListener available. The AdminMsgCollector collects all messages and offers convenience methods for checking e.g. whether any errors were reported. StdOutAdminListener simply prints all messages to StdOut. For other purposes, it can be useful or necessary to implement your own AdminListener. We will use the StdOutAdminListener in the following example.

java.net.URL myRDFData = new java.net.URL("http://www.foo.com/bar/myRdfFile.rdf");String baseURI = "http://my.base.uri#";

Page 59: User Guide for Sesame

6

boolean verifyData = true;AdminListener myListener = new StdOutAdminListener();

myRepository.addData(myRDFData, baseURI, RDFFormat.RDFXML, verifyData, myListener);

7.3. The Graph APIThe Graph API provides a representaton of an RDF graph in the form of a Java object. The main interface for the Graph API is org.openrdf.model.Graph. The purpose of this class is to offer a convenient way for handling RDF graphs from code. Graphs can be built by programmaticaly adding statements to it, or they can be created by evaluating a SeRQL-construct query on a Sesame repository.

In the next sections we will show how to use the Graph API in your own program.

7.3.1. Creating an empty Graph and adding statements to it

An empty graph can be acquired by simply creating a GraphImpl object:

Graph myGraph = new org.openrdf.model.impl.GraphImpl();

To add new statements to this graph, we have to create the building blocks of these statements (the subject, predicate, and object) first. This can be done using a ValueFactory object, which can be obtained from the graph, as is shown in the following example:

ValueFactory myFactory = myGraph.getValueFactory();String namespace = "http://www.foo.com/bar#";

URI mySubject = myFactory.createURI(namespace, "actor1");URI myPredicate = myFactory.createURI(namespace, "hasName");Literal myObject = myFactory.createLiteral("Tom Hanks");

myGraph.add(mySubject, myPredicate, myObject);

We have now added a single statement to the graph, namely that actor1 has a property hasName with the value "Tom Hanks".

More statements can be added in the same manner, but sometimes it is more convenient to use the URIs directly to add properties to it:

URI actorClass = myFactory.createURI(namespace, "Actor");URI rdfType = myFactory.createURI(org.openrdf.vocabulary.RDF.TYPE);mySubject.addProperty(rdfType, actorClass);

The above code adds a new statement to the graph that produced the ValueFactory that was used to create mySubject. This code is equivalent to the following:

URI actorClass = myFactory.createURI(namespace, "Actor");URI rdfType = myFactory.createURI(org.openrdf.vocabulary.RDF.TYPE);myGraph.add(mySubject, rdfType, actorClass);

7.3.2. Adding/removing a Graph to/from a repository

Now that we have created a graph, we can use it to add all of its statements to our repository:

myRepository.addGraph(myGraph);

Page 60: User Guide for Sesame

6

We can remove the graph from the repository in the same way:

myRepository.removeGraph(myGraph);

7.3.3. Creating a Graph for an existing repository

Often, you will not want to create a new graph from scratch, but rather create a graph that contains statements that are in a (local) Sesame repository. The Repository API allows you to do just this: it can produce a Graph object that wraps a local repository:

Graph myGraph = myLocalRepository.getGraph();

The produced Graph object allows you to use all of its convenience methods for manipulating the RDF graph. All changes that are made on the Graph object are directly passed on to the underlying repository.

7.3.4. Creating a graph using graph queries

In the previous section we have seen how to create a graph view for a local repository. This is easy, but it might not always be what you want: it doesn't work for remote repositories and it always gives you a "live" view of the complete contents of the repository. Sometimes you may want to create a local copy of (a subset of) the RDF graph. Graph queries can be used to accomplish this.

The Repository API offers two methods for evaluating graph queries, of which one returns a Graph object for the statements produced by the query. This method can be used to extract (a subset of) the statements from a repository into a local copy.

The following code fragment uses a SeRQL-construct query to create a Graph object containing all rdfs:subClassOf statements:

String query = "CONSTRUCT * FROM {SubClass} rdfs:subClassOf {SuperClass}";Graph classHierarchy = myRepository.performGraphQuery(QueryLanguage.SERQL, query);

A graph created in this fashion will be independent from the repository it was extracted from: changes to the graph will not be passed on to the repository.

7.3.5. Using graphs and graph queries for updates

The Graph API, in combination with graph queries, can be very useful when you wish to update (e.g. change the value of) a large number of statements in your repository.

For example, suppose we have a repository that contains a large number of statements with a property NumberOfWheels, and we wish to change the property value from "3" to "4" for each statement. To achieve this, we can do the following:

myRepository.addGraph(QueryLanguage.SERQL, "CONSTRUCT {X} <http://www.foo.com/bar#NumberOfWheels> {\"4\"} " + "FROM {X} <http://www.foo.com/bar#NumberOfWheels> {\"3\"}");

myRepository.removeGraph(QueryLanguage.SERQL, "CONSTRUCT * " + "FROM {X} <http://www.foo.com/bar#NumberOfWheels> {\"3\"}";

Page 61: User Guide for Sesame

6

What happens here is the following: the first query derives new statements from the existing NumberOfWheels statements, changing the object of these statements from "3" to "4". These new statements are then added to the repository.

The second query selects all NumberOfWheels statements with the object "3" and removes them from the repository.

Note that in this particular example the order in which the add and remove operation are executed is important: the add operation uses a query that selects all resource that have a property NumberOfWheels with value "3". If we had removed all of the matching statements first, the add operation would not have had any effect.

Ideally, one would have the posibility to use SQL-like INSERT and REPLACE queries to perform this kind of operations. Extending SeRQL with these types of queries is on the TODO list.

Chapter 8. Communication protocolsTable of Contents

8.1. Communicating over HTTP 8.1.1. Logging in 8.1.2. Logging out 8.1.3. Requesting a list of available repositories 8.1.4. Evaluating a SeRQL-select, RQL or RDQL query 8.1.5. Evaluating a SeRQL-construct query 8.1.6. Extracting RDF from a repository 8.1.7. Uploading data to a repository 8.1.8. Adding data from the web to a repository 8.1.9. Clearing a repository 8.1.10. Removing statements

In the previous chapter, we have seen how a Java application can communicate remotely with Sesame through the API. It is also possible to bypass this API (for example, when the client application is not a Java app) and communicate with a remote Sesame server directly through the HTTP protocol. In the first section of this chapter, the available actions and parameters for HTTP communication are explained.

8.1. Communicating over HTTPIn this section, the URL http://HOSTNAME/SESAME_DIR/ is used quite often. This URL is meant to indicate the location where Sesame is installed. HOSTNAME should be replaced by the name of the machine that is running Sesame. SESAME_DIR should be replaced by the directory where Sesame is installed (an empty string if Sesame is installed at the server's root directory).

To communicate with our public demo server, HOSTNAME should be replaced by www.openrdf.org and SESAME_DIR should be replaced by sesame. This yields http://www.openrdf.org/sesame/ as the location for the public demo server.

Sesame makes extensive use of multipart/form-data encoded HTTP-POST requests. The reason for this is that both HTTP-GET and x-www-form-url-encoded HTTP-POST requests can not properly handle non-ASCII characters. The %xx escape sequences used by this encoding is not able to represent byte values larger than 255.

Page 62: User Guide for Sesame

6

All requests described below use multipart/form-data encoded HTTP-POST requests, unless specified otherwise. All string values are assumed to be encoded in UTF-8. Sesame switched to using this communication style in version 1.1-RC2. For now, the server will also be able to handle the previously used x-www-form-url-encoded requests to facilitate the transition of all third-party tools.

8.1.1. Logging in

8.1.1.1. Request

In order to get access to non-public repositories on a Sesame server, one needs to log in to it. To do this, a request should be sent to http://HOSTNAME/SESAME_DIR/servlets/login, supplying the following parameters:

Table 8.1. Parameters for login

Parameter Required? Descriptionuser yes The user's login name.

password no The user's password. The password is only required in case the concerning user has a non-empty password.

8.1.1.2. Response

If the log in attempt succeeded, Sesame will respond with HTTP-code 200 ("OK") and will supply a cookie with a session ID that should be supplied for authentication in subsequent requests. The name of this cookie is sesame_sid.

8.1.1.3. Errors

If an invalid request is sent (e.g. the username is missing or the password was incorrect) Sesame will respond with an HTTP error code and a free format error message.

8.1.2. Logging out

8.1.2.1. Request

To log out from a Sesame server, one needs to send a request to http://HOSTNAME/SESAME_DIR/servlets/logout, supplying a session ID cookie that has been received earlier while logging in. Duplicate log out requests or log out requests for non-existing sessions are silently ignored.

8.1.2.2. Response

Sesame will respond with HTTP-code 200 ("OK") and a free format text telling you that you have been logged out.

8.1.3. Requesting a list of available repositories

8.1.3.1. Request

Information on available repositories can be acquired from Sesame by sending an HTTP-GET request to http://HOSTNAME/SESAME_DIR/servlets/listRepositories. This request requires no parameters, other than the optional session cookie.

Page 63: User Guide for Sesame

6

8.1.3.2. Response

Sesame will respond with HTTP-code 200 ("OK"). The body of the response contains an XML-document describing the repositories available to the user that is currently logged in (if any). This XML-document will adhere to the following DTD:

<!ELEMENT repositorylist (repository)*><!ELEMENT repository (title)><!ELEMENT title (#PCDATA)>

<!ATTLIST repository id ID #REQUIRED readable (true|false) #REQUIRED writeable (true|false) #REQUIRED>

The following is an example output with two repositories, one read-write and one read-only.

<?xml version="1.0" encoding="UTF-8"?><repositorylist> <repository id="repository1" readable="true" writeable="true"> <title>Public repository</title> </repository> <repository id="repository2" readable="true" writeable="false"> <title>Repository 2</title> </repository></repositorylist>

The value of the id attribute is the identifier of the repository. This identifier can be used in consecutive requests to Sesame to specify which repository that request is about.

8.1.4. Evaluating a SeRQL-select, RQL or RDQL query

8.1.4.1. Request

SeRQL-select, RQL and RDQL queries are all queries that return, in some way or another, sets of variable bindings or table-like results. SeRQL-construct queries are a different type of queries that return free-form RDF documents. Details about SeRQL-construct queries can be found in Evaluating a SeRQL-construct query.

SeRQL-select, RQL and RDQL queries can be sent to http://HOSTNAME/SESAME_DIR/servlets/evaluateTableQuery. The multipart/form-data encoded HTTP-POST method is the preferred method. HTTP-GET is also supported but can only be used if all parameter values consists of ASCII characters only. All requests can or must include the following parameters:

Table 8.2.  Parameters for evaluateTableQuery

Parameter Required? Descriptionrepository yes The id of the repository to evaluate the query on.query yes The query to evaluate.queryLanguage yes The query's language. Legal values are SeRQL, RQL and RDQL.

resultFormat no

Determines the format of the result. Legal values are xml (the default value) for an XML-representation of the query result, html for a human-readable HTML-table presentation and rdf for an RDF-representation of the variable bindings.

Page 64: User Guide for Sesame

6

Parameter Required? Description

serialization no The serialization to use when rdf is choosen as the resultFormat. Legal values are rdfxml (the default value), ntriples and turtle.

8.1.4.2. Response

If all went well, Sesame responds with HTTP-code 200 ("OK") and the results of the query evaluation. The resultFormat and serialization parameters determine the format of the results and the Content-Type header of the response:

Table 8.3. Response formats for SeRQL-select, RQL and RDQL queries

resultFormat

serialization Content-type Result Comments

xml - text/xml

An XML representation of the results table.

This is the default format and is the best format for processing by other applications.

html - text/html An HTML document

The results are formatted in a human-readable (when displayed in a browser) HTML-table. This format should only be used by the Sesame web interface.

rdf rdfxml application/rdf+xml

An XML-encoded RDF document

The result is an RDF document containing sets of variable bindings. This is an experimental format from Andy Seaborne and may be modified in the future. See http://www.w3.org/2003/03/rdfqr-tests/recording-query-results.html for details.

rdf ntriples text/plain

An N-Triples-encoded RDF document

The result is identical to the previous one, but uses another encoding: N-Triples. See http://www.w3.org/TR/rdf-testcases/#ntriples for more information about N-Triples.

rdf turtle application/x-turtle

A Turtle-encoded RDF document

The result is identical to the previous two, but uses yet another encoding: Turtle (Terse RDF Triple Language). See http://www.ilrt.bris.ac.uk/discovery/2004/01/turtle/ for more information about Turtle.

If the selected result format is xml, the output will look something like this:

<?xml version="1.0" encoding="UTF-8"?><tableQueryResult> <header> <columnName>X</columnName> <columnName>Y</columnName> </header> <tuple> <uri>http://www.foo.com/schema.rdf#change</uri> <literal>Change</literal> </tuple> <tuple> <bNode>node001</bNode> <literal datatype="http://www.w3.org/2001/XMLSchema#int">256</literal>

Page 65: User Guide for Sesame

6

</tuple></tableQueryResult>

The document starts with a header listing the names of all result columns. The names of these columns often represent variable names, but this is not guaranteed. Some query languages also allow you to use constants or functions in a query's projection. In that case, the name of the column will be the constant and the function, respectively.

Following the header, zero or more tuple-elements will follow, one for each query result (or row in the table). Each result consists of a sequence of URIs, bNodes (blank nodes, also know as anonymous nodes), and/or literals. The values appear in the order in which they were specified in the query, which is the same as the order in the header.

The example output above shows how URIs, bNodes and literals (with their optional language encoding or datatype) are exported. Next to these three, there is a fourth type of value that is only exported by the RQL engine: intersections of classes. If a query asks for a domain or range of a property, then this domain or range can consist of the intersection of zero or more classes. These intersections are exported in intersection elements containing zero or more URIs and bNodes:

<?xml version="1.0" encoding="UTF-8"?><tableQueryResult> <tuple> <uri>http://www.icom.com/schema1.rdf#creates</uri> <intersection> <uri>http://www.icom.com/schema1.rdf#Artifact</uri> <uri>http://www.schemas.org/general#Stuff</uri> </intersection> </tuple></tableQueryResult>

When a property doesn't have any range restrictions, its range will be an empty intersection element. Domains or ranges that consist of exactly one class are exported as normal resources (see first example), and not as intersections.

8.1.4.3. Errors

If an error occurred while the request was being processed, Sesame will send back an HTTP error code (i.e. not 200) and a free format error message.

8.1.5. Evaluating a SeRQL-construct query

8.1.5.1. Request

SeRQL-construct queries can be sent to http://HOSTNAME/SESAME_DIR/servlets/evaluateGraphQuery. The multipart/form-data encoded HTTP-POST method is the preferred method. HTTP-GET is also supported but can only be used if all parameter values consists of ASCII characters only. All requests can or must include the following parameters:

Table 8.4. Parameters for evaluateGraphQuery

Parameter Required? Descriptionrepository yes The id of the repository to evaluate the query on.query yes The query to evaluate.

Page 66: User Guide for Sesame

6

Parameter Required? DescriptionqueryLanguage yes The query's language. Currently, the only legal value is SeRQL.

serialization no Determines the serialization format of the returned RDF document. Legal values are rdfxml (the default value), ntriples and turtle.

8.1.5.2. Response

If all went well, Sesame responds with HTTP-code 200 (i.e. "OK") and the results of the query evaluation. The serialization parameter determines the encoding of the returned RDF document and the Content-Type header of the response:

Table 8.5. RDF encodings for SeRQL-construct queries

Serialization Content-type RDF encoding Comments

rdfxml application/rdf+xmlXML-encoded RDF.

This is the official standard format for exchanging RDF documents. See http://www.w3.org/RDF/ for more info.

ntriples text/plain N-TriplesThis is a quite verbose, line-based encoding that is the easiest one to parse. See http://www.w3.org/TR/rdf-testcases/#ntriples for more info.

turtle application/x-turtle Turtle

Turtle stands for Terse RDF Triple Language and is developed by Dave Beckett to combine useful features of N3 and N-Triples into an easy-to-read-and-parse serialization format. See http://www.ilrt.bris.ac.uk/discovery/2004/01/turtle/ for more info.

What follows are three examples of one and the same RDF document (a possible query result) in different encodings.

XML-encoded RDF:

<?xml version="1.0" encoding="UTF-8"?><rdf:RDF xml:lang="en" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cult="http://www.icom.com/schema.rdf#">

<cult:Cubist rdf:about="http://www.european-history.com/picasso.html"> <cult:paints> <cult:Painting rdf:about="http://www.european-history.com/jpg/guernica03.jpg"> <cult:technique>oil on canvas</cult:technique> </cult:Painting> </cult:paints> <cult:first_name>Pablo</cult:first_name> <cult:last_name>Picasso</cult:last_name> </cult:Cubist></rdf:RDF>

N-Triples:

<http://www.european-history.com/picasso.html> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.icom.com/schema.rdf#Cubist>.<http://www.european-history.com/picasso.html> <http://www.icom.com/schema.rdf#paints> <http://www.european-history.com/jpg/guernica03.jpg>.

Page 67: User Guide for Sesame

6

<http://www.european-history.com/jpg/guernica03.jpg> <http://www.w3.org/1999/02/22-rdf-syntax#type> <http://www.icom.com/schema.rdf#Painting>.<http://www.european-history.com/jpg/guernica03.jpg> <http://www.icom.com/schema.rdf#technique> "oil on canvas"@en.<http://www.european-history.com/picasso.html> <http://www.icom.com/schema.rdf#first_name> "Pablo"@en.<http://www.european-history.com/picasso.html> <http://www.icom.com/schema.rdf#last_name> "Picasso"@en.

Turtle:

@prefix cult: <http://www.icom.com/schema.rdf#> .@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

<http://www.european-history.com/jpg/guernica03.jpg> a cult:Painting ; cult:technique "oil on canvas"@en .<http://www.european-history.com/picasso.html> a cult:Cubist ; cult:paints <http://www.european-history.com/jpg/guernica03.jpg> ; cult:first_name "Pablo"@en ; cult:last_name "Picasso"@en .

8.1.5.3. Errors

If an error occurred while the request was being processed, Sesame will send back an HTTP error code (i.e. not 200) and a free format error message.

8.1.6. Extracting RDF from a repository

8.1.6.1. Request

Ontologies and data can be extracted from Sesame by sending a request to http://HOSTNAME/SESAME_DIR/servlets/extractRDF. This operation supports both multipart/form-data encoded HTTP-POST requests as well as HTTP-GET requests. Note that the latter can not be used when one of the parameter values contains non-ASCII characters.

The request must or can have the following parameters:

Table 8.6. Parameters for extractRDF

Parameter Required? Descriptionrepository yes The id of the repository to extract the data from.

schema noRdfExport will export the schematical data if the value of this parameter is on. The schematical data will not be exported if this parameter is missing or if it has any other value.

data noRdfExport will export the non-ontological data if the value of this parameter is on. This data will not be exported if this parameter is missing or if it has any other value.

explicitOnly noRdfExport will only export the explicitly added statements if the value of this parameter is on. If this parameter is missing or if it has any other value, all relevant statements (both explicit and inferred) will be exported.

niceOutput no

RdfExport will invest extra effort into making the exported data more readable to humans (e.g. by sorting statements by their subject) if the value of this parameter is on. If this parameter is missing or if it has any other value, no such effort is made, allowing RdfExport to export the data as efficiently as possible.

Page 68: User Guide for Sesame

6

Parameter Required? Description

serialization no Determines the serialization of the resulting RDF document. Legal values are rdfxml (the default value), ntriples and turtle.

So, to extract the ontological data only (both explicit and inferred) from a repository test-db on host www.openrdf.org you can send an HTTP-GET request to the url http://www.openrdf.org/sesame/servlets/extractRDF?repository=test-db&serialization=rdfxml&onto=on.

8.1.6.2. Response

If all went well, Sesame responds with HTTP-code 200 ("OK"). The body of the response contains the requested data. The serialization parameter determines the encoding and the Content-Type header of the response identically to what is described in Table 8.5, “RDF encodings for SeRQL-construct queries”.

8.1.6.3. Errors

If an invalid request is sent (e.g. the repository does not exist) Sesame will respond with an HTTP error code and a free format error message.

8.1.7. Uploading data to a repository

8.1.7.1. Request

Data can be uploaded to Sesame by sending it to http://HOSTNAME/SESAME_DIR/servlets/uploadData, supplying the following parameters:

Table 8.7. Parameters for uploadData

Parameter Required? Descriptionrepository yes The id of the repository to which to add the data.

data yes The RDF data that should be added to the repository. The format of the data should match the value of the dataFormat parameter.

dataFormat no The format of the data that is uploaded to Sesame. Legal values are rdfxml (the default value), ntriples and turtle.

baseURI noSpecifies the base URI of the data for resolving any relative URIs. This parameter defaults to foo:bar, which is fine if the uploaded data does not contain any relative URIs.

verifyData no

The uploaded data will be verified before it is actually added to a repository if the value of this parameter is on. If this parameter is missing or if it has any other value, the data will be added directly to the repository. Verification of the data should only be disabled if the data to upload is guaranteed to be correct.

resultFormat no Determines the response format. Legal values are xml (the default value) and html.

8.1.7.2. Response

Page 69: User Guide for Sesame

6

The response is always an HTTP-code 200 ("OK"). Streaming feedback is given on the progress, and warnings and errors are given if the data contains errors. If the selected format was html, then this feedback will be formatted in human-readable HTML (when displayed in a browser). If the selected format was xml, then the feedback will adhere to the following DTD:

<!ELEMENT transaction (status | notification | warning | error)*><!ELEMENT status (msg, line?, column?)><!ELEMENT notification (msg, line?, column?, statement?)><!ELEMENT warning (msg, line?, column?, statement?)><!ELEMENT error (msg, line?, column?, statement?)>

<!ELEMENT msg (#PCDATA)><!ELEMENT line (#PCDATA)><!ELEMENT column (#PCDATA)>

<!ELEMENT statement ( (uri|bNode), uri, (uri|bNode|literal) )><!ELEMENT uri (#PCDATA)><!ELEMENT bNode (#PCDATA)><!ELEMENT literal (#PCDATA)><!ATTLIST literal xml:lang CDATA #IMPLIED datatype CDATA #IMPLIED>

The following is a simple example of what the feedback might look like when incorrect data is uploaded to Sesame:

<?xml version="1.0" encoding="UTF-8"?><transaction> <status> <msg>Loading data</msg> </status> <status> <msg>Data loaded (756 bytes)</msg> </status> <status> <msg>Checking data for errors</msg> </status> <error> <msg>Not a legal integer: Hello World!</msg> <line>483</line> <column>42</column> <statement> <bNode>node1234</bNode> <uri>http://example.org/schema.rdf#age</uri> <literal datatype="http://www.w3.org/2001/XMLSchema#int">Hello World!</literal> </statement> </error></transaction>

8.1.7.3. Errors

Errors in the requests are signaled using HTTP error codes. Errors in the data are expressed in the streaming feedback.

8.1.8. Adding data from the web to a repository

8.1.8.1. Request

Data can also be added to a repository by specifying a URL that points to the RDF data that should be added. To do this, send an HTTP-POST request to http://HOSTNAME/SESAME_DIR/servlets/uploadURL, supplying the following parameters:

Page 70: User Guide for Sesame

6

Table 8.8. Parameters for uploadData

Parameter Required? Descriptionrepository yes The id of the repository to which to add the data.

url yesA URL pointing at the RDF data that should be added to the repository. The format of the data at the specified location should match the value of the dataFormat parameter.

dataFormat no The format of the data that is at the specified URL. Legal values are rdfxml (the default value), ntriples and turtle.

baseURI no Specifies the base URI of the data for resolving any relative URIs. This parameter defaults to the value of url.

verifyData no

The data at the specified URL will be verified before it is actually added to a repository if the value of this parameter is on. If this parameter is missing or if it has any other value, the data will be added directly to the repository. Verification of the data should only be disabled if the data to upload is guaranteed to be correct.

resultFormat no Determines the response format. Legal values are xml (the default value) and html.

8.1.8.2. Response

The response format is identical to what is described in Data upload response format.

8.1.8.3. Errors

Errors in the requests are signaled using HTTP error codes. Errors in the data are expressed in the streaming feedback.

8.1.9. Clearing a repository

8.1.9.1. Request

Data can be removed from Sesame by sending a request to http://HOSTNAME/SESAME_DIR/servlets/clearRepository. The following parameters are relevant to clearing a repository:

Table 8.9. Parameters for clearRepository

Parameter Required? Descriptionrepository yes The id of the repository that should be cleared.

resultFormat no Determines the response format. Legal values are xml (the default value) and html.

8.1.9.2. Response

Identical to the reponse when adding data to a repository. See See Data upload response format. for more information.

8.1.9.3. Errors

Page 71: User Guide for Sesame

6

Errors in the requests are signaled using HTTP error codes. Errors that occured while clearing the repository are expressed in the streaming feedback.

8.1.10. Removing statements

8.1.10.1. Request

Data can be removed from Sesame by sending a requests to http://HOSTNAME/SESAME_DIR/servlets/removeStatements. Currently, Sesame only support removing of statements using statement patterns: one can specify a subject, predicate and/or object and all statements that match that pattern will be removed. The following parameters are relevant to the removal of statements:

Table 8.10. Parameters for removeStatements

Parameter Required? Descriptionrepository yes The id of the repository from which the statements should be removed.

subject noAn N-Triples encoded URI or bNode specifying the subject of the statements that should be removed. If not specified, statements with any subject will be removed.

predicate noAn N-Triples encoded URI specifying the predicate of the statements that should be removed. If not specified, statements with any predicate will be removed.

object noAn N-Triples encoded URI, bNode or literal specifying the object of the statements that should be removed. If not specified, statements with any object will be removed.

resultFormat no Determines the result format. Legal values are xml (the default value) and html.

8.1.10.2. Response

Identical to the reponse when adding data to a repository. See Data upload response format for more information.

8.1.10.3. Errors

Errors in the requests are signaled using HTTP error codes. Errors that occured while removing statements from the repository are expressed in the streaming feedback.

Chapter 9. Frequently Asked QuestionsTable of Contents

9.1. General Questions 9.1.1. I've got a Sesame-related question, where can I get an answer? 9.1.2. Something goes wrong when I use Sesame, what do I do? 9.1.3. How do I report a bug? 9.1.4. Why doesn't Sesame support $FEATURE? 9.1.5. I need $FEATURE right now! 9.1.6. Can you keep me informed of any Sesame-related news?

Page 72: User Guide for Sesame

6

9.1.7. Is this user guide the only documentation for Sesame?9.2. Troubleshooting

9.2.1. I get a "HTTP error 500" message in the toolbar frame 9.2.2. I get a "HTTP error 500" message in the main frame 9.2.3. I get "error while adding new triples: Invalid byte 2 of 3-byte UTF-8 sequence" 9.2.4. I get a warning: "Unable to set namespace prefix 'foo' for namespace ..." 9.2.5. My in-memory repository is very slow and/or runs out of memory 9.2.6. On upload I get an error "java.lang.IllegalStateException: Post too large" 9.2.7. Can not evaluate directSubClassOf on a non-inferencing repository

9.1. General Questions9.1.1. I've got a Sesame-related question, where can I get an answer?

First of all, please make sure that your question is not already answered in this user guide. If it isn't, then feel free to post your question on the openRDF.org forum. To avoid off-topic discussions (a.k.a. "spam"), you'll have to register yourself before you can post to the forum. Also, we don't like to talk to "anonymous" all the time.

Please don't send any questions to the developers directly, unless the question is related to the public server or is somewhat confidential.

9.1.2. Something goes wrong when I use Sesame, what do I do?

In general, when something does not work as expected in Sesame, or you get an error, try and find the cause of the error before reporting it to us. See if the error message tells you anything. Check the Sesame log files in [SESAME_DIR]/WEB-INF/logs for any clues about what went wrong.

Also, check the documentation and forum to see if your problem is described there somewhere. In Section 9.2, “Troubleshooting” we provide a number of possible causes and solutions to regularly-occurring problems. On the forum, we answer user problems, your problem might have come up before, and our answer to that other person might be useful for you as well.

If you can't find any relevant information for your problem anywhere, feel free to report a bug or post a comment on the forum.

9.1.3. How do I report a bug?

If you have found a bug in Sesame then you can log it directly in the issue tracker. Please make sure that the bug is not a duplicate of an already logged issue. If you are not sure that your problem is caused by a bug in Sesame then feel free to post a description of your problem on the forum.

When posting a bug report to either issue tracker or forum, always make sure to include detailed information: in what circumstances does the bug occur, what version of Sesame are you using, what type of repository (RDBMS, in-memory, inferencing, etc.) are you using, and if available provide an exception stacktrace.

9.1.4. Why doesn't Sesame support $FEATURE?

Page 73: User Guide for Sesame

6

Sesame is used by a diverse group of people for very different purposes, who all demand different features to be implemented in Sesame. Since there are only 24 hours in a day, we can not please everybody all the time. Instead, we try to assess as best we can which features are most important for the largest part of Sesame's user base. Also, we give priority to features that we need for our own work with Sesame.

So, if Sesame doesn't support a particular feature, but this feature 'should be in any self-respecting RDF framework', chances are that we simply haven't had time for it yet. Try and see if the feature has come up on Sesame's issue tracker or web forum. If it hasn't, don't be shy to raise the issue. If you've come up with something you'd really like to see included in Sesame, we'd like to know about it.

9.1.5. I need $FEATURE right now!

There is a number of ways you can make sure a particular feature is added to Sesame:

You can let us know of your need, explaining why it is crucial, through the web forum or issue tracker (by adding a new item or by voting for an existing issue). Of course, there is no guarantee that we will immediately move it to the top of our ToDo pile.

You can implement it yourself. Yes, that's right: Sesame is open source, and we thrive on community feedback, not just in the form of comments and bug reports, but also of code contributions. If you need some feature or improvement real bad, consider implementing it yourself and sharing the result with the rest of the Sesame community. We'd be overjoyed to receive your contribution and include it in Sesame.

You can pay Aduna to implement it for you. Aduna offers commercial support contracts for Sesame, and if special features are something you need, we can provide that as part of such support. Contact [email protected] for detailed information.

9.1.6. Can you keep me informed of any Sesame-related news?

Sesame-related news items, such as release announcements, are sent to the sesame-interest mailing list, which is hosted by SourceForge. Please subscribe yourself to the mailing list if you want to be kept informed. Please note that this is a restricted mailing list: it can not be used for discussing Sesame-related issues.

If you want to keep up-to-date on Sesame developments in more detail, consider joining the web forum. The forum also provides an RSS feed that will provide you with the most recent topics of discussion. Ideal for staying in touch with the community!

9.1.7. Is this user guide the only documentation for Sesame?

No, it isn't. The project's website contains a number of references to research papers and Sesame-related projects.

9.2. TroubleshootingIn this section, we identify some commonly encountered problems with the installation, configuration and use of Sesame, and possible solutions.

Page 74: User Guide for Sesame

6

Of course, not all possible problems can be found here. If you have a problem that is not described here, you can get feedback on how to deal with it by posting a message to the openRDF.org forum. Include as many relevant details as possible, for example, which version of Sesame you are using, possible java exceptions, log error messages, and so forth.

9.2.1. I get a "HTTP error 500" message in the toolbar frame

There are several possible reasons for this error. HTTP error 500 is a generic code that means 'Internal server error'. It often helps to try and scroll down in the toolbar frame (by selecting the text with the mouse), there will be more detailed error report further down.

There are several possible problems:

The JDBC driver can not be found

This means that you have tried to access an RDBMS-based repository for which no JDBC driver is installed. Make sure that you have the correct JDBC driver, and have it installed in [SESAME_DIR]/WEB-INF/lib.

The database does not exist

This means that you have tried to access a repository for which no database was created. Verify in your repository configuration that the parameter jdbcUrl is set correctly, and verify that the database is created and accessible for Sesame (for details on how to do this, we refer you to the documentation of your RDBMS).

Access denied for user 'sesame'@'localhost'

This means that the the supplied MySQL user ('sesame') does not have sufficient access rights.

Sesame will need a user account on the MySQL server. You can create a new user account in MySQL by connecting to the mysql database mysql -u root -p mysql, and by granting the user all privileges on the concerning database(s), e.g.:

GRANT ALL ON <DATABASE>.* TO <USER>@localhost;

See http://www.mysql.com/doc/G/R/GRANT.html for MySQL's syntax of GRANT.

Other less common problems may also cause this error. In general, take a good look at the detailed error message or the repository log file (in [SESAME_DIR]/WEB-INF/logs/repositories/) to find out the cause of the problem.

9.2.2. I get a "HTTP error 500" message in the main frame

After upgrading a Sesame server to a new version of Sesame, it may occur that the web interface fails with a HTTP error 500 and an error report similar to the following:

javax.servlet.ServletException: org.openrdf.sesame.server.SesameServer.getLocalService()Lorg/openrdf/sesame/local/LocalService;(....)

Page 75: User Guide for Sesame

6

root cause

java.lang.NoSuchMethodError: org.openrdf.sesame.server.SesameServer.getLocalService()Lorg/openrdf/sesame/local/LocalService;org.apache.jsp.index_jsp._jspService(index_jsp.java:77)(....)

The root cause here indicates that the JSP page is not correctly compiled: it can not find a particular Java method.

The cause is that Apache Tomcat sometimes fails to recompile JSP pages after they have been updated. The compiled JSP pages still refer to methods in the old version of Sesame, which may not be present anymore in your new version (this is most likely to occur when upgrading to 1.0 from an earlier release, since a lot of API changes were made for that version).

The solution is to empty Tomcat's JSP compile cache. For Tomcat 4 this cache can be found in [TOMCAT_DIR]\work\Standalone\localhost\sesame, for Tomcat 5 in [TOMCAT_DIR]\work\Catalina\localhost\sesame. Simply delete all files and folders contained in this directory and re-load the web interface.

9.2.3. I get "error while adding new triples: Invalid byte 2 of 3-byte UTF-8 sequence"

This is a parser error that can occur during upload of RDF/XML documents to Sesame. The most likely cause is that the document you are uploading specifies that it is in UTF-8 encoding, but that it contains non-UTF-8 characters. As UTF-8 is the default character set for XML, it might also be the case that the document does not specify a character set at all.

The solution is to change the encoding specification of the XML file to the appropriate type. For example, if the used character set is ISO-8859-1 (this is one of the most common character sets for "Western" documents), the header of the XML file should be changed to:

<?xml version="1.0" encoding="iso-8859-1"?>

More information about character encodings can be found here.

9.2.4. I get a warning: "Unable to set namespace prefix 'foo' for namespace ..."

This happens when you try to upload data to a repository which already contains a namespace declaration with the prefix 'foo', but which maps it to a different namespace URL. In such cases, a conflict occurs. Sesame handles these cases by assigning a non-conflicting namespace prefix to the namespace in the new document (for example, 'ns1').

Most of the time, you can safely ignore this warning. Sometimes it indicates a problem with your RDF document: it may have a mistake in its namespace declarations. In such cases, examine the namespace declarations in your RDF document and fix any errors before attempting another upload.

9.2.5. My in-memory repository is very slow and/or runs out of memory

By default, Tomcat only uses a 64MB heap size for the Java process. When you are using a large in-memory repository, this can be too small: the process becomes slow because the garbage collector is invoked more often, and it can even run out of memory.

The solution is to configure Tomcat to use a larger heap size. This can be done by editing [TOMCAT_DIR]/bin/catalina.bat (MS Windows) or catalina.sh (Unix systems). You can increase

Page 76: User Guide for Sesame

6

the heap size by adding a parameter to the environment variable JAVA_OPTS. The parameter to be added is '-Xmx128M' (where the number 128 indicates that 128 Megabytes should be used. Increase as required). For catalina.bat there now should be a line in your file that looks like this:

set JAVA_OPTS=-Xmx128M

For catalina.sh the line should look like this:

JAVA_OPTS='-Xmx128M'

For more information on Tomcat memory reservation, see the Tomcat FAQ.

9.2.6. On upload I get an error "java.lang.IllegalStateException: Post too large"

Apache Tomcat by default sets a limit on the maximum size of HTTP POST requests it accepts. In Tomcat 5, this limit is set to 2 MB. When you try to upload RDF files larger than 2 MB to Sesame, this error can occur.

The solution is to reconfigure Tomcat to accept larger POST requests, either by increasing the limit, or by disabling it. This can be done by editing [TOMCAT_DIR]/conf/server.xml. Set the Tomcat configuration parameter maxPostSize for the HTTPConnector to a larger value (in bytes) to increase the limit. Setting it to 0 in will disable the size check. See the Tomcat Configuration Reference for more information.

9.2.7. Can not evaluate directSubClassOf on a non-inferencing repository

When executing queries that use a SeRQL built-in operator, such as directSubClassOf (see Chapter 6, The SeRQL query language (revision 1.2)), this error may occur:

org.openrdf.sesame.query.QueryEvaluationException: Can not evaluate directSubClassOf on a non-inferencing repository

This indicates that the repository you are trying to evaluate this query on is an RDF repository, not an RDF Schema repository. The former does not have inferencing capabilities.

SeRQL needs an inferencing repository for evaluating queries with built-in operators, because these operators work on the class hierarchy. Without inferencing support, the results of these operators would become random and unpredictable.

The solution is to either reformulate your query, removing all use of SeRQL built-in operators, or create a new repository that does have inferencing capabilities (an RdfSchemaRepository), transfer your RDF data to it, and use this new repository for your queries.

Appendix A. GNU Free Documentation LicenseTable of Contents

A.1. PREAMBLE A.2. APPLICABILITY AND DEFINITIONS A.3. VERBATIM COPYING A.4. COPYING IN QUANTITY A.5. MODIFICATIONS

Page 77: User Guide for Sesame

6

A.6. COMBINING DOCUMENTS A.7. COLLECTIONS OF DOCUMENTS A.8. AGGREGATION WITH INDEPENDENT WORKS A.9. TRANSLATION A.10. TERMINATION A.11. FUTURE REVISIONS OF THIS LICENSE A.12. How to use this License for your documents

Version 1.1, March 2000

Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

A.1. PREAMBLEThe purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

A.2. APPLICABILITY AND DEFINITIONSThis License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.

Page 78: User Guide for Sesame

6

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

A.3. VERBATIM COPYINGYou may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

A.4. COPYING IN QUANTITYIf you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

Page 79: User Guide for Sesame

6

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

A.5. MODIFICATIONSYou may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).

C. State on the Title page the name of the publisher of the Modified Version, as the publisher.

D. Preserve all the copyright notices of the Document.

E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.

H. Include an unaltered copy of this License.

I. Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

Page 80: User Guide for Sesame

6

J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

K. In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

M. Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.

N. Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

A.6. COMBINING DOCUMENTSYou may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique

Page 81: User Guide for Sesame

6

number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."

A.7. COLLECTIONS OF DOCUMENTSYou may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

A.8. AGGREGATION WITH INDEPENDENT WORKSA compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.

A.9. TRANSLATIONTranslation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.

A.10. TERMINATIONYou may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

Page 82: User Guide for Sesame

6

A.11. FUTURE REVISIONS OF THIS LICENSEThe Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

A.12. How to use this License for your documentsTo use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".

If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

_______________________________________________