Package org.mmisw.ont.triplestore.allegro4

Source Code of org.mmisw.ont.triplestore.allegro4.Ag4TripleStore

/**
*
*/
package org.mmisw.ont.triplestore.allegro4;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.mmisw.ont.JenaUtil2;
import org.mmisw.ont.OntConfig;
import org.mmisw.ont.OntologyInfo;
import org.mmisw.ont.UnversionedConverter;
import org.mmisw.ont.admin.AdminDispatcher;
import org.mmisw.ont.client.util.HttpUtil;
import org.mmisw.ont.client.util.HttpUtil.HttpResponse;
import org.mmisw.ont.db.Db;
import org.mmisw.ont.mmiuri.MmiUri;
import org.mmisw.ont.sparql.QueryResult;
import org.mmisw.ont.triplestore.ITripleStore;
import org.mmisw.ont.triplestore.TsUtil;
import org.mmisw.ont.util.OntUtil;
import org.mmisw.ont.util.Util;
import org.openrdf.OpenRDFException;
import org.openrdf.repository.RepositoryException;

import com.franz.agraph.jena.AGGraph;
import com.franz.agraph.jena.AGGraphMaker;
import com.franz.agraph.jena.AGModel;
import com.franz.agraph.repository.AGCatalog;
import com.franz.agraph.repository.AGRepository;
import com.franz.agraph.repository.AGRepositoryConnection;
import com.franz.agraph.repository.AGServer;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;

/**
* Triple store implementation using AllegroGraph 4.
*
* @author Carlos Rueda
*/
public class Ag4TripleStore implements ITripleStore {

  private final Log log = LogFactory.getLog(Ag4TripleStore.class);

  private String serverHost;
  private int serverPort;
  // private String tripleStoreDir; AG4: Not needed
  private String tripleStoreName;
 
  private String username;
  private String password;
 
  private HttpUtil.Credentials credentials;

  private String tripleStoreUrl;

  private final Db db;
  private final AdminDispatcher adminDispatcher;

  private String aquaUploadsDir;

  /**
   * Connection. Usage idiom:
   *
   * <pre>
   *   _Conn _conn = new _Conn();
   *   try {
   *       ...
   *   }
   *   finally {
   *       _conn.end();
   *   }
   * </pre>
   */
  private class _Conn {
    /*
     * TODO AG4: not sure yet what of the following should strictly be
     * around
     */
    AGServer _server;
    AGCatalog _catalog;
    AGRepositoryConnection ags;
    AGGraphMaker _maker;
    AGGraph _graph;
    AGModel _model;

    // AllegroGraph ts;
    AGRepository ts;

    /** Open a connection using access */
    _Conn() throws ServletException {
      this(false);
    }

    /**
     * If renew is true, opens a connection using renew(), so the triple
     * store is recreated Otherwise, it uses access()
     */
    _Conn(boolean renew) throws ServletException {
      log.info("Connecting to triple store...");
      try {
        _server = new AGServer(serverHost + ":" + serverPort, username,
            password);
        _catalog = _server.getCatalog();
      }
      catch (Throwable e) {
        throw new ServletException(
            "Error connecting to triple store server.", e);
      }

      try {
        if (renew) {
          _catalog.deleteRepository(tripleStoreName);

        }
        ts = _catalog.createRepository(tripleStoreName);
        ags = ts.getConnection();
        _maker = new AGGraphMaker(ags);
        _graph = _maker.getGraph();
        _model = new AGModel(_graph);

      }
      catch (RepositoryException e) {
        throw new ServletException("Error accessing triple store.", e);
      }

      if (renew) {
        log.info("CONNECTION OPEN WITH renew");
      }
      else {
        log.info("CONNECTION OPEN");
      }

    }

    void end() throws ServletException {
      try {
        if (ts != null) {
          // ts.closeTripleStore();
          ts.close();
        }
        ts = null;
        if (ags != null) {
          // ags.disable();
          ags.close();
          ags = null;
        }
        log.info("CONNECTION CLOSED");
      }
      catch (RepositoryException e) {
        throw new ServletException("Unable to close triple store.", e);
      }
    }
  }

