My favorites | Sign in
Project Logo
                
Search
for
Updated Nov 11, 2008 by andrewfnewman
GettingStarted  
Getting Started with JRDF

Getting Started with JRDF

This document is not a primer for RDF, this is. JRDF is a library that has a simple to use interface that follows the RDF standard for the creation and management of RDF graphs.

Using the Graph

The Graph interface is the primary way to manipulate RDF graphs. It has methods that allow you to add, remove, and find triples. A graph is created through a graph factory. Triples and elements (nodes) in a graph are created through triple and element factories.

The following is an example showing the creation and use of a graph:

JRDFFactory jrdfFactory = SortedMemoryJRDFFactory.getFactory();
Graph graph = jrdfFactory.getGraph();
TripleFactory tripleFactory = graph.getTripleFactory();
GraphElementFactory elementFactory = graph.getElementFactory();
URIReference foo = elementFactory.createURIReference(URI.create("urn:foo"));
URIReference bar = elementFactory.createURIReference(URI.create("urn:bar"));
graph.add(foo, foo, foo);
graph.add(bar, bar, bar);
ClosableIterator<Triple> tripleIter = graph.find(AnySubjectNode.ANY_SUBJECT, AnyPredicateNode.ANY_PREDICATE, AnyObjectNode.ANY_OBJECT);
try {
  while (tripleIter.hasNext()) {
    Triple triple = tripleIter.next();
    System.out.println("Got triple: " + triple);
  }
}
finally {
  tripleIter.close();
}
graph.remove(foo, foo, foo);

This code creates a graph with two triples in it:

urn:foo urn:foo urn:foo .
urn:bar urn:bar urn:bar .

The graph.find(SubjectNode, PredicateNode, ObjectNode) allows nodes by value to be specified or for the wildcards ANY_SUBJECT, ANY_PREDICATE and ANY_OBJECT to be used. In the above example, all three wildcards are used to return the entire graph. The code will print out:

Got triple: <urn:foo> <urn:foo> <urn:foo>
Got triple: <urn:bar> <urn:bar> <urn:bar>

It then removes the triple "<urn:foo> <urn:foo> <urn:foo>" and the graph has only one triple in it by the end:

urn:bar urn:bar urn:bar .

Creating Graphs

Local graphs are graphs that rely on a node pool and string pool for the creation of RDF data structures. This places certain limits on how these items are used. To create a local graph you must use a Factory - either an in memory factory or an on disk one.

To create an in memory graph factory, create a new graph and add the triple "urn:node, urn:node, urn:node" requires the following code:

JRDFFactory jrdfFactory = SortedMemoryJRDFFactory.getFactory();
Graph graph = jrdfFactory.getGraph();
GraphElementFactory elementFactory = graph.getElementFactory();
Node node = elementFactory.createURIReference(URI.create("urn:node"));
graph.add(node, node, node);

To create an on disk graph replace the first line with (this current requires BDB Java Edition installed in the class path):

JRDFFactory jrdfFactory = SortedDiskJRDFFactory.getFactory();

To create an persistent, named graph requires the first line to be replaced with:

DirectoryHandler handler = new TempDirectoryHandler();
PersistentJRDFFactory factory = PersistentJRDFFactoryImpl.getFactory(handler);

The factory must also be closed in order for the changes to be written to disk, see persistent graphs. JRDF has many different types of graphs that can be created through Spring, other IoC containers or through factories.

Graph Element Factory and Triple Factory

A local JRDF graph requires the creation of RDF structures (triples, literals, URI References, etc.) from a specific RDF graph. This is done using a Graph Element Factory and Triple Factory to create these structures.

Nodes

JRDF's model of RDF nodes uses a hierarchy of interfaces. At the top of the class hierarchy is the Node. This is subclassed by positional nodes: Subject, Predicate and Object. These are then further subclassed by the appropriate typed nodes: bnode (blank node), URI and Literal.

The Resource interface extends both URIReference and BlankNode.

Element Factory

URI References

A URI Reference in RDF must be an absolute URI. This is the default behaviour in JRDF. However, it can be expensive or unnecessary to check that a URI is absolute before creating a URI Reference. Both of these methods for creating URI References is supported:

// Check if URI is absolute
Node node1 = elementFactory.createURIReference(URI.create("urn:node"));
// Don't check if URI is absolute
Node node2 = elementFactory.createURIReference(URI.create("urn:node"), false);

Literals

The Element Factory also allows the creation of literals. To create a typed literal with the value "Hello World"^^xsd:string, the following code is required:

...
Literal literal = elementFactory.createLiteral("Hello World", org.jrdf.vocabulary.XSD.STRING);

Literals can also be created from native Java types. By calling "createLiteral" the Java object is converted to a JRDF Literal. For example to create the Literal "7"^^xsd:int:

...
Literal literal = elementFactory.createLiteral(7);

The mapping from Java types to XSD types is as follows:

Java Type XSD Type
String None
Boolean xsd:boolean
Decimal xsd:decimal
Float xsd:float
Double xsd:double
GregorianCalendar xsd:dateTime
java.sql.Date xsd:dateTime
java.util.Date xsd:dateTime
QName xsd:QName
BigInteger (positive value) xsd:nonNegativeInteger
BigInteger (negative value) xsd:nonPositiveInteger
Long xsd:long
Integer xsd:int
Short xsd:short
Byte xsd:byte

