Difference between revisions of "Java Examples"

From Info216
Jump to: navigation, search
(Explanation of table.forEachRemaining(...))
(Language-tagged literals (and functions, and services...))
Line 195: Line 195:
  
 
The method dataset.getNamedModel("http://ex.org/personal#Graph"); lets you output a named model instead.
 
The method dataset.getNamedModel("http://ex.org/personal#Graph"); lets you output a named model instead.
 +
 +
===SPARQL SELECT VALUES (and services)===
 +
 +
The code below retreives DBpedia descriptions of the three Scandinavian capitals, using VALUES:
 +
<nowiki>
 +
Dataset dataset = DatasetFactory.create();
 +
 +
ResultSet table = QueryExecutionFactory.create(""
 +
+ "SELECT * WHERE {"
 +
+ "    VALUES ?city {"
 +
+ "       <http://dbpedia.org/resource/Copenhagen>"
 +
+ "       <http://dbpedia.org/resource/Oslo>"
 +
+ "       <http://dbpedia.org/resource/Stockholm>"
 +
+ "    }"
 +
+ "    SERVICE <http://dbpedia.org/sparql> {"
 +
+ "   ?city <" + RDFS.comment + "> ?comment ."
 +
+ "    }"
 +
+ "}", dataset).execSelect();
 +
 +
table.forEachRemaining(row -> System.out.println(row));</nowiki>
 +
 +
To retrieve only English-language descriptions, you can add a FILTER inside the SERVICE call:
 +
<nowiki>
 +
...
 +
+ "    SERVICE <http://dbpedia.org/sparql> {"
 +
+ "   ?city <" + RDFS.comment + "> ?comment ."
 +
+ "        FILTER( lang(?comment) = 'en' )"
 +
...</nowiki>
  
 
===Language-tagged literals (and functions, and services...)===
 
===Language-tagged literals (and functions, and services...)===

Revision as of 15:42, 1 February 2018

Here are the code examples we have used in the live sessions during the lectures - along with a few additional ones.

(More will appear as the course progresses.)

Lecture 1: Java, Jena, and Eclipse

Hello Jena

package no.uib.sinoa.info216;

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.vocabulary.FOAF;

public class HelloJena {

    public static void main(String[] args) {
       
        Model model = ModelFactory.createDefaultModel();
       
	Resource andreas = model.createResource(base + "Andreas");
	Resource info216 = model.createResource(base + "INFO216");
	Property teaches = model.createProperty(base + "teaches");
	andreas.addProperty(teaches, info216);

	andreas.addLiteral(FOAF.name, "Andreas L Opdahl");

        model.write(System.out, "TURTLE");
    }   
}

Lecture 2: RDF

Resource objects

package no.uib.infomedia.info216;

...

public class HelloJena {
    public static void main(String[] args) {
        String iriBase = "http://no.uib.infomedia.info216/";
        String iriDbpedia = "http://dbpedia.org/resource/";
       
        Model model = ModelFactory.createDefaultModel();
       
        Resource resCadeTracy = model.createResource(iriBase + "Cade_Tracy");
        resCadeTracy.addLiteral(FOAF.name, "Cade Tracy");
       
        Resource resCanada = model.createResource(iriDbpedia + "Canada");
        Resource resFrance = model.createResource(iriDbpedia + "France");
        Property propVisited = model.createProperty(iriBase + "visited");
        resCadeTracy.addProperty(propVisited, resCanada);
        resCadeTracy.addProperty(propVisited, resFrance);

        model.write(System.out, "TURTLE");
    }
}

Language-tagged literals

        resFrance.addProperty(RDFS.label, "Frankrike", "no");
        resFrance.addProperty(RDFS.label, "France", "en");
        resFrance.addProperty(RDFS.label, "Francia", "es");

Typed literals

        Property propPopEst = model.createProperty(iriDbpedia + "ontology/populationEstimate");
        resFrance.addProperty(propPopEst, "66644000", XSDDatatype.XSDinteger);

Looping through statements

        for (Statement stmt : model.listStatements().toList()) {
            System.out.println(stmt.toString());
        }