  /**
   * Constructor.
   *
   * @param db
   *            The database helper.
   */
  public Ag4TripleStore(Db db, AdminDispatcher adminDispatcher) {
    this.db = db;
    this.adminDispatcher = adminDispatcher;
    log.debug(getClass().getSimpleName() + " instance created.");
  }

  /**
   * Initializes some internal parameters from OntConfig and tests connection
   * with the allegroGraph server and opening the triple store.
   *
   * @throws ServletException
   */
  public void init() throws ServletException {
    log.info("init called.");

    serverHost = OntConfig.Prop.AGRAPH_HOST.getValue();
    serverPort = Integer.parseInt(OntConfig.Prop.AGRAPH_PORT.getValue());
    // tripleStoreDir = OntConfig.Prop.AGRAPH_TS_DIR.getValue(); AG4: Not
    // needed
    tripleStoreName = OntConfig.Prop.AGRAPH_TS_NAME.getValue();
    aquaUploadsDir = OntConfig.Prop.AQUAPORTAL_UPLOADS_DIRECTORY.getValue();
   
    username = OntConfig.Prop.AGRAPH_USERNAME.getValue();
    password = OntConfig.Prop.AGRAPH_PASSWORD.getValue();
   
    _setCredentials();

    tripleStoreUrl = serverHost + ":" + serverPort + "/repositories/"
        + tripleStoreName;

    // test that we can connect to the server
    _Conn _conn = new _Conn();
    try {
      // log.info("AllegroGraph Server version = "
      // +_conn.ags.getServerVersion());
      log.info("AllegroGraph Server version = "
          + _conn._server.getVersion());
      // String[] idxFlavors = _conn.ts.getIndexFlavors();
      List<String> idxFlavors = _conn.ags.listIndices();
      // log.info(" Index flavors = " +(idxFlavors == null ? "null" :
      // Arrays.asList(idxFlavors)));
      log.info(" Index flavors = "
          + (idxFlavors == null ? "null" : idxFlavors));

      // log.info(" unindexed threshold = "
      // +_conn.ts.getUnindexedThreshold());
      // log.info(" #unindexed triples = "
      // +_conn.ts.getUnindexedTripleCount());

      // log.info(" #triples = " +_conn.ts.numberOfTriples());
      log.info(" #triples = " + _conn.ags.size());
    }
    catch (RepositoryException e) {
      log.error("Error with AlegroGraph.", e);
      throw new ServletException("Error with AlegroGraph.", e);
    }
    catch (OpenRDFException e) {
      log.error("Error with AlegroGraph.", e);
      throw new ServletException("Error with AlegroGraph.", e);
    }
    finally {
      _conn.end();
    }

    log.info("init complete.");
  }

  /**
   * Sets the credentials object.
   */
  private void _setCredentials() {
    credentials = new HttpUtil.Credentials();
    try {
      // serverHost is expected to include a protocol; get the
      // host for the credential via a URL:
      credentials.host = new URL(serverHost).getHost();
    }
    catch (MalformedURLException e) {
      // should not happen
      log.warn("Parsing of URL failed for serverHost: " + serverHost, e);
      credentials.host = serverHost;
    }
    credentials.port = serverPort;
    credentials.username = username;
    credentials.password = password;
    log.info("Credentials set to: " + credentials);
  }

  /** nothing done here */
  public void destroy() throws ServletException {
    // nothing
  }

  /**
   * Does nothing -- no need to reindex in AG4
   */
  public void reindex(boolean wait) throws ServletException {
    log.info("reindex( " + wait
        + ") called but ignored -- not needed in AG 4.");
  }

  /**
   * Reinitializes the triple store.
   *
   * @throws ServletException
   */
  public void reinit() throws ServletException {
    log.info("reinit called.");
    log.info("Creating connection to triple store ...");
    _Conn _conn = new _Conn();
    try {
      // populate the triple store:
      long start = System.currentTimeMillis();
      long numberOfTriples = _doReInit(_conn);
      log.debug("triple store populated (" + TsUtil.elapsedTime(start)
          + ").  " + "#triples= " + numberOfTriples);
    }
    finally {
      _conn.end();
    }
  }

