www.openlinksw.com
docs.openlinksw.com

Book Home

Contents
Preface

RDF Data Access and Data Management

Data Representation
SPARQL
RDF Graphs Security
Automated Generation of RDF Views over Relational Data Sources
RDF Insert Methods in Virtuoso
Integration Middleware
Linked Data
Inference Rules & Reasoning
Performance Tuning
RDF Data Access Providers (Drivers)
Virtuoso Jena Provider Virtuoso Sesame Provider Virtuoso Redland Provider

15.10. RDF Data Access Providers (Drivers)

15.10.1. Virtuoso Jena Provider

15.10.1.1. What is Jena

Jena is an open source Semantic Web framework for Java. It provides an API to extract data from and write to RDF graphs. The graphs are represented as an abstract "model". A model can be sourced with data from files, databases, URIs or a combination of these. A Model can also be queried through SPARQL and updated through SPARUL.


15.10.1.2. What is the Virtuoso Jena Provider

The Virtuoso Jena RDF Data Provider is a fully operational Native Graph Model Storage Provider for the Jena Framework, enables Semantic Web applications written using the Jena RDF Frameworks to query the Virtuoso RDF Quad store directly. The Provider has been tested against the Jena 2.5.5 version currently available.

Virtuoso Jena RDF Data Provider
Figure: 15.10.1.2.1. Virtuoso Jena RDF Data Provider

15.10.1.3. Setup

15.10.1.3.1. Required Files

15.10.1.3.2. Compiling Jena Sample Programs
  1. Edit the sample programs VirtuosoSPARQLExampleX.java, where X = 1 to 9. Set the JDBC connection strings within to point to a valid Virtuoso Server instance of the form:
    "jdbc:virtuoso://localhost:1111/charset=UTF-8/log_enable=2", "dba", "dba"
    
    • charset=UTF-8: to work correctly with different encodings such as cirilic, etc.
    • log_enable=2: to use row auto commit
    • use these settings to process large rdf data.
  2. Ensure that full paths to jena.jar, arq.jar, and virtjdbc3.jar are included in the active CLASSPATH setting.
  3. Compile the Jena Sample applications using the following command:
    javac -cp "jena.jar:arq.jar:virtjdbc3.jar:virt_jena.jar:." VirtuosoSPARQLExample1.java
    VirtuosoSPARQLExample2.java VirtuosoSPARQLExample3.java VirtuosoSPARQLExample4.java
    VirtuosoSPARQLExample5.java VirtuosoSPARQLExample6.java VirtuosoSPARQLExample7.java
    VirtuosoSPARQLExample8.java VirtuosoSPARQLExample9.java
    

15.10.1.3.3. Testing

Once the Provider classes and sample program have been successfully compiled, the Provider can be tested using the sample programs included. Ensure your active CLASSPATH includes full paths to all of the following files, before executing the example commands:

  1. VirtuosoSPARQLExample1 returns the contents of the RDF Quad store of the targeted Virtuoso instance, with the following command:
    java VirtuosoSPARQLExample1
    
  2. VirtuosoSPARQLExample2 reads in the contents of the following FOAF URIs --
    http://kidehen.idehen.net/dataspace/person/kidehen#this
    http://www.w3.org/People/Berners-Lee/card#i
    http://demo.openlinksw.com/dataspace/person/demo#this
    

    -- and returns the RDF data stored, with the following command:

    java VirtuosoSPARQLExample2
    
  3. VirtuosoSPARQLExample3 performs simple addition and deletion operation on the content of the triple store, with the following command:
    java VirtuosoSPARQLExample3
    
  4. VirtuosoSPARQLExample4 demonstrates the use of the graph.contains method for searching triples, with the following command:
    java VirtuosoSPARQLExample4
    
  5. VirtuosoSPARQLExample5 demonstrates the use of the graph.find method for searching triples, with the following command:
    java VirtuosoSPARQLExample5
    
  6. VirtuosoSPARQLExample6 demonstrates the use of the graph.getTransactionHandler method, with the following command:
    java VirtuosoSPARQLExample6
    
  7. VirtuosoSPARQLExample7 demonstrates the use of the graph.getBulkUpdateHandler method, with the following command:
    java VirtuosoSPARQLExample7
    
  8. VirtuosoSPARQLExample8 demonstrates how to insert triples into a graph, with the following command:
    java VirtuosoSPARQLExample8
    
  9. VirtuosoSPARQLExample9 demonstrates the use of the CONSTRUCT, DESCRIBE, and ASK SPARQL query forms, with the following command:
    java VirtuosoSPARQLExample9
    


15.10.1.4. Examples

15.10.1.4.1. VirtJenaSPARQLExample1
import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample1 {

	/**
	 * Executes a SPARQL query against a virtuoso url and prints results.
	 */
	public static void main(String[] args) {

		String url;
		if(args.length == 0)
		    url = "jdbc:virtuoso://localhost:1111";
		else
		    url = args[0];

/*			STEP 1			*/
		VirtGraph set = new VirtGraph (url, "dba", "dba");

/*			STEP 2			*/


/*			STEP 3			*/
/*		Select all data in virtuoso	*/
		Query sparql = QueryFactory.create("SELECT * WHERE { GRAPH ?graph { ?s ?p ?o } } limit 100");

/*			STEP 4			*/
		VirtuosoQueryExecution vqe = VirtuosoQueryExecutionFactory.create (sparql, set);

		ResultSet results = vqe.execSelect();
		while (results.hasNext()) {
			QuerySolution result = results.nextSolution();
		    RDFNode graph = result.get("graph");
		    RDFNode s = result.get("s");
		    RDFNode p = result.get("p");
		    RDFNode o = result.get("o");
		    System.out.println(graph + " { " + s + " " + p + " " + o + " . }");
		}
	}
}


