Package com.clarkparsia.empire.ds.impl

Source Code of com.clarkparsia.empire.ds.impl.SparqlEndpointDataSource

package com.clarkparsia.empire.ds.impl;

import com.clarkparsia.empire.ds.ResultSet;
import com.clarkparsia.empire.ds.QueryException;

import com.clarkparsia.empire.impl.RdfQueryFactory;

import com.clarkparsia.empire.impl.sparql.SPARQLDialect;

import com.complexible.common.openrdf.model.GraphIO;
import com.complexible.common.openrdf.util.AdunaIterations;

import com.complexible.common.web.ParameterList;
import com.complexible.common.web.Request;
import com.complexible.common.web.HttpResourceImpl;
import com.complexible.common.web.HttpResource;
import com.complexible.common.web.HttpHeaders;
import com.complexible.common.web.MimeTypes;
import com.complexible.common.web.Response;

import java.net.ConnectException;
import java.net.URL;

import java.io.IOException;

import org.openrdf.model.Graph;

import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;

import org.openrdf.query.TupleQueryResult;
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.TupleQueryResultFormat;
import org.openrdf.query.resultio.UnsupportedQueryResultFormatException;

/**
* <p>Simple implementation of the DataSource interface for a generic read-only sparql endpoint.</p>
*
* @author  Michael Grove
* @since   0.6.5
* @version 0.7
*/
public class SparqlEndpointDataSource extends AbstractDataSource {

  /**
   * Constant for the query requests
   */
  private static final String PARAM_QUERY = "query";

  /**
   * The URL of the endpoint
   */
  private URL mURL;

  /**
   * Whether or not to use HTTP GET requests for queries
   */
  private boolean mUseGetForQueries = true;

  /**
   * Create a new SparqlEndpointDataSource
   * @param theURL the URL of the sparql endpoint.
   */
  public SparqlEndpointDataSource(final URL theURL) {
    this(theURL, true, SPARQLDialect.instance());
  }

  /**
   * Create a new SparqlEndpointDataSource
   * @param theURL the URL of the sparql endpoint
   * @param theDialect the sparql query dialect to use
   */
  public SparqlEndpointDataSource(final URL theURL, SPARQLDialect theDialect) {
    this(theURL, true, theDialect);
  }

  /**
   * Create a new SparqlEndpointDataSource
   * @param theURL the URL of the sparql endpoint.
   * @param theUseGetForQueries whether or not to use HTTP GET requests for queries
   */
  public SparqlEndpointDataSource(final URL theURL, final boolean theUseGetForQueries) {
    mURL = theURL;
    mUseGetForQueries = theUseGetForQueries;

    setQueryFactory(new RdfQueryFactory(this, SPARQLDialect.instance()));
  }

  /**
   * Create a new SparqlEndpointDataSource
   * @param theURL the URL of the sparql endpoint.
   * @param theUseGetForQueries whether or not to use HTTP GET requests for queries
   * @param theDialect the query dialect to use for the endpoint
   */
  public SparqlEndpointDataSource(final URL theURL, final boolean theUseGetForQueries, SPARQLDialect theDialect) {
    mURL = theURL;
    mUseGetForQueries = theUseGetForQueries;

    setQueryFactory(new RdfQueryFactory(this, theDialect));
  }

  /**
   * @inheritDoc
   */
  public void connect() throws ConnectException {
    setConnected(true);
  }

  /**
   * @inheritDoc
   */
  public void disconnect() {
    setConnected(false);
  }

  /**
   * Return the URL of this SPARQL endpoint
   * @return the endpoint URL
   */
  public URL getURL() {
    return mURL;
  }

  /**
   * @inheritDoc
   */
  public ResultSet selectQuery(final String theQuery) throws QueryException {
    assertConnected();

    return new AbstractResultSet(AdunaIterations.iterator(executeSPARQLQuery(theQuery, TupleQueryResult.class))) {
      public void close() {
        // no-op
      }
    };
  }

  private <T> T executeSPARQLQuery(String theQuery, Class<T> clazz) throws QueryException {
    Response aResponse = null;
 
    try {
      aResponse = createSPARQLQueryRequest(theQuery).execute();

      if (aResponse.hasErrorCode()) {
        throw responseToException(theQuery, aResponse);
      }
      else {
        try {
          if (Boolean.class.equals(clazz)) {
            return (T) parseBooleanResult(aResponse);
          }
          else {
            return (T) parseTupleResult(aResponse);
          }
        }
        catch (Exception e) {
          throw new QueryException("Could not parse SPARQL-XML results", e);
        }
      }
    }
    catch (IOException e) {
      throw new QueryException(e);
    }
    finally {
      if (aResponse != null) {
        try {
          aResponse.close();
        }
        catch (IOException e) {
          System.err.println("There was an error while closing the http connection: " + e.getMessage());
        }
      }
    }
  }