  /**
   * Clears the triple store.
   *
   * @throws ServletException
   */
  public void clear() throws ServletException {
    log.info("clear called. Creating connection with call to renew() on triple store ...");
    _Conn _conn = new _Conn(true);
    try {
      log.debug("clear done.  #triples= " + _conn.ags.size());
    }
    catch (RepositoryException e) {
      log.error("Error clearing triple store", e);
      throw new ServletException("Error clearing triple store", e);
    }
    finally {
      _conn.end();
    }
  }

  /**
   * Re-Inits the triple store. This starts by calling {@link #clear()} and
   * then re-loading all the ontologies.
   *
   * @return number of triples. -1 if some error happens while obtaining this
   *         number.
   * @throws ServletException
   */
  private long _doReInit(_Conn _conn) throws ServletException {

    clear();

    // get the list of (latest-version) ontologies:
    final boolean allVersions = false;
    List<OntologyInfo> onts = db.getAllOntologies(allVersions);

    if (log.isDebugEnabled()) {
      log.debug("Using unversioned ontologies: " + USE_UNVERSIONED);
      log.debug("About to load the following " + onts.size()
          + " ontologies: ");
      for (OntologyInfo ontology : onts) {
        log.debug(ontology.getOntologyId() + " :: "
                + ontology.getUri());
      }
    }

    for (OntologyInfo ontology : onts) {
      String full_path = aquaUploadsDir + "/" + ontology.getFilePath()
          + "/" + ontology.getFilename();
      log.info("Loading: " + full_path + " in graph");
      try {
        // NOTE: the graphId here is null; the graph relationships are
        // added below.
        String graphId = null;

        boolean clearGraphFirst = false; // the triple store starts
        // empty; see above

        _loadOntology(_conn, ontology, graphId, full_path,
            clearGraphFirst);
      }
      catch (Throwable ex) {
        log.error("Error loading ontology: " + full_path
            + " (continuing..)", ex);
      }
    }

    // statements for inferencing:
    _loadSupportingStatements(_conn);

    // load internal resources (graph relationships, etc.):
    _loadInternalResources(_conn);

    long numberOfTriples = -1;
    try {
      // numberOfTriples = _conn.ts.numberOfTriples();
      numberOfTriples = _conn.ags.size();
    }
    catch (RepositoryException e) {
      log.error("Error getting number of triples", e);
      // but continue.
    }
    return numberOfTriples;
  }

  /**
   * load supporting statements for inference
   */
  private void _loadSupportingStatements(_Conn _conn) {
    log.info("Loading supporting statements to allegrograph triplestore");
      for (Entry<String, String> ns : adminDispatcher.getSupportingNamespaces().entrySet()) {
        try {
          _conn.ags.setNamespace(ns.getKey(), ns.getValue());
          log.info("namespace registered: " + ns.getKey() + " : "
              + ns.getValue());
        }
        catch (RepositoryException e) {
          log.error("Error adding namespace.", e);
        }
      }

      for (String[] statement : AgSupport.SUPPORTING_STATEMENTS) {
        Resource s = _conn._model.createResource(statement[0]);
        Property p = _conn._model.createProperty(statement[1]);
        Resource o = _conn._model.createResource(statement[2]);
        _conn._model.add(s, p, o);
        log.info("statement added: " + statement[0] + " "
            + statement[1] + " " + statement[2]);
      }
  }

  /**
   * load internal resources (graphs, etc) in the triple store.
   */
  private void _loadInternalResources(_Conn _conn) {
    log.info("_loadInternalResources called.");
   
     List<Statement> statements = adminDispatcher.getInternalStatements();
   
//     OLD
//     // then, update the triple store with the corresponding statements:
//     if ( statements != null ) {
//       for (Statement stmt : statements) {
//         String sbj = stmt.getSubject().getURI();
//         String prd = stmt.getPredicate().getURI();
//         String obj = ((Resource) stmt.getObject()).getURI();
//
//         sbj = '<' + sbj + '>';
//         prd = '<' + prd + '>';
//         obj = '<' + obj + '>';
//
//         _conn.ts.addStatement(sbj, prd, obj);
//         log.info("Added statement: " +stmt);
//       }
//     }
   
     // New AG4:
     _conn._model.add(statements);
    
  }

