8 Sesame Adapter for Oracle Database

The Sesame Adapter for Oracle Database (referred to here as the Sesame Adapter) integrates the popular Sesame Java APIs with Oracle Semantic Technologies support. Sesame, created by OpenRDF (http://www.openrdf.org/), "is an open source framework for storage, inferencing and querying of RDF data."

This chapter assumes that you are familiar with major concepts explained in Chapter 1, "Oracle Database Semantic Technologies Overview" and Chapter 2, "OWL Concepts". It also assumes that you are familiar with the overall capabilities and use of the Sesame Java framework. For information about the Sesame framework, see the Sesame Documentation page at http://www.openrdf.org/documentation.jsp.

The Sesame Adapter extends the semantic data management capabilities of Oracle Database Release 11.2 RDF/OWL.

This chapter includes the following major topics:

8.1 Sesame Adapter Overview

Like the Jena Adapter (described in Chapter 7), the Sesame Adapter provides a Java-based interface to Oracle semantic data through an open source framework and related tools. However, the Sesame Adapter adds support for context to the data:

  • Jena statements deal with triples (subject, predicate, object).

  • Sesame statements deal with triples and contexts; a Sesame statement is a quad consisting of a triple and a context. For example, with hospital patient data, the context might contain the patient's URI.

The Sesame Adapter provides a Java API for interacting with semantic data stored in Oracle Database. It also provides integration with the following Sesame tools:

  • Sesame Server, which provides an HTTP SPARQL endpoint.

  • Sesame Console, a command-line tool for creating and managing repositories. The available commands include the following:

    connect  Connects to a (local or remote) set of repositories
    disconnect  Disconnects from the current set of repositories
    create  Creates a new repository
    drop  Drops a repository
    open  Opens a repository to work on, takes a repository ID as argument
    close  Closes the current repository
    show  Displays an overview of various resources
    load  Loads a data file into a repository, takes a file path or URL as argument
    verify  Verifies the syntax of an RDF data file, takes a file path or URL as argument
    clear  Removes data from a repository
    serql  Evaluates the SeRQL query, takes a query as argument
    sparql  Evaluates the SPARQL query, takes a query as argument
    set  Allows various console parameters to be set
    exit, quit  Exits the console
    
  • OpenRDF Workbench, a graphical user interface to the Sesame Server.

The features provided by the Sesame Adapter include:

  • Loading (bulk and incremental), exporting, and removing statements, with and without context

  • Querying of data, with and without context

  • Inferencing, where inferred data is considered during query execution (if includeInferred=true), and where inferred triples have a null context

  • Managing namespaces

The Sesame Adapter for Oracle Database implements various interfaces of the Sesame Storage and Inference Layer (SAIL) API. For example, the class OracleSailConnection is an Oracle implementation of the Sesame SailConnection interface, and the class OracleSailStore is an Oracle implementation of the Sesame Sail interface.

A typical usage flow for the Sesame Adapter might include the excerpt shown in Example 8-1.

Example 8-1 Sample Usage flow for Sesame Adapter

String query =
" PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
" PREFIX dc: <http://purl.org/dc/elements/1.1/> "
" select ?s ?p ?o ?name WHERE {?s ?p ?o . OPTIONAL {?o foaf:name ?name .} } ";

SailRepository sr = new SailRepository(
   new OracleSailStore(oracle, modelName,…attachmentForInference));
RepositoryConnection repConn = sr.getConnection();
// Data loading can happen here.
repConn.add(alice, friendOf, bob, context1);
 
TupleQuery tq = repConn.prepareTupleQuery(QueryLanguage.SPARQL, query);
TupleQueryResult tqr = tq.evaluate();
while(tqr.hasNext()) {
    psOut.print((tqr.next().toString()));
};
tqr.close()
repConn.close();
sr.shutDown();

8.2 Setup and Configuration for the Sesame Adapter

Setting up and configuring the Sesame Adapter for Oracle Database involves the following actions:

  1. Setting Up the Software Environment

  2. Setting Up the SPARQL Service

  3. Setting Up the Semantic Technologies Environment

8.2.1 Setting Up the Software Environment

To use the Sesame Adapter, you must first ensure that the system environment has the necessary software, including Oracle Database 11g Release 2 with the Spatial and Partitioning options and with Semantic Technologies support enabled, Sesame version 2.3.1, the Sesame Adapter, and JDK 6. You can set up the software environment by performing these actions:

  1. Install Oracle Database Release 11.2 Enterprise Edition with the Oracle Spatial and Partitioning Options.

  2. Enable the support for Semantic Technologies, as explained in Section A.1.

  3. Download the Sesame 2.3.1 onejar library and include it in your classpath, as explained in the "Setting up to use the Sesame libraries" chapter of the User Guide for Sesame 2.2. (See http://openrdf.callimachus.net/sesame/2.7/docs/users.docbook?view, or a more recent version if available.)

  4. Install the Sesame 2.3.1 Server, as explained in the "Server software installation" chapter of the User Guide for Sesame 2.2. (See http://openrdf.callimachus.net/sesame/2.7/docs/users.docbook?view, or a more recent version if available.)

  5. Download the Sesame Adapter (sesame_adapter_for_release11.2.zip) from the Oracle Database Semantic Technologies page (http://www.oracle.com/technetwork/database/options/semantic-tech/and click Downloads), and unzip it into a temporary directory, such as (on a Linux system) /tmp/sesame_adapter. (If this temporary directory does not already exist, create it before the unzip operation.)

    The Sesame Adapter directories and files have the following structure:

     examples/
       examples/Example1.java
       examples/Example2.java
       .
       .
       .
    lib/
       lib/sdordfsesame.jar
    web/
       web/web.xml
    javadoc/
       javadoc/javadoc.zip
    
  6. Copy ojdbc6.jar into <Sesame_DIR>/lib (Linux) or <Sesame_DIR>\lib (Windows). (ojdbc6.jar is in $ORACLE_HOME/jdbc/lib or %ORACLE_HOME%\jdbc\lib.)

  7. Copy sdordf.jar into <Sesame_DIR>/lib (Linux) or <Sesame_DIR>\lib (Windows). (sdordf.jar is in $ORACLE_HOME/md/jlib or %ORACLE_HOME%\md\jlib.)

  8. If JDK 6 is not already installed, install it.

  9. If the JAVA_HOME environment variable does not already refer to the JDK 6 installation, define it accordingly. For example:

    setenv JAVA_HOME /usr/local/packages/jdk16/
    
  10. If the SPARQL service to support the SPARQL protocol is not set up, set it up as explained in Section 8.2.2.

After setting up the software environment, ensure that your Semantic Technologies environment can enable you to use the Sesame Adapter to perform queries, as explained in Section 8.2.3.

8.2.2 Setting Up the SPARQL Service

Setting up a SPARQL endpoint using the Sesame Adapter involves downloading the Sesame Server, with which client applications can communicate over HTTP protocol. The Sesame Server (and OpenRDF Workbench) is bundled with the Sesame 2.3.1 release package. This section explains how to set up a SPARQL service using a servlet deployed in WebLogic Server. The number and complexity of the steps reflect the fact that Oracle is not permitted to bundle all the dependent third-party libraries in a .war or .ear file.

  1. Download and Install Oracle WebLogic Server 11g Release 1 (10.3.1). For details, see http://www.oracle.com/technology/products/weblogic/.

  2. Ensure that you have Java 6 installed, because it is required by Sesame.

  3. Download the Sesame 2.3.1 release package (in .zip format) from http://sourceforge.net/projects/sesame/files/Sesame%202/.

  4. Unpack the .zip file into a temporary directory. For example:

    mkdir /tmp/sesame
    cp openrdf-sesame-2.3.1-sdk.zip /tmp/sesame/
    cd /tmp/sesame
    unzip openrdf-sesame-2.3.1-sdk.zip
    
  5. Ensure that you have downloaded and unzipped the Sesame Adapter for Oracle Database, as explained in Section 8.2.1.

  6. Create a directory named openrdf-sesame.war at the same level as the Sesame_adapter directory, and go to it. For example:

    /tmp/openrdf-sesame.war
    cd /tmp/openrdf-sesame.war
    
  7. Unzip necessary files into the directory created in the preceding step:

    cd /tmp/openrdf-sesame.war
    unzip /tmp/sesame/openrdf-sesame-2.3.1/war/openrdf-sesame.war
    
  8. Copy necessary files, as follows. (Assume that ORACLE_HOME points to the home directory of a Release 11.2 Oracle Database.)

    cp /tmp/Sesame_adapter/web/web.xml /tmp/openrdf-sesame.war/WEB-INF/web.xml 
    cp /tmp/Sesame_adapter/lib/*.jar   /tmp/openrdf-sesame.war/WEB-INF/lib
    cp $ORACLE_HOME/md/jlib/sdordf.jar /tmp/openrdf-sesame.war/WEB-INF/lib
    cp $ORACLE_HOME/jdbc/lib/ojdbc6.jar /tmp/openrdf-sesame.war/WEB-INF/lib
    
  9. Using the WebLogic Server Administration console, create a J2EE data source named OracleSemDS. During the data source creation, you can specify a user and password for the database schema that contains the relevant semantic data against which SPARQL queries are to be executed.

    If you need help in creating this data source, see Section 8.2.2.1, "Creating the Required Data Source Using WebLogic Server".

  10. Go to the autodeploy directory of WebLogic Server and copy files, as follows. (For information about auto-deploying applications in development domains, see: http://docs.oracle.com/cd/E11035_01/wls100/deployment/autodeploy.html)

    cd <domain_name>/autodeploy
    cp -rf  /tmp/openrdf-sesame.war  <domain_name>/autodeploy
    

    In the preceding example, <domain_name> is the name of a WebLogic Server domain.

    Note that while you can run a WebLogic Server domain in two different modes, development and production, only development mode allows you use the auto-deployment feature.

  11. Check the files and the directory structure, as in the following example:

    autodeploy/% ls -1R ./openrdf-sesame.war/
     
    openrdf-sesame.war/:
    favicon.ico
    favicon.png
    images
    META-INF
    styles
    WEB-INF
     
    openrdf-sesame.war/images:
    DEBUG.png
    ERROR.png
    INFO.png
    logo.png
    productgroup.png
    transparent.png
    WARN.png
     
    openrdf-sesame.war/META-INF:
    MANIFEST.MF
    maven
     
    openrdf-sesame.war/META-INF/maven:
    info.aduna.appbase
    org.openrdf.sesame
     
    openrdf-sesame.war/META-INF/maven/info.aduna.appbase:
    aduna-appbase-webapp-system
     
    openrdf-sesame.war/META-INF/maven/info.aduna.appbase/aduna-appbase-webapp-system:
    pom.properties
    pom.xml
     
    openrdf-sesame.war/META-INF/maven/org.openrdf.sesame:
    sesame-http-server
     
    openrdf-sesame.war/META-INF/maven/org.openrdf.sesame/sesame-http-server:
    pom.properties
    pom.xml
     
    openrdf-sesame.war/styles:
    basic
    default
    msie-png-alpha.css
    msie-png-alpha.png
    w3-html40-recommended.css
     
    openrdf-sesame.war/styles/basic:
    all.css
     
    openrdf-sesame.war/styles/default:
    images
    msie-minheight.css
    print.css
    screen.css
     
    openrdf-sesame.war/styles/default/images:
    bg_body.png
    bg_header.png
    bg_html.png
    hr_menu.png
     
    openrdf-sesame.war/WEB-INF:
    aduna-webapp-servlet.xml
    aduna-webapp-system-servlet.xml
    classes
    includes
    lib
    openrdf-http-server-servlet.xml
    sample-web.xml
    taglibs
    tags
    urlrewrite.xml
    views
    web.xml
     
    openrdf-sesame.war/WEB-INF/classes:
    logback.xml
     
    openrdf-sesame.war/WEB-INF/includes:
    components
    stylesheets.html.jspf
    taglibs.jspf
     
    openrdf-sesame.war/WEB-INF/includes/components:
    bodyStart.html.jspf
    bodyStop.html.jspf
    ContentHeader.html.jspf
    Footer.html.jspf
    Header.html.jspf
    head.html.jspf
    htmlStart.html.jspf
    htmlStop.html.jspf
    logfilterform.html.jspf
    logpaginationfooter.html.jspf
    logpaginationheader.html.jspf
    Message.html.jspf
    Navigation.html.jspf
    page.html.jspf
    tabs.html.jspf
     
    openrdf-sesame.war/WEB-INF/lib:
    activation-1.1.jar
    aduna-appbase-core-3.9.0.jar
    aduna-appbase-logging-api-3.9.0.jar
    aduna-appbase-logging-file-3.9.0.jar
    aduna-appbase-webapp-base-core-3.9.0.jar
    aduna-appbase-webapp-system-core-3.9.0.jar
    aduna-commons-collections-2.7.0.jar
    aduna-commons-concurrent-2.6.0.jar
    aduna-commons-i18n-1.3.0.jar
    aduna-commons-io-2.8.0.jar
    aduna-commons-iteration-2.7.0.jar
    aduna-commons-lang-2.8.0.jar
    aduna-commons-net-2.6.0.jar
    aduna-commons-platform-info-2.8.0.jar
    aduna-commons-text-2.6.0.jar
    aduna-commons-webapp-core-2.8.0.jar
    aduna-commons-xml-2.6.0.jar
    aopalliance-1.0.jar
    asm-1.5.3.jar
    cglib-2.1_3.jar
    commons-codec-1.3.jar
    commons-dbcp-1.2.2.jar
    commons-httpclient-3.1.jar
    commons-pool-1.3.jar
    jcl-over-slf4j-1.5.10.jar
    jstl-1.1.2.jar
    logback-classic-0.9.18.jar
    logback-core-0.9.18.jar
    ojdbc6.jar
    sdordf.jar
    sdordfsesame.jar
    sesame-http-client-2.3.1.jar
    sesame-http-protocol-2.3.1.jar
    sesame-http-server-2.3.1.jar
    sesame-http-server-spring-2.3.1.jar
    sesame-model-2.3.1.jar
    sesame-query-2.3.1.jar
    sesame-queryalgebra-evaluation-2.3.1.jar
    sesame-queryalgebra-model-2.3.1.jar
    sesame-queryparser-api-2.3.1.jar
    sesame-queryparser-serql-2.3.1.jar
    sesame-queryparser-sparql-2.3.1.jar
    sesame-queryresultio-api-2.3.1.jar
    sesame-queryresultio-binary-2.3.1.jar
    sesame-queryresultio-sparqljson-2.3.1.jar
    sesame-queryresultio-sparqlxml-2.3.1.jar
    sesame-queryresultio-text-2.3.1.jar
    sesame-repository-api-2.3.1.jar
    sesame-repository-contextaware-2.3.1.jar
    sesame-repository-dataset-2.3.1.jar
    sesame-repository-event-2.3.1.jar
    sesame-repository-http-2.3.1.jar
    sesame-repository-manager-2.3.1.jar
    sesame-repository-sail-2.3.1.jar
    sesame-rio-api-2.3.1.jar
    sesame-rio-n3-2.3.1.jar
    sesame-rio-ntriples-2.3.1.jar
    sesame-rio-rdfxml-2.3.1.jar
    sesame-rio-trig-2.3.1.jar
    sesame-rio-trix-2.3.1.jar
    sesame-rio-turtle-2.3.1.jar
    sesame-runtime-2.3.1.jar
    sesame-sail-api-2.3.1.jar
    sesame-sail-inferencer-2.3.1.jar
    sesame-sail-memory-2.3.1.jar
    sesame-sail-nativerdf-2.3.1.jar
    sesame-sail-rdbms-2.3.1.jar
    slf4j-api-1.5.10.jar
    spring-aop-2.5.6.jar
    spring-beans-2.5.6.jar
    spring-context-2.5.6.jar
    spring-context-support-2.5.6.jar
    spring-core-2.5.6.jar
    spring-web-2.5.6.jar
    spring-webmvc-2.5.6.jar
    standard-1.1.2.jar
    urlrewritefilter-3.0.4.jar
     
    openrdf-sesame.war/WEB-INF/taglibs:
    navigation.tld
     
    openrdf-sesame.war/WEB-INF/tags:
    errors.tag
     
    openrdf-sesame.war/WEB-INF/views:
    home
    overview.jsp
    system
     
    openrdf-sesame.war/WEB-INF/views/home:
    overview.jsp
     
    openrdf-sesame.war/WEB-INF/views/system:
    info
    logging
    overview.jsp
     
    openrdf-sesame.war/WEB-INF/views/system/info:
    debug.jsp
    overview.jsp
     
    openrdf-sesame.war/WEB-INF/views/system/logging:
    overview.jsp
    
  12. Start or restart WebLogic Server.

  13. Verify your deployment by using your Web browser to connect to a URL in the following format (assume that the Web application is deployed at port 7001): http://<hostname>:7001/openrdf-sesame/querymgt?abortqid=0

    You should see an XML response, which indicates a successful deployment of the Sesame Server with the Sesame Adapter query management servlet.

You can also install the OpenRDF Workbench, which is a graphical user interface (GUI) for communicating with the Sesame Server. To deploy the OpenRDF Workbench into the Oracle WebLogic Server, you must have performed at least the first 7 steps in the preceding instructions for setting up the SPARQL endpoint (explained earlier in this section); then, follow these steps:

  1. Go to the autodeploy directory of WebLogic Server and copy files, as follows. (For information about auto-deploying applications in development domains, see: http://docs.oracle.com/cd/E11035_01/wls100/deployment/autodeploy.html)

    cd <domain_name>/autodeploy
    cp -rf  /tmp/openrdf-workbench.war  <domain_name>/autodeploy
    

    In the preceding example, <domain_name> is the name of a WebLogic Server domain.

  2. Check the files and the directory structure, as in the following example:

    autodeploy/% ls -1R ./openrdf-workbench.war/
     openrdf-workbench.war/:
    
    favicon.ico
    favicon.png
    images
    locale
    META-INF
    scripts
    styles
    transformations
    WEB-INF
     
    openrdf-workbench.war/images:
    affirmative.png
    edit.png
    logo.png
    negative.png
    productgroup.png
    server_network.png
    server.png
    view.png
     
    openrdf-workbench.war/locale:
    messages.xsl
     
    openrdf-workbench.war/META-INF:
    MANIFEST.MF
    maven
     
    openrdf-workbench.war/META-INF/maven:
    org.openrdf.sesame
     
    openrdf-workbench.war/META-INF/maven/org.openrdf.sesame:
    sesame-http-workbench
     
    openrdf-workbench.war/META-INF/maven/org.openrdf.sesame/sesame-http-workbench:
    pom.properties
    pom.xml
     
    openrdf-workbench.war/scripts:
    cookies.html
     
    openrdf-workbench.war/styles:
    basic
    default
    msie-png-alpha.css
    msie-png-alpha.png
    w3-html40-recommended.css
     
    openrdf-workbench.war/styles/basic:
    all.css
     
    openrdf-workbench.war/styles/default:
    images
    msie-minheight.css
    print.css
    screen.css
     
    openrdf-workbench.war/styles/default/images:
    bg_body.png
    bg_header.png
    bg_html.png
    hr_menu.png
     
    openrdf-workbench.war/transformations:
    add.xsl
    boolean.xsl
    clear.xsl
    contexts.xsl
    create-memory-rdfs-dt.xsl
    create-memory-rdfs.xsl
    create-memory.xsl
    create-mysql.xsl
    create-native-rdfs-dt.xsl
    create-native-rdfs.xsl
    create-native.xsl
    create-pgsql.xsl
    create-remote.xsl
    create.xsl
    delete.xsl
    explore.xsl
    export.xsl
    graph.xsl
    information.xsl
    list.xsl
    namespaces.xsl
    query.xsl
    remove.xsl
    repositories.xsl
    server.xsl
    summary.xsl
    table.xsl
    template.xsl
    tuple.xsl
    types.xsl
    url-encode.xsl
     
    openrdf-workbench.war/WEB-INF:
    classes
    lib
    web.xml
     
    openrdf-workbench.war/WEB-INF/classes:
    org
     
    openrdf-workbench.war/WEB-INF/classes/org:
    openrdf
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf:
    workbench
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench:
    base
    commands
    exceptions
    proxy
    RepositoryServlet.class
    util
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench/base:
    BaseRepositoryServlet.class
    BaseServlet.class
    TransformationServlet.class
    TupleServlet.class
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench/commands:
    AddServlet.class
    ClearServlet.class
    ContextsServlet.class
    CreateServlet.class
    DeleteServlet.class
    ExploreServlet.class
    ExportServlet.class
    InformationServlet.class
    InfoServlet.class
    NamespacesServlet.class
    QueryServlet.class
    RemoveServlet.class
    RepositoriesServlet.class
    SummaryServlet.class
    TypesServlet.class
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench/exceptions:
    BadRequestException.class
    MissingInitParameterException.class
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench/proxy:
    CookieCacheControlFilter$CacheAwareRequest.class
    CookieCacheControlFilter$CacheAwareResponse.class
    CookieCacheControlFilter.class
    ProxyRepositoryServlet.class
    RedirectFilter.class
    WorkbenchGateway.class
    WorkbenchServlet.class
     
    openrdf-workbench.war/WEB-INF/classes/org/openrdf/workbench/util:
    BasicServletConfig.class
    ConfigTemplate.class
    DynamicHttpRequest.class
    TupleResultBuilder.class
    WorkbenchRequest.class
     
    openrdf-workbench.war/WEB-INF/lib:
    aduna-appbase-core-3.9.0.jar
    aduna-appbase-logging-api-3.9.0.jar
    aduna-appbase-logging-file-3.9.0.jar
    aduna-commons-collections-2.7.0.jar
    aduna-commons-concurrent-2.6.0.jar
    aduna-commons-i18n-1.3.0.jar
    aduna-commons-io-2.8.0.jar
    aduna-commons-iteration-2.7.0.jar
    aduna-commons-lang-2.8.0.jar
    aduna-commons-net-2.6.0.jar
    aduna-commons-platform-info-2.8.0.jar
    aduna-commons-text-2.6.0.jar
    aduna-commons-xml-2.6.0.jar
    commons-cli-1.1.jar
    commons-codec-1.3.jar
    commons-dbcp-1.2.2.jar
    commons-fileupload-1.2.1.jar
    commons-httpclient-3.1.jar
    commons-io-1.3.2.jar
    commons-pool-1.3.jar
    jcl-over-slf4j-1.5.10.jar
    sesame-console-2.3.1.jar
    sesame-http-client-2.3.1.jar
    sesame-http-protocol-2.3.1.jar
    sesame-model-2.3.1.jar
    sesame-query-2.3.1.jar
    sesame-queryalgebra-evaluation-2.3.1.jar
    sesame-queryalgebra-model-2.3.1.jar
    sesame-queryparser-api-2.3.1.jar
    sesame-queryparser-serql-2.3.1.jar
    sesame-queryparser-sparql-2.3.1.jar
    sesame-queryresultio-api-2.3.1.jar
    sesame-queryresultio-binary-2.3.1.jar
    sesame-queryresultio-sparqljson-2.3.1.jar
    sesame-queryresultio-sparqlxml-2.3.1.jar
    sesame-queryresultio-text-2.3.1.jar
    sesame-repository-api-2.3.1.jar
    sesame-repository-contextaware-2.3.1.jar
    sesame-repository-dataset-2.3.1.jar
    sesame-repository-event-2.3.1.jar
    sesame-repository-http-2.3.1.jar
    sesame-repository-manager-2.3.1.jar
    sesame-repository-sail-2.3.1.jar
    sesame-rio-api-2.3.1.jar
    sesame-rio-n3-2.3.1.jar
    sesame-rio-ntriples-2.3.1.jar
    sesame-rio-rdfxml-2.3.1.jar
    sesame-rio-trig-2.3.1.jar
    sesame-rio-trix-2.3.1.jar
    sesame-rio-turtle-2.3.1.jar
    sesame-runtime-2.3.1.jar
    sesame-sail-api-2.3.1.jar
    sesame-sail-inferencer-2.3.1.jar
    sesame-sail-memory-2.3.1.jar
    sesame-sail-nativerdf-2.3.1.jar
    sesame-sail-rdbms-2.3.1.jar
    slf4j-api-1.5.10.jar
    slf4j-jdk14-1.5.10.jar
    
  3. Start or restart WebLogic Server.

  4. Verify your deployment by using your Web browser to connect to a URL in the following format (assume that the Web application is deployed at port 7001): http://<hostname>:7001/openrdf-workbench

    You should see a web page with the OpenRDF Workbench logo. Click the Repositories link on the left to see a list of repositories.

8.2.2.1 Creating the Required Data Source Using WebLogic Server

If you need help creating the required J2EE data source using the WebLogic Server admin console, you can follow these steps:

  1. Login to: http://<hostname>:7001/console

  2. In the Domain Structure panel, click Services.

  3. Click JDBC

  4. Click Data Sources.

  5. In the Summary of JDBC Data Sources panel, click New under the Data Sources table.

  6. In the Create a New JDBC Data Source panel, enter or select the following values.

    Name: OracleSemDS

    JNDI Name: OracleSemDS

    Database Type: Oracle

    Database Driver: Oracle's Driver (Thin) Versions: 9.0.1,9.2.0,10,11

  7. Click Next twice.

  8. In the Connection Properties panel, enter the appropriate values for the Database Name, Host Name, Port, Database User Name (schema that contains semantic data), Password fields.

  9. Click Next.

  10. Select (check) the target server or servers to which you want to deploy this OracleSemDS data source.

  11. Click Finish.

    You should see a message that all changes have been activated and no restart is necessary.

8.2.2.2 Configuring the SPARQL Service

You can use the OracleSailStore API and other relevant APIs to create semantic models, load data (incrementally or in bulk), and perform logical inference.

After the semantic models are in the Oracle database, you can use the Sesame Console (described in Section 8.9) to connect to the Sesame Server and create an Oracle semantic model-backed repository. For example, you might create a repository with the repository ID myOracleRepos that uses a semantic model named LUBM and the OWLPRIME rulebase.

This newly created repository provides a new service endpoint on the Sesame Server.

8.2.2.3 Terminating Long-Running SPARQL Queries

Because some applications need to be able to terminate long-running SPARQL queries, an abort framework has been introduced with the Sesame Adapter and the Sesame Server setup. Basically, for queries that may take a long time to run, you must stamp each with a unique query ID (qid) value.

For example, the following SPARQL query selects out the subject of all triples. A query ID (qid) is set so that this query can be terminated upon request.

PREFIX ORACLE_SEM_FS_NS:  <http://example.com/semtech#qid=8761>
SELECT ?subject WHERE {?subject ?property ?object }

The qid attribute value is of long integer type. You can choose a value for the qid for a particular query based on your own application needs.

To terminate a SPARQL query that has been submitted with a qid value, applications can send an abort request to a servlet in the following format and specify a matching QID value

http://<hostname>:7001/openrdf-sesame/querymgt?abortqid=8761

8.2.3 Setting Up the Semantic Technologies Environment

To use the Sesame Adapter to perform queries, you can connect as any user (with suitable privileges) and use any models in the semantic network. If your Semantic Technologies environment already meets the requirements, you can go directly to compiling and running Java code that uses the Sesame Adapter. If your Semantic Technologies environment is not yet set up to be able to use the Sesame Adapter, you can perform actions similar to the following example steps:

  1. Connect as SYS with the SYSDBA role:

    sqlplus sys/<password-for-sys> as sysdba
    
  2. Create a tablespace for the system tables. For example:

    CREATE TABLESPACE rdf_users datafile 'rdf_users01.dbf' 
        size 128M reuse autoextend on next 64M 
        maxsize unlimited segment space management auto;
    
  3. Create the semantic network. For example:

    EXECUTE sem_apis.create_sem_network('RDF_USERS');
    
  4. Create a database user (for connecting to the database to use the semantic network and the Sesame Adapter). For example:

    CREATE USER rdfusr IDENTIFIED BY <password-for-udfusr>
                       DEFAULT TABLESPACE rdf_users;
    
  5. Grant the necessary privileges to this database user. For example:

    GRANT connect, resource TO rdfusr;
    
  6. To use the Sesame Adapter with your own semantic data, perform the appropriate steps to store data, create a model, and create database indexes, as explained in Section 1.10, "Quick Start for Using Semantic Data". Then perform queries by compiling and running Java code; see Section 8.10 for information about example queries.

    To use the Sesame Adapter with supplied example data, see Section 8.10.

8.3 SEM_MATCH and Sesame Adapter Queries Compared

There are two ways to query semantic data stored in Oracle Database: SEM_MATCH-based SQL statements and SPARQL queries through the Sesame Adapter. Queries using each approach are similar in appearance, but there are important behavioral differences. To ensure consistent application behavior, you must understand the differences and use care when dealing with query results coming from SEM_MATCH queries and SPARQL queries.

The following simple examples show the two approaches.

Query 1 (SEM_MATCH-based)

select s, p, o
    from table(sem_match('{?s ?p ?o}', sem_models('Test_Model'), ....))

Query 2 (SPARQL query through the Sesame Adapter)

select ?s ?p ?o
where {?s ?p ?o}

These two queries perform the same kind of functions; however, there are some important differences. Query 1 (SEM_MATCH-based):

  • Reads all triples out of Test_Model.

  • Does not differentiate among URI, bNode, plain literals, and typed literals, and it does not handle long literals.

  • Does not unescape certain characters (such as '\n').

Query 2 (SPARQL query executed through the Sesame Adapter) also reads all triples out of Test_Model (assume it executed a call to ModelOracleSem referring to the same underlying Test_Model). However, Query 2:

  • Reads out additional columns (as opposed to just the s, p, and o columns with the SEM_MATCH table function), to differentiate URI, bNodes, plain literals, typed literals, and long literals. This is to ensure proper creation of Sesame Node objects.

  • Unescapes those characters that are escaped when stored in Oracle Database

Blank node handling is another difference between the two approaches:

  • In a SEM_MATCH-based query, blank nodes are always treated as constants.

  • In a SPARQL query, a blank node that is not wrapped inside < and > is treated as a variable when the query is executed through the Sesame Adapter. This matches the SPARQL standard semantics. However, a blank node that is wrapped inside < and > is treated as a constant when the query is executed, and the Sesame Adapter adds a proper prefix to the blank node label as required by the underlying data modeling.

The maximum length for the name of a semantic model created using the Sesame Adapter API is 22 characters.

8.4 Optimized Handling of SPARQL Queries

This section describes some performance-related features of the Sesame Adapter that can enhance SPARQL query processing. These features are performed automatically by default.

8.4.1 Compilation of SPARQL Queries to a Single SEM_MATCH Call

SPARQL queries involving DISTINCT, OPTIONAL, GRAPH, FILTER, UNION, ORDER BY, and LIMIT are converted to a single SQL query based on the SEM_MATCH table function. For SPARQL ASK, DESCRIBE, and CONSTRUCT queries, the Sesame Adapter employs additional query transformation logic and mid-tier processing.

If the SQL query based on SEM_MATCH fails to execute, the Sesame Adapter employs the Sesame evaluation strategy to execute the query.

8.5 Recommendations for Best Performance

The following are recommendations for enhancing the performance of queries using the Sesame Adapter:

  • Put only relevant triple patterns in the GRAPH clause of a SPARQL query, to reduce the number of additional joins with the application table. (For an explanation, see Section 8.5.1.)

  • For the triple patterns inside GRAPH clause of a named graph query, do not use variables with null bindings. A null binding will not match any row in the join with the relevant application table, and therefore this binding will be dropped.

  • Because of the preceding item, do not put an OPTIONAL clause in a GRAPH clause, or a GRAPH clause in an OPTIONAL clause.

  • Do not use blank nodes for the CONTEXT column in the application table (see Section 8.5.1), because blank nodes in named graphs from two different semantic models will be treated as the same resource if they have the same label. This is not the case for blank nodes in triples (they are stored separately if coming from different models).

8.5.1 Statement Storage and Implications for Sesame Adapter Queries

Because the MDSYS.SEMM_model-name view (described in Table 1-2 in Section 1.3.1) does not have columns for the graph name or context for each model, these two pieces of information are not stored inside that Oracle semantic model. Rather, this information is kept in the CONTEXT column in the user's application table.

When an OracleSailStore object is created for the first time using a model name that does not exist in the semantic network, a new application table is created automatically, and it includes these columns:

  • TRIPLE, of type SDO_RDF_TRIPLE_S

  • CONTEXT, of type VARCHAR2

A semantic model with the specified model name is then created. To enhance the performance of named graph queries and statement-oriented operations, a default index is created on the application table, and this index covers the CONTEXT column (leading column) as well as the three numeric ID attributes for triple's subject, predicate, and object field of the TRIPLE column.

When a SPARQL query runs against a semantic model, if the query does not use a named graph (that is, does not contain a GRAPH clause), the generated SQL statement will not use the model's application table. However, if the query has a GRAPH clause, the generated SQL statement will join a SEM_MATCH-based subquery with the model's application table to scope the results down to relevant contexts or named graphs. The number of joins with the application table depends on how many triple patterns are in the GRAPH clause, and therefore it is best to put only relevant triple patterns in the GRAPH clause, to reduce the number of additional joins with the application table.

8.6 Additions to the SPARQL Syntax to Support Other Features

The Sesame Adapter allows you to pass in hints and additional query options. It implements these capabilities by overloading the SPARQL namespace prefix syntax by using Oracle-specific namespaces that contain query options. The namespaces are in the form PREFIX ORACLE_SEM_xx_NS, where xx indicates the type of feature (such as HT for hint or AP for additional predicate)

8.6.1 SQL Hints

SQL hints can be passed to a SEM_MATCH query including a line in the following form:

PREFIX ORACLE_SEM_HT_NS: <http://oracle.com/semtech#hint>

Where hint can be any hint supported by SEM_MATCH. For example:

PREFIX ORACLE_SEM_HT_NS: <http://oracle.com/semtech#leading(t0,t1)> 
SELECT ?book ?title ?isbn     
WHERE { ?book <http://title> ?title. ?book <http://ISBN> ?isbn }

In this example, t0,t1 refers to the first and second patterns in the query.

Note the slight difference in specifying hints when compared to SEM_MATCH. Due to restrictions of namespace value syntax, a comma (,) must be used to separate t0 and t1 (or other hint components) instead of a space.

For more information about using SQL hints, see Section 1.6, "Using the SEM_MATCH Table Function to Query Semantic Data", specifically the material about the HINT0 keyword in the options attribute.

8.6.2 Additional WHERE Clause Predicates

The SEM_MATCH filter attribute can specify additional selection criteria as a string in the form of a WHERE clause without the WHERE keyword. Additional WHERE clause predicates can be passed to a SEM_MATCH query including a line in the following form:

PREFIX ORACLE_SEM_AP_NS: <http://oracle.com/semtech#pred>

Where pred reflects the WHERE clause content to be appended to the query. For example:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ORACLE_SEM_AP_NS:<http://www.oracle.com/semtech#label$RDFLANG='fr'>  
SELECT DISTINCT ?inst ?label
  WHERE { ?inst a <http://someCLass>. ?inst rdfs:label ?label . }
  ORDER BY (?label) LIMIT 20

In this example, a restriction is added to the query that the language type of the label variable must be 'fr'.

8.6.3 Additional Query Options

Additional query options can be passed to a SEM_MATCH query including a line in the following form:

PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#option>

Where option reflects a query option (or multiple query options delimited by commas) to be appended to the query. For example:

PREFIX ORACLE_SEM_FS_NS:   
<http://oracle.com/semtech#timeout=3,dop=4,INF_ONLY,ORDERED,ALLOW_DUP=T>
SELECT * WHERE {?subject ?property ?object }

The following query options are supported:

  • ALLOW_DUP=t chooses a faster way to query multiple semantic models, although duplicate results may occur.

  • DOP=n specifies the degree of parallelism (n) for the query. With multi-core or multi-CPU processors, experimenting with different DOP values (such as 4 or 8) may improve performance.

  • INF_ONLY causes only the inferred model to be queried. (For this option, you should also specify the includeInferred=true option for the query.)

  • ORDERED is translated to a LEADING SQL hint for the query triple pattern joins, while performing the necessary RDF_VALUE$ joins last.

  • QID=n specifies a query ID number; this feature can be used to cancel the query if it is not responding.

  • REWRITE=F disables ODCI_Table_Rewrite for the SEM_MATCH table function.

  • SKIP_CLOB=T causes CLOB values not to be returned for the query.

  • TIMEOUT=n (query timeout) specifies the number of seconds (n) that the query will run until it is terminated.

  • USE_BIND_VAR(n) specifies that a bind variable be used during query parsing for the nth constant in triple patterns. (Do not apply this feature to constants inside an OPTIONAL clause.)

8.7 Support for Server-Side APIs

This section describes some of the Oracle Database Semantic Technologies features that are exposed by the Sesame Adapter. For comprehensive documentation of the API calls that support the available features, see the Sesame Adapter reference information (Javadoc). For additional information about the server-side features exposed by the Sesame Adapter, see the relevant chapters in this manual.

8.7.1 Virtual Models Support

Virtual models (explained in Section 1.3.8) are specified in the OracleSailStore constructor, and they are handled transparently. If a virtual model exists for the model-rulebase combination, it is used in query answering; if such a virtual model does not exist, it is created in the database.

Note:

Virtual model support through the Sesame Adapter is available only with Oracle Database Release 11.2 or later.

The following example reuses an existing virtual model.

public void vm(String jdbcUrl, 
                        String user, 
                        String password, 
                        String model,                              
                        PrintStream psOut) 
{
String m1 = "TEST_1";
String m2 = "TEST_2";
OraclePool op = new OraclePool(
    OraclePool.getOracleDataSource(jdbcUrl, user, password));
        
// create the attachment semantic model in case it doesn't exist 
// (constructor handles it)
OracleSailStore store = new OracleSailStore(op, m1);
store.shutDown();
                
store= new OracleSailStore(op, m2);
store.shutDown();
 
String vmName = "VM_" + m1;
 
// create a virtual model with name vmName that will be used in the 
// OracleSailStore
Oracle oracle = op.getOracle();
oracle.executeCall(
"begin sem_apis.create_virtual_model(?,sem_models(?,?), null); end;", 
 vmName, m1, m2);
op.returnOracle(oracle);
 
 String[] modelNames = {m2};
 String[] rulebaseNames = {};
 
 Attachment attachment = Attachment.createInstance(modelNames,
 rulebaseNames); 
 
    store = new OracleSailStore(op, m1, attachment, vmName);
 
OracleSailConnection conn = store.getConnection();
conn.clear();
conn.addStatement(
        store.getValueFactory().createURI("http://a1"), 
        store.getValueFactory().createURI("http://p1"), 
        store.getValueFactory().createURI("http://b1"));
   
CloseableIteration res = conn.getStatements(null, null, null, false);
while (res.hasNext()) {
  Statement stmt = (Statement) res.next();
  System.out.println(stmt);
}    
conn.close();
store.shutDown();
}

You can also use the OracleSailStore constructor to create a virtual model, as in the following example:

OracleSailStore store = new OracleSailStore(oracle, modelName, attachment, true);

In this example, the fourth parameter (true) specifies that a virtual model needs to be created for the specified modelName and attachment.

8.7.2 Connection Pooling Support

Oracle Database Connection Pooling is provided through the Sesame Adapter OraclePool class. Usually, OraclePool is initialized with a DataSource, using the OraclePool (DataSource ods) constructor. In this case, OraclePool acts as an extended wrapper for the DataSource, while using the connection pooling capabilities of the data source. When you create an OracleSailStore object, it is sufficient to specify the OraclePool object in the store constructor; the database connections will then be managed automatically by the Sesame Adapter.

If you need to retrieve Oracle connection objects (which are essentially database connection wrappers) explicitly, you can invoke the OraclePool.getOracle method. After finishing with the connection, you can invoke the OraclePool.returnOracle method to return the object to the connection pool.

OraclePool can also be initialized with an OracleConnection object. In this case, only a single database connection is used when referring to this OraclePool; and because multiple Sesame SailConnection objects will use the same database connection, you must be aware that "dirty" reads across different SailConnection objects are possible.

More information about using OraclePool can be found in the Sesame Adapter API reference information (Javadoc).

The following example sets up an OracleSailStore object using the OraclePool class, with two initial connections.

public void op(String jdbcUrl, 
                 String user, 
                 String password, 
                 String model,                              
                 PrintStream psOut)
  throws Exception
  {          
    // test with connection properties 
    java.util.Properties prop = new java.util.Properties();
    prop.setProperty("MinLimit", "2");     // the cache size is 2 at least 
    prop.setProperty("MaxLimit", "10");
    prop.setProperty("InitialLimit", "2"); // create 2 connections at startup
    prop.setProperty("InactivityTimeout", "1800");    //  seconds
    prop.setProperty("AbandonedConnectionTimeout", "900");  //  seconds
    prop.setProperty("MaxStatementsLimit", "10");
    prop.setProperty("PropertyCheckInterval", "60"); // seconds
 
    System.out.println("Creating Data Source");
    OracleDataSource ods = 
OraclePool.getOracleDataSource(jdbcUrl, user, password,
        prop, "OracleSemConnPool");
    System.out.println("Done creating Data Source");
    
    OraclePool op = new OraclePool(ods);
 
    // create an OracleSailStore with the OraclePool
    OracleSailStore store = new OracleSailStore(op, model);
    store.shutDown();
    op.close();
    ods.close();
  }

8.7.3 Semantic Model PL/SQL Interfaces

Several semantic PL/SQL subprograms are available through the Sesame Adapter. Table 8-1 lists the subprograms and their corresponding Java class and methods.

Table 8-1 PL/SQL Subprograms and Corresponding Sesame Adapter Java Class and Methods

PL/SQL Subprogram Corresponding Java Class and Methods

SEM_APIS.DROP_SEM_MODEL

OracleUtils.dropSemanticModel

SEM_APIS.MERGE_MODELS

OracleUtils.mergeModels

SEM_APIS.SWAP_NAMES

OracleUtils.swapNames

SEM_APIS.REMOVE_DUPLICATES

OracleUtils.removeDuplicates

SEM_APIS.RENAME_MODEL

OracleUtils.renameModels


For information about these PL/SQL utility subprograms, see the reference information in Chapter 9. For information about the corresponding Java class and methods, see the Sesame Adapter API Reference documentation (Javadoc).

8.7.4 Inference Options

You can add options to entailment calls by using the setInferenceOption(String options) procedure with the OracleSailConnection object. The following example enables incremental inference and specifies a parallelism value of 4 when creating an entailment.

conn.setInferenceOption("INC=T,DOP=4");

For information about inference options, see Section 2.2.

8.8 Oracle-Specific Extensions to Sesame APIs

This section describes the extensions that the Sesame Adapter for Oracle Database provides to the Sesame SailConnection and Sail APIs.

8.8.1 Statement Uniqueness

In Sesame 2.3.0, statement uniqueness is enforced at the context level: the same triple cannot occur twice in a single context. In the Oracle Sesame Adapter, such uniqueness is enforced through a unique index on the context, predicate, subject, and object. However, in the Sesame Adapter, statement uniqueness is not enabled by default. When constructing an OracleSailStore object, the default value for statement uniqueness is DONTCARE, meaning that if such a unique index does not already exist, it will not be created.

You can explicitly enable and disable the requirement for statement uniqueness either through the OracleSailStore constructor, or through the enableUniquenessConstraint and disableUniquenessConstraint methods.

8.8.2 Indexes and Interoperability with the Jena Adapter

Indexes on the application table are critical for good performance when performing DML operations (especially deletes) and named graph queries against an OracleSailStore object. When creating a new OracleSailStore object, a default CPSO index is created (where C,P,S,O stands for the context, predicate, subject, and object columns).

There are some storage differences between Oracle semantic models created using the Sesame Adapter and the Jena Adapter. For example, the default application table index is different in Jena Adapter. To access data in a Jena Adapter model from the Sesame Adapter (and vice versa), you can use the OracleUtils.migrateFromJena and OracleUtils.migrateToJena methods. These methods preserve the semantic data while making changes to the underlying storage structures. In particular, all triples along with their context information are preserved when migrating from Sesame Adapter to Jena Adapter and back.

Example 8-2 illustrates migration between models created using the Sesame Adapter and the Jena Adapter:

Example 8-2 Migration Between Jena Adapter and Sesame Adapter Models

public void migrate(String jdbcUrl, 
                         String user, 
                         String password, 
                         String model,                                
                         PrintStream psOut)
  throws Exception
  {
    OraclePool oraclePool= new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
       
    OracleSailStore store = new OracleSailStore(oraclePool, model);
    
    OracleSailConnection conn = store.getConnection();
    conn.clear();
    
    // create a statement and add it to the store
    URI subject = 
store.getValueFactory().createURI("http://example.org/foo");
    URI object = store.getValueFactory().createURI("http://example.org/bar");
    URI ngURI = store.getValueFactory().createURI("http://example.org/bar");
  
    conn.addStatement(subject, RDF.TYPE, object, ngURI);
    conn.commit();    
    
    // convert it to a jena model    
    OracleUtils.migrateToJena(oraclePool, model);    
 
    Oracle newOra = oraclePool.getOracle();
    oracle.spatial.rdf.client.jena.Oracle ora =
      new oracle.spatial.rdf.client.jena.Oracle(newOra.getConnection());
    
    GraphOracleSem graph = new GraphOracleSem(ora, model);
   
    // check size of jena graph
    System.out.print("GraphOracleSem size:" + graph.getSize());
    
    store.shutDown();
    
    // now convert it back to an Oracle sailstore.
    OracleUtils.migrateFromJena(oraclePool, model);
    conn = store.getConnection();   
 
    // check overall store size
    System.out.println("Size of store :" +conn.size());
    // check context size, should be 1
    System.out.println("Size of context " + ngURI + ":" + conn.size(ngURI));
    store.shutDown();
    ora.dispose();
    oraclePool.returnOracle(newOra);
  }

8.8.3 Inference

You can perform inference using the OracleSailConnection.performInference method. This method builds an entailment for the OracleSailStore object, given the models and rulebases that were specified in the attachment when constructing the store.

For information about creating entailments, see Section 1.3.7, "Entailments (Rules Indexes)".

8.8.4 Performing Analysis Operations

It is strongly recommended that you analyze the application table, semantic model, and inferred graph (if it exists) before performing inference and after loading a significant amount of semantic data into the database. Performing the analysis operations causes statistics to be gathered, which will help the Oracle optimizer select efficient execution plans when answering queries.

To gather relevant statistics, you can use the following methods in the OracleSailConnection and OracleSailStore classes:

  • OracleSailConnection.analyze

  • OracleSailConnection.analyzeApplicationTable

  • OracleSailConnection.analyzeInferredGraph

For information about these methods, including their parameters, see the Sesame Adapter reference information (Javadoc).

8.9 Using the Sesame Console with the Sesame Adapter

The Sesame Console is, as OpenRDF.org explains, "a command-line application for interacting with Sesame. For now, the best way to create and manage repositories in a SYSTEM repository is to use the Sesame Console. " For basic usage and reference information about the Sesame Console, see the documentation at http://openrdf.callimachus.net/sesame/2.7/docs/users.docbook?view.

This section describes how to use the Sesame Console with the Sesame Adapter for Oracle Database.

To create a new SAIL repository (OracleSailStore object) using the Sesame Console command-line tool, use the following command:

create oracle.

When you are prompted for parameters, you can specify the following:

Repository ID

ID string associated with the repository. Example: myOracleRepos

Repository Title

Title string associated with the repository. Example: My Oracle Repository

Model Name

Name of the Oracle semantic model that corresponds to this repository. All DML operations are performed against this model.

Additional Models

Comma-separated list of any additional semantic models to be included in this repository. Any additional models are used only for inference and query operations.

Rulebases

Comma-separated list of rulebases to be considered when building the entailment closure for this repository. The default is no rulebases, which means that no inference will be performed.

Use Virtual Model (TRUE|FALSE) [TRUE]

Specifies whether to use a virtual model when answering queries. The default is TRUE, which means to use a virtual model.

Virtual Model Name

If Use Virtual Model is TRUE, specify the name of the virtual model to be used to answer queries, if the database user that owns the repository has read permission on the specified virtual model.

Inference Maintenance Mode (NO_UPDATE|UPDATE_WHEN_COMMIT) [NO_UPDATE]

Specifies whether to update the entailment closure on each commit operation (UPDATE_WHEN_COMMIT) or only when the OracleSailConnection.performInference method is invoked (NO_UPDATE). The default is NO_UPDATE.

Allow Duplicates in Query (TRUE|FALSE) [TRUE]

Specifies whether, when querying a repository that has additional models, the query response can include duplicates across the different models. The default is TRUE, allows duplicates to be included, and which speeds query performance.

Allow Query with Non-Valid Inference status (INVALID|VALID|INCOMPLETE) [INVALID]

Specifies whether to allow queries when the entailment is not updated, that is, when the inference status is not valid. The default value is INVALID, which means that the entailment status can be INVALID when querying.

To allow queries only when entailments have a valid status, specify VALID. To allow queries when entailments have either a valid or incomplete status, specify INCOMPLETE.

Application Table Indexes [CPSO]

Specifies the custom index to be created on the application table for this repository. You can specify the columns to be included (and their order) by using a string of up to 4 of the following characters: C (context), P (property), S (subject), O (object). (You can use only those characters and cannot repeat any characters.) The default is CPSO, which creates an index on all four columns with context as the leading column.

Index Option: Degree of Parallelism [1]

Specifies the DOP (degree of parallelism) value for the application table indexes. With multi-core or multi-CPU processors, experimenting with different DOP values (such as 4 or 8) may improve performance. The default is 1 (no parallelism).

Index Option: Prefix Length to Compress [2]

Specifies whether to use key compression on the application table indexes. The default is 2, which specifies compression on the first two columns. A value of 0 (zero) means that no compression will be used.

Enforce Uniqueness (FALSE|TRUE) []

Specifies whether to enforce statement uniqueness across multiple contexts in the repository. Note that statement uniqueness is enforced by a unique index on the application table. The default is [] (that is, no value specified), which means that if the model exists, the uniqueness setting will be inherited from that model; and if the model does not already exist, a non-unique index will be created.

If you specify FALSE and if a unique index exists, that index is dropped and it is re-created as a non-unique index.

Data Source Name [OracleSemDS]

Name of the JDBC data source that provides the database connection setting for accessing the Oracle semantic models and application tables for this repository. The default is OracleSemDS.

Example 8-3 shows a sample scenario of using the Sesame Console.

Example 8-3 Using the Sesame Console

> connect http://localhost:8080/openrdf-sesame.
Disconnecting from default data directory
Connected to http://localhost:8080/openrdf-sesame
> create oracle.
Please specify values for the following variables:
Repository ID: model2Repos
Repository title: Repository for Model 2
Model Name: model2
Additional Models (comma separated):    
Rulebases (comma separated): OWLPRIME    -- OWLPRIME inference will be performed when this model is created
Use Virtual Model (TRUE|FALSE) [TRUE]:  TRUE
Virtual Model Name:     -- a new virtual model will be created if nonexistent
Inference Maintenance Mode (UPDATE_WHEN_COMMIT|NO_UPDATE) [UPDATE_WHEN_COMMIT]: NO_UPDATE
Allow duplicates in query (TRUE|FALSE) [TRUE]: TRUE
Allow query with non-valid inference status (NONE|INCOMPLETE|INVALID) [NONE]: NONE – inference must be up to date before query
Application Table Index [CPSO]: CPSO      –- default, recommended index
Index option: Degree of parallelism [1]: 1
Index option: Leading columns to compress [2]: 2
Enforce Uniqueness (|FALSE|TRUE) []: FALSE
DataSource Name [OracleSemDS]: OracleSemDS
Repository created
> open model2Repos.
Opened repository 'model2Repos'
model2Repos> show c.
--no contexts found--
model2Repos>

8.10 Example Queries Using the Sesame Adapter

This section includes example queries using the Sesame Adapter. Each example is self-contained: it typically starts an OraclePool object, creates an OracleSailStore object, adds and perhaps removes statements, performs a query that may involve inference, displays the result, shuts down the OracleSailStore object, and closes the OraclePool object.

For these examples, the following libraries must be included in the CLASSPATH definition:

sesame-console-2.3.1.jar
sesame-http-client-2.3.1.jar
sesame-http-protocol-2.3.1.jar
sesame-http-server-spring-2.3.1.jar
sesame-model-2.3.1.jar
sesame-query-2.3.1.jar
sesame-queryalgebra-evaluation-2.3.1.jar
sesame-queryalgebra-model-2.3.1.jar
sesame-queryparser-api-2.3.1.jar
sesame-queryparser-serql-2.3.1.jar
sesame-queryparser-sparql-2.3.1.jar
sesame-queryresultio-api-2.3.1.jar
sesame-queryresultio-binary-2.3.1.jar
sesame-queryresultio-sparqljson-2.3.1.jar
sesame-queryresultio-sparqlxml-2.3.1.jar
sesame-queryresultio-text-2.3.1.jar
sesame-repository-api-2.3.1.jar
sesame-repository-contextaware-2.3.1.jar
sesame-repository-dataset-2.3.1.jar
sesame-repository-event-2.3.1.jar
sesame-repository-http-2.3.1.jar
sesame-repository-manager-2.3.1.jar
sesame-repository-sail-2.3.1.jar
sesame-rio-api-2.3.1.jar
sesame-rio-n3-2.3.1.jar
sesame-rio-ntriples-2.3.1.jar
sesame-rio-rdfxml-2.3.1.jar
sesame-rio-trig-2.3.1.jar
sesame-rio-trix-2.3.1.jar
sesame-rio-turtle-2.3.1.jar
sesame-runtime-2.3.1.jar
sesame-sail-api-2.3.1.jar
sesame-sail-inferencer-2.3.1.jar
sesame-sail-memory-2.3.1.jar
sesame-sail-nativerdf-2.3.1.jar
sesame-sail-rdbms-2.3.1.jar
sdordf.jar
sdordfsesame.jar
ojdbc6.jar

To simplify the examples, an environment variable named CP was defined, as follows:

setenv CP ./:sesame-console-2.3.1.jar:sesame-http-client-2.3.1.jar:sesame-http-protocol-2.3.1.jar:sesame-http-server-spring-2.3.1.jar:sesame-model-2.3.1.jar:sesame-query-2.3.1.jar:sesame-queryalgebra-evaluation-2.3.1.jar:sesame-queryalgebra-model-2.3.1.jar:sesame-queryparser-api-2.3.1.jar:sesame-queryparser-serql-2.3.1.jar:sesame-queryparser-sparql-2.3.1.jar:sesame-queryresultio-api-2.3.1.jar:sesame-queryresultio-binary-2.3.1.jar:sesame-queryresultio-sparqljson-2.3.1.jar:sesame-queryresultio-sparqlxml-2.3.1.jar:sesame-queryresultio-text-2.3.1.jar:sesame-repository-api-2.3.1.jar:sesame-repository-contextaware-2.3.1.jar:sesame-repository-dataset-2.3.1.jar:sesame-repository-event-2.3.1.jar:sesame-repository-http-2.3.1.jar:sesame-repository-manager-2.3.1.jar:sesame-repository-sail-2.3.1.jar:sesame-rio-api-2.3.1.jar:sesame-rio-n3-2.3.1.jar:sesame-rio-ntriples-2.3.1.jar:sesame-rio-rdfxml-2.3.1.jar:sesame-rio-trig-2.3.1.jar:sesame-rio-trix-2.3.1.jar:sesame-rio-turtle-2.3.1.jar:sesame-runtime-2.3.1.jar:sesame-sail-api-2.3.1.jar:sesame-sail-inferencer-2.3.1.jar:sesame-sail-memory-2.3.1.jar:sesame-sail-nativerdf-2.3.1.jar:sesame-sail-rdbms-2.3.1.jar:sdordf.jar:sdordfsesame.jar:ojdbc6.jar

Note:

Enter the setenv command, as well as each javac and java command, on a single command line.

To run a query, you must do the following:

  1. Include the code in a Java source file. The examples used in this section are supplied in files in the examples directory of the Sesame Adapter download.

  2. Compile the Java source file. For example:

    > javac -classpath $CP Example1.java
    
  3. Run the compiled file. For example:

    > java -classpath $CP Test jdbc:oracle:thin:@localhost:1521:orcl scott <password-for-scott> M1
    

8.10.1 Example1.java: Basic Operations

Example 8-4 shows the Example1.java file, which performs some basic operations.

Example 8-4 Basic Operations

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
 
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
 
public class Example1
{
  public static void main(String[] args) throws SQLException, SailException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);       
 
    OracleSailConnection conn = store.getConnection();
 
    ValueFactory vf = store.getValueFactory();
    URI p = vf.createURI("http://p");   
    URI cls = vf.createURI("http://cls");
    URI a = vf.createURI("http://a");
    URI b = vf.createURI("http://b");
    URI ng1 = vf.createURI("http://ng1");
 
    conn.clear();
    conn.addStatement(p, RDFS.DOMAIN, cls);
    conn.addStatement(a, p, b, ng1);
 
    psOut.println("size of context " + ng1 + ":" + conn.size(ng1));
 
    // returns OracleStatements
    CloseableIteration<? extends Statement, SailException> it =
      conn.getStatements(null, null, null, false);
 
    while (it.hasNext()) {   
      Statement stmt = it.next();
      psOut.println("getStatements: stmt: " + stmt.toString());
    }
 
    conn.removeStatements(null, null, null, ng1);
 
    psOut.println("size of context " + ng1 + ":" + conn.size(ng1));
 
    conn.removeAll();   
 
    psOut.println("size of store: " + conn.size());
 
    conn.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

/usr/local/packages/jdk16/bin/javac -classpath $CP Example1.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example1 jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel

The expected output of the java command might appear as follows:

size of context http://ng1:1
getStatements: stmt:  O: (http://a, http://p, http://b) [http://ng1]
getStatements: stmt:  O: (http://p, http://www.w3.org/2000/01/rdf-schema#domain, http://cls) [null]
size of context http://ng1:0
size of store: 0

8.10.2 Example2.java: Add a Data File (in TRIG format)

Example 8-5 shows the Example2.java file, which adds a data file in TRIG format.

Example 8-5 Add a Data File (in TRIG format)

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
 
public class Example2
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String trigFile = args[4];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);       
    SailRepository sr = new SailRepository(store);
    RepositoryConnection repConn = sr.getConnection();
 
    repConn.setAutoCommit(false);
    repConn.add(new File(trigFile), "http://my.com/", RDFFormat.TRIG);
    repConn.commit();
 
    psOut.println("size " + Long.toString(repConn.size()));
 
    repConn.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example2.java

For running this example, assume that a sample TRIG data file named test.trig was created as:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix swp: <http://www.w3.org/2004/03/trix/swp-1/> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix ex: <http://example.org/> .
@prefix : <http://example.org/> .
 
# default graph
{
<http://example.org/bob>    dc:publisher  "Bob Hacker" .
<http://example.org/alice>  dc:publisher  "Alice Hacker" .
}
 
:bob {
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
}
 
:alice {
_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .
}
 
:jack {
_:a foaf:name "Jack" .
_:a foaf:mbox <mailto:jack@oracle.example.org> .
}

To run this example using the test.trig data file, enter the following command:

/usr/local/packages/jdk16/bin/java -classpath $CP Example2 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  TestModel ./test.trig

The expected output of the java command might appear as follows:

size 7

8.10.3 Example3.java: Simple Query

Example 8-6 shows the Example3.java file, which performs a simple query.

Example 8-6 Simple Query

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example3
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
    SailRepository myRepository = new SailRepository(store);
 
    ValueFactory f = myRepository.getValueFactory();
    RepositoryConnection conn = myRepository.getConnection();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    conn.clear(); // to start from scratch
    conn.add(alice, RDF.TYPE, person);
    conn.add(alice, name, alicesName);
    conn.commit();
 
    store.analyze();
    store.analyzeApplicationTable();
 
    try {
      //run a query against the repository
      String queryString = " SELECT * WHERE {?x ?p ?y} LIMIT 1 ";
      TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
      TupleQueryResult result = tupleQuery.evaluate();
      try {
        while (result.hasNext()) {
          BindingSet bindingSet = result.next();
          psOut.println("value of x: " + bindingSet.getValue("x"));
        }
      }
      finally {
        result.close();
      }
    }
    finally {  
      conn.clear();
      if (conn != null && conn.isOpen()) {
        conn.close();
      }       
 
      myRepository.shutDown();
      op.close();
    }
  }
}

To compile this example, enter the following command:

/usr/local/packages/jdk16/bin/javac -classpath $CP Example3.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example3 jdbc:oracle:thin:@localhost:1521:ORCL scott <password-for-scott> TestModel

The expected output of the java command might appear as follows:

value of x: http://example.org/people/alice

8.10.4 Example4.java: Simple Bulk Load

Example 8-7 shows the Example4.java file, which performs a simple bulk load operation.

Example 8-7 Simple Bulk Load

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Resource;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example4
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String filename = args[4]; // N-TRIPLES file
 
    OraclePool op = new OraclePool(OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    psOut.println("testBulkLoad: start");
 
    OracleSailStore store = new OracleSailStore(op, model);
    OracleSailConnection osc = store.getConnection();
    FileInputStream fis = new FileInputStream(filename);
   
    long loadBegin = System.currentTimeMillis();
    osc.getBulkUpdateHandler().addInBulk(
        fis,
        "http://abc",                // baseURI
        RDFFormat.NTRIPLES,          // dataFormat
        null,                        // tablespaceName
        null,                        // flags
        null,                        // StatusListener
        (Resource[]) null            // Resource... for contexts
        );
 
    long loadEnd = System.currentTimeMillis();
    psOut.println("testBulkLoad: " + (loadEnd - loadBegin) + "ms.\n");
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example4.java

For running this example, assume that a sample ntriples data file named test.ntriples was created as:

<http://example.org/bob>    <http://purl.org/dc/elements/1.1/publisher>  "Bob Hacker" .
<http://example.org/alice>  <http://purl.org/dc/elements/1.1/publisher>  "Alice Hacker" .

To run this example using the test.ntriples file, enter the following command:

/usr/local/packages/jdk16/bin/java -classpath $CP Example4 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  TestModel ./test.ntriples

The expected output of the java command might appear as follows:

testBulkLoad: start
testBulkLoad: 756ms

8.10.5 Example5.java: Bulk Load RDF/XML and Application Table Index Maintenance

Example 8-8 shows the Example5.java file, which disables indexes on the application table, performs a bulk load operation from an RDF file in XML format, and re-enables the indexes.

Example 8-8 Bulk Load RDF/XML and Application Table Index Maintenance

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Resource;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example5
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String filename = args[4]; // RDF/XML
 
    OraclePool op = new OraclePool(OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    psOut.println("testBulkLoad: start");
 
    OracleSailStore store = new OracleSailStore(op, model);
    OracleSailConnection osc = store.getConnection();
 
    // disable indexes on application table
    store.disableAllAppTabIndexes();
 
    // NOTE: can be a gzipped file!
    FileInputStream fis = new FileInputStream(filename);
   
    long loadBegin = System.currentTimeMillis();
    osc.getBulkUpdateHandler().addInBulk(
        fis,
        "http://abc",                // baseURI
        RDFFormat.RDFXML,            // dataFormat
        null,                        // tablespaceName
        null,                        // flags
        null,                        // StatusListener
        (Resource[]) null            // Resource... for contexts
        );
 
    long loadEnd = System.currentTimeMillis();
    psOut.println("testBulkLoad: " + (loadEnd - loadBegin) + "ms.\n");
   
    // enable indexes on application table
    // Note: one can also specify to rebuild indexes in parallel.
    store.enableAllAppTabIndexes();
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example5.java

For running this example, assume that a sample file named test.rdfxml was created as:

<?xml version="1.0"?>
<!DOCTYPE owl [
     <!ENTITY owl  "http://www.w3.org/2002/07/owl#" >
     <!ENTITY xsd  "http://www.w3.org/2001/XMLSchema#" >
   ]>
 
<rdf:RDF
  xmlns     = "http://a/b#" xml:base  = "http://a/b#" xmlns:my  = "http://a/b#"
  xmlns:owl = "http://www.w3.org/2002/07/owl#"
  xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:rdfs= "http://www.w3.org/2000/01/rdf-schema#"
  xmlns:xsd = "http://www.w3.org/2001/XMLSchema#">
  <owl:Class rdf:ID="Color">
    <owl:oneOf rdf:parseType="Collection">
      <owl:Thing rdf:ID="Red"/>
      <owl:Thing rdf:ID="Blue"/>
    </owl:oneOf>
  </owl:Class>
</rdf:RDF>

To run this example using the test.rdfxml file, enter the following command:

/usr/local/packages/jdk16/bin/java -classpath $CP Example5 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  EX5 ./test.rdfxml

The expected output of the java command might appear as follows:

testBulkLoad: start
testBulkLoad: 825ms

8.10.6 Example6.java: Bulk Load With StatusListener to Handle Loading with Bad Data

Example 8-9 shows the Example6.java file, which performs the bulk load and index maintenance operations shown in Example 8-7, but also registers and implements a StatusListener class to check for and report any data errors.

Example 8-9 Bulk Load With StatusListener to Handle Loading with Bad Data

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Resource;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.model.Statement;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example6
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String filename = args[4]; // RDF/XML
 
    OraclePool op = new OraclePool(OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    psOut.println("testBulkLoad: start");
 
    OracleSailStore store = new OracleSailStore(op, model);
    OracleSailConnection osc = store.getConnection();
 
    // disable indexes on application table
    store.disableAllAppTabIndexes();
 
    // NOTE: can be a gzipped file!
    FileInputStream fis = new FileInputStream(filename);
   
    long loadBegin = System.currentTimeMillis();
    osc.getBulkUpdateHandler().addInBulk(
        fis,
        "http://abc",                // baseURI
        RDFFormat.NTRIPLES,          // dataFormat
        null,                        // tablespaceName
        null,                        // flags
        new MyListener(psOut),       // register a StatusListener
        (Resource[]) null            // Resource... for contexts
        );
 
    long loadEnd = System.currentTimeMillis();
    psOut.println("testBulkLoad: " + (loadEnd - loadBegin) + "ms.\n");
   
    // enable indexes on application table
    // Note: one can also specify to rebuild indexes in parallel.
    store.enableAllAppTabIndexes();
 
    osc.close();
    store.shutDown();
    op.close();
  }

  static class MyListener implements StatusListener {
    PrintStream m_ps = null;
    public MyListener(PrintStream ps) { m_ps = ps; }
 
    public void statusChanged(long count)
    {
      m_ps.println("process to " + Long.toString(count));
    }
 
    public int illegalStmtEncountered(Statement statement, long count)
    {
      m_ps.println("hit illegal statement with object " + statement.getObject().toString());
      return 0; // skip it
    }
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example6.java

For running this example, assume that a sample N-TRIPLES file named test-include-badtriple.ntriples was created as follows. In this file, the first and last triples have illegal typed literal values for objects.

<http://example.org/x>      <http://my.com/#age> "123.3456"^^<http://www.w3.org/2001/XMLSchema#integer> .
<http://example.org/bob>    <http://purl.org/dc/elements/1.1/publisher>  "Bob Hacker" .
<http://example.org/alice>  <http://purl.org/dc/elements/1.1/publisher>  "Alice Hacker" .
<http://example.org/y>      <http://my.com/#age> "hello"^^<http://www.w3.org/2001/XMLSchema#float> .

To run this example using the test-include-badtriple.ntriples file, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example6 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  EX6 ./test-include-badtriple.ntriples

The expected output of the java command might appear as follows:

testBulkLoad: start
hit illegal statement with object "123.3456"^^<http://www.w3.org/2001/XMLSchema#integer>
process to 2
process to 3
hit illegal statement with object "hello"^^<http://www.w3.org/2001/XMLSchema#float>
testBulkLoad: 725ms.

8.10.7 Example7.java: Load Data from Sesame Store into Oracle Database

Example 8-10 shows the Example7.java file, disables indexes on the application table, loads an RDF file in XML format into an in-memory Sesame store, loads the data into the Oracle database, and re-enables the indexes.

Example 8-10 Load Data from Sesame Store into Oracle Database

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.Resource;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.sail.memory.MemoryStore;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.model.Statement;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example7
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String filename = args[4]; // RDF/XML
 
    OraclePool op = new OraclePool(OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    psOut.println("testBulkLoad: start");
 
    SailRepository srInMem = null;
    RepositoryConnection repConnInMem = null;
    { // build an in memory Sesame store for testing purpose
      srInMem = new SailRepository(new MemoryStore());
      srInMem.initialize();
      repConnInMem = srInMem.getConnection();
      File file = new File(filename);
      repConnInMem.setAutoCommit(false);
      repConnInMem.add(file, "http://my.com", RDFFormat.RDFXML);
      repConnInMem.commit();
    }
 
    OracleSailStore store = new OracleSailStore(op, model);
    OracleSailConnection osc = store.getConnection();
 
    // disable indexes on application table
    store.disableAllAppTabIndexes();
 
    long loadBegin = System.currentTimeMillis();
    // load all statements from in memory store to Oracle
    osc.getBulkUpdateHandler().addInBulk(
        repConnInMem.getStatements(null, null, null, false),
        null                       // tablespaceName
        );
 
    long loadEnd = System.currentTimeMillis();
    psOut.println("testBulkLoad: " + (loadEnd - loadBegin) + "ms.\n");
   
    // enable indexes on application table
    // Note: one can also specify to rebuild indexes in parallel.
    store.enableAllAppTabIndexes();
 
    repConnInMem.close();
    srInMem.shutDown();
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example7.java

For running this example, assume that a file (to be loaded into memory) with the same format and content as the file described in Section 8.10.5, "Example5.java: Bulk Load RDF/XML and Application Table Index Maintenance" has been created.

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example7 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  EX7 ./test.rdfxml

The expected output of the java command might appear as follows:

testBulkLoad: start
testBulkLoad: 720ms

8.10.8 Example8.java: SPARQL ASK Query

Example 8-11 shows the Example8.java file, which performs a SPARQL ASK query.

Example 8-11 SPARQL ASK Query

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example8
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);
 
    SailRepository sr = new SailRepository(store);
    RepositoryConnection repConn = sr.getConnection();
 
    ValueFactory vf = sr.getValueFactory();
    URI p   = vf.createURI("http://p");   
    URI cls = vf.createURI("http://cls");    
 
    repConn.clear();
    repConn.add(p, RDFS.DOMAIN, cls);
    repConn.commit();
 
    store.analyze();                 // analyze the semantic model
    store.analyzeApplicationTable(); // and then the application table
 
    BooleanQuery tq = null;
    tq = repConn.prepareBooleanQuery(QueryLanguage.SPARQL, "ASK { ?x ?p <http://cls> }" );
    boolean b = tq.evaluate();
    psOut.print("\nAnswer is " + Boolean.toString(b));
 
    repConn.close(); 
    sr.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example8.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example4 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  EX8

The expected output of the java command might appear as follows:

Answer is true

8.10.9 Example9.java: SPARQL CONSTRUCT and DESCRIBE

Example 8-12 shows the Example9.java file, which performs SPARQL CONSTRUCT and DESCRIBE queries.

Example 8-12 SPARQL CONSTRUCT and DESCRIBE

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example9
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);
 
    SailRepository sr = new SailRepository(store);
    RepositoryConnection repConn = sr.getConnection();
 
    ValueFactory vf = sr.getValueFactory();
    URI p   = vf.createURI("http://p");   
    URI cls = vf.createURI("http://cls");    
 
    repConn.clear();
    repConn.add(p, RDFS.DOMAIN, cls);
    repConn.commit();
 
    store.analyze();                 // analyze the semantic model
    store.analyzeApplicationTable(); // and then the application table
 
    GraphQuery tq = null;
    tq = repConn.prepareGraphQuery(QueryLanguage.SPARQL,
        "CONSTRUCT {?x <http://new_eq_p> ?o } WHERE { ?x ?p ?o }" );
    {
      psOut.println("Start construct query");
      GraphQueryResult result = tq.evaluate();
      while (result.hasNext()) {
        Statement stmt = (Statement) result.next();
        psOut.println(stmt.toString());
        // do something interesting with the values here...
      }
      result.close();
    }
 
    tq = repConn.prepareGraphQuery(QueryLanguage.SPARQL,
        "DESCRIBE <http://p> ");
    {
      psOut.println("Start describe query");
      GraphQueryResult result = tq.evaluate();
      while (result.hasNext()) {
        Statement stmt = (Statement) result.next();
        psOut.println(stmt.toString());
        // do something interesting with the values here...
      }
      result.close();
    }
 
    repConn.close(); 
    sr.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example9.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example9 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX9

The expected output of the java command might appear as follows:

Start construct query
(http://p, http://new_eq_p, http://cls)
Start describe query
(http://p, http://www.w3.org/2000/01/rdf-schema#domain, http://cls)

8.10.10 Example10.java: Inference

Example 8-13 shows the Example10.java file, which performs OWLPrime inference using the incremental (INC) and degree of parallelism (DOP) options.

Example 8-13 Inference

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example10
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    String[] rulebaseNames = new String[1];
    rulebaseNames[0] = "owlprime";
 
    Attachment attachment = Attachment.createInstance(
        Attachment.NO_ADDITIONAL_MODELS, rulebaseNames,
        InferenceMaintenanceMode.NO_UPDATE,
        QueryOptions.DEFAULT);
 
    OracleSailStore store = new OracleSailStore(op, model, attachment);   
    OracleSailConnection osc = store.getConnection();
 
    ValueFactory vf = osc.getValueFactory();
 
    URI sub, pred, obj;
    {
      sub = vf.createURI("http://C1");
      pred = vf.createURI("http://www.w3.org/2000/01/rdf-schema#subClassOf");
      obj  = vf.createURI("http://C2");
      osc.addStatement(sub, pred, obj);
 
      sub = vf.createURI("http://C2");
      pred = vf.createURI("http://www.w3.org/2000/01/rdf-schema#subClassOf");
      obj  = vf.createURI("http://C3");
      osc.addStatement(sub, pred, obj);
    }
 
    osc.commit();
    osc.analyze();                 // analyze the semantic model
    osc.analyzeApplicationTable(); // and then the application table
 
    // parallel inference is certainly an overkill for this ontology
    osc.setInferenceOption("INC=T,DOP=4,RAW8=T");
    osc.performInference();
    osc.analyzeInferredGraph();
 
    TupleQuery tq = null;
    RepositoryConnection repConn = osc.asRepositoryConnection();
    tq = repConn.prepareTupleQuery(QueryLanguage.SPARQL,
        "SELECT ?s ?p ?o WHERE {?s ?p ?o } ");
    {
      TupleQueryResult result = tq.evaluate();
      int idx = 0;
      try {
        psOut.print("\nStart printing solution\n");
        while (result.hasNext()) {
          idx++;
          BindingSet bindingSet = result.next();
        }
      }
      finally {
        psOut.println("\ntotal # of solution " + Integer.toString(idx));
        result.close();
      }
    }
 
 
    {
      sub  = vf.createURI("http://C3");
      pred = vf.createURI("http://www.w3.org/2000/01/rdf-schema#subClassOf");
      obj  = vf.createURI("http://C4");
      osc.addStatement(sub, pred, obj);
    }
 
    // make a small change and then perform inference again
    osc.commit();
    osc.analyze();                 // analyze the semantic model
    osc.analyzeApplicationTable(); // and then the application table
    osc.performInference();
    osc.analyzeInferredGraph();
 
    {
      TupleQueryResult result = tq.evaluate();
      int idx = 0;
      try {
        psOut.print("\nStart printing solution\n");
        while (result.hasNext()) {
          idx++;
          BindingSet bindingSet = result.next();
        }
      }
      finally {
        psOut.println("\ntotal # of solution " + Integer.toString(idx));
        result.close();
      }
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example10.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example10 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX10

The expected output of the java command might appear as follows:

Start printing solution
 
total # of solution 3
 
Start printing solution
 
total # of solution 6

8.10.11 Example11.java: Named Graph Query

Example 8-14 shows the Example9.java file, which performs a named graph query.

Example 8-14 Named Graph Query

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example11
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
    String trigFile = args[4];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    OracleSailStore store = new OracleSailStore(op, model);
    OracleSailConnection osc = store.getConnection();
    RepositoryConnection repConn = osc.asRepositoryConnection();
    repConn.setAutoCommit(false);
 
    // load the data incrementally since it is very small file
    repConn.add(new File(trigFile), "http://my.com/", RDFFormat.TRIG);
 
    osc.commit();
    osc.analyze();                 // analyze the semantic model
    osc.analyzeApplicationTable(); // and then the application table
 
    TupleQuery tq = null;
    tq = repConn.prepareTupleQuery(QueryLanguage.SPARQL,
        "SELECT ?g ?s ?p ?o WHERE {?g <http://purl.org/dc/elements/1.1/publisher> ?o1 . GRAPH ?g {?s ?p ?o}}");
    {
      TupleQueryResult result = tq.evaluate();
      int idx = 0;
      try {
        while (result.hasNext()) {
          idx++;
          BindingSet bindingSet = result.next();
          psOut.print("\nsolution " + bindingSet.toString());
        }
      }
      finally {
        psOut.println("\ntotal # of solution " + Integer.toString(idx));
        result.close();
      }
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example9.java

For running this example, assume that the test.trig file described in Section 8.10.2, "Example2.java: Add a Data File (in TRIG format)" has been created.

To run this example using the test.trig data file, enter the following command:

/usr/local/packages/jdk16/bin/java -classpath $CP Example11 jdbc:oracle:thin:@localhost:1521:ORCL scott  <password>  EX11 ./test.trig

The expected output of the java command might appear as follows:

solution [g=http://example.org/alice;s=_:node14r2238h1x1;p=http://xmlns.com/foaf/0.1/mbox;o=mailto:alice@work.example.org]
solution [g=http://example.org/alice;s=_:node14r2238h1x1;p=http://xmlns.com/foaf/0.1/name;o="Alice"]
solution [g=http://example.org/bob;s=_:node14r2238h1x1;p=http://xmlns.com/foaf/0.1/mbox;o=mailto:bob@oldcorp.example.org]
total # of solution 3

8.10.12 Example12.java: Indexes on Application Table [Advanced]

Example 8-15 shows the Example12.java file, an advanced example that creates indexes on the application table.

Example 8-15 Indexes on Application Table [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example12
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    OracleSailStore store = new OracleSailStore(op, model);
 
    // create an index with compress 2, parallel 4
    store.createAppTabIndex("spoc", 2, 4);
 
    // create another index w/o parallel or compression
    store.createAppTabIndex("cspo", 0, 1);
 
    // will print out the default index (cpso) as well
    psOut.println("index signatures before dropping indexes:");
    for (String sig : store.getAppTabIndexSignatures()) {
      psOut.println("index signature:" + sig);     
    }
 
    store.dropAllAppTabIndexes();
    psOut.println("index signatures after dropping indexes...");
    for (String sig : store.getAppTabIndexSignatures()) {
      psOut.println("index signature:" + sig);     
    }
 
    store.shutDown();
 
    // clean up oracle tables and models
    OracleUtils.dropSemanticModelAndTables(op, model);
 
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example12.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example12 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX12

The expected output of the java command might appear as follows:

index signatures before dropping indexes:
index signature:spoc
index signature:cpso
index signature:cspo
index signatures after dropping indexes...

8.10.13 Example13.java: Uniqueness Constraint on Application Table [Advanced]

Example 8-16 shows the Example13.java file, an advanced example that enables and disables the uniqueness constraint on the application table.

Example 8-16 Uniqueness Constraint on Application Table [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example13
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
 
    OracleSailStore store = new OracleSailStore(op, model);
    store.enableUniquenessConstraint();    ValueFactory f = store.getValueFactory();
 
    OracleSailConnection osc = store.getConnection();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");   
 
    osc.addStatement(alice, name, person);
    osc.addStatement(alice, name, person);
    psOut.println("size of store after adding duplicate triple with uniqueness ON :" + osc.size());
 
    osc.clear();       
    store.disableUniquenessConstraint();    osc.addStatement(alice, name, person);
    osc.addStatement(alice, name, person);
    psOut.println("size of store after adding duplicate triple with uniqueness OFF:" + osc.size());
 
    osc.close();
 
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example13.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example13 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX13

The expected output of the java command might appear as follows:

size of store after adding duplicate triple with uniqueness ON :1
size of store after adding duplicate triple with uniqueness OFF:2

8.10.14 Example14.java: Query Timeout and Parallel Execution [Advanced]

Example 8-17 shows the Example14.java file, an advanced example that specifies a query timeout and parallel execution (TIMEOUT and DOP options).

Example 8-17 Query Timeout and Parallel Execution [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example14
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
 
    OracleSailConnection osc = store.getConnection();
    ValueFactory f = osc.getValueFactory();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    osc.addStatement(alice, RDF.TYPE, person);
    osc.addStatement(alice, name, alicesName);
    osc.commit();
 
    osc.analyze();
    osc.analyzeApplicationTable();
 
    // Run a query while specifying parallel execution (through DOP=2)
    // and max query execution time (through tmieout=3)
    String queryString =
      " PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#dop=2,timeout=3> " +
      " SELECT * WHERE {?x ?p ?y} ";
 
    TupleQuery tupleQuery = osc.asRepositoryConnection().prepareTupleQuery(
        QueryLanguage.SPARQL, queryString);
 
    TupleQueryResult result = tupleQuery.evaluate();
    try {
      while (result.hasNext()) {
        BindingSet bindingSet = result.next();
        psOut.println("value of x: " + bindingSet.getValue("x"));
      }
    }
    finally {
      result.close();
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example14.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example14 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX14

The expected output of the java command might appear as follows:

value of x: http://example.org/people/alice
value of x: http://example.org/people/alice

8.10.15 Example15.java: Get COUNT of Matches [Advanced]

Example 8-18 shows the Example15.java file, an advanced example that returns the total number (COUNT) of matches (and only of matches).

Example 8-18 Get COUNT of Matches [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example15
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
 
    OracleSailConnection osc = store.getConnection();
    ValueFactory f = osc.getValueFactory();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    osc.addStatement(alice, RDF.TYPE, person);
    osc.addStatement(alice, name, alicesName);
    osc.commit();
 
    osc.analyze();
    osc.analyzeApplicationTable();
 
    // Run a query and only return the number of matches (the count!)
    String queryString =
      " PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#count_only> " +
      " SELECT ?totalCount WHERE {?s ?p ?y} ";
 
    TupleQuery tupleQuery = osc.asRepositoryConnection().prepareTupleQuery(
        QueryLanguage.SPARQL, queryString);
 
    TupleQueryResult result = tupleQuery.evaluate();
    try {
      if (result.hasNext()) {
        BindingSet bindingSet = result.next();
        psOut.println("number of matches: " + bindingSet.getValue("totalCount"));
      }
    }
    finally {
      result.close();
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example15.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example15 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX15

The expected output of the java command might appear as follows:

number of matches: "2"^^<http://www.w3.org/2001/XMLSchema#integer>

8.10.16 Example16.java: Specify Bind Variable for Constant in Query Pattern [Advanced]

Example 8-19 shows the Example16.java file, an advanced example that specifies a bind variable for a constant in the SPARQL query pattern.

Example 8-19 Specify Bind Variable for Constant in Query Pattern [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example16
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
 
    OracleSailConnection osc = store.getConnection();
    ValueFactory f = osc.getValueFactory();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    osc.addStatement(alice, RDF.TYPE, person);
    osc.addStatement(alice, name, alicesName);
    osc.commit();
 
    osc.analyze();
    osc.analyzeApplicationTable();
 
    String queryString =
      " PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#use_bind_var(1)> " +
      " SELECT ?p WHERE { <http://example.org/people/alice> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?p} ";
 
    TupleQuery tupleQuery = osc.asRepositoryConnection().prepareTupleQuery(
        QueryLanguage.SPARQL, queryString);
 
    TupleQueryResult result = tupleQuery.evaluate();
    try {
      if (result.hasNext()) {
        BindingSet bindingSet = result.next();
        psOut.println("solution " + bindingSet.toString());
      }
    }
    finally {
      result.close();
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example16.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example16 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX16

The expected output of the java command might appear as follows:

solution [p=http://example.org/ontology/Person]

8.10.17 Example17.java: Specify Bind Variable for Constant in Different Position in Query Pattern [Advanced]

Example 8-20 shows the Example17.java file, an advanced example that specifies a bind variable for a constant in a different position in the SPARQL query pattern than in Example16.java (Example 8-19).

Example 8-20 Specify Bind Variable for Constant in Different Position in Query Pattern [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example17
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
 
    OracleSailConnection osc = store.getConnection();
    ValueFactory f = osc.getValueFactory();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    osc.addStatement(alice, RDF.TYPE, person);
    osc.addStatement(alice, name, alicesName);
    osc.commit();
 
    osc.analyze();
    osc.analyzeApplicationTable();
 
    String queryString =
      " PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#use_bind_var(2)> " +
      " SELECT ?s WHERE { ?s <http://example.org/ontology/name> \"Alice\" } ";
 
    TupleQuery tupleQuery = osc.asRepositoryConnection().prepareTupleQuery(
        QueryLanguage.SPARQL, queryString);
 
    TupleQueryResult result = tupleQuery.evaluate();
    try {
      if (result.hasNext()) {
        BindingSet bindingSet = result.next();
        psOut.println("solution " + bindingSet.toString());
      }
    }
    finally {
      result.close();
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example17.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example17 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX17

The expected output of the java command might appear as follows:

solution [s=http://example.org/people/alice]

8.10.18 Example18.java: Build URIs from Internal Numeric IDs [Advanced]

Example 8-21 shows the Example18.java file, an advanced example that builds URIs from internal numeric IDs.

Example 8-21 Build URIs from Internal Numeric IDs [Advanced]

import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import info.aduna.iteration.CloseableIteration;
 
import java.io.*;
import java.sql.SQLException;
 
import oracle.spatial.rdf.client.sesame.*;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.SailConnection;
import org.openrdf.sail.SailException;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.model.Literal;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.MalformedQueryException;
 
public class Example18
{
  public static void main(String[] args) throws SQLException, SailException,
    RepositoryException, IOException, RDFParseException, QueryEvaluationException,
    MalformedQueryException
  {
    PrintStream psOut = System.out;
    String jdbcUrl  = args[0];
    String user     = args[1];
    String password = args[2];
    String model    = args[3];
 
    OraclePool op = new OraclePool(
        OraclePool.getOracleDataSource(jdbcUrl, user, password));
    OracleSailStore store = new OracleSailStore(op, model);   
 
    OracleSailConnection osc = store.getConnection();
    ValueFactory f = osc.getValueFactory();
 
    // create some resources and literals to make statements out of
    URI alice = f.createURI("http://example.org/people/alice");
    URI name = f.createURI("http://example.org/ontology/name");
    URI person = f.createURI("http://example.org/ontology/Person");
    Literal alicesName = f.createLiteral("Alice");
 
    osc.addStatement(alice, RDF.TYPE, person);
    osc.addStatement(alice, name, alicesName);
    osc.commit();
 
    osc.analyze();
    osc.analyzeApplicationTable();
 
    String queryString =
      " PREFIX ORACLE_SEM_FS_NS: <http://oracle.com/semtech#build-uri-for-id(?p)> " +
      " SELECT ?p WHERE { <http://example.org/people/alice> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?p} ";
 
    TupleQuery tupleQuery = osc.asRepositoryConnection().prepareTupleQuery(
        QueryLanguage.SPARQL, queryString);
 
    TupleQueryResult result = tupleQuery.evaluate();
    try {
      if (result.hasNext()) {
        BindingSet bindingSet = result.next();
        psOut.println("solution " + bindingSet.toString());
      }
    }
    finally {
      result.close();
    }
 
    osc.close();
    store.shutDown();
    op.close();
  }
}

To compile this example, enter the following command:

usr/local/packages/jdk16/bin/javac -classpath $CP Example18.java

To run this example, enter a command in the following format:

/usr/local/packages/jdk16/bin/java -classpath $CP Example18 jdbc:oracle:thin:@localhost:1521:ORCL scott <password> EX18

The expected output of the java command might appear as follows:

solution [p=rdfvid:428072448720587401]