I have been getting feedback about the current java RDF API from potential
RDF users in HPLabs. A number of issues with the current API are inhibiting
the adoption of RDF in this organisation. I have been exploring some ideas
for addressing these issues in the form of an evolution of the SiRPAC API.
I'd appreciate the comments of this group on the results.
I am in the process of building an implementation of these enhancements
which I intend to make freely available. I have got far enough with the
design that I am reasonably confident that it is implementable. I would
like to get early feedback before getting too far into the implementation.
In particular I'd welcome comments on:
* is the overall style appealing?
* preferences for strict evolution from the current SiRPAC API versus
conforming to current java stylistic conventions
* detailed comments on the interfaces
I'd like to stress that what I am proposing is an evolution of the excellent
work that has already been done on RDF API's. This evolution has been
motivated by a desire to address specific concerns raised by potential
users. I'd also like to acknowledge that I 'borrowed' the core idea from
Dave Beckett at ILRT.
The main changes are:
* whilst maintaining the current statement centric method calls, added
a set of resource centric method calls which are cascadable to make code
easier to read and write
* explicit container support
* typed data values in literals - supports built in types and user
defined objects
* property as an explicit type
* subclassing of resource to provide resource specific behaviour (used
by containers)
* explicit support for reification (... dare I mention this :)
* a style more consistent with current java api practice
Here are some brief code samples:
// create the structure in Figure 2 of m&s
Resource ora = model.createResource()
.addProperty(Dc.name, "Ora Lassila")
.addProperty(Dc.email, <mailto:lassila@w3.org>
lassila@w3.org);
Resource page = model.createResource( <http://www.w3.org/Home/Lassila>
http://www.w3.org/Home/Lassila)
.addProperty(Dc.creator, ora);
The alternative in the current API (as I have implemented it) might be:
Resource ora = model.createResource();
model.add(model.createStatement(ora, DC.name, "Ora Lassila"));
model.add(model.createStatement(ora, DC.email, lassila@w3.org
<mailto:lassila@w3.org> ));
Resource page = model.createResource();
model.add(model.createStatement(page, DC.creator, ora);
// create bag structure from figure 4 of m&s
Resource bag = model.createBag()
.addResource("/Students/Amy")
.addResource("/Students/Tim")
.addResource("/Students/John")
.addResource("/Students/Mary")
.addResource("/Students/Sue");
Resource course = model.createResource("/courses/6.001")
.addProperty(Myschema.students, bag);
Again the alternative:
Resource student = null;
Resource course = model.createResource("/courses/6.001");
Resource bag = model.createResource();
model.add(model.createStatement(bag, RDF.type, RDF.Bag));
model.add(model.createStatement(course, MYSCHEMA.students, bag));
student = model.createResource("/Students/Amy");
model.add(model.createStatement(bag, RDF.li(1), student));
student = model.createResource("/Students/Tim");
model.add(model.createStatement(bag, RDF.li(2), student));
student = model.createResource("/Students/John"));
model.add(model.createStatement(bag, RDF.li(3), student));
student = model.createResource("/Students/Mary");
model.add(model.createStatement(bag, RDF.li(4), student));
student = model.createResource("/Students/Sue");
model.add(model.createStatement(bag, RDF.li(5), student));
// access the i'th element of the bag starting from course
Resource student = course.getProperty(Myschema.students)
.getProperty(Rdf.li(i)).getResource();
Again the alternative
Model m = model.find(course, MYSCHEMA.students, null)
Statement s = (Statement) m.elements.next();
m = model.find(s.subject(), RDF.li(i), null);
s = (Statement) m.elements.next());
Resource student = (Resource) s.object();
// a reification from figure 8 of m&s
Resource page = model.createResource("http://www.w3.org/Home/Lassila")
Model.createStatement(page, Dc.creator, "Ora Lassila")
.addProperty(SomeSchema.attributedTo, "Ralph Swick");
// creating and accessing a compound value from figure 15 of m&s
john.addProperty(Nschema.weight, model.createResource()
.addProperty(Rdf.value, 200)
.addProperty(Nschema.units.
Nschema.Pounds));
int weight = john.getProperty(Nschema.weight)
.getProperty(Rdf.value).getInt();
// transactions (if supported) are also inline
Resource bag = model.begin()
.createBag()
.addResource("/Students/Amy")
.addResource("/Students/Tim")
.addResource("/Students/John")
.addResource("/Students/Mary")
.addResource("/Students/Sue")
.commit();
// there are two kinds of query operation - one group returns iterators on
the
// the current model, the other group, as with the original returns, a new
model.
// return an iterator over all bags in the model
ResIterator iter = model.listSubjectsWithPredicate(Rdf.type, Rdf.Bag);
// return all the creators in a model
ResIterator iter = model.listObjectsOfPredicate(Dc.creator);
That should be enough to give a flavour. The current (work in progress)
interface files are attached.
Brian McBride
HPLabs