  public void loadOntology(OntologyInfo ontology, String graphId)
      throws Exception {
    _Conn _conn = new _Conn();
    try {
      String full_path = aquaUploadsDir + "/" + ontology.getFilePath()
          + "/" + ontology.getFilename();
      log.info("Loading: " + full_path + " in graph: "
          + (graphId == null ? "(default graph)" : graphId));
      boolean clearGraphFirst = true;
      _loadOntology(_conn, ontology, graphId, full_path, clearGraphFirst);

      // launch indexing of new triples in the background and return:
      // NO: indexing not needed in AG 4
      // boolean wait = false;
      // _conn.ts.indexNewTriples(wait);
    }
    finally {
      _conn.end();
    }

  }

  /**
   * Loads an ontology to the given graph.
   *
   * @param _conn
   * @param ontology
   * @param graphId
   *            User-specified graph. Can be null.
   * @param full_path
   * @param clearGraphFirst
   *            true to remove all statements associated with the graph
   *            directly associated with the ontology.
   */
  private void _loadOntology(_Conn _conn, OntologyInfo ontology,
      String graphId, String full_path, boolean clearGraphFirst) {

    String graphUri;

    String ontologyUri = ontology.getUri();
    OntModel model;
//    String serialization;   Not used in the AG4 impl

    if (USE_UNVERSIONED) {
      model = JenaUtil2.loadModel("file:" + full_path, false);

      if (OntUtil.isOntResolvableUri(ontologyUri)) {
        MmiUri mmiUri;
        try {
          mmiUri = new MmiUri(ontologyUri);
          OntModel unversionedModel = UnversionedConverter
              .getUnversionedModel(model, mmiUri);

//          serialization = JenaUtil2.getOntModelAsString(
//              unversionedModel, "RDF/XML-ABBREV");
         
          // AG$: we don;t use the serialization; but here we need to update
          // the model reference to be unversionedModel:
          model = unversionedModel;

          ontologyUri = mmiUri.copyWithVersion(null).getOntologyUri();
        }
        catch (URISyntaxException e) {
          log.error("shouldn't happen", e);
          return;
        }
        log.info("To load Ont-resolvable ontology in graph.");
      }
      else {
//        serialization = JenaUtil2.getOntModelAsString(model,
//            "RDF/XML-ABBREV");
        log.info("To load re-hosted ontology in graph.");
      }
    }
    else {
      model = JenaUtil2.loadModel("file:" + full_path, false);
//      serialization = JenaUtil2.getOntModelAsString(model,
//          "RDF/XML-ABBREV");
    }

    // /////////////////////////////////////////////////////////////
    // now, update graph with model captured in serialization
    // /////////////////////////////////////////////////////////////

    try {
      // 'ownGraph' is the graph for the ontology itself.
      // All the statements in the ontology are associated with this
      // graph.
      final String ownGraph = "<" + ontologyUri + ">";

      if (clearGraphFirst) {
        // remove all statements associated with the graph:
        if (log.isDebugEnabled()) {
          log.debug("Removing all statements in graph " + ownGraph
              + " ...");
        }
        // OLD AG3: _conn.ts.removeStatements(null, null, null, ownGraph);
        // New AG4:
        _removeStatementsFromDefaultGraph(ownGraph);
        _clearGraph(ownGraph);
      }

      // now, create the new graph:
      // OLD AG3: AgUtil.parseWithTiming(_conn.ts, true, serialization,
      // ownGraph);
      _addModelToGraph(_conn, model, ontologyUri);

      // add the graph statement to the graphs resource:
      String ownGraphUri = adminDispatcher
          .getWellFormedGraphUri(ownGraph);
      adminDispatcher.newGraph(ownGraphUri);

      // now, add the subGraphOf relationship if graphId != null
      if (graphId != null) {
        graphUri = adminDispatcher.getWellFormedGraphUri(graphId);
        _addSubGraph(_conn, ownGraphUri, graphUri);
      }

    }
    catch (Exception e) {
      log.error("Error parsing/loading RDF in graph.", e);
    }

  }

