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;
    }
}


Keine Kommentare:

Kommentar veröffentlichen