I've just started a project where I'm using the Sesame libraries to do some SemWebbery. I was looking for a good way to declare a method that takes two URIs and an Object, returning a Statement with the object declared to be either a Resource or a properly-typed Literal:

public Statement makeStatement(URI subj, URI pred, Object obj) { ... }

The tricky part, of course, is figuring out whether that 'obj' is a valid URI or a valid type of Literal. It seems that the most straightforward approach is to do something like:

if (XMLDatatypeUtil.isValidBoolean(obj)) { 
   do something fancy with XMLDatatypeUtil.qnameToURI(obj);

However, that's a lot of typing. Does Sesame have something akin to Jena's TypeMapper class? Or maybe a method call that does some behind-the-scenes magic?

asked 17 Dec '12, 21:43

Ryan%20Kohl's gravatar image

Ryan Kohl
accept rate: 17%


Is it possible that the object be a blank node in your case?

(18 Dec '12, 03:29) Antoine Zimm... ♦ Antoine%20Zimmermann's gravatar image

No, fortunately the data we're using are either URIs or literals. But you're right - a more robust sol'n would distinguish URIs and blank nodes. In fact, the longer I stare at that section of the code, the more I think I just might put that change in :)

(21 Dec '12, 08:31) Ryan Kohl Ryan%20Kohl's gravatar image

I think what you want is the ValueFactory:

 if ( <insert check to see that your object is in fact URI> ) {
    result = valueFactory.createURI(obj); 
 else { // obj is a literal of some sort
    // create a datatyped literal for the suplied object.
    result = valueFactory.createLiteral(obj); 

createLiteral is overloaded to accept several kinds of input object. See the javadoc for a list of all supported types.

permanent link

answered 17 Dec '12, 23:53

Jeen%20Broekstra's gravatar image

Jeen Broekstra ♦
accept rate: 37%

edited 17 Dec '12, 23:53


Valuefactory.createLiteral doesn't take an Object argument, so your code doesn't compile. If you do it this way you need to cast the obj to one of the overloaded types first, which requires a whole lot of additional "else if (obj instanceof ...)" code blocks

(18 Dec '12, 09:09) Gerrit V Gerrit%20V's gravatar image

@Gerrit V, good point, hadn't thought of that. Feature request logged. https://openrdf.atlassian.net/browse/SES-1671 . Should be trivial.

(18 Dec '12, 14:13) Jeen Broekstra ♦ Jeen%20Broekstra's gravatar image

Appreciate the feature request! For now, though, we have enough control over literal values coming into the system (ie nobody's passing a java.io.File object into that position) that I can just call result= ValueFactory.createLiteral(obj.toString()).

(21 Dec '12, 08:48) Ryan Kohl Ryan%20Kohl's gravatar image

Starting from Sesame-2.7.0 you can also solve the issue with the new DatatypeHandler interface, either extending the default XMLSchemaDatatypeHandler or replacing it with your own.

To implement the replacement you need to use ParserConfig to tell the Parser's and RepositoryConnection's what to use:

ParserConfig parserConfig = new ParserConfig();
parserConfig.set(BasicParserSettings.DATATYPE_HANDLERS, Arrays.asList(customDatatypeHandlers...))
// Normalisation is off by default
parserConfig.set(BasicParserSettings.NORMALIZE_DATATYPE_VALUES, true);
// or:

Inside of DatatypeHandler.normalizeLiteral you can create the Literal using any method you want, including not using the given ValueFactory if necessary.

By the way, Jeen's idea for ValueFactory.createLiteral(Object) was migrated to a new helper method as Literals.createLiteral(ValueFactory, Object) method in the final 2.7.0 release. Having a ValueFactory.createLiteral(Object) method may have hampered our ability to add to the interface in future. The Literals method will resort to using obj.toString if the datatype is unknown, but you can also using Literals.createLiteralOrFail if you wish to fail instead of using obj.toString as a backup.

permanent link

answered 02 May '13, 22:00

Peter%20Ansell's gravatar image

Peter Ansell
accept rate: 9%

edited 02 May '13, 22:04

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:


question asked: 17 Dec '12, 21:43

question was seen: 1,560 times

last updated: 02 May '13, 22:04