Posts mit dem Label SPARQL werden angezeigt. Alle Posts anzeigen
Posts mit dem Label SPARQL werden angezeigt. Alle Posts anzeigen

Donnerstag, 17. Januar 2013

DELETE triples from Virtuoso via Java

I already wrote about how to access a triple store via Java using Jena. There I also mentioned that writing SPARQL UPDATE queries (INSERT, UPDATE, DELETE) against external triple stores may not work if the triple store does not support SPARQL 1.1 UPDATE.

In my scenario I wanted to DELETE triples from a Virtuoso endpoint. The query syntax Virtuoso supports is
DELETE FROM <graph> { ?s ?p ?o.} WHERE { GRAPH <graph> { ?s ?p ?o.} }
which is not the syntax defined by SPARQL 1.1 UPDATE - DELETE. If you hand this query string over to Jena, it will transform it into valid SPARQL 1.1 UPDATE syntax, which will result in an error at the Virtuoso side.

To be able to submit a DELETE query to Virtuoso anyway, Jena cannot be used. Instead HTTP Post has to be used directly.

Therefore I found a nice solution in the Jena Users Mailinglist archive, which I minimally updated to fit Virtuosos needs.
private boolean runUpdateQuery(String queryString) throws Exception {
    SPARQLUpdate p = new SPARQLUpdate();
    p.setEndpoint(endpoint);
    p.setUpdateString(queryString);
    String response = p.execute();
    if (!response.contains("done")) {
        System.err.println("UPDATE/SPARQL failed: " + queryString);
        return false;
    }
    return true;
}
Whereby SPARQLUpdate is defined as: 
package de.semweb.sparql;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
 *
 * @author admos0
 */
public class SPARQLUpdate {

    private String updateString = "";
    private String endpoint = "";

    public SPARQLUpdate() {
        // empty constructor
    }

    public SPARQLUpdate(String input) {
        this.updateString = input;
    }

    /**
     * @method  execute the update
     * @return  the response <String>
     */
    public String execute() throws Exception {
        if (this.endpoint.equals("")) throw new Exception("No endpoint specified");
        if (this.updateString.equals("")) throw new Exception("No update string specified");
   
   
        // Construct data
        String data = URLEncoder.encode("query", "UTF-8") + "=" +
                URLEncoder.encode(this.getUpdateString(), "UTF-8");
   
   
        // Send data
        URL url = new URL(endpoint);
   
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
        wr.write(data);
        wr.flush();
   
        // Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String response = "";
        String line;
        while ((line = rd.readLine()) != null) {
            response += line;
        }
       
        wr.close();
        rd.close();
       
        return response;
    }

    /**
     * @param set the endpoint
     */
    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    /**
     * @return the endpoint
     */
    public String getEndpoint() {
        return this.endpoint;
    }


    /**
     * @param updateString the updateString to set
     */
    public void setUpdateString(String updateString) {
        this.updateString = updateString;
    }

    /**
     * @return the updateString
     */
    public String getUpdateString() {
        return updateString;
    }
}


Access Triple Store via Java

The easiest way to access triple stores via Java is to use Jena ARQ.
ARQ is a query engine for Jena that supports the SPARQL RDF Query language. SPARQL is the query language developed by the W3C RDF Data Access Working Group.
You can easily access the data in the store using SELECT, ASK, DESCRIBE, and CONSTRUCT queries.
Query query = QueryFactory.create("queryString");
QueryExecution queryExec = QueryExecutionFactory.sparqlService( endpoint, query );
ResultSet result = queryExec.execSelect(); // or execSelectTriples()
It results in a ResultSet or an Interator of triples which can easily be processed further.
while (result.hasNext()) {
    QuerySolution solution = result.next();
    Resource id = solution.getResource("id");
    Resource title = solution.getLiteral("title");
}
One QuerySolution thereby is one result row of the query and each cell can be accessed by the variable name used in the SPARQL query.

But sometimes you do not want to just extract data from your triple store, but INSERT, UPDATE or DELETE triples. This can also be done using Jena.
UpdateRequest update = UpdateFactory.create(queryString);           
UpdateProcessor uExec = UpdateExecutionFactory.createRemote(update, endpoint);
uExec.execute(); 
Attention: This just works with triple stores supporting SPARQL 1.1 UPDATE.