Semweb4j/filesQueries/step3

From semanticweb.org
Jump to: navigation, search

Up | Previous step | Next step

Contents

[edit] Step 3: Finding statements

[edit] use case: peopleTag

We will now develop a little semantic web application which allows us to tag persons. Tagging is a special kind of statement adding: tag(a with b) should produce "a is tagged by b" or "a has tag b". We chose this implementation:

Inside the class:

private static Model model;
private static URI hasTag;

In the main method, after initialization of model:

hasTag = model.createURI("http://example.com/relations#hasTag");

Inside the class:

public static void tag(Resource resource, Node tag) throws ModelRuntimeException {
	model.addStatement(resource, hasTag, tag);
}

Our tag is a Node instance and therefore can be an URI or any kind of Literal.

[edit] the different node types

Let's see how RDF2Go managed URIs, Literals, etc.. The different node types are implemented as interfaces:

interface URI extends Resource, UriOrVariable
interface PlainLiteral extends Literal
interface LanguageTagLiteral extends Literal
interface DatatypeLiteral extends Literal
interface Literal extends Node
interface BlankNode extends Resource

interface Resource extends Node, ResourceOrVariable 
interface Node extends NodeOrVariable, Comparable<Node>
interface UriOrVariable extends ResourceOrVariable
interface ResourceOrVariable extends NodeOrVariable
interface NodeOrVariable

Of course, using model.createURI(), you don't get an instance of the interface URI mentioned above but an instance of a URI class which implements this interface.

The special node

Variable.ANY

is a wildcard in triple pattern finding. It's the only instance of the class Variable, which looks like

class Variable implements Node, ResourceOrVariable, UriOrVariable, NodeOrVariable

and therefore can be used always if any of such interfaces are required in a method.

It has to be mentioned that using BlankNodes *can* cause several problems (in RDF, generally), so use them only if you know what you're doing.

[edit] example setup

Now we will use "peopleTag" to demonstrate finding with triple patterns. For finding, we need data to find.

First, we need something to tag - resources, identified by URIs:

URI max = model.createURI("http://xam.de/foaf.rdf.xml#i");
URI konrad = model.createURI("http://example.com/persons#konrad");
URI guido = model.createURI("http://example.com/persons#guido");
URI james = model.createURI("http://example.com/persons#james");

Now let's create some tags:

PlainLiteral tagJava = model.createPlainLiteral("Java");
PlainLiteral tagPython = model.createPlainLiteral("Python");

Tagging the resources is easy now, as we have the method tag(Resource, Node): (URIs are Resources and PlainLiterals are Nodes, as seen above)

tag(max, tagJava);
tag(james, tagJava);
tag(konrad, tagJava);
tag(konrad, tagPython);
tag(guido, tagPython);

[edit] ClosableIterators

ClosableIterators are special iterators which provide a it.close() method. Because ClosableIterators maintain database connections, the close() method must always be called when you don't need the iterator any longer. As long as a ClosableIterator is open, it drains server resources. There is auto-close-functionallity, so after iterating over all objects in the iterator, it will be closed. Make sure you call it.close() even after iterating over all objects because you may have had an exception and therefore not iterated over all objects.

ClosableIterables provide an iterator() method which returns a ClosableIterator. If you use ClosableIterables in for-each-loops, you don't have direct access to the ClosableIterator. If an exception breaks the for-each-loop, the iterator will never get closed. Because of this, for-each-loops with ClosableIterables should be used with care.

[edit] finding

Finding every statement "xyz tagged with Java" (or, more formally, ? hasTag "Java"):

ClosableIterable<? extends Statement> foundTaggedJava;
foundTaggedJava = model.findStatements(Variable.ANY, hasTag, tagJava);
System.out.println("Everything tagged 'Java':");
for(Statement s : foundTaggedJava) {
	System.out.println(s.getSubject());
}

The ClosableIterable is from AIFBcommons:

import org.ontoware.aifbcommons.collection.ClosableIterable;

and implements an Iterable interface which closes the file/stream/connection after iteration.

model.findStatements(ResourceOrVariable subject, UriOrVariable predicate, NodeOrVariable object);

returns a ClosableIterable of Statements, as you can see. If called with (Variable.ANY, Variable.ANY, Variable.ANY), you get all statements in this model.

[edit] finding with a triple pattern

Now we're looking for "xyz tagged with Python":

TriplePattern taggedAsPythonPattern = model.createTriplePattern(Variable.ANY, hasTag, tagPython);
ClosableIterable<? extends Statement> foundTaggedPython;
foundTaggedPython = model.findStatements(taggedAsPythonPattern);
System.out.println("Everything tagged 'Python':");
for(Statement s : foundTaggedPython) {
	System.out.println(s.getSubject());
}

It's almost the same as above, findStatements can simply also be called with

model.findStatements(TriplePattern);

and a TriplePattern instance is created via

model.createTriplePattern(ResourceOrVariable subject, UriOrVariable predicate, NodeOrVariable object);

If you're using the same pattern at different locations in your code, TriplePattern objects make managing your code easier.

[edit] output

Everything tagged 'Java':
http://example.com/persons#konrad
http://example.com/persons#james
http://xam.de/foaf.rdf.xml#i
Everything tagged 'Python':
http://example.com/persons#guido
http://example.com/persons#konrad
Personal tools
Namespaces

Variants
Actions
Navigation
services
Toolbox