  private Request createSPARQLQueryRequest(String theQuery) {
    HttpResource aRes = new HttpResourceImpl(mURL);

    Request aQueryRequest;

    // auto prefix queries w/ rdf and rdfs namespaces
    ParameterList aParams = new ParameterList()
        .add(PARAM_QUERY, theQuery);

    if (mUseGetForQueries) {
      aQueryRequest = aRes.initGet()
          .addHeader(HttpHeaders.Accept.getName(), TupleQueryResultFormat.SPARQL.getDefaultMIMEType())
          .setParameters(aParams);
    }
    else {
      aQueryRequest = aRes.initPost()
          .addHeader(HttpHeaders.ContentType.getName(), MimeTypes.FormUrlEncoded.getMimeType())
          .addHeader(HttpHeaders.Accept.getName(), TupleQueryResultFormat.SPARQL.getDefaultMIMEType())
          .setBody(aParams.getURLEncoded());
    }

    return aQueryRequest;
  }


  /**
   * Given a response, return it as a QueryException by parsing out the errore message and content
   * @param theQuery the query being executed that caused the error
   * @param theResponse the response which indicate a server error
   * @return the Response as an Exception
   */
  private QueryException responseToException(String theQuery, Response theResponse) {
    return new QueryException("Error evaluating query: " + theQuery + "\n(" + theResponse.getResponseCode() + ") " + theResponse.getMessage() + "\n\n" + theResponse.getContent());
  }

  /**
   * @inheritDoc
   */
  public boolean ask(final String theQuery) throws QueryException {
    assertConnected();

    return executeSPARQLQuery(theQuery, Boolean.class);
  }

  private Boolean parseBooleanResult(Response theResponse) throws QueryResultParseException, UnsupportedQueryResultFormatException, IOException {
    return QueryResultIO.parse(theResponse.getContent(), BooleanQueryResultFormat.SPARQL);
  }
 
  private TupleQueryResult parseTupleResult(Response theResponse) throws QueryResultParseException, TupleQueryResultHandlerException, UnsupportedQueryResultFormatException, IOException {
    return QueryResultIO.parse(theResponse.getContent(), TupleQueryResultFormat.SPARQL);
  }
 
  /**
   * @inheritDoc
   */
  public Graph describe(final String theQuery) throws QueryException {
    return graphQuery(theQuery);
  }

  /**
   * @inheritDoc
   */
  public Graph graphQuery(final String theQuery) throws QueryException {
    assertConnected();

    HttpResource aRes = new HttpResourceImpl(mURL);

    ParameterList aParams = new ParameterList()
        .add(PARAM_QUERY, theQuery);

    Request aQueryRequest;
    Response aResponse = null;
    try {

      if (mUseGetForQueries) {
        aQueryRequest = aRes.initGet()
            .addHeader(HttpHeaders.Accept.getName(), RDFFormat.TURTLE.getDefaultMIMEType())
            .setParameters(aParams);
      }
      else {
        aQueryRequest = aRes.initPost()
            .addHeader(HttpHeaders.ContentType.getName(), MimeTypes.FormUrlEncoded.getMimeType())
            .addHeader(HttpHeaders.Accept.getName(), RDFFormat.TURTLE.getDefaultMIMEType())
            .setBody(aParams.getURLEncoded());
      }

      aResponse = aQueryRequest.execute();

      if (aResponse.hasErrorCode()) {
        throw responseToException(theQuery, aResponse);
      }
      else {
        try {
          return GraphIO.readGraph(aResponse.getContent(), RDFFormat.TURTLE);
        }
        catch (RDFParseException e) {
          throw new QueryException("Error while parsing rdf/xml-formatted query results", e);
        }
      }
    }
    catch (IOException e) {
      throw new QueryException(e);
    }
    finally {
      if (aResponse != null) {
        try {
          aResponse.close();
        }
        catch (IOException e) {
          System.err.println("There was an error while closing the http connection: " + e.getMessage());
        }
      }
    }
  }
}
TOP

Related Classes of com.clarkparsia.empire.ds.impl.SparqlEndpointDataSource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.