package org.bbaw.wsp.cms.mdsystem.metadata.rdfmanager.fuseki;
import org.apache.jena.fuseki.DatasetAccessor;
import org.apache.jena.fuseki.DatasetAccessorFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.update.UpdateExecutionFactory;
import com.hp.hpl.jena.update.UpdateFactory;
import com.hp.hpl.jena.update.UpdateProcessor;
import com.hp.hpl.jena.update.UpdateRequest;
/**
* This (singleton) class offers methods to communicate with a Fuseki server.
* @author Sascha Feldmann (wsp-shk1)
* @date 08.11.2012
*
*/
public class FusekiClient {
/**
* The select-mode for a SparQl query.
*/
public static final String MODE_SELECT = "SELECT";
/**
* This is the standard query, no named graph is specified within the incoming query.
*/
private static final String NONE_GRAPH_SPECIFIED = "";
/**
* The fuseki endpoint to do a SparQl query. Will be concatenated to the dataset URL.
*/
public static String ENDPOINT_QUERY = "/query";
/**
* The fuseki endpoint to do an update on a dataset. Will be concatenated to the dataset URL.
*/
public static String ENDPOINT_UPDATE = "/update";
/**
* The fuseki endpoint to do a manipulate the dataset. Will be concatenated to the dataset URL.
*/
public static String ENDPOINT_DATA = "/data";
/**
* The name of the default model (if not specifying a name for the graph).
*/
public static String DEFAULT_NAMED_MODEL = "default";
private static FusekiClient instance;
/**
*
* @return the only existing instance.
*/
public static FusekiClient getInstance() {
if(instance == null) {
return new FusekiClient();
}
return instance;
}
/**
* Execute a SparQl query on a remote fuseki server.
* @param datasetUrl - the URL to the dataset on which the query will be done.
* @param queryCommand - the SparQl query.
* @return a {@link ResultSet} or null, e.g. if the mode doesn't return anything
*/
public ResultSet performSelect(final String datasetUrl, final String queryCommand) {
// perform a query on an unspecified (default) graph
return performSelect(datasetUrl, queryCommand, NONE_GRAPH_SPECIFIED);
}
/**
* Execute a SparQl query on a remote fuseki server.
* @param datasetUrl - the URL to the dataset on which the query will be done.
* @param queryCommand - the SparQl query.
* @param defaultGraphUri - the Uri of the default graph which will be queried.
* @return a {@link ResultSet} or null, e.g. if the mode doesn't return anything
*/
public ResultSet performSelect(final String datasetUrl, final String queryCommand, final String defaultGraphUri) {
final String pathToQueryEndpoint = datasetUrl+ENDPOINT_QUERY;
return queryServerWithDefaultGraph(pathToQueryEndpoint, queryCommand, MODE_SELECT, defaultGraphUri);
}
/**
* Perform the select query.
* @param pathToQueryEndpoint
* @param queryCommand
* @param resultFormat
* @param defaultGraph
* @return a {@link ResultSet} containing the specified response.
*/
private ResultSet queryServerWithDefaultGraph(final String pathToQueryEndpoint, final String queryCommand, final String resultFormat, final String defaultGraph) {
Query q = QueryFactory.create(queryCommand);
QueryExecution queryEx = QueryExecutionFactory.sparqlService(pathToQueryEndpoint, q, defaultGraph);
if(resultFormat.equals(MODE_SELECT)) {
ResultSet results = queryEx.execSelect(); // SELECT returns a ResultSet
return results;
}
return null;
}
/**
* Put a model to a remote dataset. Consider, that an existing dataset will be replaced if you don't specify a modelName (for a named model).
* If you don't prefer a named model, use {@link FusekiClient}.DEFAULT_NAMED_MODEL.
* @param url - the URL to the dataset on which the model will be putted.
* @param model - the Jena model
* @param modelName - the name of the model.
*/
public void putModel(final String url, final Model model, final String modelName) {
String pathToQueryEndpoint = url+ENDPOINT_DATA;
DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(pathToQueryEndpoint);
accessor.putModel(modelName, model);
}
/**
* Execute an update (manipulation) on a remote fuseki server.
* @param datasetUrl - the URL to the dataset on which the update will be done.
* @param updateCommand - the update Command (e.g. CLEAR DEFAULT)
*/
public void performUpdate(final String datasetUrl, final String updateCommand) {
String pathToUpdateEndpoint = datasetUrl+ENDPOINT_UPDATE;
UpdateRequest request = UpdateFactory.create(updateCommand);
UpdateProcessor proc = UpdateExecutionFactory.createRemote(request, pathToUpdateEndpoint);
proc.execute(); // perform the update
}
public void deleteRecord(Model model, String command) {
}
}