  /**
   * Updates the graphs resource and then the triple store.
   *
   * @param _conn
   * @param subGraphUri
   *            Assumed to be well-formed
   * @param superGraphUri
   *            Assumed to be well-formed
   * @throws AllegroGraphException
   */
  private void _addSubGraph(_Conn _conn, String subGraphUri,
      String superGraphUri)  {

    // first, update the graphs resource:
    List<Statement> statements = adminDispatcher.newSubGraph(subGraphUri,
        superGraphUri);

    // then, update the triple store with the corresponding statements:
    if (statements != null) {
      // OLD AG3 way:
      // for (Statement stmt : statements) {
      // String sbj = stmt.getSubject().getURI();
      // String prd = stmt.getPredicate().getURI();
      // String obj = ((Resource) stmt.getObject()).getURI();
      // 
      // sbj = '<' + sbj + '>';
      // prd = '<' + prd + '>';
      // obj = '<' + obj + '>';
      //       
      // _conn.ts.addStatement(sbj, prd, obj);
      // log.info("Added statement: " +stmt);
      // }
     
      // New AG4:
      _conn._model.add(statements);
      log.info("Added statements: " + statements.size());
    }
  }

  public void removeOntology(OntologyInfo ontology) throws Exception {
    _Conn _conn = new _Conn();
    try {
      log.info("Removing: id=" + ontology.getId() + " of ontologyId="
          + ontology.getOntologyId() + " ...");
      _removeOntology(_conn, ontology);
    }
    finally {
      _conn.end();
    }

  }

  /**
   * i) removes all statements associated with the "proper" graph (ie., the
   * graph whose URI is the same as the ontology URI);
   * <p>
   * If the ontology URI will be completely gone (ie., no previous version is
   * available), then:
   * <p>
   * ii) removes all statements having the "proper" graph as subject (in
   * particular, subGraphOf relationships and the typeOf-graph statement will
   * be removed).
   *
   * @param _conn
   * @param ontology
   * @throws Exception
   *
   */
  private void _removeOntology(_Conn _conn, OntologyInfo ontology)
      throws Exception {

    String ontologyUri = ontology.getUri();

    if (USE_UNVERSIONED) {

      if (OntUtil.isOntResolvableUri(ontologyUri)) {
        MmiUri mmiUri;
        try {
          mmiUri = new MmiUri(ontologyUri);
          ontologyUri = mmiUri.copyWithVersion(null).getOntologyUri();
        }
        catch (URISyntaxException e) {
          log.error("shouldn't happen", e);
          return;
        }
        log
            .debug("About to remove Ont-resolvable ontology from graph.");
      }
      else {
        log.debug("About to remove re-hosted ontology from graph.");
      }
    }
    // Else: nothing -- just keep the given ontologyUri.

    // now, update graph:

    // this is the graph for the ontology itself.
    // All the statements in the ontology are associated with this graph.
    String ownGraph = "<" + ontologyUri + ">";

    try {
      ////////////////////////////////////////////////////////////////////
      // //
      // i) first, remove all statements associated with the ownGraph:
      //
      if (log.isDebugEnabled()) {
        log.debug("Removing all statements in graph " + ownGraph
            + " ...");
      }
      // OLD AG3: _conn.ts.removeStatements(null, null, null, ownGraph);
     
      // New AG4:
      _removeStatementsFromDefaultGraph(ownGraph);
      _clearGraph(ownGraph);
    }
    catch (Exception e) {
      log.error("Error removing ontology statements from graph.", e);
      return;
    }

    // if any, get latest version that may remain:
    OntologyInfo latestOntology = null;
    try {
      latestOntology = db.getRegisteredOntologyLatestVersion(ontologyUri);
    }
    catch (ServletException e) {
      log
          .warn(
              "Warning: error while trying to retrieve existing version of ontology. Ignoring error.",
              e);
    }

    if (latestOntology != null) {
      /*
       * there still is an existing ontology version.
       * Existing subGraphOf statements will remain valid.
       * Just load the found latest ontology:
       */
      log.debug("_removeOntology: Loading latestOntology after removal");
      loadOntology(latestOntology, null);

      return;
    }

    // here: ontologyUri completely gone.

    // ////////////////////////////////////////////////////////////////////
    // ii) So, remove all statements having ownGraph as subject (in
    // particular,
    // subGraphOf relationships and the typeOf-graph statement will be
    // removed):
    //
    String ownGraphUri = adminDispatcher.getWellFormedGraphUri(ownGraph);
    _removeAllStatementsForSubject(_conn, ownGraphUri);

  }

