03 July 2008

Building a Web Service with Java, Jena and mySQL [Part 4]

Author's note : This has been replaced by Part 4.1 of this tutorial. It remains here for reference. It still works, it's just deprecated.

Well we've reached the end of the Jena Web Service, renamed to JAWS. This is now an official Google Code project. More on this to come.

Today we're going to add an a way to insert, delete and update, yes update data back into the triple store.

In order to insert data, one would need to post an entire triple. That is: subject, predicate, object. The best way to do this is to add objects and predicates to an existing subject. This ensures everything matches up in the Jena persistent store. Additionally the way the store accepts a predicate is through a URI, formatted as a URI.

@deprecated
public static boolean insertTriple(String resourceURI, String predicateURI,
String subject, String predicate, String object) {
ModelMaker maker = initDBStore(M_DB_URL, M_DB_USER, M_DB_PASSWD,
M_DB_TYPE, CLEAN_DB);
Model model = maker.openModel(M_NAME, false);
model.begin();
Resource resource = model.createResource(resourceURI + "/"
+ subject);
Property property = model.createProperty(predicateURI, predicate);
resource.addProperty(property, object);
model.commit();
return true;
}

The next major important utility for managing the triples is a delete method. Delete is very particular, requiring fully qualified URIs for each part of the triple. Additionally, you can delete entire subjects, predicates or object by nulling any of the parameters.

@deprecated
public static void deleteTriple(String subject, String predicate,
String object, String modelName) {
ModelMaker maker = initDBStore(M_DB_URL, M_DB_USER, M_DB_PASSWD,
M_DB_TYPE, CLEAN_DB);
Model model = maker.openModel(modelName);
model.begin();
Resource sub = (subject != null) ? model.getResource(subject)
: null;
Property pred = (predicate != null) ? model.getProperty(predicate)
: null;
if (sub != null && pred != null) {
StmtIterator iter = model.listStatements(new SimpleSelector(
sub, pred, (RDFNode) null));
while (iter.hasNext()) {
Statement s = iter.nextStatement();
// The only decent way to match an object without killing
// resources
// ////////////
if (s.getObject().toString().equals(object))
iter.remove();
if (object == null)
iter.remove();
}
}
return true;
}

On the rare occasion that you may want to actually update a triple from the store, just use the above methods and verify the returns are true along the way. Again, the :s :p :o must be fully qualified. Feel free to modify as you see fit.

@deprecated
public static boolean updateTriple(String subject, String predicate,
String object, String newObject, String modelName) {
if (deleteTriple(subject, predicate, object, modelName))
if (insertTriple(subject, predicate, newObject, modelName))
System.out.println("Update Completed :" + subject + " :"
+ PREDICATE_URI + predicate + " :" + newObject + " [" + modelName + "]");
return true;
} else {
return false;
}
}

Well there it is, the final method. Here is the entire Jena Web Service. Remember there is no main(), this expects to run as a web service as a .jws file on Apache Axis 1. In later posts we'll talk about extending this service, overloading the methods and adding business logic. This will be done under Axis2.
Jaws.java

9 comments:

Junior said...

Great Tutorial, I'm using this code like a base in my graduate's project in Switzerland.

garrett wyrwas said...

@junior: Glad it helps. Feel free to ask anything.

I saw I had posted the wrong method for the update. IT has been corrected now.

Robbie said...

I got a question,

In the deleteTriple function, when you want iter.remove(); i got an exception of type: UnsupportedOperationException. Im using a ModelRDB on Postgre. Any problem there?

My way to solve it was to use model.remove(s);

It works, but I still would like to know why it doesnt work as you explained in your tutorial.

Thanks a lot for this tutorial, you save me a lot of headaches :D

garrett wyrwas said...

Interesting issue. I tested and use the deleteTriple method just fine. I can't conceive why it would have a problem with Postgres. If I recall I had issue using model.remove when deleting a triple or classes in the store. It was only effective, for me, when deleting the entire model.

Which version of Jena are you using? I tested and am using it daily with 2.5.5. Are you importing com.hp.hpl.jena.rdf.model.StmtIterator?

If you would like, email me a code snip to kilsoft@gmail.com or a stacktrace.

robbie said...

Hi garret, i sent you an email describing the problem, couple of days ago.
Let me know if you didn't get it.

garrett wyrwas said...

I got it, haven't had any time to try and run your example. I can confirm that the way I have the delete is working. I will followup here if there is a code change.

garrett wyrwas said...

Robbie, I'm thinking you had trouble with the Iterator because of that object is created. It is written here as a raw type, not really proper for Java.

Any issues with this post, try out the Part 4.1 above.

Benjamin said...

Thank you for your work.
One remark to the methods sparqlSelect and inferSelect: If you intent to build an xml out of the result to send it to a web-client, one should think about using the Jena ResultSetFormatter

Instead of iterating two times to build a String-Array, you just need one line:
String xmlResult = ResultSetFormatter.asXMLString(results);

Sven said...

Nice tutorial man, thx a lot!