Selecting statements

        for (Statement stmt : model
                .listStatements((Resource)null, RDFS.label, (RDFNode)null)
                .toList()) {
            System.out.println("Subject:   " + stmt.getSubject().toString());
            System.out.println("Predicate: " + stmt.getPredicate().toString());
            System.out.println("Object:    " + stmt.getObject().toString());
        }

Using a selector

        for (Statement stmt : model
                .listStatements(new SimpleSelector() {
                    public boolean test(Statement s) {
                        return (s.getPredicate().equals(FOAF.name));
                    }
                })
                .toList()) {
            System.out.println(stmt.getObject().toString());
        }

Writing to file

        try {
            model.write(new FileOutputStream("test.ttl"), "TURTLE");
        } catch (Exception e) {
            // TODO: handle exception
        }

Contents of test.ttl

<http://no.uib.infomedia.info216/Cade_Tracy>
        <http://no.uib.infomedia.info216/visited>
                <http://dbpedia.org/resource/France> , <http://dbpedia.org/resource/Canada> ;
        <http://xmlns.com/foaf/0.1/name>
                "Cade Tracy" .

<http://dbpedia.org/resource/France>
        <http://www.w3.org/2000/01/rdf-schema#label>
                "Francia"@es , "France"@en , "Frankrike"@no ;
        <http://dbpedia.org/resource/ontology/populationEstimate>
                66644000 .

Reading from file

package no.uib.infomedia.sinoa.info216;

import java.io.FileInputStream;

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;

public class ReadJena {

    public static void main(String[] args) {
        Model model = ModelFactory.createDefaultModel();
       
        try {
            model.read(new FileInputStream("test.ttl"), "http://ex.org/", "TURTLE");
        } catch (Exception e) {
            // TODO: handle exception
        }
       
        model.write(System.out);
    }
}

Reading from web resource

package no.uib.infomedia.sinoa.info216;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;

public class HttpTest {

    public static void main(String[] args) {
        Model model = ModelFactory.createDefaultModel();
       
        try {
            URL url = new URL("http://people.uib.no/sinoa/test.ttl");  
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
            InputStream is = urlConnection.getInputStream();
            model.read(is, "http://ex.org/", "TURTLE");
        } catch (Exception e) {
            // TODO: handle exception
        }
       
        model.write(System.out);
    }
}

(There are more advanced ways to download web resources from Java, but HttpUrlConnection is a straightforward and built-in way to get started.)

Lecture 3: SPARQL Query and Update

Basic INSERT DATA update

		Dataset dataset = DatasetFactory.create();
		
		UpdateAction.parseExecute(""
				+ "PREFIX info216: <http://ex.org/teaching#>"
				+ "INSERT DATA {"
				+ "    info216:cade info216:teaches info216:ECO001 . "
				+ "    GRAPH <http://ex.org/personal#Graph> {"
				+ "        info216:cade info216:age '29' . "
				+ "    }"
				+ "}", dataset);

		RDFDataMgr.write(System.out, dataset, Lang.TRIG);

To output only the default graph use:

		dataset.getDefaultModel().write(System.out, "TURTLE");

The method dataset.getNamedModel("http://ex.org/personal#Graph"); lets you output a named model instead.

SPARQL SELECT VALUES (and services)

The code below retreives DBpedia descriptions of the three Scandinavian capitals, using VALUES:

		Dataset dataset = DatasetFactory.create();
		
		ResultSet table = QueryExecutionFactory.create(""
				+ "SELECT * WHERE {"
				+ "    VALUES ?city {"
				+ "	       <http://dbpedia.org/resource/Copenhagen>"
				+ "	       <http://dbpedia.org/resource/Oslo>"
				+ "	       <http://dbpedia.org/resource/Stockholm>"
				+ "    }"
				+ "    SERVICE <http://dbpedia.org/sparql> {"
				+ "		   ?city <" + RDFS.comment + "> ?comment ."
				+ "    }"
				+ "}", dataset).execSelect();
		
		table.forEachRemaining(row -> System.out.println(row));

To retrieve only English-language descriptions, you can add a FILTER inside the SERVICE call:

		...
				+ "    SERVICE <http://dbpedia.org/sparql> {"
				+ "		   ?city <" + RDFS.comment + "> ?comment ."
				+ "        FILTER( lang(?comment) = 'en' )"
		...