  /**
   * Removes all statements for a given subject. Updates the graphs resource
   * and then the triple store.
   *
   * @param _conn
   * @param subGraphUri
   *            Assumed to be well-formed
   * @throws Exception
   */
  private void _removeAllStatementsForSubject(_Conn _conn, String subGraphUri)
      throws Exception {

    log.debug("_removeAllStatementsForSubject: " + subGraphUri);

    // remove the statements from the graphs resource:
    adminDispatcher.removeAllStatementsFromSubject(subGraphUri);

    // then, update the triple store by removing corresponding statements:
    // OLD AG3: _conn.ts.removeStatements("<" + subGraphUri + ">", null, null);
    // New AG4:
    String subj = "<" + subGraphUri + ">";
    _doUpdate(
        "delete { " + subj + " ?p ?o .} " +
        "where  { " + subj + " ?p ?o .}"
    );

  }

  /**
   * Executes a SPARQL query.
   *
   * @param sparqlQuery
   * @param infer With inference?
   * @param form
   *            Only used for a "select" query.
   * @return
   * @throws Exception
   */
  public QueryResult executeQuery(String query, boolean infer, String form) throws Exception {

    final QueryResult queryResult = new QueryResult();

    /*
     * Make the request to the AllegroGraph HTTP endpoint.
     */
    query = URLEncoder.encode(query, "UTF-8");
    String urlRequest = tripleStoreUrl + "?infer=" +infer+ "&query=" + query;
    String accept = AgUtil.mimeType(form);
    if (log.isDebugEnabled()) {
      log.debug("Making http get request: " +urlRequest+ " Accept: " +accept);
    }
    HttpResponse httpResponse = HttpUtil.httpGet(urlRequest, accept);
        if (log.isDebugEnabled()) {
            log.debug(_debugHttpResponse(httpResponse));
        }

        /*
         * Fix 300:No suitable response format available.
         * If error returned is 406 Not Acceptable, retry with "application/rdf+xml".
         * If this also fails then retry with "text/plain".
         */
        if ( 406 == httpResponse.statusCode ) {
        accept = "application/rdf+xml";
        if (log.isDebugEnabled()) {
          log.debug("Got 406 Not Acceptable. Trying with Accept: " + accept + " Request: " +urlRequest);
        }
        httpResponse = HttpUtil.httpGet(urlRequest, accept);
            if (log.isDebugEnabled()) {
                log.debug(_debugHttpResponse(httpResponse));
            }

            /*
             * 406 Not Acceptable got again?
             * Then, just retry with "text/plain":
             */
            if ( 406 == httpResponse.statusCode ) {
            accept = "text/plain";
            if (log.isDebugEnabled()) {
              log.debug("Got 406 Not Acceptable. Trying with Accept: " + accept + " Request: " +urlRequest);
            }
            httpResponse = HttpUtil.httpGet(urlRequest, accept);
                if (log.isDebugEnabled()) {
                    log.debug(_debugHttpResponse(httpResponse));
                }
            }
        }

        /*
         * Note that AgUtil.mimeType returns a CSV format for form="html"
         * The following checks that case to convert the returned CSV into HTML.
         * (the regex is for application/processed-csv and text/csv)
         */
        if ("html".equals(form) && accept.matches(".*\\Wcsv$")
    && httpResponse.statusCode == HttpServletResponse.SC_OK ) {
      String html = Util.csv2html(httpResponse.body);
      queryResult.setResult(html);
      queryResult.setContentType("text/html");
    }
    else {
      queryResult.setResult(httpResponse.body);
      queryResult.setContentType(httpResponse.contentType);
    }

    return queryResult;
  }
 
