public class - Meetup

religiondressInternet and Web Development

Oct 21, 2013 (3 years and 10 months ago)

74 views

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


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


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.fluentwriter

http://thewebsemantic.com

http://jenabean.googlecode.com


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


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


http://thewebsemantic.com

http://jenabean.googlecode.com


6

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


7

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


8

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


9

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


10

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


11

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


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

}

12



<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

.

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
("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

.

13

http://thewebsemantic.com

http://jenabean.googlecode.com


Overriding the Default Namespace

package

examples.model
;


import

thewebsemantic.Id
;

import

thewebsemantic.Namespace
;


@
Namespace
(
"http://mydomain#"
)

public

class

Person { … }

14


<
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

.

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
;




15


<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

.

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

16

http://thewebsemantic.com

http://jenabean.googlecode.com


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



17

http://thewebsemantic.com

http://jenabean.googlecode.com


JenaBean

Support for OWL Entailments

18

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


Reading Existing RDF/OWL

19

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



Example
Geonames

“feature” entry

20

<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

http://thewebsemantic.com

http://jenabean.googlecode.com


Crafting beans for existing RDF requires care

21

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

1

2

3

4

1.
Namespace must accurately match

2.
Your java’s
classname

must match the

Ontology class

3.
Your @Id must be of type
java.net.URI

4.
All property

URI’s must match the Ontology property



http://thewebsemantic.com

http://jenabean.googlecode.com


JenaBean

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

22

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 class

reader.bind
(
Feature.
class
);


// or package

reader.bind
(
Feature.
class
.getPackage
());

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“





23

public

Collection<
LocalizedString
>
alternateName
;

example.geonames

http://thewebsemantic.com

http://jenabean.googlecode.com


Query Support

24

// load using a Jena Resource

reader.load
(
Human.
class
,
jenaResource
);


// load any node using it’s URI

reader.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…


http://thewebsemantic.com

http://jenabean.googlecode.com


thewebsemantic.Sparql

Util

25

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


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.

26

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

27

http://thewebsemantic.com

http://jenabean.googlecode.com


JenaBean

Fluent Programming API

28

>
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

>
A
llows

use of vocabulary terms against any Individual regardless
of classification.


http://thewebsemantic.com

http://jenabean.googlecode.com


Example: wgs84 geo vocabulary

29

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


A fluent
api

+ good IDE makes things fun

30

http://thewebsemantic.com

http://jenabean.googlecode.com


Create a new anonymous iCal event.

31

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


Full Example: Creating an iCal event for the
meetup

32

1:
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

.

http://thewebsemantic.com

http://jenabean.googlecode.com


JenaBean

comes with a few common vocabulary
interfaces

33


>
t
hewebsemantic.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


Fluent API summary:

34


>
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


35

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 Cowan

http://thewebsemantic.com


http://twitter.com/tcowan

Travelocity

taylor.cowan@travelocity.com