Practical RDF Chapter 8. Jena: RDF in Java Shelley Powers, O’Reilly SNU IDB Lab. Somin Kim Outline Introduction Jena Architecture Creating and Serializing an RDF Model Parsing and Querying an RDF Document Persistent Model Storage 2 Introduction A Java Framework for RDF, DAML and OWL Developed by Brian McBride of HP Labs Derived from SiRPAC Can create, parse, navigate and search RDF, DAML and OWL model Easy to use Available at http://jena.sourceforge.net 3 Jena Architecture Joseki Network API RDQL SesameEngine Sesame Query RDFS API DAML API OWL API ARP N3 Inference ARP Ontology API N3 n-triple Readers Memory RDBMS Berkeley DB Storages 4 n-triple Writers Creating and Serializing an RDF Model (1/8) Example1 …… // Create an empty graph Model model = new ModelMem( ); // Create the resource Resource postcon = model.createResource(sURI); A new model is created, with the resource and one predicate repeated with two different objects // Create the predicate (property) Property related = model.createProperty(sPostcon, sRelated); // Add the properties with associated values (objects) addProperty( property, property value) postcon.addProperty(related, "http://burningbird.net/articles/monsters3.htm"); postcon.addProperty(related, "http://burningbird.net/articles/monsters2.htm"); // Print RDF/XML of model to system output model.write(new PrintWriter(System.out)); …… 5 Creating and Serializing an RDF Model (2/8) Output <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:NS0='http://www.burningbird.net/postcon/elements/1.0/' > <rdf:Description rdf:about='http://burningbird.net/articles/monsters1.htm'> <NS0:related>http://burningbird.net/articles/monsters3.htm</NS0:related> <NS0:related>http://burningbird.net/articles/monsters2.htm</NS0:related> </rdf:Description> </rdf:RDF> http://www.w3.org/1999/02 /22-rdf-syntax-ns#type Document http://burningbird.net/articles/monsters1.htm http://burningbird.net/articles/monsters2.htm http://burningbird.net/ bbd/postcon/elements/1.0/ 6 Creating and Serializing an RDF Model (3/8) Problem with creating the Property and Resource objects directly in the application – You have to duplicate this functionality across all applications that want to use the vocabulary – It adds to the overall size and complexity of an application A Java Wrapper Class is a better approach 7 Creating and Serializing an RDF Model (4/8) Example2 : Using wrapper class to add properties to resource …… // Resource names String sResource = "http://burningbird.net/articles/monsters1.htm"; String sRelResource1 = "http://burningbird.net/articles/monsters2.htm"; String sRelResource2 = "http://burningbird.net/articles/monsters3.htm"; try { // Create an empty graph Model model = new ModelMem( ); // Create the resource and add the properties cascading style Resource article = model.createResource(sResource) .addProperty(POSTCON.related, model.createResource(sRelResource1)) .addProperty(POSTCON.related, model.createResource(sRelResource2)); // Print RDF/XML of model to system output model.write(new PrintWriter(System.out)); } …… 8 Creating and Serializing an RDF Model (5/8) (cont.) vocabulary wrapper class <POSTCON> public class POSTCON extends Object { // URI for vocabulary elements protected static final String uri = "http://burningbird.net/postcon/elements/1.0/"; public static String getURI( ) { return uri; } // Return URI for vocabulary elements static final String nbio = "bio"; // Define the property labels and objects public static Property bio = null; static final String nrelated = "related"; public static Property related = null; ...... static { // Instantiate the properties and the resource try { // Instantiate the properties bio = new PropertyImpl(uri, nbio); related = new PropertyImpl(uri, nrelated); ...... } catch (RDFException e) { ErrorHelper.logInternalError("POSTCON", 1, e); } } } 9 Creating and Serializing an RDF Model (6/8) Example3 : Adding a blank node to a model …… // Create the bio bnode resource and add properties Resource bio = model.createResource( ) .addProperty(DC.creator, "Shelley Powers") .addProperty(DC.publisher, "Burningbird") .addProperty(DC.title, model.createLiteral("Tale of Two Monsters: Legends", "en")); …… – Blank node : a resource that does not have a specific URI 10 Creating and Serializing an RDF Model (7/8) Example4 : Creating a Typed Node …… // Create an empty graph Model model = new ModelMem( ); // Create the resource // and add the properties cascading style Resource article = model.createResource(sResource).addProperty(RDF.type, POSTCON.resource); …… – Typed node means that it is defined with a specific rdf:type property http://www.w3.org/1999/02 /22-rdf-syntax-ns#type http://burningbird.net/articles/monsters1.htm http://burningbird.net/postcon/elements/1.0/Document 11 Creating and Serializing an RDF Model (8/8) Example5 : Creating a Container ...... Model model = new ModelMem( ); // Create an empty graph Seq hist = model.createSeq( ) // Create Seq .add (1, model.createResource(sHistory1) .addProperty(POSTCON.movementtype, model.createLiteral("Add")) .addProperty(POSTCON.reason, model.createLiteral("New Article")) .addProperty(DC.date, model.createLiteral("1998-01-01T00:00:00-05:00"))) .add (2, model.createResource(sHistory2) .addProperty(POSTCON.movementtype, model.createLiteral("Move")) ...... // Create the resource and add the properties cascading style Resource article = model.createResource(sResource) .addProperty(POSTCON.history, hist); ...... – RDF container : a grouping of related items Alt, Seq, Bag 12 Parsing and Querying an RDF Document (1/2) Basic dump : to print it out in N-Triples format …… // Create memory model, read in RDF/XML document ModelMem model = new ModelMem( ); model.read(sUri); // Print out objects in model using toString NodeIterator iter = model.listObjects( ); while (iter.hasNext( )) { System.out.println(" " + iter.next( ).toString( } …… )); – Instead of objects, you could also dump out the subjects(ResIterator and listSubjects) or even the entire statement (StmtIterator and listStatements) 13 Parsing and Querying an RDF Document (2/2) Accessing Specific Values import com.burningbird.postcon.vocabulary.POSTCON; public class pracRDFSeventh extends Object { public static void main (String args[]) { String sUri = args[0]; String sResource = args[1]; try { ModelMem model = new ModelMem( ); // Create memory model, read in RDF/XML document model.read(sUri); Resource res = model.getResource(sResource); //Find Resource StmtIterator iter = res.listProperties( ); //Find Properties while (iter.hasNext( )) { // Next statement in queue Statement stmt = iter.next( // Print out triple - subject | property | object ); // Get subject, print Resource res2 = stmt.getSubject( ); System.out.print(res2.getNameSpace( ) + res2.getLocalName( // Get predicate, print // Get object, print …… …… } ...... 14 )); Persistent Model Storage (1/3) Jena also provides the capability to persist data to relational database storage Jena supports differing storage layouts – Generic : all statements are stored in a single table and resources and literals are indexed using integer identifiers generated by the database – GenericProc : similar to generic, but data access is through stored procedures – MMGeneric : similar to generic, but can store multiple models – Hash : similar to generic, but uses MD5 hashes to generate the identifiers – MMHash : Similar to hash, but can store multiple models 15 Persistent Model Storage (2/3) Persisting two RDF/XML models to a MySQL database public class pracRDFEighth extends Object { public static void main (String args[]) { // Pass two RDF documents, connection string, String sUri = args[0]; String sUri2 = args[1]; String sConn = args[2]; String sUser = args[3]; String sPass = args[4]; Class.forName("com.mysql.jdbc.Driver").newInstance( ); // Load driver class // Establish connection - replace with your own conn info Connection con = DriverManager.getConnection(sConn, "user", "pass"); DBConnection dbcon = new DBConnection(con); ModelRDB.create(dbcon, "MMGeneric", "Mysql"); // Format database ModelRDB model1 = ModelRDB.createModel(dbcon, "one"); // Create and read first model model1.read(sUri); ModelRDB model2 = ModelRDB.createModel(dbcon, "two"); // Create and read second model model2.read(sUri2); } } 16 Persistent Model Storage (3/3) Accessing RDF models stored in MySQL database public class pracRDFNinth extends Object { public static void main (String args[]) { String sConn = args[0]; String sUser = args[1]; String sPass = args[2]; // 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); DBConnection dbcon = new DBConnection(con); // Open two existing models ModelRDB model1 = ModelRDB.open(dbcon, "one"); ModelRDB model2 = ModelRDB.open(dbcon, "two"); // Print out objects in first model using toString …… // Print out triples in second model - find resource …… }}} 17