Language-tagged literals (and functions, and services...)

This works because we use the language-tagged literal 'Copenhagen'@en in the INSERT DATA update (and, as a result, it outputs DBpedia-triples about Copenhagen):

		Dataset dataset = DatasetFactory.create();
		
		String prefixes = ""
				+ "PREFIX rex: <http://ex.org#>"
				+ "PREFIX dbpedia: <http://dbpedia.org/resource/>";
		UpdateAction.parseExecute(prefixes
				+ "INSERT DATA {"
				+ "    rex:Margrethe <" + FOAF.based_near + "> 'Copenhagen'@en ."
				+ "}", dataset);

		ResultSet table = QueryExecutionFactory.create(prefixes
				+ "SELECT * WHERE {"
				+ "    ?person <" + FOAF.based_near + "> ?label ."
				+ "    SERVICE <http://dbpedia.org/sparql> {"
				+ "        ?city <" + RDFS.label + "> ?label ."
				+ "    }"
				+ "}", dataset).execSelect();
		
		table.forEachRemaining(row -> System.out.println(row.toString()));

If we do INSERT DATA without the language tag @en, we get no result (because the city labels in DBpedia are language-tagged):

		UpdateAction.parseExecute(prefixes
				+ "INSERT DATA {"
				+ "    rex:Margrethe <" + FOAF.based_near + "> 'Copenhagen'@en ."
				+ "}", dataset);

We can, however, rewrite the query to use the strlang function that adds language tags to labels. So this works with the previous INSERT DATA:

		ResultSet table = QueryExecutionFactory.create(prefixes
				+ "SELECT * WHERE {"
				+ "    ?person <" + FOAF.based_near + "> ?label ."
				+ "    BIND(strlang(?label, 'en') AS ?taglabel)"				
				+ "    SERVICE <http://dbpedia.org/sparql> {"
				+ "        ?city <" + RDFS.label + "> ?taglabel ."
				+ "    }"
				+ "}", dataset).execSelect();

To go the other way (if our local labels were language-tagged and DBpedia's not, we could do a similar thing, but use the reverse str-function instead of strlang.

Explanation of table.forEachRemaining(...)

The lambda-syntax in this code line may be new for you:

	table.forEachRemaining(row -> System.out.println(row.toString()));

The straightforward way to write it (that doesn't work), would be just:

	table.forEachRemaining(System.out.println(row.toString()));

But this doesn't work because we cannot send a method call as a parameter in Java, and our code introduces a row variable that is not declared anywhere.

Instead, we could try to define a new method somewhere else inside our class:

	void printRow(QuerySolution row) {
		System.out.println(row.toString());
	};

and then pass that function to forEachRemaining (doesn't work either):

	table.forEachRemaining(printRow);

But this doesn't work because you cannot pass functions as arguments like that in Java.

Finally, we could try to define a whole new class - a subclass of a Consumer class:

class RowPrinter implements Consumer<QuerySolution> {
	public void accept(QuerySolution row) {
		System.out.println(row.toString());
	}
}

Here, we define the class RowPrinter as a Consumer of QuerySolutions, because Jena defines each row in a ResultSet-table to be a QuerySolution. In other words, we can view a ResultSet (table) as a stream of QuerySolutions (rows) that the RowPrinter consumes one by one. The method name accept is defined by the Consumer-class. We cannot chose another name (and, actually, Consumer is a Java interface, not a class).

We can pass an object of this class to forEachRemaining - this is exactly what it expects (this works!):

	table.forEachRemaining(new RowPrinter());

But it is pretty cumbersome to write a new class like RowPrinter every time we want to do a forEachRemaining-call - or some other streaming call. Therefore Java 8 has introduced a shorthand, a lambda expression:

	table.forEachRemaining(row -> System.out.println(row.toString());

Whenever Java 8 or later sees code like this, it behaves as if we had explicitly written a RowPrinter or similar Consumer-class like the one above.

 

INFO216, UiB, Spring 2017-2018, Andreas L. Opdahl (c). All code examples are CC0.