Jena Sources for examples can be found http jenabeangooglecodecomsvnjenabeanlab1 http jenabeangooglecodecomsvnjenaclass Taylor Cowan Travelocity 8982 2 a foafPerson ID: 569068
Download Presentation The PPT/PDF document "Programming with" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
Programming with Jena
Sources for examples can be found @http://jenabean.googlecode.com/svn/jenabean-lab1http://jenabean.googlecode.com/svn/jenaclass
Taylor CowanTravelocity8982Slide2
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>;Slide3
3
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.fluentwriterSlide4
4
AGENDASemantic Web IntroductionRDF basicsCoding Towards Jena’s Semantic Web Framework APIJava to Model Binding with JenaBean
Java to Model Binding with Fluent InterfacesSlide5
Why Not Microformats?
5<
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(ancestor-or-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
(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'abbr')]/@title) and (string-length(normalize-space(.//*[not(ancestor-or-self::*[local-name() = 'del']) = true() and contains(concat(' ',normalize-space(@class),' '),' fn ') and (local-name() = 'abbr')]/@title)) = string-length(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 local-name() = '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(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
')][1]),' ','')))))
">
http://suda.co.uk/projects/microformats/hcard/xhtml2vcard.xslSlide6
RDF != XML
“The site at http://www.travelocity.com, also known as Travelocity, is an online travel agency competing with expedia.com”6Slide7
Concepts as a Directed Graph
7Slide8
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> .Slide9
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
>Slide10
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> <rdf:type> <owl:Class> .10
Subject
,
Verb
, Object = a tripleSlide11
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"));11Slide12
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");12
<http://jazoon.com/>
foaf:primaryTopic
<http://dbpedia.org/resource/Java_(software_platform)> .Slide13
Assertion
13
jazoon.comj
ava
foaf:primaryTopicSlide14
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);14<http://dbpedia.org/resource/Java_(software_platform)> foaf:isPrimaryTopicOf <http://jazoon.com/>In addition to known data, a new triple is inferred…Slide15
Knowledge after Inference
15
jazoon.comj
ava
foaf:primaryTopic
foaf:isPrimaryTopicOf
foaf:Document
Is a Slide16
16
The Semantic Web is Property focusedProperties have Classes, not vice versaDon’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 propertiesProperties can be declared as inverse, symmetric, and transitive, all resulting in new inferences.Slide17
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());}17Slide18
Models Can be Populated from URL, Either Public or Local
OntModel model = ModelFactory.createOntologyModel();// read from URLmodel.read
("http://xmlns.com/foaf/spec/index.rdf"); model.read("file:mydata.n3","N3");
18Slide19
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
);
19Slide20
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
.Slide21
21
Equivalent Raw Jena API Client CodeString 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"
);Slide22
22
Pain Points of Raw Jena API ProgrammingYou 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 RDBMSSlide23
23
Creating The Same Assertions with JenaBeanModel 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");Slide24
24
The JenaBean ProjectHosted at Google codeBean binding, not code generationDoesn’t use byte code interweavingDoesn’t require implementing an interface
http://jenabean.googlecode.comSlide25
25
Programming with JenaBean is SimpleBean2RDF writes objectsRDF2Bean reads objects3 Annotations
@Id specifies unique field@Namespace provides a domain@RdfProperty maps java properties to RDF propertiesSlide26
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;}}26
<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/thewebsemantic@gmail.com>
a <http://examples.model/Person> ;
<http://examples.model/email> "thewebsemantic@gmail.com"^^
xsd:string
.Slide27
Saving an Instance of Person
Model m = ModelFactory.createOntologyModel(); Bean2RDF writer = new Bean2RDF(m); Person p = new Person();
p.setEmail("person@example.com"); writer.save(p); m.write(System.out, "N3"); …<http://example/Person> a
owl:Class ;
<http://thewebsemantic.com/javaclass> "
example.Person
" .
<http://example/Person/taylor_cowan@yahoo.com> a <http://example/Person> ;
<http://example/email> "taylor_cowan@yahoo.com"^^
xsd:string .27Slide28
Overriding the Default Namespace
package examples.model;
import thewebsemantic.Id;import thewebsemantic.Namespace;@
Namespace(
"http://mydomain#"
)
public
class
Person { … }28<http://mydomain#Person> a <http://www.w3.org/2000/01/rdf-schema#Class> ; <http://thewebsemantic.com/javaclass> "examples.model.Person" .<http://mydomain#Person/thewebsemantic@gmail.com> a <http://mydomain
#Person> ;
<
http://mydomain
#email>
"thewebsemantic@gmail.com"^^
xsd:string
.Slide29
Overriding the Default Property Bindings
@Namespace(“http://mydomain#”)public class
Person { private String email; @RdfProperty(FOAF.NS +
"name")
private
String
name
;
29<http://mydomain#Person> a <http://www.w3.org/2000/01/rdf-schema#Class> ; <http://thewebsemantic.com/javaclass> "examples.model.Person" .<http://mydomain#Person/thewebsemantic@gmail.com> a <http://mydomain#Person> ; <http://xmlns.com/foaf/0.1/name> "Taylor Cowan"^^xsd:string .Slide30
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
;}
30Slide31
Loading Beans from a Model
RDF2Bean reader = new RDF2Bean(m);Person p = reader.load
(Person.class,"person@example.com");Collection<Person> allPeople = reader.load
(Person.class
);
31Slide32
JenaBean Support for OWL Entailments
32
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> .Slide33
Reading Existing RDF/OWL
33
Up till this point we were generating the triplesJenaBean + annotations controlled the URI’sThe model knew the provenance of all data (the originating java class)Slide34
Example Geonames “feature” entry
34<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>
Jenabean
will bind to existing URI’sSlide35
Crafting beans for existing RDF requires care
35@Namespace("http://www.geonames.org/ontology#"
)public class Feature { @Id private URI uri; @
RdfProperty("http://www.w3.org/2003/01/geo/wgs84_pos#lat"
)
public
double
lat;12
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 propertySlide36
JenaBean can auto discover JenaBeans, provided it knows the package(s)
361: Model m = ModelFactory.
createDefaultModel();2: m.read("http://ws.geonames.org/search?q=london&type=rdf");3: RDF2Bean reader = new RDF2Bean(m);4: reader.bindAll
("com.foo"
,
"com.bar"
);
// type safe binding by class
reader.bind
(Feature.class);// or packagereader.bind(Feature.class.getPackage());Slide37
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“
37public Collection<LocalizedString> alternateName;
example.geonamesSlide38
Query Support
38// load using a Jena Resourcereader.load(
Human.class, jenaResource);// load any node using it’s URIreader.load(Human.class, "http://any.uri"
);
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…Slide39
thewebsemantic.Sparql Util
39String 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.querySlide40
Summary
@Namespace(“http://yournamespace.goes.here”)Applies to class declaration@IdApplies to field or getter methodShould be a String or primitive type, or wrapper typetype java.net.URI is special
@RdfProperty(“http://specific.property.uri”)Applies to field or getter methodRemember: by definition, JavaBeans must have a default constructor.40Slide41
Summary
writer.save(mybean)writer.saveDeep(mybean) Save this and all related objectsreader.load(Class.class
, key);reader.loadDeep(…); take care, could place entire graph into memory.reader.bindAll(package, package, …); Makes jenabean aware of your beans41Slide42
JenaBean Fluent Programming API
42
AKA method chaining, foo.this().that().bar();A “Fluent Interface” aims to provide more readable codeA 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.Slide43
Example: wgs84 geo vocabulary
43import 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_();}Slide44
A fluent api + good IDE makes things fun
44Slide45
Create a new anonymous iCal event.
45Ical 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);Slide46
Full Example: Creating an iCal event for the meetup
461: Ical.Vevent t =
new Thing(m).isa(Ical.Vevent.class);2: t.uid("event_11978192@meetup.com").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);[] a ical:Vevent ; ical:dtend "20100124T220000Z" ; ical:dtstart "20100124T200000Z" ;
ical:location
"
Parisoma
- " ;
ical:summary
"Jena Semantic Web…" ;
ical:uid
"event_11978192@meetup.com" ;
geo:lat
"37.77"^^
xsd:float
;
geo:long
"-122.41"^^
xsd:float
.Slide47
JenaBean comes with a few common vocabulary interfaces
47
thewebsemantic.vocabulary.Foaf
Geo
Ical
DCTerms
Sioc
Skos
Rdfs
ReviewVocab
You
may want to copy and modify in some cases.Slide48
Fluent API summary:
48
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 vocabularyName 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.Slide49
49
Project IdeasCreate your own foaf document using the fluent interface.Integrate Jena/JenaBean with restlets
restlets.orgUse 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.orgWrite a foaf crawler beginning with Berners-Lee that traverses his social graph.
cc
nickjohnson
http://flickr.com/photots/npj/Slide50
50
Open Source Tools For Java DevsJava Triple StoresJena (HP Labs)Sesame OpenRDF (Aduna
)MulgaraJava Binding toolsJenaBean (Jena)Jastor (Jena)Owl2Java (Jena)Elmo (Sesame)Empirecc
nickjohnson http://flickr.com/photots/npj/Slide51
Taylor Cowan
http://thewebsemantic.com http://twitter.com/tcowanTravelocity taylor.cowan@travelocity.com