Categories
RDF

Jena Week: final examples

Recovered from the Wayback Machine.

I converted the rest of the Jena1 examples to Jena2 without any major reworking being necessary. At the end of this post is a zipped file of all of the Java source that you can download, use to start your own explorations.

In Example 7, reading in an RDF/XML file in is no different with Jena2 than it was with Jena1. The examples don’t change (other than class structure and creating the memory model using the factory object), except that iterating through statements using StmtIterator exhibits better Java behavior now. StmtIterator now returns an Object when you use next rather than a Statement, and you’ll need to cast it. Or you can use the new nextStatement function call:

// next statement in queue
Statement stmt = iter.nextStatement();

Examples 8 and 9 work against graphs/models persisted to a relational database. I used MySQL in Windows 2000 to test the examples, but you can also use Oracle or other supported database systems.

There have been some significant changes, for the better, with using a relational data model for persistence in Jena2. For instance, you don’t have to specify a storage type or preformat the storage as you did with Jena1; this is all automated in the new classes, by passing in the type of database when you create the model. Another change is that you don’t use the RDBModel.create method, which is deprecated – you can use a new class, ModelMaker, or you can call the static function, createModel.

In the following, the driver is loaded, a connection is established and a model created. Once created, a serialized RDF/XML graph is read.

// load driver class
Class.forName(“com.mysql.jdbc.Driver”).newInstance();

// establish connection – replace with your own conn info
Connection con = DriverManager.getConnection(sConn, sUser, sPass);
IDBConnection dbcon = new DBConnection(con, “MySQL”);

ModelRDB model = ModelRDB.createModel(dbcon, “one”);
model.read(sUri);

Check the documentation for Jena2, and in the DB directory, you’ll find a discussion on migrating Jena1 databases to Jena2, as well as a good description of these changes, and example code.

One interesting aspect of storing Jena within a relational database, especially as it relates to previous postings, is whether Jena2 maintains a reference to the actual source of the external data, and from what I can see, it does not.

Within Jena, you create a graph (termed a model in Jena) and can load many serialized sub-graphs (individual RDF/XML files) into it, or add statements directly using the API. I did so, loading in several FOAF files from people I know. I then looked through the data to see if the source of the sub-graph, the actual file, was maintained and couldn’t find anything.

Once the sub-graphs are merged into one graph, all blank nodes are resolved, and any traces of their separate natures are not maintained. This is proper behavior for RDF according to the RDF specifications, and this merging of sub-graphs is one of strengths of the RDF model.

Now, you can perform a little deductive work and find that a person’s properties have a specific blank node identifier, which is then the object of a “knows” predicate, which is then the property of another blank node identifier of another person with a given name – a bit of a fun challenge with RDQL – but there’s nothing I can see that identifies the source of the actual RDF/XML file, itself.

It could be among the information stored in the BLOB that makes up the graph’s name, but the only way to know this for sure is to examine the contents of BLOB itself, or to find a specific class that allows us to interrogate this data. However, that breaks into new territory not covered in the book examples, and best left for further essays.

Download file