What's new? | Help | Directory | Sign in
Google
jrdf
A project designed to create a standard mapping of RDF to Java.
  
  
  
  
    
Search
for
Updated Feb 05, 2008 by andrewfnewman
GettingStarted  
Getting Started with Local JRDF Graphs

Getting Started with JRDF Local Graphs

JRDF has a simple to use interface that follows the RDF standard for the creation and management of RDF 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.

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 subclasses by the appropriate typed nodes: bnode (blank node), URI and Literal.

The Resource interface extends both the URI References and blank nodes.

Graph and Graph Element Factory

To create a local graph you must use a Factory - either an in memory factory or an on disk one. A local 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.

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.getNewGraph();
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 db4o and BDB Java Edition installed in the class path):

JRDFFactory jrdfFactory = SortedDiskJRDFFactory.getFactory();

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 the typed literal "Hello World"^^xsd:string:

...
Node node = elementFactory.createURIReference(URI.create("urn:node"));
Literal literal = elementFactory.createLiteral("Hello World", org.jrdf.vocabulary.XSD.STRING);
graph.add(node, node, literal);

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 an Java type is used that has no mapping an exception will be thrown. New mappings can be added through add a DatatypeValue to the DatatypeFactory.

Note: To create a literal with an xsd:string type use:

...
Literal literal = elementFactory.createLiteral("foo", XSD.STRING);

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);

Using the Graph

The Graph has methods that allow you to add, remove, and find triples.

The following is an example showing all three operations:

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);

Finding nodes in the graph 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.

Resources

An RDF Resource is either a blank node or a URI Reference. JRDF provides a way to create new Resource or wrap an existing Blank Node or URI Reference. Resources provide an easier way to add or remove values associated to the 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 taken the 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 chouser, Dec 24, 2007

There's a line in the section Using the Graph:

ClosableIterator<Triple> tripleIter = graph.find(AnySubject.ANY_SUBJECT, AnyPredicate.ANY_PREDICATE, AnyObject.ANY_OBJECT);

Perhaps this line should be:

ClosableIterator<Triple> tripleIter = graph.find(AnySubjectNode.ANY_SUBJECT_NODE, AnyPredicateNode.ANY_PREDICATE_NODE, AnyObjectNode.ANY_OBJECT_NODE);
Comment by andrewfnewman, Jan 03, 2008

Thanks. This is fixed.


Sign in to add a comment