  private static String _debugHttpResponse(HttpResponse httpResponse) {
        String body = httpResponse.body;
        if (body.length() > 300) {
                body = body.substring(0, 256) + " ... " + body.substring(body.length() - 44);
        }
        return "httpResponse: statusCode: " +httpResponse.statusCode+ "\n" +
                  "statusLine: " +httpResponse.statusLine+ "\n" +
                  "contentType: " +httpResponse.contentType+ "\n" +
                  "body: " +body+ "\n"
        ;
  }

  /**
   * Adds the statements in an OntModel to a graph in the triple store.
   *
   * @param _conn
   * @param ontologyUri
   *            Graph URI
   * @param model
   *            Model containing the statements.
   */
  private void _addModelToGraph(_Conn _conn, OntModel model,
      String ontologyUri) {
    AGGraph agGraph = _conn._maker.createGraph(ontologyUri);
    AGModel agModel = new AGModel(agGraph);
    agModel.add(model);

    // finally, add the new stuff into the triple store:
    _conn._model.add(agModel);
  }

  /**
   * Removes all statements in the given graph from the default graph.
   *
   * @param graph The graph whose statements are to be removed from the default graph.
   */
  private void _removeStatementsFromDefaultGraph(String graph) throws Exception {
        /*
         * first, get the statements in the given graph:
         */
        String query = "select ?s ?p ?o" +
                        " from " + graph +
                        " where { ?s ?p ?o }";
        if ( log.isDebugEnabled() ) {
                log.debug("Executing query to get statements in graph: " + query);
        }
        QueryResult qr = executeQuery(query, false, "json");
        String result = qr.getResult();

        /*
         * remove them from the default graph: Use a "delete data" statement, which
         * requires explicit triples (no template or variables):
         */
        JSONTokener jsonParser = new JSONTokener(result);
        JSONObject jsonObj = new JSONObject(jsonParser);
//      JSONArray names = jsonObj.getJSONArray("names");
        JSONArray values = jsonObj.getJSONArray("values");
        if ( values.length() > 0 ) {
            if ( log.isDebugEnabled() ) {
                log.debug("Preparing query to delete " +values.length() + " triples from default graph");
            }
          StringBuffer sb = new StringBuffer("delete data {\n");
          for (int i = 0; i < values.length(); i++ ) {
                  JSONArray t = (JSONArray) values.get(i);
                  sb.append(t.get(0).toString() + " " + t.get(1) + " " + t.get(2) + " . \n");
          }
          sb.append("}");
          String delQuery = sb.toString();
          _doUpdate(delQuery);
        }
        else {
            if ( log.isDebugEnabled() ) {
                log.debug("No statements in graph: " + graph);
            }
        }
  }

  /**
   * Clears the given graph, ie., removes all associated statements from the given graph.
   */
  private void _clearGraph(String graph) throws Exception {
    _doUpdate("clear graph " + graph);
  }
 
  /**
   * Makes a SPARL Update request.
   *
   * @param update
   * @throws Exception
   */
  private void _doUpdate(String update) throws Exception {
    if (log.isDebugEnabled()) {
      String mu = update;
      if (update.length() > 300) {
        mu = mu.subSequence(0, 128) + " ... " + mu.substring(update.length() - 100);
      }
      log.debug("update: " + mu);
    }

    final String encUpdate = URLEncoder.encode(update, "UTF-8");

    Map<String, String> vars = new HashMap<String, String>();
    vars.put("update", encUpdate);

    String urlRequest = tripleStoreUrl + "?update=" + encUpdate;

    if (log.isDebugEnabled()) {
      log.debug("_doUpdate: Making request...");
    }
    HttpResponse httpResponse = HttpUtil.httpPost(credentials, urlRequest, vars);
    if (log.isDebugEnabled()) {
      log.debug("_doUpdate: httpResponse = " + httpResponse);
    }
  }

}
TOP

Related Classes of org.mmisw.ont.triplestore.allegro4.Ag4TripleStore

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.