Programming with JenaBean Sources for examples can be found @ Taylor Cowan Travelocity 8982.

36
http://thewebsemantic.com http://jenabean.googlecode.com Programming with JenaBean Sources for examples can be found @ http://jenabean.googlecode.com/svn/ jenabean-lab1 Taylor Cowan Travelocity 8982

Transcript of Programming with JenaBean Sources for examples can be found @ Taylor Cowan Travelocity 8982.

http://thewebsemantic.com http://jenabean.googlecode.com

Programming with JenaBeanSources for examples can be found @

http://jenabean.googlecode.com/svn/jenabean-lab1

Taylor Cowan

Travelocity

8982

2

http://thewebsemantic.com http://jenabean.googlecode.com

[] 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>;

3

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

4

http://thewebsemantic.com http://jenabean.googlecode.com

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

5

http://thewebsemantic.com http://jenabean.googlecode.com

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(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.xsl

6

http://thewebsemantic.com http://jenabean.googlecode.com

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 .

7

http://thewebsemantic.com http://jenabean.googlecode.com

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");

8

http://thewebsemantic.com http://jenabean.googlecode.com

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

9

http://thewebsemantic.com http://jenabean.googlecode.com

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");

10

http://thewebsemantic.com http://jenabean.googlecode.com

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

11

http://thewebsemantic.com http://jenabean.googlecode.com

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

12

http://thewebsemantic.com http://jenabean.googlecode.com

The Simplest Possible Examplepackage 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 .

13

http://thewebsemantic.com http://jenabean.googlecode.com

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 .

14

http://thewebsemantic.com http://jenabean.googlecode.com

Overriding the Default Namespacepackage 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 .

15

http://thewebsemantic.com http://jenabean.googlecode.com

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 .

16

http://thewebsemantic.com http://jenabean.googlecode.com

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;}

17

http://thewebsemantic.com http://jenabean.googlecode.com

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);

18

http://thewebsemantic.com http://jenabean.googlecode.com

JenaBean Support for OWL Entailments

public class Location {@Idpublic 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> .

19

http://thewebsemantic.com http://jenabean.googlecode.com

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)

20

Example Geonames “feature” entry

<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’s

21

http://thewebsemantic.com http://jenabean.googlecode.com

Crafting beans for existing RDF requires care

@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

1. Namespace must accurately match2. Your java’s classname must match the Ontology class3. Your @Id must be of type java.net.URI4. All property URI’s must match the Ontology property

22

http://thewebsemantic.com http://jenabean.googlecode.com

JenaBean can auto discover JenaBeans, provided it knows the package(s)

1: 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 classreader.bind(Feature.class);

// or packagereader.bind(Feature.class.getPackage());

23

http://thewebsemantic.com http://jenabean.googlecode.com

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

24

http://thewebsemantic.com http://jenabean.googlecode.com

Query Support

// 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…

25

http://thewebsemantic.com http://jenabean.googlecode.com

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

26

http://thewebsemantic.com http://jenabean.googlecode.com

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.

27

http://thewebsemantic.com http://jenabean.googlecode.com

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

28

http://thewebsemantic.com http://jenabean.googlecode.com

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.

29

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_();

}

30

http://thewebsemantic.com http://jenabean.googlecode.com

A fluent api + good IDE makes things fun

31

http://thewebsemantic.com http://jenabean.googlecode.com

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);

32

http://thewebsemantic.com http://jenabean.googlecode.com

Full Example: Creating an iCal event for the meetup1: 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);

[] 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 .

33

http://thewebsemantic.com http://jenabean.googlecode.com

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.

34

http://thewebsemantic.com http://jenabean.googlecode.com

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.

35

http://thewebsemantic.com http://jenabean.googlecode.com

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.

cc nickjohnson http://flickr.com/photots/npj/

http://thewebsemantic.com http://jenabean.googlecode.com

Taylor Cowanhttp://thewebsemantic.com

http://twitter.com/tcowan

[email protected]