Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Programming with Jena Sources for examples can be found @ http://jenabean.googlecode.com/svn/jenabean-lab1 http://jenabean.googlecode.com/svn/jenaclass Taylor Cowan Travelocity 8982 http://thewebsemantic.com http://jenabean.googlecode.com 2 [] a foaf:Person; foaf:name Taylor Cowan; foaf:weblog <http://thewebsemantic.com>; foaf:workplaceHomepage <http://www.travelocity.com>; foaf:holdsAccount <http://twitter.com/tcowan>; foaf:currentProject <http://jenabean.googlecode.com>; foaf:currentProject <http://geosparql.googlecode.com>; foaf:currentProject <http://jo4neo.googlecode.com>; http://thewebsemantic.com http://jenabean.googlecode.com Model m = ModelFactory.createDefaultModel(); Thing todaysTopic = new Thing("http://jenabean.googlecode.com", m); new Thing(m).isa(Foaf.Person.class) .name("Taylor Cowan") .weblog(URI.create("http://thewebsemantic.com")) .holdsAccount(URI.create("http://twitter.com/tcowan")) .currentProject(todaysTopic) .currentProject(URI.create("http://jo4neo.googlecode.com")); @see Card.java in package example.fluentwriter http://thewebsemantic.com http://jenabean.googlecode.com 3 4 AGENDA > > > > > Semantic Web Introduction RDF basics Coding Towards Jena’s Semantic Web Framework API Java to Model Binding with JenaBean Java to Model Binding with Fluent Interfaces http://thewebsemantic.com http://jenabean.googlecode.com 5 Why Not Microformats? <xsl:choose> <xsl:when test="(false() = not((.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'img' or local-name() = 'area')]/@alt) and (string-length(normalize-space(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'img' or local-name() = 'area')]/@alt)) = string-length(translate(normalize-space(.//*[not(ancestoror-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'img' or local-name() = 'area')]/@alt),' ',''))))) or (false() = not((.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalizespace(@class),' '),' fn ') and (local-name() = 'abbr')]/@title) and (string-length(normalizespace(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'abbr')]/@title)) = stringlength(translate(normalize-space(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'abbr')]/@title),' ',''))))) or (false() = not((.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and not(local-name() = 'abbr' or localname() = 'img')]) and (string-length(normalize-space(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and not(local-name() = 'abbr' or local-name() = 'img' or local-name() = 'area')][1])) = string-length(translate(normalizespace(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and not(local-name() = 'abbr' or local-name() = 'img')][1]),' ','')))))"> http://suda.co.uk/projects/microformats/hcard/xhtml2vcard.xsl http://thewebsemantic.com http://jenabean.googlecode.com 6 RDF != XML “The site at http://www.travelocity.com, also known as Travelocity, is an online travel agency competing with expedia.com” http://thewebsemantic.com http://jenabean.googlecode.com 7 Concepts as a Directed Graph Travelocity Travelocity.com Online travel agency Expedia.com http://thewebsemantic.com http://jenabean.googlecode.com 8 Concepts Serialized as N3 :OnlineTravelAgency a owl:Class . :hasCompetitor a rdf:Property . <http://www.travelocity.com> a :OnlineTravelAgency ; rdfs:label "Travelocity"@en ; :hasCompetitor <http://www.expedia.com> . http://thewebsemantic.com http://jenabean.googlecode.com 9 Concepts Serialized as RDF/XML <rdf:RDF …> <owl:Class rdf:about="http://foo#OnlineTravelAgency"/> <rdf:Property rdf:about="http://foo#hasCompetitor"/> <OnlineTravelAgency rdf:about="http://www.travelocity.com"> <hasCompetitor rdf:resource="http://www.expedia.com"/> <rdfs:label xml:lang="en">Travelocity</rdfs:label> </OnlineTravelAgency> </rdf:RDF> http://thewebsemantic.com http://jenabean.googlecode.com 10 As N-Triples (Most Canonical or Normalized) <hasCompetitor> <rdf:type> <rdf:Property> . <http://travelocity.com> <hasCompetitor> <http://expedia.com>. <http://travelocity.com> <rdfslabel> "Travelocity"@en <http://travelocity.com> <rdf:type> <OnlineTravelAgency> . <OnlineTravelAgency> <owl:Class> . <rdf:type> Subject, Verb, Object = a triple http://thewebsemantic.com http://jenabean.googlecode.com 11 As Java Code, using the Jena API OntModel m = ModelFactory.createOntologyModel(); OntClass ota = m.createClass("OnlineTravelAgency"); Individual tvly = ota.createIndividual("http://www.travelocity.com"); tvly.setLabel("Travelocity", "en"); OntProperty p = m.createOntProperty("hasCompetitor"); tvly.setPropertyValue(p, m.createResource("http://www.expedia.com")); http://thewebsemantic.com http://jenabean.googlecode.com 12 Creating a Model 1: Model m = ModelFactory.createDefaultModel(); 2: m.setNsPrefix("foaf", FOAF.NS); 3: Resource jazoon = m.createResource("http://jazoon.com/"); 4: Resource java = m.createResource( 5: "http://dbpedia.org/resource/Java_(software_platform)"); 6: jazoon.addProperty(FOAF.primaryTopic, java); 7: m.write(System.out, "N3"); <http://jazoon.com/> foaf:primaryTopic <http://dbpedia.org/resource/Java_(software_platform)> . http://thewebsemantic.com http://jenabean.googlecode.com 13 Assertion foaf:primaryTopic jazoon.com http://thewebsemantic.com java http://jenabean.googlecode.com 14 Creating an Inferencing Model OntModel infModel = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM_MICRO_RULE_INF, m); infModel.read("http://xmlns.com/foaf/spec/index.rdf"); infModel.writeAll(System.out, "N3",null); In addition to known data, a new triple is inferred… <http://dbpedia.org/resource/Java_(software_platform)> foaf:isPrimaryTopicOf <http://jazoon.com/> http://thewebsemantic.com http://jenabean.googlecode.com 15 Knowledge after Inference foaf:Document Is a foaf:primaryTopic jazoon.com java foaf:isPrimaryTopicOf http://thewebsemantic.com http://jenabean.googlecode.com 16 The Semantic Web is Property focused > Properties have Classes, not vice versa > Don’t read “the domain of foaf:knows is a foaf:Person”, but instead “anything with foaf:knows relationship is a foaf:Person” > Properties can extend other properties > Properties can be declared as inverse, symmetric, and transitive, all resulting in new inferences. http://thewebsemantic.com http://jenabean.googlecode.com 17 List All Classes from an Ontology OntModel model = ModelFactory.createOntologyModel(); model.read("http://xmlns.com/foaf/spec/index.rdf"); ExtendedIterator<OntClass> it = model.listClasses(); while(it.hasNext()) { OntClass cls = it.next(); if (cls.getNameSpace().equals(FOAF.NS)) System.out.println(cls.getURI()); } http://thewebsemantic.com http://jenabean.googlecode.com 18 Models Can be Populated from URL, Either Public or Local OntModel model = ModelFactory.createOntologyModel(); // read from URL model.read("http://xmlns.com/foaf/spec/index.rdf"); model.read("file:mydata.n3","N3"); http://thewebsemantic.com http://jenabean.googlecode.com 19 Models can be Populated from Other Models Model modelA = ModelFactory.createDefaultModel(); Model modelB = ModelFactory.createDefaultModel(); … //Add all statements from modelB to modelA modelA.add(modelB); http://thewebsemantic.com http://jenabean.googlecode.com 20 Some example foaf: <http://www.ibm.com/developerworks/xml/library/j-jena/> a dc:Article ; dc:creator "Philip McCarthy"^^xsd:string ; dc:subject "jena, rdf, java, semantic web"^^xsd:string ; dc:title "Introduction to Jena"^^xsd:string . http://thewebsemantic.com http://jenabean.googlecode.com 21 Equivalent Raw Jena API Client Code String NS = "http://purl.org/dc/elements/1.1/"; OntModel m = ModelFactory.createOntologyModel(); OntClass articleCls = m.createClass(NS +"Article"); Individual i = articleCls.createIndividual( "http://www.ibm.com/developerworks/xml/library/j-jena/"); Property title = m.getProperty(NS + "title"); Literal l = m.createTypedLiteral("Introduction to Jena"); i.setPropertyValue(title,l); Property creator = m.getProperty(NS + "creator"); l = m.createTypedLiteral("Philip McCarthy"); i.setPropertyValue(creator,l); Property subject = m.getProperty(NS + "subject"); l = m.createTypedLiteral("jena, rdf, java, semantic web"); i.setPropertyValue(subject,l); m.write(System.out, "N3"); http://thewebsemantic.com http://jenabean.googlecode.com 22 Pain Points of Raw Jena API Programming > > > > You need to create unique URI’s for every entity. You must specify the type of each primitive value. Properties must be created for each bean property. The impedance mismatch is similar to what we had with RDBMS http://thewebsemantic.com http://jenabean.googlecode.com 23 Creating The Same Assertions with JenaBean Model m = ModelFactory.createDefaultModel(); Bean2RDF writer = new Bean2RDF(m); Article article = new Article( "http://www.ibm.com/developerworks/xml/library/j-jena/"); article.setCreator("Philip McCarthy"); article.setTitle("Introduction to Jena"); article.setSubject("jena, rdf, java, semantic web"); writer.save(article); m.write(System.out, "N3"); http://thewebsemantic.com http://jenabean.googlecode.com 24 The JenaBean Project > > > > > Hosted at Google code Bean binding, not code generation Doesn’t use byte code interweaving Doesn’t require implementing an interface http://jenabean.googlecode.com http://thewebsemantic.com http://jenabean.googlecode.com 25 Programming with JenaBean is Simple > Bean2RDF writes objects > RDF2Bean reads objects > 3 Annotations – @Id specifies unique field – @Namespace provides a domain – @RdfProperty maps java properties to RDF properties http://thewebsemantic.com http://jenabean.googlecode.com 26 The Simplest Possible Example package examples.model; import thewebsemantic.Id; public class Person { @Id private String email; public String getEmail() { return email;} public void setEmail(String email) { this.email = email;} } <http://examples.model/Person> a <http://www.w3.org/2000/01/rdf-schema#Class> ; <http://thewebsemantic.com/javaclass> "examples.model.Person" . <http://examples.model/Person/[email protected]> a <http://examples.model/Person> ; <http://examples.model/email> "[email protected]"^^xsd:string . http://thewebsemantic.com http://jenabean.googlecode.com 27 Saving an Instance of Person Model m = ModelFactory.createOntologyModel(); Bean2RDF writer = new Bean2RDF(m); Person p = new Person(); p.setEmail("[email protected]"); writer.save(p); m.write(System.out, "N3"); … <http://example/Person> a owl:Class ; <http://thewebsemantic.com/javaclass> "example.Person" . <http://example/Person/[email protected]> a <http://example/Person> ; <http://example/email> "[email protected]"^^xsd:string . http://thewebsemantic.com http://jenabean.googlecode.com 28 Overriding the Default Namespace package examples.model; import thewebsemantic.Id; import thewebsemantic.Namespace; @Namespace("http://mydomain#") public class Person { … } <http://mydomain#Person> a <http://www.w3.org/2000/01/rdf-schema#Class> ; <http://thewebsemantic.com/javaclass> "examples.model.Person" . <http://mydomain#Person/[email protected]> a <http://mydomain#Person> ; <http://mydomain#email> "[email protected]"^^xsd:string . http://thewebsemantic.com http://jenabean.googlecode.com 29 Overriding the Default Property Bindings @Namespace(“http://mydomain#”) public class Person { private String email; @RdfProperty(FOAF.NS + "name") private String name; <http://mydomain#Person> a <http://www.w3.org/2000/01/rdf-schema#Class> ; <http://thewebsemantic.com/javaclass> "examples.model.Person" . <http://mydomain#Person/[email protected]> a <http://mydomain#Person> ; <http://xmlns.com/foaf/0.1/name> "Taylor Cowan"^^xsd:string . http://thewebsemantic.com http://jenabean.googlecode.com 30 Extending Person to Support Friendship public Collection<Person> friends = new LinkedList<Person>(); @RdfProperty("http://xmlns.com/foaf/0.1/knows") public Collection<Person> getFriends() { return friends;} http://thewebsemantic.com http://jenabean.googlecode.com 31 Loading Beans from a Model RDF2Bean reader = new RDF2Bean(m); Person p = reader.load(Person.class,"[email protected]"); Collection<Person> allPeople = reader.load(Person.class); http://thewebsemantic.com http://jenabean.googlecode.com 32 JenaBean Support for OWL Entailments public class Location { @Id public String id; public String name; @RdfProperty(transitive=true) public Collection<Location> within; @RdfProperty(inverseOf="within") public Collection<Location> contains; … <http://example.transitive/within> a rdf:Property , owl:TransitiveProperty . <http://example.transitive/contains> a rdf:Property ; owl:inverseOf <http://example.transitive/within> . http://thewebsemantic.com http://jenabean.googlecode.com 33 Reading Existing RDF/OWL > Up till this point we were generating the triples > JenaBean + annotations controlled the URI’s > The model knew the provenance of all data (the originating java class) http://thewebsemantic.com http://jenabean.googlecode.com 34 Example Geonames “feature” entry Jenabean will bind to existing URI’s <Feature rdf:about="http://sws.geonames.org/3333156/"> <name>London Borough of Islington</name> <alternateName xml:lang="fr">Islington</alternateName> <inCountry rdf:resource="http://www.geonames.org/countries/#GB"/> <population>185500</population> <wgs84_pos:lat>51.5333333</wgs84_pos:lat> <wgs84_pos:long>-0.1333333</wgs84_pos:long> </Feature> 35 Crafting beans for existing RDF requires care @Namespace("http://www.geonames.org/ontology#") 1 public class Feature { 2 @Id 3 private URI uri; 4 @RdfProperty("http://www.w3.org/2003/01/geo/wgs84_pos#lat") public double lat; 1. 2. 3. 4. Namespace must accurately match Your java’s classname must match the Ontology class Your @Id must be of type java.net.URI All property URI’s must match the Ontology property http://thewebsemantic.com http://jenabean.googlecode.com 36 JenaBean can auto discover JenaBeans, provided it knows the package(s) 1: 2: 3: 4: Model m = ModelFactory.createDefaultModel(); m.read("http://ws.geonames.org/search?q=london&type=rdf"); RDF2Bean reader = new RDF2Bean(m); reader.bindAll("com.foo", "com.bar"); // type safe binding by class reader.bind(Feature.class); // or package reader.bind(Feature.class.getPackage()); http://thewebsemantic.com http://jenabean.googlecode.com 37 JenaBean tip: handling lang encoded strings If your data has something like this: <alternateName xml:lang="es">Londres</alternateName> Then use JenaBean‘s special type “LocalizedString“ public Collection<LocalizedString> alternateName; example.geonames http://thewebsemantic.com http://jenabean.googlecode.com 38 Query Support > Most most practical purposes there’s no need to utilize anything other than Jena’s ARQ api to query. JenaBean’s reader (RDF2Bean) can transform a node given it’s URI or it’s representation as a jena Resource… // load using a Jena Resource reader.load(Human.class, jenaResource); // load any node using it’s URI reader.load(Human.class, "http://any.uri"); http://thewebsemantic.com http://jenabean.googlecode.com 39 thewebsemantic.Sparql Util String query = "prefix ntn: <http://semanticbible.org/ns/2006/NTNames#>\n" + "SELECT ?s WHERE { ?s a ntn:Woman }"; Model m = ModelFactory.createOntologyModel(); m.read("file:NTNames.owl"); m.read("file:NTN-individuals.owl"); RDF2Bean reader = new RDF2Bean(m); reader.bindAll("example.query"); Collection<Woman> women = Sparql.exec(m, Woman.class, query); for (Human human : women) System.out.println(human.label + ":" + human.comment); example.query http://thewebsemantic.com http://jenabean.googlecode.com 40 Summary @Namespace(“http://yournamespace.goes.here”) Applies to class declaration @Id Applies to field or getter method Should be a String or primitive type, or wrapper type type java.net.URI is special @RdfProperty(“http://specific.property.uri”) Applies to field or getter method Remember: by definition, JavaBeans must have a default constructor. http://thewebsemantic.com http://jenabean.googlecode.com 41 Summary writer.save(mybean) writer.saveDeep(mybean) Save this and all related objects reader.load(Class.class, key); reader.loadDeep(…); take care, could place entire graph into memory. reader.bindAll(package, package, …); Makes jenabean aware of your beans http://thewebsemantic.com http://jenabean.googlecode.com 42 JenaBean Fluent Programming API > > > > > > > AKA method chaining, foo.this().that().bar(); A “Fluent Interface” aims to provide more readable code A significant departure from JavaBeans Is always connected to the jena graph Entirely interface (not class) driven Allows Individuals to morph into their various classes Allows use of vocabulary terms against any Individual regardless of classification. http://thewebsemantic.com http://jenabean.googlecode.com Example: wgs84 geo vocabulary import thewebsemantic.As; import thewebsemantic.Functional; import thewebsemantic.Namespace; @Namespace("http://www.w3.org/2003/01/geo/wgs84_pos#") public interface Geo extends As { interface Point extends Geo{} @Functional Geo lat(float l); Float lat(); @Functional Geo long_(float l); Float long_(); } http://thewebsemantic.com http://jenabean.googlecode.com 43 44 A fluent api + good IDE makes things fun http://thewebsemantic.com http://jenabean.googlecode.com 45 Create a new anonymous iCal event. Ical t = new Thing(m).isa(Ical.Vevent.class); Create a new iCal event with URI Ical t = new Thing(“http://uri”, m). isa(Ical.Vevent.class); http://thewebsemantic.com http://jenabean.googlecode.com 46 Full Example: Creating an iCal event for the meetup 1: Ical.Vevent t = new Thing(m).isa(Ical.Vevent.class); 2: t.uid("[email protected]"). 3: dtstart("20100124T200000Z"). 4: dtend("20100124T220000Z"). 5: summary("Jena Semantic Web…"). 6: location("Parisoma - …") 7: .as(Geo.class). 8: lat(37.77f). 9: long_(-122.41f); [] http://thewebsemantic.com a ical:Vevent ; ical:dtend "20100124T220000Z" ; ical:dtstart "20100124T200000Z" ; ical:location "Parisoma - " ; ical:summary "Jena Semantic Web…" ; ical:uid "[email protected]" ; geo:lat "37.77"^^xsd:float ; geo:long "-122.41"^^xsd:float . http://jenabean.googlecode.com 47 JenaBean comes with a few common vocabulary interfaces > > > > > > > > > thewebsemantic.vocabulary.Foaf Geo Ical DCTerms Sioc Skos Rdfs ReviewVocab You may want to copy and modify in some cases. http://thewebsemantic.com http://jenabean.googlecode.com 48 Fluent API summary: > Your interface should extend thewebsemantic.As > Provides polymorphic “as(Class)” to other vocabs. > Provides easy type declaration with “isa(Class)” > Use the @Namespace annotation to bind to the vocabulary > Name setters according to vocab, taking either an Object (literal) or anther Thing (relationship to other Individuals) > Name getters according to vocab, returning the same vocabulary type and taking no arguments. > If the vocabulary term collides with reserved term (as with long), append a dash. > Plural properties should return a Collection. http://thewebsemantic.com http://jenabean.googlecode.com 49 Project Ideas > Create your own foaf document using the fluent interface. > Integrate Jena/JenaBean with restlets – restlets.org > Use your favorite framework (struts, stripes, spring mvc) and create a user registration screen. > Write JenaBeans that bind to jamendo or other music ontology at http://dbtune.org > Write a foaf crawler beginning with Berners-Lee that traverses his social graph. http://thewebsemantic.com cc nickjohnson http://flickr.com/photots/npj/ http://jenabean.googlecode.com 50 Open Source Tools For Java Devs > Java Triple Stores – Jena (HP Labs) – Sesame OpenRDF (Aduna) – Mulgara > Java Binding tools – JenaBean (Jena) – Jastor (Jena) – – – Owl2Java (Jena) Elmo (Sesame) Empire http://thewebsemantic.com cc nickjohnson http://flickr.com/photots/npj/ http://jenabean.googlecode.com Taylor Cowan http://thewebsemantic.com http://twitter.com/tcowan Travelocity [email protected] http://thewebsemantic.com http://jenabean.googlecode.com