blob: 640e86e18ac96cc8a0632b9653c8cf5ad2211abd [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.marmotta.client.clients;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.marmotta.client.ClientConfiguration;
import org.apache.marmotta.client.exception.MarmottaClientException;
import org.apache.marmotta.client.model.rdf.BNode;
import org.apache.marmotta.client.model.rdf.Literal;
import org.apache.marmotta.client.model.rdf.RDFNode;
import org.apache.marmotta.client.model.rdf.URI;
import org.apache.marmotta.client.model.sparql.SPARQLResult;
import org.apache.marmotta.client.util.HTTPUtil;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.query.Binding;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryResultHandler;
import org.openrdf.query.QueryResultHandlerException;
import org.openrdf.query.TupleQueryResultHandlerException;
import org.openrdf.query.resultio.BooleanQueryResultFormat;
import org.openrdf.query.resultio.QueryResultIO;
import org.openrdf.query.resultio.QueryResultParseException;
import org.openrdf.query.resultio.QueryResultParser;
import org.openrdf.query.resultio.TupleQueryResultFormat;
import org.openrdf.query.resultio.UnsupportedQueryResultFormatException;
import org.openrdf.query.resultio.helpers.QueryResultCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Add file description here!
* <p/>
* Author: Sebastian Schaffert
*/
public class SPARQLClient {
private static Logger log = LoggerFactory.getLogger(SPARQLClient.class);
private static final String URL_QUERY_SERVICE = "/sparql/select";
private static final String URL_UPDATE_SERVICE = "/sparql/update";
private ClientConfiguration config;
public SPARQLClient(ClientConfiguration config) {
this.config = config;
}
/**
* Run a SPARQL Select query against the Marmotta Server and return the results as SPARQL Result. Results will be
* transfered and parsed using the SPARQL JSON format.
* @param query a SPARQL Select query to run on the database
* @return
* @throws IOException
* @throws MarmottaClientException
*/
public SPARQLResult select(String query) throws IOException, MarmottaClientException {
String serviceUrl = config.getMarmottaUri() + URL_QUERY_SERVICE + "?query=" + URLEncoder.encode(query, "utf-8");
HttpGet get = new HttpGet(serviceUrl);
get.setHeader("Accept", TupleQueryResultFormat.JSON.getDefaultMIMEType());
try(CloseableHttpClient httpClient = HTTPUtil.createClient(config)) {
HttpResponse response = httpClient.execute(get);
switch(response.getStatusLine().getStatusCode()) {
case 200:
log.debug("SPARQL Query {} evaluated successfully",query);
QueryResultCollector results = new QueryResultCollector();
parse(response.getEntity().getContent(), TupleQueryResultFormat.JSON, results, ValueFactoryImpl.getInstance());
if(!results.getHandledTuple() || results.getBindingSets().isEmpty()) {
return null;
} else {
List<String> fieldNames = results.getBindingNames();
SPARQLResult result = new SPARQLResult(new LinkedHashSet<String>(fieldNames));
//List<?> bindings = resultMap.get("results").get("bindings");
for(BindingSet nextRow : results.getBindingSets()) {
Map<String,RDFNode> row = new HashMap<String, RDFNode>();
for(String nextBindingName : fieldNames) {
if(nextRow.hasBinding(nextBindingName)) {
Binding nextBinding = nextRow.getBinding(nextBindingName);
//Map<String,String> nodeDef = (Map<String,String>) entry.getValue();
Value nodeDef = nextBinding.getValue();
RDFNode node = null;
if(nodeDef instanceof org.openrdf.model.URI) {
node = new URI(nodeDef.stringValue());
} else if(nodeDef instanceof org.openrdf.model.BNode) {
node = new BNode(((org.openrdf.model.BNode)nodeDef).getID());
} else if(nodeDef instanceof org.openrdf.model.Literal) {
org.openrdf.model.Literal nodeLiteral = (org.openrdf.model.Literal)nodeDef;
if(nodeLiteral.getLanguage() != null) {
node = new Literal(nodeLiteral.getLabel(), nodeLiteral.getLanguage());
} else if(nodeLiteral.getDatatype() != null) {
node = new Literal(nodeLiteral.getLabel(), new URI(nodeLiteral.getDatatype().stringValue()));
} else {
node = new Literal(nodeLiteral.getLabel());
}
} else {
log.error("unknown result node type: {}",nodeDef);
}
if(node != null) {
row.put(nextBindingName, node);
}
}
}
result.add(row);
}
return result;
}
default:
log.error("error evaluating SPARQL Select Query {}: {} {}",new Object[] {query,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
throw new MarmottaClientException("error evaluating SPARQL Select Query "+query+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
}
} catch(TupleQueryResultHandlerException e) {
throw new MarmottaClientException("error evaluating SPARQL Select Query ", e);
} catch(QueryResultParseException e) {
throw new MarmottaClientException("error evaluating SPARQL Select Query ", e);
} catch(UnsupportedQueryResultFormatException e) {
throw new MarmottaClientException("error evaluating SPARQL Select Query ", e);
} catch(IllegalStateException e) {
throw new MarmottaClientException("error evaluating SPARQL Select Query ", e);
} catch(QueryResultHandlerException e) {
throw new MarmottaClientException("error evaluating SPARQL Select Query ", e);
} finally {
get.releaseConnection();
}
}
/**
* Carry out a SPARQL ASK Query and return either true or false, depending on the query result.
*
* @param askQuery
* @return
* @throws IOException
* @throws MarmottaClientException
*/
public boolean ask(String askQuery) throws IOException, MarmottaClientException {
String serviceUrl = config.getMarmottaUri() + URL_QUERY_SERVICE + "?query=" + URLEncoder.encode(askQuery, "utf-8");
HttpGet get = new HttpGet(serviceUrl);
get.setHeader("Accept", BooleanQueryResultFormat.JSON.getDefaultMIMEType());
try(CloseableHttpClient httpClient = HTTPUtil.createClient(config)) {
HttpResponse response = httpClient.execute(get);
switch(response.getStatusLine().getStatusCode()) {
case 200:
log.debug("SPARQL ASK Query {} evaluated successfully",askQuery);
QueryResultCollector results = new QueryResultCollector();
parse(response.getEntity().getContent(), BooleanQueryResultFormat.JSON, results, ValueFactoryImpl.getInstance());
if(!results.getHandledBoolean()) {
return false;
} else {
return results.getBoolean();
}
default:
log.error("error evaluating SPARQL ASK Query {}: {} {}",new Object[] {askQuery,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
throw new MarmottaClientException("error evaluating SPARQL ASK Query "+askQuery+": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
}
} catch(TupleQueryResultHandlerException e) {
throw new MarmottaClientException("error evaluating SPARQL Ask Query ", e);
} catch(QueryResultParseException e) {
throw new MarmottaClientException("error evaluating SPARQL Ask Query ", e);
} catch(UnsupportedQueryResultFormatException e) {
throw new MarmottaClientException("error evaluating SPARQL Ask Query ", e);
} catch(IllegalStateException e) {
throw new MarmottaClientException("error evaluating SPARQL Ask Query ", e);
} catch(QueryResultHandlerException e) {
throw new MarmottaClientException("error evaluating SPARQL Ask Query ", e);
} finally {
get.releaseConnection();
}
}
/**
* Execute a SPARQL Update query according to the SPARQL 1.1 standard. The query will only be passed to the server,
* which will react either with ok (in this the method simply returns) or with error (in this case, the method
* throws an MarmottaClientException).
*
* @param updateQuery the SPARQL Update 1.1 query string
* @throws IOException in case a connection problem occurs
* @throws MarmottaClientException in case the server returned and error and did not execute the update
*/
public void update(String updateQuery) throws IOException, MarmottaClientException {
String serviceUrl = config.getMarmottaUri() + URL_UPDATE_SERVICE + "?update=" + URLEncoder.encode(updateQuery, "utf-8");
HttpGet get = new HttpGet(serviceUrl);
try(CloseableHttpClient httpClient = HTTPUtil.createClient(config)) {
HttpResponse response = httpClient.execute(get);
switch(response.getStatusLine().getStatusCode()) {
case 200:
log.debug("SPARQL UPDATE Query {} evaluated successfully",updateQuery);
break;
default:
log.error("error evaluating SPARQL UPDATE Query {}: {} {}",new Object[] {updateQuery,response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase()});
throw new MarmottaClientException("error evaluating SPARQL UPDATE Query "+updateQuery +": "+response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase());
}
} finally {
get.releaseConnection();
}
}
/**
* FIXME: Replace this with QueryResultIO.parse after Sesame-2.7.3.
*
* @param in
* @param format
* @param handler
* @param valueFactory
* @throws IOException
* @throws QueryResultParseException
* @throws TupleQueryResultHandlerException
* @throws UnsupportedQueryResultFormatException
*/
private static void parse(InputStream in, TupleQueryResultFormat format, QueryResultHandler handler,
ValueFactory valueFactory)
throws IOException, QueryResultParseException, QueryResultHandlerException,
UnsupportedQueryResultFormatException
{
QueryResultParser parser = QueryResultIO.createParser(format);
parser.setValueFactory(valueFactory);
parser.setQueryResultHandler(handler);
parser.parseQueryResult(in);
}
/**
* FIXME: Replace this with QueryResultIO.parse after Sesame-2.7.3.
*
* @param in
* @param format
* @param handler
* @param valueFactory
* @throws IOException
* @throws QueryResultParseException
* @throws TupleQueryResultHandlerException
* @throws UnsupportedQueryResultFormatException
*/
private static void parse(InputStream in, BooleanQueryResultFormat format, QueryResultHandler handler,
ValueFactory valueFactory)
throws IOException, QueryResultParseException, QueryResultHandlerException,
UnsupportedQueryResultFormatException
{
QueryResultParser parser = QueryResultIO.createParser(format);
parser.setValueFactory(valueFactory);
parser.setQueryResultHandler(handler);
parser.parseQueryResult(in);
}
}