If a Java type is used that has no mapping an exception will be thrown. New mappings can be added through calling addValueCreator(URI, Class<?>, ValueCreator) on the DatatypeFactory.

Blank Nodes

Blank nodes can also be created using the Element Factory:

...
Node node1 = elementFactory.createURIReference(URI.create("urn:node"));
Node node2 = elementFactory.createBlankNode();
graph.add(node2, node1, node2);

Resources

An RDF Resource is either a blank node or a URI Reference. JRDF provides creation of new resources or for an existing blank node or URI Reference to be wrapped in a resource. Resources provide an easy way to add or remove values associated with a resource or to return any associated values. For example, to represent a supplier with a supplier number (S1), name ("urn:Smith"), status (20) and city ("London"):

Resource supplier = elementFactory.createResource();
supplier.addValue(sno, "S1");
supplier.addValue(name, URI.create("urn:Smith"));
supplier.addValue(status, 20);
supplier.addValue(city, "London", XSD.STRING);

This creates a graph with 4 triples in it:

_:1 urn:sno "S1"
_:1 urn:name urn:Smith
_:1 urn:status "20"^^xsd:int
_:1 urn:city "London"^^xsd:string

Resources give you a way to get all the values of a given predicate for a Resource or to get all the subjects of a Resource of a given predicate.

For example, to find the status of the supplier:

ClosableIterator<ObjectNode> objects = supplier.getObjects(status);

Or to find the supplier(s) with the name "urn:Smith":

ClosableIterator<SubjectNode> subjects = smith.getSubjects(name);

Triple Factory

The Triple factory offers a short cut for some frequent operations such as adding RDF standard data structures. It allows:

URI Reference

To create a triple with URI References requires the following code:

...
URI node = URI.create("urn:node");
tripleFactory.add(node, node, node);

Literals

To create literals, replace the last parameter with one or two parameters specifying the Literal. For example, to create a literal with a data type of "xsd:string" requires the following code:

...
URI node = URI.create("urn:node");
tripleFactory.add(node, node, "Hello World", org.jrdf.vocabulary.XSD.STRING);

Blank Nodes

Blank nodes are difficult to add across multiple triples as a reference to the same blank node must be kept. For example:

_1 urn:node urn:node
urn:node urn:node _1

Requires the following code:

...
Node uriNode = elementFactory.createURIReference(URI.create("urn:node"));
Node bnode = elementFactory.createBlankNode();
graph.add(bnode, uriNode, uriNode);
graph.add(uriNode, uriNode, bnode);

Each time createBlankNode() is called a new blank node is created so they cannot be added using the TripleFactory. The combination of using a variable, the Graph Element Factory and then adding them to the Graph is therefore required.

Reifying Triples

RDF Reification allows you to make statements about a triple. The triple may or may not exist and reifying a triple does not add it to the graph - it only adds the 4 triples indicating that the triple is reified.

To reify a triple:

// Note: Creating a triple - not adding it to the Graph.
Triple triple = tripleFactory.createTriple(uriNode, uriNode, uriNode);
BlankNode bnode = elementFactory.createBlankNode();
tripleFactory.reifyTriple(triple, bnode);

This creates four triples:

_:1 rdf:Type rdf:Statement 
_:1 rdf:Subject urn:node
_:1 rdf:Predicate urn:node
_:1 rdf:Object urn:node

RDF Containers and Collections

RDF Containers and Collections have many similarities with Java's Collection classes. JRDF has extended Java Collections and implemented the 3 different types of RDF Containers and the one RDF Collection. They have the following properties:

Type Ordered Duplicates Closed
Alt No No No
Bag No Yes No
Collection Yes, Linked list Yes Yes
Sequence Yes, FIFO (First In, First Out) Yes No

Being closed means being able to say that there are only the currently specified number of members that belong to the group. For more information see: RDF Primer's entry on Collections.

You can create a collection, add triples to it and then add it to the graph using the Triple Factory. For example:

Collection collection = new CollectionImpl();
URIReference fruit1 = elementFactory.createURIReference(URI.create("http://example.org/banana"));
URIReference fruit2 = elementFactory.createURIReference(URI.create("http://example.org/kiwi"));
collection.add(fruit1);
collection.add(fruit2);
BlankNode list = elementFactory.createBlankNode();
tripleFactory.add(list, collection);

After the collection has been added to the graph, via the TripleFactory, new values can be added but the collection must be re-added to the graph.


Comment by srikalyansswayam, Nov 25, 2008

hi,

I am doing my class project on rdf in which i would like to read the rdf file and get the triples and then play with it. I thought of using jena but it is slow and I would like to use jrdf but the problem is there is no good documentation for it and I would like to know about the documentation and if I want to read a file what Class should i look into?

please send your reply to srikalyansswayam@gmail.com

Comment by imranjami, Nov 27, 2008

do u think Jena is easier than JRDF? Which one is better if we forget the issue if speed?

Comment by PedroDedinho, Jun 16, 2009

Hi

I'm doing a program to generate graphs from a RDF link...Do you know what is the best framework for it??

Can someone help me with that?? Please send the reply for pedrodedinho@gmail.com

Thanks anyway

Comment by pmurray.bigpond.com, Jul 05 (4 days ago)

I would like, on this page, a section on "how to read an existing rdf file into a graph".


Sign in to add a comment
Hosted by Google Code