15.10.1.4.2. VirtJenaSPARQLExample2
import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample2 {

	/**
	 * Executes a SPARQL query against a virtuoso url and prints results.
	 */
	public static void main(String[] args) {

		String url;
		if(args.length == 0)
		    url = "jdbc:virtuoso://localhost:1111";
		else
		    url = args[0];

/*			STEP 1			*/
		VirtGraph graph = new VirtGraph ("Example2", url, "dba", "dba");

/*			STEP 2			*/
/*		Load data to Virtuoso		*/
		graph.clear ();

		System.out.print ("Begin read from 'http://www.w3.org/People/Berners-Lee/card#i'  ");
		graph.read("http://www.w3.org/People/Berners-Lee/card#i", "RDF/XML");
		System.out.println ("\t\t\t Done.");

		System.out.print ("Begin read from 'http://demo.openlinksw.com/dataspace/person/demo#this'  ");
		graph.read("http://demo.openlinksw.com/dataspace/person/demo#this", "RDF/XML");
		System.out.println ("\t Done.");

		System.out.print ("Begin read from 'http://kidehen.idehen.net/dataspace/person/kidehen#this'  ");
		graph.read("http://kidehen.idehen.net/dataspace/person/kidehen#this", "RDF/XML");
		System.out.println ("\t Done.");


/*			STEP 3			*/
/*		Select only from VirtGraph	*/
		Query sparql = QueryFactory.create("SELECT ?s ?p ?o WHERE { ?s ?p ?o }");

/*			STEP 4			*/
		VirtuosoQueryExecution vqe = VirtuosoQueryExecutionFactory.create (sparql, graph);

		ResultSet results = vqe.execSelect();
		while (results.hasNext()) {
			QuerySolution result = results.nextSolution();
		    RDFNode graph_name = result.get("graph");
		    RDFNode s = result.get("s");
		    RDFNode p = result.get("p");
		    RDFNode o = result.get("o");
		    System.out.println(graph_name + " { " + s + " " + p + " " + o + " . }");
		}

		System.out.println("graph.getCount() = " + graph.getCount());
	}
}

15.10.1.4.3. VirtJenaSPARQLExample3
import java.util.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample3
{
    public static void main(String[] args)
    {
	String url;

	if(args.length == 0)
	    url = "jdbc:virtuoso://localhost:1111";
	else
	    url = args[0];

	Node foo1 = Node.createURI("http://example.org/#foo1");
	Node bar1 = Node.createURI("http://example.org/#bar1");
	Node baz1 = Node.createURI("http://example.org/#baz1");

	Node foo2 = Node.createURI("http://example.org/#foo2");
	Node bar2 = Node.createURI("http://example.org/#bar2");
	Node baz2 = Node.createURI("http://example.org/#baz2");

	Node foo3 = Node.createURI("http://example.org/#foo3");
	Node bar3 = Node.createURI("http://example.org/#bar3");
	Node baz3 = Node.createURI("http://example.org/#baz3");

	List <Triple> triples = new ArrayList <Triple> ();

	VirtGraph graph = new VirtGraph ("Example3", url, "dba", "dba");

	graph.clear ();

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("Add 3 triples to graph <Example3>.");

	graph.add(new Triple(foo1, bar1, baz1));
	graph.add(new Triple(foo2, bar2, baz2));
	graph.add(new Triple(foo3, bar3, baz3));

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	triples.add(new Triple(foo1, bar1, baz1));
	triples.add(new Triple(foo2, bar2, baz2));

	graph.isEmpty();

	System.out.println("Remove 2 triples from graph <Example3>");
	graph.remove(triples);
	System.out.println("graph.getCount() = " + graph.getCount());
	System.out.println("Please check result with isql tool.");

	/* EXPECTED RESULT:

SQL> sparql select ?s ?p ?o from <Example3> where {?s ?p ?o};
s                                                    p                                                             o
VARCHAR                                    VARCHAR                                              VARCHAR
_______________________________________________________________________________

http://example.org/#foo3              http://example.org/#bar3                         http://example.org/#baz3

1 Rows. -- 26 msec.
SQL>

*/

	}
}

15.10.1.4.4. VirtJenaSPARQLExample4
import java.util.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample4
{

    public static void main(String[] args)
    {
	String url;
	if(args.length == 0)
	    url = "jdbc:virtuoso://localhost:1111";
	else
	    url = args[0];

	Node foo1 = Node.createURI("http://example.org/#foo1");
	Node bar1 = Node.createURI("http://example.org/#bar1");
	Node baz1 = Node.createURI("http://example.org/#baz1");

	Node foo2 = Node.createURI("http://example.org/#foo2");
	Node bar2 = Node.createURI("http://example.org/#bar2");
	Node baz2 = Node.createURI("http://example.org/#baz2");

	Node foo3 = Node.createURI("http://example.org/#foo3");
	Node bar3 = Node.createURI("http://example.org/#bar3");
	Node baz3 = Node.createURI("http://example.org/#baz3");

	VirtGraph graph = new VirtGraph ("Example4", url, "dba", "dba");

	graph.clear ();

	System.out.println("graph.isEmpty() = " + graph.isEmpty());

	System.out.println("Add 3 triples to graph <Example4>.");

	graph.add(new Triple(foo1, bar1, baz1));
	graph.add(new Triple(foo2, bar2, baz2));
	graph.add(new Triple(foo3, bar3, baz3));

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	System.out.println ("graph.contains(new Triple(foo2, bar2, baz2) - " + graph.contains(new Triple(foo2, bar2, baz2)));
	System.out.println ("graph.contains(new Triple(foo2, bar2, baz3) - " + graph.contains(new Triple(foo2, bar2, baz3)));

	graph.clear ();

    }
}

