|
|
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:
- adding triples directly to the Graph without having to create the individual nodes first,
- triple reification and
- creation of RDF Containers and Collections (Bag, Alt, Collection and Sequence).
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.
Sign in to add a comment

There's a line in the section Using the Graph:
Perhaps this line should be:
Thanks. This is fixed.