15.10.1.4.5. VirtJenaSPARQLExample5
import java.util.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample5
{

    public static void main(String[] args)
    {
	String url;
	if(args.length == 0)
	    url = "jdbc:virtuoso://localhost:1111";
	else
	    url = args[0];

	Node foo1 = Node.createURI("http://example.org/#foo1");
	Node bar1 = Node.createURI("http://example.org/#bar1");
	Node baz1 = Node.createURI("http://example.org/#baz1");

	Node foo2 = Node.createURI("http://example.org/#foo2");
	Node bar2 = Node.createURI("http://example.org/#bar2");
	Node baz2 = Node.createURI("http://example.org/#baz2");

	Node foo3 = Node.createURI("http://example.org/#foo3");
	Node bar3 = Node.createURI("http://example.org/#bar3");
	Node baz3 = Node.createURI("http://example.org/#baz3");

	VirtGraph graph = new VirtGraph ("Example5", url, "dba", "dba");

	graph.clear ();

	System.out.println("graph.isEmpty() = " + graph.isEmpty());

	System.out.println("Add 3 triples to graph <Example5>.");

	graph.add(new Triple(foo1, bar1, baz1));
	graph.add(new Triple(foo2, bar2, baz2));
	graph.add(new Triple(foo3, bar3, baz3));
	graph.add(new Triple(foo1, bar2, baz2));
	graph.add(new Triple(foo1, bar3, baz3));

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	ExtendedIterator iter = graph.find(foo1, Node.ANY, Node.ANY);
	System.out.println ("\ngraph.find(foo1, Node.ANY, Node.ANY) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	iter = graph.find(Node.ANY, Node.ANY, baz3);
	System.out.println ("\ngraph.find(Node.ANY, Node.ANY, baz3) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	iter = graph.find(foo1, Node.ANY, baz3);
	System.out.println ("\ngraph.find(foo1, Node.ANY, baz3) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	graph.clear ();

    }
}

15.10.1.4.6. VirtJenaSPARQLExample6
import java.util.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample6
{

    public static void main(String[] args)
    {
	String url;
	if(args.length == 0)
	    url = "jdbc:virtuoso://localhost:1111";
	else
	    url = args[0];

	Node foo1 = Node.createURI("http://example.org/#foo1");
	Node bar1 = Node.createURI("http://example.org/#bar1");
	Node baz1 = Node.createURI("http://example.org/#baz1");

	Node foo2 = Node.createURI("http://example.org/#foo2");
	Node bar2 = Node.createURI("http://example.org/#bar2");
	Node baz2 = Node.createURI("http://example.org/#baz2");

	Node foo3 = Node.createURI("http://example.org/#foo3");
	Node bar3 = Node.createURI("http://example.org/#bar3");
	Node baz3 = Node.createURI("http://example.org/#baz3");

	VirtGraph graph = new VirtGraph ("Example6", url, "dba", "dba");

	graph.clear ();

	System.out.println("graph.isEmpty() = " + graph.isEmpty());

	System.out.println("test Transaction Commit.");
	graph.getTransactionHandler().begin();
	System.out.println("begin Transaction.");
	System.out.println("Add 3 triples to graph <Example6>.");

	graph.add(new Triple(foo1, bar1, baz1));
	graph.add(new Triple(foo2, bar2, baz2));
	graph.add(new Triple(foo3, bar3, baz3));

	graph.getTransactionHandler().commit();
	System.out.println("commit Transaction.");
	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	ExtendedIterator iter = graph.find(Node.ANY, Node.ANY, Node.ANY);
	System.out.println ("\ngraph.find(Node.ANY, Node.ANY, Node.ANY) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	graph.clear ();
	System.out.println("\nCLEAR graph <Example6>");
	System.out.println("graph.isEmpty() = " + graph.isEmpty());

	System.out.println("Add 1 triples to graph <Example6>.");
	graph.add(new Triple(foo1, bar1, baz1));

	System.out.println("test Transaction Abort.");
	graph.getTransactionHandler().begin();
	System.out.println("begin Transaction.");
	System.out.println("Add 2 triples to graph <Example6>.");

	graph.add(new Triple(foo2, bar2, baz2));
	graph.add(new Triple(foo3, bar3, baz3));

	graph.getTransactionHandler().abort();
	System.out.println("abort Transaction.");
	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	iter = graph.find(Node.ANY, Node.ANY, Node.ANY);
	System.out.println ("\ngraph.find(Node.ANY, Node.ANY, Node.ANY) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	graph.clear ();
	System.out.println("\nCLEAR graph <Example6>");

    }
}



15.10.1.4.7. VirtJenaSPARQLExample7
import java.util.*;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample7
{

    public static void main(String[] args)
    {
	String url;
	if(args.length == 0)
	    url = "jdbc:virtuoso://localhost:1111";
	else
	    url = args[0];

	Node foo1 = Node.createURI("http://example.org/#foo1");
	Node bar1 = Node.createURI("http://example.org/#bar1");
	Node baz1 = Node.createURI("http://example.org/#baz1");

	Node foo2 = Node.createURI("http://example.org/#foo2");
	Node bar2 = Node.createURI("http://example.org/#bar2");
	Node baz2 = Node.createURI("http://example.org/#baz2");

	Node foo3 = Node.createURI("http://example.org/#foo3");
	Node bar3 = Node.createURI("http://example.org/#bar3");
	Node baz3 = Node.createURI("http://example.org/#baz3");

	List triples1 = new ArrayList();
	triples1.add(new Triple(foo1, bar1, baz1));
	triples1.add(new Triple(foo2, bar2, baz2));
	triples1.add(new Triple(foo3, bar3, baz3));

	List triples2 = new ArrayList();
	triples2.add(new Triple(foo1, bar1, baz1));
	triples2.add(new Triple(foo2, bar2, baz2));

	VirtGraph graph = new VirtGraph ("Example7", url, "dba", "dba");

	graph.clear ();

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("Add List with 3 triples to graph <Example7> via BulkUpdateHandler.");

	graph.getBulkUpdateHandler().add(triples1);

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	ExtendedIterator iter = graph.find(Node.ANY, Node.ANY, Node.ANY);
	System.out.println ("\ngraph.find(Node.ANY, Node.ANY, Node.ANY) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());


	System.out.println("\n\nDelete List of 2 triples from graph <Example7> via BulkUpdateHandler.");

	graph.getBulkUpdateHandler().delete(triples2);

	System.out.println("graph.isEmpty() = " + graph.isEmpty());
	System.out.println("graph.getCount() = " + graph.getCount());

	iter = graph.find(Node.ANY, Node.ANY, Node.ANY);
	System.out.println ("\ngraph.find(Node.ANY, Node.ANY, Node.ANY) \nResult:");
	for ( ; iter.hasNext() ; )
	    System.out.println ((Triple) iter.next());

	graph.clear ();
	System.out.println("\nCLEAR graph <Example7>");

    }
}

15.10.1.4.8. VirtJenaSPARQLExample8
import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample8 {

	/**
	 * Executes a SPARQL query against a virtuoso url and prints results.
	 */
	public static void main(String[] args) {

		String url;
		if(args.length == 0)
		    url = "jdbc:virtuoso://localhost:1111";
		else
		    url = args[0];

/*			STEP 1			*/
		VirtGraph set = new VirtGraph (url, "dba", "dba");

/*			STEP 2			*/
System.out.println("\nexecute: CLEAR GRAPH <http://test1>");
                String str = "CLEAR GRAPH <http://test1>";
                VirtuosoUpdateRequest vur = VirtuosoUpdateFactory.create(str, set);
                vur.exec();

System.out.println("\nexecute: INSERT INTO GRAPH <http://test1> { <aa> <bb> 'cc' . <aa1> <bb1> 123. }");
                str = "INSERT INTO GRAPH <http://test1> { <aa> <bb> 'cc' . <aa1> <bb1> 123. }";
                vur = VirtuosoUpdateFactory.create(str, set);
                vur.exec();

/*			STEP 3			*/
/*		Select all data in virtuoso	*/
System.out.println("\nexecute: SELECT * FROM <http://test1> WHERE { ?s ?p ?o }");
		Query sparql = QueryFactory.create("SELECT * FROM <http://test1> WHERE { ?s ?p ?o }");

/*			STEP 4			*/
		VirtuosoQueryExecution vqe = VirtuosoQueryExecutionFactory.create (sparql, set);

		ResultSet results = vqe.execSelect();
		while (results.hasNext()) {
			QuerySolution rs = results.nextSolution();
		    RDFNode s = rs.get("s");
		    RDFNode p = rs.get("p");
		    RDFNode o = rs.get("o");
		    System.out.println(" { " + s + " " + p + " " + o + " . }");
		}


System.out.println("\nexecute: DELETE FROM GRAPH <http://test1> { <aa> <bb> 'cc' }");
                str = "DELETE FROM GRAPH <http://test1> { <aa> <bb> 'cc' }";
                vur = VirtuosoUpdateFactory.create(str, set);
                vur.exec();

System.out.println("\nexecute: SELECT * FROM <http://test1> WHERE { ?s ?p ?o }");
		vqe = VirtuosoQueryExecutionFactory.create (sparql, set);
                results = vqe.execSelect();
		while (results.hasNext()) {
			QuerySolution rs = results.nextSolution();
		    RDFNode s = rs.get("s");
		    RDFNode p = rs.get("p");
		    RDFNode o = rs.get("o");
		    System.out.println(" { " + s + " " + p + " " + o + " . }");
		}


	}
}

15.10.1.4.9. VirtJenaSPARQLExample9
import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.rdf.model.*;
import java.util.Iterator;

import virtuoso.jena.driver.*;

public class VirtuosoSPARQLExample9 {

	/**
	 * Executes a SPARQL query against a virtuoso url and prints results.
	 */
	public static void main(String[] args) {

		String url;
		if(args.length == 0)
		    url = "jdbc:virtuoso://localhost:1111";
		else
		    url = args[0];

/*			STEP 1			*/
		VirtGraph set = new VirtGraph (url, "dba", "dba");

/*			STEP 2			*/
                String str = "CLEAR GRAPH <http://test1>";
                VirtuosoUpdateRequest vur = VirtuosoUpdateFactory.create(str, set);
                vur.exec();

                str = "INSERT INTO GRAPH <http://test1> { <http://aa> <http://bb> 'cc' . <http://aa1> <http://bb> 123. }";
                vur = VirtuosoUpdateFactory.create(str, set);
                vur.exec();


/*		Select all data in virtuoso	*/
		Query sparql = QueryFactory.create("SELECT * FROM <http://test1> WHERE { ?s ?p ?o }");
		VirtuosoQueryExecution vqe = VirtuosoQueryExecutionFactory.create (sparql, set);
		ResultSet results = vqe.execSelect();
                System.out.println("\nSELECT results:");
		while (results.hasNext()) {
			QuerySolution rs = results.nextSolution();
		    RDFNode s = rs.get("s");
		    RDFNode p = rs.get("p");
		    RDFNode o = rs.get("o");
		    System.out.println(" { " + s + " " + p + " " + o + " . }");
		}

		sparql = QueryFactory.create("DESCRIBE <http://aa> FROM <http://test1>");
		vqe = VirtuosoQueryExecutionFactory.create (sparql, set);

		Model model = vqe.execDescribe();
 	        Graph g = model.getGraph();
                System.out.println("\nDESCRIBE results:");
	        for (Iterator i = g.find(Node.ANY, Node.ANY, Node.ANY); i.hasNext();)
	           {
	              Triple t = (Triple)i.next();
		      System.out.println(" { " + t.getSubject() + " " +
		      				 t.getPredicate() + " " +
		      				 t.getObject() + " . }");
	        }



		sparql = QueryFactory.create("CONSTRUCT { ?x <http://test> ?y } FROM <http://test1> WHERE { ?x <http://bb> ?y }");
		vqe = VirtuosoQueryExecutionFactory.create (sparql, set);

		model = vqe.execConstruct();
 	        g = model.getGraph();
                System.out.println("\nCONSTRUCT results:");
	        for (Iterator i = g.find(Node.ANY, Node.ANY, Node.ANY); i.hasNext();)
	           {
	              Triple t = (Triple)i.next();
		      System.out.println(" { " + t.getSubject() + " " +
		      				 t.getPredicate() + " " +
		      				 t.getObject() + " . }");
	        }


		sparql = QueryFactory.create("ASK FROM <http://test1> WHERE { <http://aa> <http://bb> ?y }");
		vqe = VirtuosoQueryExecutionFactory.create (sparql, set);

		boolean res = vqe.execAsk();
                System.out.println("\nASK results: "+res);


	}
}


15.10.1.5. Javadoc API Documentation

Jena Provider Javadoc API Documentation is available enabling the complete set of classes, interfaces and methods implemented for the provider to be viewed.



15.10.2. Virtuoso Sesame Provider

15.10.2.1. What is Sesame

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


15.10.2.2. What is the Virtuoso Sesame Provider

The Virtuoso Sesame Provider is a fully operational Native Graph Model Storage Providers for the Sesame Framework, allowing users of Virtuoso to leverage the Sesame framework for modifying, querying, and reasoning with the Virtuoso quad store using the Java language. The Sesame Repository API offers a central access point for connecting to the Virtuoso quad store. Its purpose is to provides a java-friendly access point to Virtuoso. It offers various methods for querying and updating the data, while abstracting the details of the underlying machinery. The Provider has been tested against the Sesame 2.1.2 version currently available.

Fig. 1 Sesame Component Stack
Figure: 15.10.2.2.1. Fig. 1 Sesame Component Stack

If you need more information about how to set up your environment for working with the Sesame APIs, take a look at Chapter 4 of the Sesame User Guide, Setting up to use the Sesame libraries.


15.10.2.3. Setup

15.10.2.3.1. Required Files

This tutorial assumes you have Virtuoso server installed and that the database is accessible at "localhost:1111". In addition, you will need the latest version of the Virtuoso Sesame Provider, and Sesame 2 or greater installed.


15.10.2.3.2. Compiling Jena Sample Programs
  1. Ensure that full paths to the following files are all included in the active CLASSPATH setting --
    • openrdf-sesame-2.1.2-onejar.jar
    • slf4j-api-1.5.0.jar
    • slf4j-jdk14-1.5.0.jar
    • virtjdbc3.jar
    • virt_sesame2.jar
  2. Execute the following command --
    javac VirtuosoTest.java
    

    Note: to use utf-8 and to use row auto commit is recommended to add the following to the connect string:

    "/charset=UTF-8/log_enable=2"
    -- i.e. in VirtuosoTest.java the line:
    Repository repository = new VirtuosoRepository("jdbc:virtuoso://" + sa[0] + ":" + sa[1], sa[2], sa[3]);
    -- should become:
    Repository repository = new VirtuosoRepository("jdbc:virtuoso://" + sa[0] + ":" + sa[1]+ "/charset=UTF-8/log_enable=2", sa[2], sa[3]);
    

15.10.2.3.3. Testing
  1. Ensure that full paths to the following files are all included in the active CLASSPATH setting --
    • openrdf-sesame-2.1.2-onejar.jar
    • slf4j-api-1.5.0.jar
    • slf4j-jdk14-1.5.0.jar
    • virtjdbc3.jar
    • virt_sesame2.jar
    • virtuoso_driver
  2. Test the Sesame 2 Provider with the following command
    java VirtuosoTest <hostname> <port> <uid> <pwd>
    
  3. The test run should look like this --
    $ java VirtuosoTest localhost 1111 dba dba
    
    == TEST 1:  : Start
       Loading data from URL: http://www.openlinksw.com/dataspace/person/kidehen@openlinksw.com/foaf.rdf
    == TEST 1:  : End
    PASSED: TEST 1
    
    == TEST 2:  : Start
       Clearing triple store
    == TEST 2:  : End
    PASSED: TEST 2
    
    == TEST 3:  : Start
       Loading data from file: virtuoso_driver/data.nt
    == TEST 3:  : End
    PASSED: TEST 3
    
    == TEST 4:  : Start
       Loading UNICODE single triple
    == TEST 4:  : End
    PASSED: TEST 4
    
    == TEST 5:  : Start
       Loading single triple
    == TEST 5:  : End
    PASSED: TEST 5
    
    == TEST 6:  : Start
       Casted value type
    == TEST 6:  : End
    PASSED: TEST 6
    
    == TEST 7:  : Start
       Selecting property
    == TEST 7:  : End
    PASSED: TEST 7
    
    == TEST 8:  : Start
       Statement does not exists
    == TEST 8:  : End
    PASSED: TEST 8
    
    == TEST 9:  : Start
       Statement exists (by resultset size)
    == TEST 9:  : End
    PASSED: TEST 9
    
    == TEST 10:  : Start
       Statement exists (by hasStatement())
    == TEST 10:  : End
    PASSED: TEST 10
    
    == TEST 11:  : Start
       Retrieving namespaces
    == TEST 11:  : End
    PASSED: TEST 11
    
    == TEST 12:  : Start
       Retrieving statement (http://myopenlink.net/dataspace/person/kidehen http://myopenlink.net/foaf/name null)
    == TEST 12:  : End
    PASSED: TEST 12
    
    == TEST 13:  : Start
       Writing the statements to file: (/Users/hughwilliams/src/virtuoso-opensource/binsrc/sesame2/results.n3.txt)
    == TEST 13:  : End
    PASSED: TEST 13
    
    == TEST 14:  : Start
       Retrieving graph ids
    == TEST 14:  : End
    PASSED: TEST 14
    
    == TEST 15:  : Start
       Retrieving triple store size
    == TEST 15:  : End
    PASSED: TEST 15
    
    == TEST 16:  : Start
       Sending ask query
    == TEST 16:  : End
    PASSED: TEST 16
    
    == TEST 17:  : Start
       Sending construct query
    == TEST 17:  : End
    PASSED: TEST 17
    
    == TEST 18:  : Start
       Sending describe query
    == TEST 18:  : End
    PASSED: TEST 18
    
    ============================
    PASSED:18 FAILED:0
    


15.10.2.4. Getting Started

This section covers the essentials for connecting to and manipulating data stored in a Virtuoso repository using the Sesame API. More information on the Sesame Framework, including extended examples on how to use the API, can be found in Chapter 8 of the Sesame User’s guide, the RepositoryConnection API.

The interfaces for the Repository API can be found in packages virtuoso.sesame2.driver and org.openrdf.repository. Several implementations for these interface exist in the Virtuoso Provider download package. The Javadoc reference for the Sesame API is available online and can also be found in the doc directory of the download.

15.10.2.4.1. Creating a VirtuosoRepositoryRDF object

The first step to connecting to Virtuoso through the Sesame API is to create a Repository for it. The Repository object operates on (stacks of) Sail object(s) for storage and retrieval of RDF data.

One of the simplest configurations is a repository that just stores RDF data in main memory without applying any inference or whatsoever. This is also by far the fastest type of repository that can be used. The following code creates and initialize a non-inferencing main-memory repository:

import virtuoso.sesame2.driver.VirtuosoRepository;

Repository myRepository = VirtuosoRepositoryRDF?("jdbc:virtuoso://localhost:1111”,”dba”,”dba”);

myRepository.initialize();

The constructor of the VirtuosoRepositoryRDF class accepts the JDBC URL of the Virtuoso engine (the default port is 1111), the username and password of an authorized user. Following this example, the repository needs to be initialized to prepare the Sail(s) that it operates on, which includes operations such as restoring previously stored data, setting up connections to a relational database, etc.

The repository that is created by the above code is volatile: its contents are lost when the object is garbage collected or when the program is shut down. This is fine for cases where, for example, the repository is used as a means for manipulating an RDF model in memory. Using the Virtuoso repository with RepositoryConnection.

Now that we have created a VirtuosoRepositoryRDF, we want to do something with it. This is achieved through the use of the VirtuosoRepositoryConnection, which can be created by the VirtuosoRepositoryRDF.

A VirtuosoRepositoryConnection represents - as the name suggests - a connection to the actual Virtuoso quad store. We can issue operations over this connection, and close it when we are done to make sure we are not keeping resources unnecessarily occupied.

In the following sections, we will show some examples of basic operations using the Northwind dataset.


15.10.2.4.2. Adding RDF to Virtuoso

The Repository implements the Sesame Repository API offers various methods for adding data to a repository. Data can be added pro grammatically by specifying the location of a file that contains RDF data, and statements can be added individually or in collections.

We perform operations on the repository by requesting a RepositoryConnection from the repository, which returns a VirtuosoRepositoryConnection object. On this VirtuosoRepositoryConnection object we can perform the various operations, such as query evaluation, getting, adding, or removing statements, etc.

The following example code adds two files, one local and one located on the WWW, to a repository:

import org.openrdf.repository.RepositoryException;

import org.openrdf.repository.Repository;

import org.openrdf.repository.RepositoryConnection;

import org.openrdf.rio.RDFFormat;

import java.io.File;

import java.net.URL;

File file = new File("/path/to/example.rdf");

String baseURI = "http://example.org/example/localRDF";

?

try {

   RepositoryConnection con = myRepository.getConnection();

   try {

      con.add(file, baseURI, RDFFormat.RDFXML);

      URL url = new URL("http://example.org/example/remoteRDF");

      con.add(url, url.toString(), RDFFormat.RDFXML);

   }

   finally {

      con.close();

   }

}

catch (RepositoryException rex) {

   // handle exception

}

catch (java.io.IOEXception e) {

   // handle io exception

}

More information on other available methods can be found in the javadoc reference of the RepositoryConnection interface.


15.10.2.4.3. Querying Virtuoso

The Repository API has a number of methods for creating and evaluating queries. Three types of queries are distinguished: tuple queries, graph queries and boolean queries. The query types differ in the type of results that they produce.

Select Query: The result of a select query is a set of tuples (or variable bindings), where each tuple represents a solution of a query. This type of query is commonly used to get specific values (URIs, blank nodes, literals) from the stored RDF data. The method QueryFactory.executeQuery() returns a Value[][] for sparql "SELECT" queries. The method QueryFactory.executeQuery() also calls the QueryFactory.setResult() which populates a set of tuples for SPARQL "SELECT" queries. The graph can be retrieved using QueryFactory.getBooleanResult().

Graph Query: The result of graph queries is an RDF graph (or set of statements). This type of query is very useful for extracting sub-graphs from the stored RDF data, which can then be queried further, serialized to an RDF document, etc. The method QueryFactory.executeQuery() calls the QueryFactory.setGraphResult() which populates a graph for SPARQL "DESCRIBE" and "CONSTRUCT" queries. The graph can be retrieved using QueryFactory.getGraphResult().

Boolean Query: The result of boolean queries is a simple boolean value, i.e. true of false. This type of query can be used to check if a repository contains specific information. The method QueryFactory.executeQuery() calls the QueryFactory.setBooleanResult() which sets a boolean value for sparql "ASK" queries. The value can be retrieved using QueryFactory.getBooleanResult().

Note: Although Sesame 2 currently supports two query languages: SeRQL and SPARQL, the Virtuoso provider only supports the W3C SPARQL specification.


15.10.2.4.4. Evaluating a SELECT Query

To evaluate a tuple query we simply do the following:

import java.util.List;

import org.openrdf.OpenRDFException;

import org.openrdf.repository.RepositoryConnection;

import org.openrdf.query.TupleQuery;

import org.openrdf.query.TupleQueryResult;

import org.openrdf.query.BindingSet;

import org.openrdf.query.QueryLanguage;

?

try {

   RepositoryConnection? con = myRepository.getConnection();

   try {

      String queryString = "SELECT x, y FROM  WHERE {x} p {y}";

      TupleQuery? tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);

      TupleQueryResult? result = tupleQuery.evaluate();

      try {

         ? // do something with the result

      }

      finally {

         result.close();

      }

   }

   finally {

      con.close();

   }

}

catch (RepositoryException? e) {

   // handle exception

}

This evaluates a SPARQL query and returns a TupleQueryResult, which consists of a sequence of BindingSet objects. Each BindingSet contains a set of pairs called Binding objects. A Binding object represents a name/value pair for each variable in the query’s projection.

We can use the TupleQueryResult to iterate over all results and get each individual result for x and y:

while (result.hasNext()) {

   BindingSet bindingSet = result.next();

   Value valueOfX = bindingSet.getValue("x");

   Value valueOfY = bindingSet.getValue("y");

   // do something interesting with the query variable values here?

}

As you can see, we retrieve values by name rather than by an index. The names used should be the names of variables as specified in your query. The TupleQueryResult.getBindingNames() method returns a list of binding names, in the order in which they were specified in the query. To process the bindings in each binding set in the order specified by the projection, you can do the following:

List bindingNames = result.getBindingNames();

while (result.hasNext()) {

   BindingSet bindingSet = result.next();

   Value firstValue = bindingSet.getValue(bindingNames.get(0));

   Value secondValue = bindingSet.getValue(bindingNames.get(1));

   // do something interesting with the values here?

}

It is important to invoke the close() operation on the TupleQueryResult, after we are done with it. A TupleQueryResult evaluates lazily and keeps resources (such as connections to the underlying database) open. Closing the TupleQueryResult frees up these resources. Do not forget that iterating over a result may cause exceptions! The best way to make sure no connections are kept open unnecessarily is to invoke close() in the finally clause.

An alternative to producing a TupleQueryResult is to supply an object that implements the TupleQueryResultHandler interface to the query's evaluate() method. The main difference is that when using a return object, the caller has control over when the next answer is retrieved, whereas with the use of a handler, the connection simply pushes answers to the handler object as soon as it has them available.

As an example we will use SPARQLResultsXMLWriter, which is a TupleQueryResultHandler implementation that writes SPARQL Results XML documents to an output stream or to a writer:

import org.openrdf.query.resultio.sparqlxml.SPARQLResultsXMLWriter;

?

FileOutputStream out = new FileOutputStream("/path/to/result.srx");

try {

   SPARQLResultsXMLWriter sparqlWriter = new SPARQLResultsXMLWriter(out);

   RepositoryConnection con = myRepository.getConnection();

   try {

      String queryString = "SELECT * FROM  WHERE {x} p {y}";

      TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);

      tupleQuery.evaluate(sparqlWriter);

   }

   finally {

      con.close();

   }

}

finally {

   out.close();

}

You can just as easily supply your own application-specific implementation of TupleQueryResultHandler though.

Lastly, an important warning: as soon as you are done with the RepositoryConnection object, you should close it. Notice that during processing of the TupleQueryResult object (for example, when iterating over its contents), the RepositoryConnection should still be open. We can invoke con.close() after we have finished with the result.


15.10.2.4.5. Evaluating a CONSTRUCT query

The following code evaluates a graph query on a repository:

import org.openrdf.query.GraphQueryResult;

GraphQueryResult graphResult = con.prepareGraphQuery(

      QueryLanguage.SPARQL, "CONSTRUCT * FROM {x} p {y}").evaluate();

A GraphQueryResult is similar to TupleQueryResult in that is an object that iterates over the query results. However, for graph queries the query results are RDF statements, so a GraphQueryResult iterates over Statement objects:

while (graphResult.hasNext()) {

   Statement st = graphResult.next();

   // ? do something with the resulting statement here.


}

The TupleQueryResultHandler equivalent for graph queries is org.openrdf.rio.RDFHandler. Again, this is a generic interface, each object implementing it can process the reported RDF statements in any way it wants.

All writers from Rio (such as the RDFXMLWriter, TurtleWriter, TriXWriter, etc.) implement the RDFHandler interface. This allows them to be used in combination with querying quite easily. In the following example, we use a TurtleWriter to write the result of a SPARQL graph query to standard output in Turtle format:

import org.openrdf.rio.turtle.TurtleWriter;

?

RepositoryConnection con = myRepository.getConnection();

try {

   TurtleWriter turtleWriter = new TurtleWriter(System.out);

   con.prepareGraphQuery(QueryLanguage.SPARQL, "CONSTRUCT * FROM  WHERE {x} p {y}").evaluate(turtleWriter);

}

finally {

   con.close();

}

Again, note that as soon as we are done with the result of the query (either after iterating over the contents of the GraphQueryResult or after invoking the RDFHandler), we invoke con.close() to close the connection and free resources.



15.10.2.5. Javadoc API Documentation

Sesame Provider Javadoc API Documentation is available enabling the complete set of classes, interfaces and methods implemented for the provider to be viewed.



15.10.3. Virtuoso Redland Provider

15.10.3.1. What is Redland

Redland is a set of free software 'C' libraries that provide support for the Resource Description Framework (RDF), providing modular, object based libraries and APIs for manipulating the RDF graph, triples, URIs and Literals. Redland includes several high-level language APIs providing RDF manipulation and storage and requires the Raptor RDF parser and Rasqal RDF syntax and query library for its use.


15.10.3.2. What is the Virtuoso Redland Provider

The Virtuoso Redland RDF Provider is an implementation of the Storage API, Model and Query interfaces of the Redland framework for RDF. This provider enables the execution of queries via the Redland Rasqal query engine or via Virtuoso query engine directly against the Virtuoso Quad store. The Virtuoso Redland Provider uses ODBC as the data access mechanism for communicating the Virtuoso Quad Store and requires the Virtuoso ODBC Driver be installed on the Redland client and a suitable ODBC DSN be configured for connecting to the target Virtuoso Quad Store instance. The provider has been tested against the Redland 1.0.8 version currently available for download.

Redland Component Stack
Figure: 15.10.3.2.1. Redland Component Stack

As indicated in the above diagram the Virtuoso Provider can be used to execute RDF queries either directly against the Virtuoso graph storage module supporting the SPARQL, SPARQLSPARUL, SPARQL-BI query languages or via the Rasqal query engine built into Redland which supports the SPARQL query language. This is done by simply changing the syntax of the query using the "vsparql" rather then default "sparql" construct when executing a query as indicated in the sample queries below:

rdfproc -r xml -t "user='dba',password='dba',dsn='Demo'" gr query sparql - "SELECT * WHERE { ?s ?p ?o }"   ;; via Redland Rasqal engine

rdfproc -r xml -t "user='dba',password='dba',dsn='Demo'" gr query vsparql - "SELECT * WHERE { ?s ?p ?o }"  ;; direct to Virtuoso storage module

The Virtuoso Provider uses the SPASQL query language for querying the remote Virtuoso QUAD store.


15.10.3.3. Setup

15.10.3.3.1. Required Files

The Virtuoso Redland Provider has been integrated into the Redland RDF Framework and submitted to the open source project to become part of the standard distribution available for download. Until this submission has been accepted and committed into the available Redland release a tar ball created by OpenLink Software and a diff for application to a Redland 1.0.8 tree can be obtained from:


15.10.3.3.2. Compiling Redland with Virtuoso storage support

15.10.3.3.3. Connection Parameters

The Virtuoso provider has the following connection parameters available fro use:

NOTE: Take care exposing the password as for example, program arguments or environment variables. The rdfproc utility can help this by reading the password from standard input. Inside programs, one way to prevent storing the password in a string is to construct a Redland hash of the storage options such as via librdf hash_from_string and use librdf_new_storage_with_options to create a storage. The rdfproc utility source code demonstrates this.

The storage name parameter given to the storage constructor librdf new_storage is used inside the virtuoso store to allow multiple stores inside one Virtuoso database instance as parameterized with the above options.

This store always provides contexts; the boolean storage option contexts is not checked.

Examples:

  /* A new Virtuoso store */
  storage=librdf_new_storage(world, "virtuoso", "db1",
      "dsn='Local Virtuoso',user='demo',password='demo'");

  /* A different, existing Virtuoso store in the same database as above */
  storage=librdf_new_storage(world, "virtuoso", "db2",
      "dsn='Local Virtuoso',user='demo',password='demo'");

  /* An existing Virtuoso store on a different database server */
  storage=librdf_new_storage(world, "virtuoso", "http://red3",
      "dsn='Remote Virtuoso',user='demo',password='demo'");

  /* Opening with an options hash */
  options=librdf_new_hash(world, NULL);
  librdf_hash_from_string(options,
      "dsn='Local Virtuoso',user='demo'");
  librdf_hash_put_strings(options, "password", user_password);
  storage=librdf_new_storage_with_options(world, "virtuoso", "http://red3", options);


15.10.3.4. References