Package virtuoso.sesame2.driver

Source Code of virtuoso.sesame2.driver.VirtuosoRepositoryConnection

/*
*  $Id$
*
*  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
*  project.
*
*  Copyright (C) 1998-2014 OpenLink Software
*
*  This project is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; only version 2 of the License, dated June 1991.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License along
*  with this program; if not, write to the Free Software Foundation, Inc.,
*  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

package virtuoso.sesame2.driver;

import info.aduna.iteration.CloseableIteration;
import info.aduna.iteration.CloseableIteratorIteration;
import info.aduna.iteration.Iteration;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Array;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.NoSuchElementException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Set;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import org.openrdf.OpenRDFUtil;
import org.openrdf.model.BNode;
import org.openrdf.model.Graph;
import org.openrdf.model.Literal;
import org.openrdf.model.Namespace;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.ContextStatementImpl;
import org.openrdf.model.impl.NamespaceImpl;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.query.Dataset;
import org.openrdf.query.BindingSet;
import org.openrdf.query.BooleanQuery;
import org.openrdf.query.GraphQuery;
import org.openrdf.query.GraphQueryResult;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.Query;
import org.openrdf.query.Update;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.query.TupleQueryResultHandler;
import org.openrdf.query.TupleQueryResultHandlerException;
import org.openrdf.query.algebra.evaluation.QueryBindingSet;
import org.openrdf.query.impl.GraphQueryResultImpl;
import org.openrdf.query.impl.TupleQueryResultImpl;
import org.openrdf.query.UnsupportedQueryLanguageException;
import org.openrdf.query.UpdateExecutionException;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.openrdf.repository.UnknownTransactionStateException;
import org.openrdf.rio.ParserConfig;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFHandler;
import org.openrdf.rio.RDFHandlerException;
import org.openrdf.rio.RDFParseException;
import org.openrdf.rio.RDFParser;
import org.openrdf.rio.Rio;
import org.openrdf.rio.helpers.RDFHandlerBase;
import org.openrdf.rio.helpers.ParseErrorLogger;
import org.openrdf.rio.n3.N3ParserFactory;
import org.openrdf.rio.ntriples.NTriplesParserFactory;
import org.openrdf.rio.rdfxml.RDFXMLParserFactory;
import org.openrdf.rio.trig.TriGParserFactory;
import org.openrdf.rio.trix.TriXParserFactory;
import org.openrdf.rio.turtle.TurtleParserFactory;

import virtuoso.sql.ExtendedString;
import virtuoso.sql.RdfBox;
import virtuoso.jdbc4.VirtuosoDate;
import virtuoso.jdbc4.VirtuosoTime;
import virtuoso.jdbc4.VirtuosoTimestamp;


/**
* Main interface for updating data in and performing queries on a Sesame
* repository. By default, a RepositoryConnection is in autoCommit mode, meaning
* that each operation corresponds to a single transaction on the underlying
* store. autoCommit can be switched off in which case it is up to the user to
* handle transaction commit/rollback. Note that care should be taking to always
* properly close a RepositoryConnection after one is finished with it, to free
* up resources and avoid unnecessary locks.
* <p>
* Several methods take a vararg argument that optionally specifies a (set of)
* context(s) on which the method should operate. Note that a vararg parameter
* is optional, it can be completely left out of the method call, in which case
* a method either operates on a provided statements context (if one of the
* method parameters is a statement or collection of statements), or operates on
* the repository as a whole, completely ignoring context. A vararg argument may
* also be 'null' (cast to Resource) meaning that the method operates on those
* statements which have no associated context only.
* <p>
* Examples:
*
* <pre>
* // Ex 1: this method retrieves all statements that appear in either context1 or context2, or both.
* RepositoryConnection.getStatements(null, null, null, true, context1, context2);
*
* // Ex 2: this method retrieves all statements that appear in the repository (regardless of context).
* RepositoryConnection.getStatements(null, null, null, true);
*
* // Ex 3: this method retrieves all statements that have no associated context in the repository.
* // Observe that this is not equivalent to the previous method call.
* RepositoryConnection.getStatements(null, null, null, true, (Resource)null);
*
* // Ex 4: this method adds a statement to the store. If the statement object itself has
* // a context (i.e. statement.getContext() != null) the statement is added to that context. Otherwise,
* // it is added without any associated context.
* RepositoryConnection.add(statement);
*
* // Ex 5: this method adds a statement to context1 in the store. It completely ignores any
* // context the statement itself has.
* RepositoryConnection.add(statement, context1);
* </pre>
*
*/
public class VirtuosoRepositoryConnection implements RepositoryConnection {
  private static Resource nilContext;
  private Connection quadStoreConnection;
  protected VirtuosoRepository repository;
        static final String S_DELETE = "sparql delete from graph iri(??) {`iri(??)` `iri(??)` `bif:__rdf_long_from_batch_params(??,??,??)`}";
        static final String S_BATCH_INSERT = "DB.DBA.rdf_insert_triple_c (?,?,?,?,?,?)";
        static final String S_CLEAR_GRAPH = "DB.DBA.rdf_clear_graphs_c (?)";

        static final int MAX_CMD_SIZE = 36000;

  private int BATCH_SIZE = 5000;
  private PreparedStatement psInsert;
  private int psInsertCount = 0;
  private boolean useLazyAdd = false;
  private int prefetchSize = 200;
  private boolean useReprepare = true;

  private volatile ParserConfig parserConfig = new ParserConfig();


  public VirtuosoRepositoryConnection(VirtuosoRepository repository, Connection connection) throws RepositoryException {
    this.quadStoreConnection = connection;
    this.repository = repository;
    this.useLazyAdd = repository.useLazyAdd;
    this.prefetchSize = repository.prefetchSize;
    this.BATCH_SIZE = repository.batchSize;
    this.nilContext = new ValueFactoryImpl().createURI(repository.defGraph);
    this.repository.initialize();

    try {
      virtuoso.jdbc4.Driver drv = new virtuoso.jdbc4.Driver();
      if (drv.getMajorVersion()>=3 && drv.getMinorVersion()>=72)
        useReprepare = false;
    } catch(Exception e) {}
  }

  /**
   * Returns the Repository object to which this connection belongs.
   */
  public Repository getRepository() {
    return repository;
  }


  /**
   * Set the parser configuration this connection should use for
   * RDFParser-based operations.
   *
   * @param config
   *        a Rio RDF Parser configuration.
   */
  public void setParserConfig(ParserConfig config)
  {
    this.parserConfig = parserConfig;
  }

  /**
   * Returns the parser configuration this connection uses for Rio-based
   * operations.
   *
   * @return a Rio RDF parser configuration.
   */
  public ParserConfig getParserConfig()
  {
    return parserConfig;
  }
 
  /**
   * Gets a ValueFactory for this RepositoryConnection.
   *
   * @return A repository-specific ValueFactory.
   */
  public ValueFactory getValueFactory() {
    return repository.getValueFactory();
        }

  /**
   * Checks whether this connection is open. A connection is open from the moment it is created until it is closed.
   *
   * @see #close()
   */
  public boolean isOpen() throws RepositoryException {
    try {
      return !this.getQuadStoreConnection().isClosed();
    }
    catch (SQLException e) {
      throw new RepositoryException("Problem inspecting connection", e);
    }
  }

  /**
   * Closes the connection, freeing resources. If the connection is not in
   * autoCommit mode, all non-committed operations will be lost.
   *
   * @throws RepositoryException
   *         If the connection could not be closed.
   */
  public void close() throws RepositoryException {
    dropDelayAdd();
    try {
      if (!getQuadStoreConnection().isClosed()) {
        getQuadStoreConnection().close();
      }
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }

  /**
   * Prepares a query for evaluation on this repository (optional operation).
   * In case the query contains relative URIs that need to be resolved against
   * an external base URI, one should use
   * {@link #prepareQuery(QueryLanguage, String, String)} instead.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @return A query ready to be evaluated on this repository.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   * @throws UnsupportedOperationException
   *         If the <tt>prepareQuery</tt> method is not supported by this
   *         repository.
   */
  public Query prepareQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException {
    return prepareQuery(language, query, null);
  }

  /**
   * Prepares a query for evaluation on this repository (optional operation).
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the query
   *        against, can be <tt>null</tt> if the query does not contain any
   *        relative URIs.
   * @return A query ready to be evaluated on this repository.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   * @throws UnsupportedOperationException
   *         If the <tt>prepareQuery</tt> method is not supported by this
   *         repository.
   */
  public Query prepareQuery(QueryLanguage language, String query, String baseURI) throws RepositoryException, MalformedQueryException {
   
    if (language != QueryLanguage.SPARQL)
      throw new UnsupportedQueryLanguageException(" : Only SPARQL queries are supported");

    StringTokenizer st = new StringTokenizer(query);
    String type = null;

    while(st.hasMoreTokens()) {
      type = st.nextToken().toLowerCase();
      if (type.equals("select"))
          break;
      else if(type.equals("construct") || type.equals("describe"))
          break;
      else if(type.equals("ask"))
          break;
    }

    flushDelayAdd();
    if(type.equals("select"))
      return prepareTupleQuery(language, query, baseURI);
    else if(type.equals("construct") || type.equals("describe"))
      return prepareGraphQuery(language, query, baseURI);
    else if(type.equals("ask"))
      return prepareBooleanQuery(language, query, baseURI);
    else
      return new VirtuosoQuery();
  }

  /**
   * Prepares a query that produces sets of value tuples. In case the query
   * contains relative URIs that need to be resolved against an external base
   * URI, one should use
   * {@link #prepareTupleQuery(QueryLanguage, String, String)} instead.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @throws IllegalArgumentException
   *         If the supplied query is not a tuple query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public TupleQuery prepareTupleQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException {
    return prepareTupleQuery(language, query, null);
  }

  /**
   * Prepares a query that produces sets of value tuples.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the query
   *        against, can be <tt>null</tt> if the query does not contain any
   *        relative URIs.
   * @throws IllegalArgumentException
   *         If the supplied query is not a tuple query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public TupleQuery prepareTupleQuery(QueryLanguage language, final String query, String baseeURI) throws RepositoryException, MalformedQueryException {

    if (language != QueryLanguage.SPARQL)
      throw new UnsupportedQueryLanguageException(" : Only SPARQL queries are supported");

    TupleQuery q = new VirtuosoTupleQuery() {
      public TupleQueryResult evaluate() throws QueryEvaluationException {
        return executeSPARQLForTupleResult(query, getDataset(), getIncludeInferred(), getBindings());
      }

      public void evaluate(TupleQueryResultHandler handler) throws QueryEvaluationException, TupleQueryResultHandlerException {
        executeSPARQLForHandler(handler, query, getDataset(), getIncludeInferred(), getBindings());
      }
    };
    return q;
  }

  /**
   * Prepares queries that produce RDF graphs. In case the query contains
   * relative URIs that need to be resolved against an external base URI, one
   * should use {@link #prepareGraphQuery(QueryLanguage, String, String)}
   * instead.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @throws IllegalArgumentException
   *         If the supplied query is not a graph query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public GraphQuery prepareGraphQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException {
    return prepareGraphQuery(language, query, null);
  }

  /**
   * Prepares queries that produce RDF graphs.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the query
   *        against, can be <tt>null</tt> if the query does not contain any
   *        relative URIs.
   * @throws IllegalArgumentException
   *         If the supplied query is not a graph query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public GraphQuery prepareGraphQuery(QueryLanguage language, final String query, String baseURI) throws RepositoryException, MalformedQueryException {

    if (language != QueryLanguage.SPARQL)
      throw new UnsupportedQueryLanguageException(" : Only SPARQL queries are supported");

    GraphQuery q = new VirtuosoGraphQuery() {
      public GraphQueryResult evaluate() throws QueryEvaluationException {
        return executeSPARQLForGraphResult(query, getDataset(), getIncludeInferred(), getBindings());
      }

      public void evaluate(RDFHandler handler) throws QueryEvaluationException, RDFHandlerException {
        executeSPARQLForHandler(handler, query, getDataset(), getIncludeInferred(), getBindings());
      }
    };
    return q;
  }

  /**
   * Prepares <tt>true</tt>/<tt>false</tt> queries. In case the query
   * contains relative URIs that need to be resolved against an external base
   * URI, one should use
   * {@link #prepareBooleanQuery(QueryLanguage, String, String)} instead.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @throws IllegalArgumentException
   *         If the supplied query is not a boolean query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public BooleanQuery prepareBooleanQuery(QueryLanguage language, String query) throws RepositoryException, MalformedQueryException {
    return prepareBooleanQuery(language, query, null);
  }

  /**
   * Prepares <tt>true</tt>/<tt>false</tt> queries.
   *
   * @param ql
   *        The query language in which the query is formulated.
   * @param query
   *        The query string.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the query
   *        against, can be <tt>null</tt> if the query does not contain any
   *        relative URIs.
   * @throws IllegalArgumentException
   *         If the supplied query is not a boolean query.
   * @throws MalformedQueryException
   *         If the supplied query is malformed.
   * @throws UnsupportedQueryLanguageException
   *         If the supplied query language is not supported.
   */
  public BooleanQuery prepareBooleanQuery(QueryLanguage language, final String query, String baseURI) throws RepositoryException, MalformedQueryException {

    if (language != QueryLanguage.SPARQL)
      throw new UnsupportedQueryLanguageException(" : Only SPARQL queries are supported");

    BooleanQuery q = new VirtuosoBooleanQuery() {
      public boolean evaluate() throws QueryEvaluationException {
        return executeSPARQLForBooleanResult(query, getDataset(), getIncludeInferred(), getBindings());
      }
    };
    return q;
  }

  public Update prepareUpdate(QueryLanguage language, String update) throws RepositoryException, MalformedQueryException
  {
          return prepareUpdate(language, update, null);
  }

  public Update prepareUpdate(QueryLanguage language, final String update, String baseURI) throws RepositoryException, MalformedQueryException
  {
    if (language != QueryLanguage.SPARQL)
      throw new UnsupportedQueryLanguageException(" : Only SPARQL queries are supported");

    Update u = new VirtuosoUpdate() {
      public void execute() throws UpdateExecutionException {
        executeSPARUL(update, getDataset(), getIncludeInferred(), getBindings());
      }
    };
    return u;
  }

 
  /**
   * Gets all resources that are used as content identifiers. Care should be
   * taken that the returned {@link RepositoryResult} is closed to free any
   * resources that it keeps hold of.
   *
   * @return a RepositoryResult object containing Resources that are used as
   *         context identifiers.
   */
  public RepositoryResult<Resource> getContextIDs() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    Vector<Resource> v = new Vector<Resource>();
    String query = "DB.DBA.SPARQL_SELECT_KNOWN_GRAPHS()";
    try {
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(query);

      // begin at onset one
      while (rs.next()) {
        Object obj = rs.getObject(1);
        try {
          Value graphId = castValue(obj);
          // add that graph to the results
          v.add((Resource)graphId);
        }
        catch (IllegalArgumentException iiaex) {
          throw new RepositoryException("VirtuosoRepositoryConnection.getContextIDs() Non-URI context encountered: " + obj);
        }
      }
      rs.close();
      stmt.close();

    }
    catch (Exception e) {
      throw new RepositoryException(": SPARQL execute failed." + "\n" + query.toString(), e);
    }
    return createRepositoryResult(v);
  }

  /**
   * Gets all statements with a specific subject, predicate and/or object from
   * the repository. The result is optionally restricted to the specified set
   * of named contexts.
   *
   * @param subj
   *        A Resource specifying the subject, or <tt>null</tt> for a
   *        wildcard.
   * @param pred
   *        A URI specifying the predicate, or <tt>null</tt> for a wildcard.
   * @param obj
   *        A Value specifying the object, or <tt>null</tt> for a wildcard.
   * @param contexts
   *        The context(s) to get the data from. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @param includeInferred
   *        if false, no inferred statements are returned; if true, inferred
   *        statements are returned if available. The default is true.
   * @return The statements matching the specified pattern. The result object
   *         is a {@link RepositoryResult} object, a lazy Iterator-like object
   *         containing {@link Statement}s and optionally throwing a
   *         {@link RepositoryException} when an error when a problem occurs
   *         during retrieval.
   */
  public RepositoryResult<Statement> getStatements(Resource subject, URI predicate, Value object, boolean includeInferred, Resource... contexts) throws RepositoryException {
    contexts = checkContext(contexts);
    return new RepositoryResult<Statement>(selectFromQuadStore(subject, predicate, object, includeInferred, false, contexts));
  }

  /**
   * Checks whether the repository contains statements with a specific subject,
   * predicate and/or object, optionally in the specified contexts.
   *
   * @param subj
   *        A Resource specifying the subject, or <tt>null</tt> for a
   *        wildcard.
   * @param pred
   *        A URI specifying the predicate, or <tt>null</tt> for a wildcard.
   * @param obj
   *        A Value specifying the object, or <tt>null</tt> for a wildcard.
   * @param contexts
   *        The context(s) the need to be searched. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @param includeInferred
   *        if false, no inferred statements are considered; if true, inferred
   *        statements are considered if available
   * @return true If a matching statement is in the repository in the specified
   *         context, false otherwise.
   */
  public boolean hasStatement(Resource subject, URI predicate, Value object, boolean includeInferred, Resource... contexts) throws RepositoryException {
    contexts = checkContext(contexts);
                CloseableIteration<Statement, RepositoryException> it;
                it = selectFromQuadStore(subject, predicate, object, includeInferred, true, contexts);
                try {
                  return it.hasNext();
                } finally {
                  it.close();
                }
  }

  /**
   * Checks whether the repository contains the specified statement, optionally
   * in the specified contexts.
   *
   * @param st
   *        The statement to look for. Context information in the statement is
   *        ignored.
   * @param contexts
   *        The context(s) to get the data from. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @param includeInferred
   *        if false, no inferred statements are considered; if true, inferred
   *        statements are considered if available
   * @return true If the repository contains the specified statement, false
   *         otherwise.
   */
  public boolean hasStatement(Statement statement, boolean includeInferred, Resource... contexts) throws RepositoryException {
          return hasStatement(statement.getSubject(), statement.getPredicate(), statement.getObject(), includeInferred, contexts);
  }

  /**
   * Exports all statements with a specific subject, predicate and/or object
   * from the repository, optionally from the specified contexts.
   *
   * @param subj
   *        The subject, or null if the subject doesn't matter.
   * @param pred
   *        The predicate, or null if the predicate doesn't matter.
   * @param obj
   *        The object, or null if the object doesn't matter.
   * @param contexts
   *        The context(s) to get the data from. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @param handler
   *        The handler that will handle the RDF data.
   * @param includeInferred
   *        if false, no inferred statements are returned; if true, inferred
   *        statements are returned if available
   * @throws RDFHandlerException
   *         If the handler encounters an unrecoverable error.
   */
  public void exportStatements(Resource subject, URI predicate, Value object, boolean includeInferred, RDFHandler handler, Resource... contexts) throws RepositoryException, RDFHandlerException {
    contexts = checkContext(contexts);
                CloseableIteration<Statement, RepositoryException> it;
    handler.startRDF();

    // Export namespace information
    RepositoryResult<Namespace> nsIt = getNamespaces();
    try {
      while (nsIt.hasNext()) {
        Namespace ns = nsIt.next();
        handler.handleNamespace(ns.getPrefix(), ns.getName());
      }
    }
    finally {
      nsIt.close();
    }

                it = selectFromQuadStore(subject, predicate, object, includeInferred, false, contexts);
    try {
      while (it.hasNext())
        handler.handleStatement(it.next());
    }
    finally {
      it.close();
    }
    handler.endRDF();
  }


  private Resource[] checkDMLContext(Resource... contexts) throws RepositoryException {
    OpenRDFUtil.verifyContextNotNull(contexts);
    if(contexts != null && contexts.length == 1 && contexts[0] == null) {
      contexts = new Resource[] {nilContext};
    }
    else if (contexts == null || contexts.length == 0) {
      contexts = new Resource[] {nilContext};
    }
    return contexts;
  }

  private Resource[] checkContext(Resource... contexts) throws RepositoryException {
    OpenRDFUtil.verifyContextNotNull(contexts);
    if(contexts != null && contexts.length == 1 && contexts[0] == null) {
      contexts = new Resource[] {nilContext};
    }
    else if (contexts == null || contexts.length == 0) {
      contexts = new Resource[0];
    }
    return contexts;
  }

  /**
   * Exports all explicit statements in the specified contexts to the supplied
   * RDFHandler.
   *
   * @param contexts
   *        The context(s) to get the data from. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @param handler
   *        The handler that will handle the RDF data.
   * @throws RDFHandlerException
   *         If the handler encounters an unrecoverable error.
   */
  public void export(RDFHandler handler, Resource... contexts) throws RepositoryException, RDFHandlerException {
    exportStatements(null, null, null, false, handler, contexts);
  }

  /**
   * Returns the number of (explicit) statements that are in the specified
   * contexts in this repository.
   *
   * @param contexts
   *        The context(s) to get the data from. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @return The number of explicit statements from the specified contexts in
   *         this repository.
   */
  public long size(Resource... contexts) throws RepositoryException {
    long ret = 0;
    verifyIsOpen();
    flushDelayAdd();

    contexts = checkContext(contexts);
    StringBuffer query = new StringBuffer("select count(*) from (sparql define input:storage \"\" select * ");

    for (int i = 0; i < contexts.length; i++) {
      query.append("from named <");
      query.append(contexts[i].toString());
      query.append("> ");
          }
    query.append("where { graph ?g {?s ?p ?o }})f");
    try {
            java.sql.Statement st = createStatement();
            ResultSet rs = st.executeQuery(query.toString());

      if (rs.next())
          ret = rs.getLong(1);
                        rs.close();
                        st.close();
    }
    catch (Exception e) {
      throw new RepositoryException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
    return ret;
  }

  /**
   * Returns <tt>true</tt> if this repository does not contain any (explicit)
   * statements.
   *
   * @return <tt>true</tt> if this repository is empty, <tt>false</tt>
   *         otherwise.
   * @throws RepositoryException
   *         If the repository could not be checked to be empty.
   */
  public boolean isEmpty() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    boolean result = false;
    String query = "sparql define input:storage \"\" select * where {?s ?o ?p} limit 1";
    try {
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(query);
      result = !rs.next();
                        rs.close();
                        stmt.close();
                        return result;
    }
    catch (Exception e) {
      throw new RepositoryException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }

  /**
   * Enables or disables auto-commit mode for the connection. If a connection
   * is in auto-commit mode, then all updates will be executed and committed as
   * individual transactions. Otherwise, the updates are grouped into
   * transactions that are terminated by a call to either {@link #commit} or
   * {@link #rollback}. By default, new connections are in auto-commit mode.
   * <p>
   * <b>NOTE:</b> If this connection is switched to auto-commit mode during a
   * transaction, the transaction is committed.
   *
   * @throws RepositoryException
   *         In case the mode switch failed, for example because a currently
   *         active transaction failed to commit.
   * @see #commit
   */
  public void setAutoCommit(boolean autoCommit) throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();

    try {
      getQuadStoreConnection().setAutoCommit(autoCommit);
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }

  /**
   * Checks whether the connection is in auto-commit mode.
   *
   * @see #setAutoCommit
   */
  public boolean isAutoCommit() throws RepositoryException {
    verifyIsOpen();
    try {
      return getQuadStoreConnection().getAutoCommit();
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }


  /**
   * Indicates if a transaction is currently active on the connection. A
   * transaction is active if {@link #begin()} has been called, and becomes
   * inactive after {@link #commit()} or {@link #rollback()} has been called.
   *
   * @since 2.7.0
   * @return <code>true</code> iff a transaction is active, <code>false</code>
   *         iff no transaction is active.
   * @throws UnknownTransactionStateException
   *         if the transaction state can not be determined. This can happen
   *         for instance when communication with a repository fails or times
   *         out.
   * @throws RepositoryException
   */
  public boolean isActive()
    throws UnknownTransactionStateException, RepositoryException
  {
    verifyIsOpen();
    try {
      return !getQuadStoreConnection().getAutoCommit();
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }

  /**
   * Begins a transaction requiring {@link #commit()} or {@link #rollback()} to
   * be called to end the transaction.
   *
   * @throws RepositoryException
   *         If the connection could not start a transaction.
   * @see #isActive()
   * @see #commit()
   * @see #rollback()
   * @since 2.7.0
   */
  public void begin() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    verifyNotTxnActive("Connection already has an active transaction");

    try {
      getQuadStoreConnection().setAutoCommit(false);
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }
  /**
   * Commits all updates that have been performed as part of this connection
   * sofar.
   *
   * @throws RepositoryException
   *         If the connection could not be committed.
   */
  public void commit() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    try {
      getQuadStoreConnection().commit();
//      getQuadStoreConnection().setAutoCommit(true);
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }

  /**
   * Rolls back all updates that have been performed as part of this connection
   * sofar.
   *
   * @throws RepositoryException
   *         If the connection could not be rolled back.
   */
  public void rollback() throws RepositoryException {
    verifyIsOpen();
    dropDelayAdd();
    try {
      getQuadStoreConnection().rollback();
//      getQuadStoreConnection().setAutoCommit(true);
    }
    catch (SQLException e) {
      throw new RepositoryException("Problem with rollback", e);
    }
  }

  /**
   * Adds RDF data from an InputStream to the repository, optionally to one or
   * more named contexts.
   *
   * @param in
   *        An InputStream from which RDF data can be read.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the data
   *        against.
   * @param dataFormat
   *        The serialization format of the data.
   * @param contexts
   *        The contexts to add the data to. If one or more contexts are
   *        supplied the method ignores contextual information in the actual
   *        data. If no contexts are supplied the contextual information in the
   *        input stream is used, if no context information is available the
   *        data is added without any context.
   * @throws IOException
   *         If an I/O error occurred while reading from the input stream.
   * @throws UnsupportedRDFormatException
   *         If no parser is available for the specified RDF format.
   * @throws RDFParseException
   *         If an error was found while parsing the RDF data.
   * @throws RepositoryException
   *         If the data could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public void add(InputStream dataStream, String baseURI, RDFFormat format, Resource... contexts) throws IOException, RDFParseException, RepositoryException {
    Reader reader = new InputStreamReader(dataStream);
    add(reader, baseURI, format, contexts);
  }

  /**
   * Adds RDF data from a Reader to the repository, optionally to one or more
   * named contexts. <b>Note: using a Reader to upload byte-based data means
   * that you have to be careful not to destroy the data's character encoding
   * by enforcing a default character encoding upon the bytes. If possible,
   * adding such data using an InputStream is to be preferred.</b>
   *
   * @param reader
   *        A Reader from which RDF data can be read.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the data
   *        against.
   * @param dataFormat
   *        The serialization format of the data.
   * @param contexts
   *        The contexts to add the data to. If one or more contexts are
   *        specified the data is added to these contexts, ignoring any context
   *        information in the data itself.
   * @throws IOException
   *         If an I/O error occurred while reading from the reader.
   * @throws UnsupportedRDFormatException
   *         If no parser is available for the specified RDF format.
   * @throws RDFParseException
   *         If an error was found while parsing the RDF data.
   * @throws RepositoryException
   *         If the data could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public synchronized void add(Reader reader, String baseURI, RDFFormat format, final Resource... contexts) throws IOException, RDFParseException, RepositoryException {
    verifyIsOpen();
    sendDelayAdd();

    final boolean useStatementContext = (contexts != null && contexts.length == 0); // If no context are specified, each statement is added to statement context

    try {
      RDFParser parser = Rio.createParser(format, getValueFactory());
            parser.setParserConfig(getParserConfig());
            parser.setParseErrorListener(new ParseErrorLogger());

      // set up a handler for parsing the data from reader

      parser.setRDFHandler(new RDFHandlerBase() {
       
              Resource[] _contexts = checkDMLContext(contexts);

        public void startRDF() throws RDFHandlerException {
        }

        public void endRDF() throws RDFHandlerException {
          try {
            flushDelayAdd();
          }
          catch (RepositoryException e) {
            throw new RDFHandlerException("Problem executing query: ", e);
          }
        }

        public void handleNamespace(String prefix, String name) throws RDFHandlerException {
          String query = "DB.DBA.XML_SET_NS_DECL(?, ?, 1)";
          try {
            PreparedStatement psn = prepareStatement(query);
            psn.setString(1, prefix);
            psn.setString(2, name);
            psn.execute();
            psn.close();
          }
          catch (SQLException e) {
            throw new RDFHandlerException("Problem executing query: " + query, e);
          }
        }

        public void handleStatement(Statement st) throws RDFHandlerException {
           try {
          Resource[] hcontexts;
          if (st.getContext() != null && useStatementContext) {
            hcontexts = new Resource[] {st.getContext()};
          } else {
            hcontexts = _contexts;
          }
                addToQuadStore(st.getSubject(), st.getPredicate(), st.getObject(), hcontexts);
          
           catch(Exception e) {
             throw new RDFHandlerException(e);
           }
        }
      });
      parser.parse(reader, baseURI); // parse out each tripled to be handled by the handler above
    }
    catch (Exception e) {
      throw new RepositoryException("Problem parsing triples", e);
    }
  }

  /**
   * Adds the RDF data that can be found at the specified URL to the
   * repository, optionally to one or more named contexts.
   *
   * @param url
   *        The URL of the RDF data.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the data
   *        against. This defaults to the value of {@link
   *        java.net.URL#toExternalForm() url.toExternalForm()} if the value is
   *        set to <tt>null</tt>.
   * @param dataFormat
   *        The serialization format of the data.
   * @param contexts
   *        The contexts to add the data to. If one or more contexts are
   *        specified the data is added to these contexts, ignoring any context
   *        information in the data itself.
   * @throws IOException
   *         If an I/O error occurred while reading from the URL.
   * @throws UnsupportedRDFormatException
   *         If no parser is available for the specified RDF format.
   * @throws RDFParseException
   *         If an error was found while parsing the RDF data.
   * @throws RepositoryException
   *         If the data could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public void add(URL dataURL, String baseURI, RDFFormat format, Resource... contexts) throws IOException, RDFParseException, RepositoryException {
    // add data to Sesame
    if (baseURI == null) {
      baseURI = dataURL.toExternalForm();
    }
    Reader reader = new InputStreamReader(dataURL.openStream());
    try {
      add(reader, baseURI, format, contexts);
    } finally {
      reader.close();
    }
  }

  /**
   * Adds RDF data from the specified file to a specific contexts in the
   * repository.
   *
   * @param file
   *        A file containing RDF data.
   * @param baseURI
   *        The base URI to resolve any relative URIs that are in the data
   *        against. This defaults to the value of
   *        {@link java.io.File#toURI() file.toURI()} if the value is set to
   *        <tt>null</tt>.
   * @param dataFormat
   *        The serialization format of the data.
   * @param contexts
   *        The contexts to add the data to. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are specified, the
   *        data is added to any context specified in the actual data file, or
   *        if the data contains no context, it is added without context. If
   *        one or more contexts are specified the data is added to these
   *        contexts, ignoring any context information in the data itself.
   * @throws IOException
   *         If an I/O error occurred while reading from the file.
   * @throws UnsupportedRDFormatException
   *         If no parser is available for the specified RDF format.
   * @throws RDFParseException
   *         If an error was found while parsing the RDF data.
   * @throws RepositoryException
   *         If the data could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public void add(File file, String baseURI, RDFFormat format, Resource... contexts) throws IOException, RDFParseException, RepositoryException {
    if (baseURI == null) {
      // default baseURI to file
      baseURI = file.toURI().toString();
    }
    InputStream reader = new FileInputStream(file);
    try {
      add(reader, baseURI, format, contexts);
    } finally {
      reader.close();
    }
  }

  /**
   * Adds a statement with the specified subject, predicate and object to this
   * repository, optionally to one or more named contexts.
   *
   * @param subject
   *        The statement's subject.
   * @param predicate
   *        The statement's predicate.
   * @param object
   *        The statement's object.
   * @param contexts
   *        The contexts to add the data to. Note that this parameter is a
   *        vararg and as such is optional. If no contexts are specified, the
   *        data is added to any context specified in the actual data file, or
   *        if the data contains no context, it is added without context. If
   *        one or more contexts are specified the data is added to these
   *        contexts, ignoring any context information in the data itself.
   * @throws RepositoryException
   *         If the data could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public void add(Resource subject, URI predicate, Value object, Resource... contexts) throws RepositoryException {
    contexts = checkDMLContext(contexts);
    addToQuadStore(subject, predicate, object, contexts);
  }
  public void addQuad(Resource subject, URI predicate, Value object, Resource context) throws RepositoryException {
    addToQuadStore(subject, predicate, object, context);
  }

  /**
   * Adds the supplied statement to this repository, optionally to one or more
   * named contexts.
   *
   * @param st
   *        The statement to add.
   * @param contexts
   *        The contexts to add the statements to. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are specified, the
   *        statement is added to any context specified in each statement, or
   *        if the statement contains no context, it is added without context.
   *        If one or more contexts are specified the statement is added to
   *        these contexts, ignoring any context information in the statement
   *        itself.
   * @throws RepositoryException
   *         If the statement could not be added to the repository, for example
   *         because the repository is not writable.
   */
  public void add(Statement statement, Resource... contexts) throws RepositoryException {
    if (contexts != null && contexts.length == 0 &&  statement.getContext() != null) {
        contexts = new Resource[] { statement.getContext() }; // try the context given by the statement
    }
    add(statement.getSubject(), statement.getPredicate(), statement.getObject(), contexts);
  }

  /**
   * Adds the supplied statements to this repository, optionally to one or more
   * named contexts.
   *
   * @param statements
   *        The statements that should be added.
   * @param contexts
   *        The contexts to add the statements to. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are specified,
   *        each statement is added to any context specified in the statement,
   *        or if the statement contains no context, it is added without
   *        context. If one or more contexts are specified each statement is
   *        added to these contexts, ignoring any context information in the
   *        statement itself. ignored.
   * @throws RepositoryException
   *         If the statements could not be added to the repository, for
   *         example because the repository is not writable.
   */
  public synchronized void add(Iterable<? extends Statement> statements, Resource... contexts) throws RepositoryException {
    verifyIsOpen();
    sendDelayAdd();

    Iterator it = statements.iterator();
    boolean useStatementContext = (contexts != null && contexts.length == 0); // If no context are specified, each statement is added to statement context
    Resource[] _contexts = checkDMLContext(contexts); // otherwise, either use all contexts, or do not specify a context

    try {
      while (it.hasNext()) {
        Statement st = (Statement) it.next();

        if (st.getContext() != null && useStatementContext) {
          contexts = new Resource[] {st.getContext()};
        } else {
          contexts = _contexts;
        }

        addToQuadStore(st.getSubject(),
                  st.getPredicate(),
                  st.getObject(), contexts);
      }
      flushDelayAdd();
   
    catch(Exception e) {
         throw new RepositoryException(e);
    }
  }

  /**
   * Adds the supplied statements to this repository, optionally to one or more
   * named contexts.
   *
   * @param statementIter
   *        The statements to add. In case the iterator is a
   *        {@link CloseableIteration}, it will be closed before this method
   *        returns.
   * @param contexts
   *        The contexts to add the statements to. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are specified,
   *        each statement is added to any context specified in the statement,
   *        or if the statement contains no context, it is added without
   *        context. If one or more contexts are specified each statement is
   *        added to these contexts, ignoring any context information in the
   *        statement itself. ignored.
   * @throws RepositoryException
   *         If the statements could not be added to the repository, for
   *         example because the repository is not writable.
   */
  public synchronized <E extends Exception> void add(Iteration<? extends Statement, E> statements, Resource... contexts) throws RepositoryException, E {
          verifyIsOpen();
    sendDelayAdd();

    boolean useStatementContext = (contexts != null && contexts.length == 0); // If no context are specified, each statement is added to statement context
    Resource[] _contexts = checkDMLContext(contexts); // otherwise, either use all contexts, or do not specify a context

    try {
      while (statements.hasNext()) {
        Statement st = (Statement) statements.next();

        if (st.getContext() != null && useStatementContext) {
          contexts = new Resource[] {st.getContext()};
        } else {
          contexts = _contexts;
        }

        addToQuadStore(st.getSubject(),
            st.getPredicate(),
            st.getObject(), contexts);
      }
      flushDelayAdd();
    }
    catch(Exception e) {
         throw new RepositoryException(e);
    }
  }

  /**
   * Removes the statement(s) with the specified subject, predicate and object
   * from the repository, optionally restricted to the specified contexts.
   *
   * @param subject
   *        The statement's subject, or <tt>null</tt> for a wildcard.
   * @param predicate
   *        The statement's predicate, or <tt>null</tt> for a wildcard.
   * @param object
   *        The statement's object, or <tt>null</tt> for a wildcard.
   * @param contexts
   *        The context(s) to remove the data from. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @throws RepositoryException
   *         If the statement(s) could not be removed from the repository, for
   *         example because the repository is not writable.
   */
  public void remove(Resource subject, URI predicate, Value object, Resource... contexts) throws RepositoryException {
    OpenRDFUtil.verifyContextNotNull(contexts);
          verifyIsOpen();
    flushDelayAdd();

    contexts = checkDMLContext(contexts);

    try {
      for (int i = 0; i < contexts.length; i++)
             removeContext(subject, predicate, object, contexts[i]);
    }
    catch(RepositoryException e) {
         throw e;
    }
  }

  /**
   * Removes the supplied statement from the specified contexts in the
   * repository.
   *
   * @param st
   *        The statement to remove.
   * @param contexts
   *        The context(s) to remove the data from. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the contexts associated with the statement
   *        itself, and if no context is associated with the statement, on the
   *        entire repository.
   * @throws RepositoryException
   *         If the statement could not be removed from the repository, for
   *         example because the repository is not writable.
   */
  public void remove(Statement statement, Resource... contexts) throws RepositoryException {
    if (contexts != null && contexts.length == 0 &&  statement.getContext() != null) {
      contexts = new Resource[] { statement.getContext() }; // try the context given by the statement
    }
    remove(statement.getSubject(), statement.getPredicate(), statement.getObject(), contexts);
  }

  /**
   * Removes the supplied statements from the specified contexts in this
   * repository.
   *
   * @param statements
   *        The statements that should be removed.
   * @param contexts
   *        The context(s) to remove the data from. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the contexts associated with the statement
   *        itself, and if no context is associated with the statement, on the
   *        entire repository.
   * @throws RepositoryException
   *         If the statements could not be added to the repository, for
   *         example because the repository is not writable.
   */
  public void remove(Iterable<? extends Statement> statements, Resource... contexts) throws RepositoryException {
    OpenRDFUtil.verifyContextNotNull(contexts);
    verifyIsOpen();
    flushDelayAdd();

    Resource[] _contexts;
    Iterator<? extends Statement> it = statements.iterator();
    int count = 0;
    HashMap<String, StringBuilder> map = new HashMap<String,StringBuilder>();

    try {
      while (it.hasNext()) {
        Statement st = it.next();

        if (contexts != null && contexts.length == 0 &&  st.getContext() != null)
          _contexts = new Resource[] { st.getContext() }; // try the context given by the statement
        else
          _contexts = contexts;
        _contexts = checkDMLContext(_contexts);

        for (int i=0; i < _contexts.length; i++) {
          String ctx = _contexts[i].toString();
          StringBuilder row = new StringBuilder(256);

          append(st.getSubject(), row);
          row.append(' ');
          append(st.getPredicate(), row);
          row.append(' ');
          append(st.getObject(), row);
          row.append(" .\n");

          StringBuilder data = map.get(ctx);
          if (count > 0 && data!=null && data.length()+row.length()>MAX_CMD_SIZE) {
                           removeData(map);
                           map.clear();
                     count = 0;
                     data = null;
          }

          if (data == null)
            data = new StringBuilder(256);
          data.append(row);
          map.put(ctx, data);
          count++;
        }
      }
      if (count > 0)
               removeData(map);
           map.clear();
    }
    catch(RepositoryException e) {
         throw e;
    }
  }

  /**
   * Removes the supplied statements from a specific context in this
   * repository, ignoring any context information carried by the statements
   * themselves.
   *
   * @param statementIter
   *        The statements to remove. In case the iterator is a
   *        {@link CloseableIteration}, it will be closed before this method
   *        returns.
   * @param contexts
   *        The context(s) to remove the data from. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the contexts associated with the statement
   *        itself, and if no context is associated with the statement, on the
   *        entire repository.
   * @throws RepositoryException
   *         If the statements could not be removed from the repository, for
   *         example because the repository is not writable.
   */
  public <E extends Exception> void remove(Iteration<? extends Statement, E> statements, Resource... contexts) throws RepositoryException, E {
    OpenRDFUtil.verifyContextNotNull(contexts);
    verifyIsOpen();
    flushDelayAdd();

    Resource[] _contexts;
    int count = 0;
    HashMap<String, StringBuilder> map = new HashMap<String,StringBuilder>();

    try {
      while (statements.hasNext()) {
        Statement st = statements.next();

        if (contexts != null && contexts.length == 0 &&  st.getContext() != null)
          _contexts = new Resource[] { st.getContext() }; // try the context given by the statement
        else
          _contexts = contexts;
        _contexts = checkDMLContext(_contexts);

        for (int i=0; i < _contexts.length; i++) {
          String ctx = _contexts[i].toString();
          StringBuilder row = new StringBuilder(256);

          append(st.getSubject(), row);
          row.append(' ');
          append(st.getPredicate(), row);
          row.append(' ');
          append(st.getObject(), row);
          row.append(" .\n");

          StringBuilder data = map.get(ctx);
          if (count > 0 && data!=null && data.length()+row.length()>MAX_CMD_SIZE) {
                           removeData(map);
                           map.clear();
                     count = 0;
                     data = null;
          }

          if (data == null)
            data = new StringBuilder(256);
          data.append(row);
          map.put(ctx, data);
          count++;
        }
           }
      if (count > 0)
               removeData(map);
           map.clear();
    }
    catch(RepositoryException e) {
         throw e;
    }
  }

  /**
   * Removes all statements from a specific contexts in the repository.
   *
   * @param contexts
   *        The context(s) to remove the data from. Note that this parameter is
   *        a vararg and as such is optional. If no contexts are supplied the
   *        method operates on the entire repository.
   * @throws RepositoryException
   *         If the statements could not be removed from the repository, for
   *         example because the repository is not writable.
   */
  public void clear(Resource... contexts) throws RepositoryException {
    OpenRDFUtil.verifyContextNotNull(contexts);
    verifyIsOpen();
    flushDelayAdd();

    contexts = checkDMLContext(contexts);

    try {
      clearQuadStore(contexts);
    }
    catch(RepositoryException e) {
         throw e;
    }
  }

  /**
   * Gets all declared namespaces as a RepositoryResult of {@link Namespace}
   * objects. Each Namespace object consists of a prefix and a namespace name.
   *
   * @return A RepositoryResult containing Namespace objects. Care should be
   *         taken to close the RepositoryResult after use.
   * @throws RepositoryException
   *         If the namespaces could not be read from the repository.
   */
  public RepositoryResult<Namespace> getNamespaces() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    List<Namespace> namespaceList = new LinkedList<Namespace>();
    String query = "DB.DBA.XML_SELECT_ALL_NS_DECLS (3)";
    try {
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(query);

      // begin at onset one
      while (rs.next()) {
        String prefix = rs.getString(1);
        String name = rs.getString(2);
        if (name != null && prefix != null) {
          Namespace ns = new NamespaceImpl(prefix, name);
          namespaceList.add(ns);
        }
      }
                        rs.close();
                        stmt.close();
    }
    catch (Exception e) {
      throw new RepositoryException(e);
    }
    return createRepositoryResult(namespaceList);// new RepositoryResult<Namespace>(new IteratorWrapper(v.iterator()));
  }

  /**
   * Gets the namespace that is associated with the specified prefix, if any.
   *
   * @param prefix
   *        A namespace prefix.
   * @return The namespace name that is associated with the specified prefix,
   *         or <tt>null</tt> if there is no such namespace.
   * @throws RepositoryException
   *         If the namespace could not be read from the repository.
   */
  public String getNamespace(String prefix) throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    String retVal = null;
    String query = "SELECT __xml_get_ns_uri (?, 3)";
    try {
      PreparedStatement ps = prepareStatement(query);
      ps.setString(1, prefix);
      ResultSet rs = ps.executeQuery();

      // begin at onset one
      while (rs.next()) {
        retVal = rs.getString(1);
        break;
      }
      ps.close();
    }
    catch (Exception e) {
      throw new RepositoryException(e);
    }
    return retVal;
  }

  /**
   * Sets the prefix for a namespace.
   *
   * @param prefix
   *        The new prefix.
   * @param name
   *        The namespace name that the prefix maps to.
   * @throws RepositoryException
   *         If the namespace could not be set in the repository, for example
   *         because the repository is not writable.
   */
  public void setNamespace(String prefix, String name) throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    String query = "DB.DBA.XML_SET_NS_DECL(?, ?, 1)";
    try {
      PreparedStatement ps = prepareStatement(query);
      ps.setString(1, prefix);
      ps.setString(2, name);
      ps.execute();
      ps.close();
    }
    catch (SQLException e) {
      throw new RepositoryException("Problem executing query: " + query, e);
    }
  }

  /**
   * Removes a namespace declaration by removing the association between a
   * prefix and a namespace name.
   *
   * @param prefix
   *        The namespace prefix of which the assocation with a namespace name
   *        is to be removed.
   * @throws RepositoryException
   *         If the namespace prefix could not be removed.
   */
  public void removeNamespace(String prefix) throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    String query = "DB.DBA.XML_REMOVE_NS_BY_PREFIX(?, 1)";
    try {
      PreparedStatement ps = prepareStatement(query);
      ps.setString(1, prefix);
      ps.execute(query);
      ps.close();
    }
    catch (SQLException e) {
      throw new RepositoryException("Problem executing query: " + query, e);
    }
  }

  /**
   * Removes all namespace declarations from the repository.
   *
   * @throws RepositoryException
   *         If the namespace declarations could not be removed.
   */
  public void clearNamespaces() throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();
    String query = "DB.DBA.XML_CLEAR_ALL_NS_DECLS()";
    try {
      java.sql.Statement stmt = createStatement();
      stmt.execute(query);
      stmt.close();
    }
    catch (SQLException e) {
      throw new RepositoryException("Problem executing query: " + query, e);
    }
  }


  protected TupleQueryResult executeSPARQLForTupleResult(String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws QueryEvaluationException {

    Vector<String> names = new Vector<String>();
    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(fixQuery(false, query, dataset, includeInferred, bindings));

      ResultSetMetaData rsmd = rs.getMetaData();

      // begin at onset one
      for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        String col = rsmd.getColumnName(i);
        if (names.indexOf(col) < 0)
          names.add(col); // no duplicates
      }

      return new TupleQueryResultImpl(names, new CloseableIterationBindingSet(stmt, rs));
    }
    catch (Exception e) {
      throw new QueryEvaluationException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }
 
  protected GraphQueryResult executeSPARQLForGraphResult(String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws QueryEvaluationException {

    HashMap<String,Integer> names = new HashMap<String,Integer>();

    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(fixQuery(false, query, dataset, includeInferred, bindings));

      ResultSetMetaData rsmd = rs.getMetaData();

      // begin at onset one
      for (int i = 1; i <= rsmd.getColumnCount(); i++)
        names.put(rsmd.getColumnName(i), new Integer(i));
      return new GraphQueryResultImpl(new HashMap<String,String>(), new CloseableIterationGraphResult(stmt, rs));
    }
    catch (Exception e) {
      throw new QueryEvaluationException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
   
  }

  protected boolean executeSPARQLForBooleanResult(String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws QueryEvaluationException {
    boolean result = false;
    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(fixQuery(false, query, dataset, includeInferred, bindings));

      while(rs.next())
      {
        if (rs.getInt(1) == 1)
          result = true;
      }
      stmt.close();

      return result;
    }
    catch (Exception e) {
      throw new QueryEvaluationException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }


  protected void executeSPARQLForHandler(TupleQueryResultHandler tqrh, String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws QueryEvaluationException, TupleQueryResultHandlerException {
    LinkedList<String> names = new LinkedList<String>();
    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(fixQuery(false, query, dataset, includeInferred, bindings));

      ResultSetMetaData rsmd = rs.getMetaData();
      // begin at onset one
      for (int i = 1; i <= rsmd.getColumnCount(); i++)
        names.add(rsmd.getColumnName(i));

      tqrh.startQueryResult(names);
      // begin at onset one
      while (rs.next()) {
        QueryBindingSet qbs = new QueryBindingSet();
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
          // TODO need to parse these into appropriate resource values
          String col = rsmd.getColumnName(i);
          Object val = rs.getObject(i);
          Value v = castValue(val);
          qbs.addBinding(col, v);
        }
        tqrh.handleSolution(qbs);
      }
      tqrh.endQueryResult();
                        stmt.close();
    }
    catch (Exception e) {
      throw new QueryEvaluationException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }


  protected void executeSPARQLForHandler(RDFHandler tqrh, String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws QueryEvaluationException, RDFHandlerException {
    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      ResultSet rs = stmt.executeQuery(fixQuery(false, query, dataset, includeInferred, bindings));
      ResultSetMetaData rsmd = rs.getMetaData();
                  int col_g = -1;
                  int col_s = -1;
                  int col_p = -1;
                  int col_o = -1;

      // begin at onset one
      for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        String label = rsmd.getColumnName(i);
        if (label.equalsIgnoreCase("g"))
          col_g = i;
        else if (label.equalsIgnoreCase("s"))
          col_s = i;
        else if (label.equalsIgnoreCase("p"))
          col_p = i;
        else if (label.equalsIgnoreCase("o"))
          col_o = i;
      }

      tqrh.startRDF();
      while (rs.next()) {
              Integer col = null;
        Resource sval = null;
        URI pval = null;
        Value oval = null;
        Resource gval = null;

              if (col_s != -1)
          sval = (Resource) castValue(rs.getObject(col_s));
       
              if (col_p != -1)
          pval = (URI) castValue(rs.getObject(col_p));
       
              if (col_o != -1)
           oval = castValue(rs.getObject(col_o));
       
              if (col_g != -1)
          gval = (Resource) castValue(rs.getObject(col_g));

        Statement st = new ContextStatementImpl(sval,pval,oval,gval);
        tqrh.handleStatement(st);
      }
      tqrh.endRDF();
      stmt.close();
    }
    catch (Exception e) {
      throw new QueryEvaluationException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }
 

        protected void executeSPARUL(String query, Dataset dataset, boolean includeInferred, BindingSet bindings) throws UpdateExecutionException
        {
    try {
      verifyIsOpen();
      flushDelayAdd();
      java.sql.Statement stmt = createStatement();
      stmt.execute(fixQuery(true, query, dataset, includeInferred, bindings));
      stmt.close();

    }
    catch (Exception e) {
      throw new UpdateExecutionException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
  }


  /**
   * Execute SPARUL query on this repository.
   *
   * @param query
   *        The query string.
   * @return A rowUpdateCount.
   * @throws RepositoryException
   *         If the <tt>prepareQuery</tt> method is not supported by this
   *         repository.
   */
  public int executeSPARUL(String query) throws RepositoryException {

    java.sql.Statement stmt = null;
    try {
      verifyIsOpen();
      flushDelayAdd();
      stmt = createStatement();
      stmt.execute("sparql\n " + query);
      return stmt.getUpdateCount();
    }
    catch (SQLException e) {
      throw new RepositoryException(": SPARQL execute failed:["+query+"] \n Exception:"+e);
    }
    finally {
      try {
        if (stmt != null)
        stmt.close();
      } catch (Exception e) {}
    }
  }

  /**
   * Get Reposetory Connection.
   *
   * @return Repository Connection
   */
  public Connection getQuadStoreConnection() {
    return quadStoreConnection;
  }

  /**
   * Set Repository Connection.
   *
   * @param quadStoreConnection
   *        The Repository Connection.
   */
  public void setQuadStoreConnection(Connection quadStoreConnection) {
    this.quadStoreConnection = quadStoreConnection;
  }


  private java.sql.Statement createStatement() throws java.sql.SQLException
  {
    java.sql.Statement stmt = quadStoreConnection.createStatement();
    int timeout = repository.getQueryTimeout();
          if (timeout > 0)
            stmt.setQueryTimeout(timeout);
          stmt.setFetchSize(prefetchSize);
          return stmt;
  }

  private java.sql.PreparedStatement prepareStatement(String sql) throws java.sql.SQLException
  {
    java.sql.PreparedStatement stmt = quadStoreConnection.prepareStatement(sql);
    int timeout = repository.getQueryTimeout();
          if (timeout > 0)
             stmt.setQueryTimeout(timeout);
          stmt.setFetchSize(prefetchSize);
          return stmt;
  }
 
 
  private String substBindings(String query, BindingSet bindingsthrows RepositoryException
  {
    StringBuffer buf = new StringBuffer();
    String delim = " ,)(;.";
      int i = 0;
      char ch;
      int qlen = query.length();
      while( i < qlen) {
          ch = query.charAt(i++);
          if (ch == '\\') {
            buf.append(ch);
            if (i < qlen)
              buf.append(query.charAt(i++));

          } else if (ch == '"' || ch == '\'') {
              char end = ch;
              buf.append(ch);
              while (i < qlen) {
                ch = query.charAt(i++);
                buf.append(ch);
                if (ch == end)
                    break;
              }
          } else  if ( ch == '?' ) {  //Parameter
              String varData = null;
              int j = i;
              while(j < qlen && delim.indexOf(query.charAt(j)) < 0) j++;
              if (j != i) {
                String varName = query.substring(i, j);
                Value val = bindings.getValue(varName);
                if (val != null) {
                          varData = stringForValue(val);
                          i=j;
                      }
              }
              if (varData != null)
                buf.append(varData);
              else
                buf.append(ch);
          } else {
              buf.append(ch);
          }
      }
    return buf.toString();
  }
 
  private String fixQuery(boolean isSPARUL, String query, Dataset dataset, boolean includeInferred, BindingSet bindingsthrows RepositoryException
  {
    StringBuffer ret = new StringBuffer("sparql\n ");

    if (includeInferred && repository.ruleSet!=null && repository.ruleSet.length() > 0)
      ret.append("define input:inference '"+repository.ruleSet+"'\n ");

    if (dataset != null)
    {
       Set<URI> list = dataset.getDefaultGraphs();
       if (list != null)
       {
         Iterator<URI> it = list.iterator();
         while(it.hasNext())
         {
           URI v = it.next();
           ret.append(" define input:default-graph-uri <" + v.toString() + "> \n");
         }
       }

       list = dataset.getNamedGraphs();
       if (list != null)
       {
         Iterator<URI> it = list.iterator();
         while(it.hasNext())
         {
           URI v = it.next();
           ret.append(" define input:named-graph-uri <" + v.toString() + "> \n");
         }
       }
    }
    ret.append(substBindings(query, bindings));
    return ret.toString();
  }


  private synchronized void addToQuadStore(Resource subject, URI predicate, Value object, Resource... contexts) throws RepositoryException
  {
    verifyIsOpen();

    try {
      boolean isAutoCommit = getQuadStoreConnection().getAutoCommit();
            if (psInsert == null)
        psInsert = prepareStatement(VirtuosoRepositoryConnection.S_BATCH_INSERT);

            if (!isAutoCommit && useLazyAdd) {
        for (int i = 0; i < contexts.length; i++) {
          bindParams(subject, predicate, object, contexts[i]);

          psInsert.addBatch();
          psInsertCount++;
        }
     
        if (psInsertCount >= BATCH_SIZE)
          flushDelayAdd();
            } else {
        for (int i = 0; i < contexts.length; i++) {
          bindParams(subject, predicate, object, contexts[i]);

          psInsert.addBatch();
          psInsertCount++;
        }

        flushDelayAdd();
            }
    }
    catch (Exception e) {
      throw new RepositoryException(e);
    }
  }

  private void bindParams(Resource subject, URI predicate, Value object, Resource context) throws SQLException, RepositoryException
  {
    psInsert.setString(1, subject.toString());
    psInsert.setString(2, predicate.toString());

        if (object instanceof Resource)
    {
      psInsert.setString(3,  object.toString());
      psInsert.setNull(4, java.sql.Types.VARCHAR);
      psInsert.setInt(5, 0);
    }
    else if (object instanceof Literal)
    {
      Literal lit = (Literal) object;
      psInsert.setString(3, lit.getLabel());

      if (lit.getDatatype() != null)
      {
        psInsert.setString(4, lit.getDatatype().toString());
        psInsert.setInt(5, 3);
      }
      else if (lit.getLanguage() != null)
      {
        psInsert.setString(4, lit.getLanguage());
        psInsert.setInt(5, 2);
      }
      else
      {
        psInsert.setNull(4, java.sql.Types.VARCHAR);
        psInsert.setInt(5, 1);
      }
    }
    else
    {
      throw new RepositoryException("Unknown value type: " + object.getClass());
    }
     
    psInsert.setString(6, context.toString());
  }


  private synchronized void flushDelayAdd() throws RepositoryException
  {
    try {
      if (psInsertCount > 0 && psInsert!=null) {
        psInsert.executeBatch();
        psInsert.clearBatch();
        psInsertCount = 0;
        if (useReprepare) {
          try{
            psInsert.close();
          } catch(Exception e){}
          psInsert = null;
        }
       
      }
    }
    catch (Exception e) {
      throw new RepositoryException(e);
    }
  }

  private synchronized void dropDelayAdd() throws RepositoryException
  {
    try {
      if (psInsertCount > 0 && psInsert!=null) {
        psInsert.clearBatch();
        psInsertCount = 0;
        if (useReprepare) {
          try{
            psInsert.close();
          } catch(Exception e){}
          psInsert = null;
        }
      }
    } catch (Exception e) {
      throw new RepositoryException(e);
    }
  }


  private synchronized void sendDelayAdd() throws RepositoryException
  {
    try {
      if (psInsertCount >= BATCH_SIZE)
        flushDelayAdd();
    }
    catch (Exception e) {
      throw new RepositoryException(e);
    }
  }


  private void append(Value value, StringBuilder sb)
    throws RepositoryException
  {
    if (value instanceof Resource) {
      append((Resource)value, sb);
    }
    else if (value instanceof Literal) {
      append((Literal)value, sb);
    }
    else {
      throw new RepositoryException("Unknown value type: " + value.getClass());
    }
  }

  private void append(Resource resource, StringBuilder sb)
    throws RepositoryException
  {
    if (resource instanceof URI) {
      append((URI)resource, sb);
    }
    else if (resource instanceof BNode) {
      append((BNode)resource, sb);
    }
    else {
      throw new RepositoryException("Unknown resource type: " + resource.getClass());
    }
  }

  private void append(URI uri, StringBuilder sb)
    throws RepositoryException
  {
    sb.append("<");
    escapeString(uri.toString(), sb);
    sb.append(">");
  }

  private void append(BNode bNode, StringBuilder sb)
    throws RepositoryException
  {
    sb.append(bNode.toString());
  }


  private void append(Literal lit, StringBuilder sb)
    throws RepositoryException
  {
    sb.append("\"");
    escapeString(lit.getLabel(), sb);
    sb.append("\"");

    if (lit.getDatatype() != null) {
      // Append the literal's datatype
      sb.append("^^");
      append(lit.getDatatype(), sb);
    }
    else if (lit.getLanguage() != null) {
      // Append the literal's language
      sb.append("@");
      sb.append(lit.getLanguage());
    }
  }

  private void escapeString(String label, StringBuilder sb)
    throws RepositoryException
  {
    int labelLength = label.length();

    for (int i = 0; i < labelLength; i++) {
      char c = label.charAt(i);
      int cInt = c;

      if (c == '\\') {
        sb.append("\\\\");
      }
      else if (c == '"') {
        sb.append("\\\"");
      }
      else if (c == '\n') {
        sb.append("\\n");
      }
      else if (c == '\r') {
        sb.append("\\r");
      }
      else if (c == '\t') {
        sb.append("\\t");
      }
      else if (
        cInt >= 0x0 && cInt <= 0x8 ||
        cInt == 0xB || cInt == 0xC ||
        cInt >= 0xE && cInt <= 0x1F ||
        cInt >= 0x7F && cInt <= 0xFFFF)
      {
        sb.append("\\u");
        sb.append(toHexString(cInt, 4));
      }
      else if (cInt >= 0x10000 && cInt <= 0x10FFFF) {
        sb.append("\\U");
        sb.append(toHexString(cInt, 8));
      }
      else {
        sb.append(c);
      }
    }
  }

  private String toHexString(int decimal, int stringLength) {
    StringBuilder sb = new StringBuilder(stringLength);
    String hexVal = Integer.toHexString(decimal).toUpperCase();

    int nofZeros = stringLength - hexVal.length();
    for (int i = 0; i < nofZeros; i++)
      sb.append('0');

    sb.append(hexVal);
    return sb.toString();
  }


 
  private void clearQuadStore(Resource[] contexts) throws RepositoryException {

                if (contexts!=null && contexts.length > 0)
      try {
            String [] graphs = new String[contexts.length];
      PreparedStatement ps = prepareStatement(S_CLEAR_GRAPH);
      for (int i = 0; i < contexts.length; i++)
        graphs[i] = contexts[i].stringValue();

      Array gArray = quadStoreConnection.createArrayOf ("VARCHAR", graphs);
      ps.setArray (1, gArray);
      ps.executeUpdate ();
       ps.close();
      gArray.free();
      }
      catch (Exception e) {
      throw new RepositoryException(e);
      }
  }


  private CloseableIteration<Statement, RepositoryException> selectFromQuadStore(Resource subject, URI predicate, Value object, boolean includeInferred, boolean hasOnly, Resource... contexts) throws RepositoryException {
    verifyIsOpen();
    flushDelayAdd();

    ResultSet rs = null;
    java.sql.Statement stmt = null;
    String s = "?s";
    String p = "?p";
    String o = "?o";

    if (subject != null)
      s = stringForResource(subject);
    if (predicate != null)
      p = stringForURI(predicate);
    if (object != null)
      o = stringForValue(object);

    StringBuffer query = new StringBuffer("sparql ");

    if (includeInferred && repository.ruleSet != null && repository.ruleSet.length() > 0)
      query.append("define input:inference '"+repository.ruleSet+"' ");

    query.append("select * ");

    for (int i = 0; i < contexts.length; i++) {

      query.append("from named <");
      query.append(contexts[i].toString());
      query.append("> ");
          }

    query.append("where { graph ?g {");
    query.append(s);
    query.append(" ");
    query.append(p);
    query.append(" ");
    query.append(o);
    query.append(" }}");
    if (hasOnly)
      query.append(" LIMIT 1");

    try {
      stmt = createStatement();
      rs = stmt.executeQuery(query.toString());
    }
    catch (Exception e) {
      throw new RepositoryException(getClass().getCanonicalName() + ": SPARQL execute failed." + "\n" + query.toString() + "[" + e + "]", e);
    }

    return new CloseableIterationStmt(stmt, rs, subject, predicate, object);
  }



  private void removeData(Map<String,StringBuilder> data) throws RepositoryException {
    java.sql.Statement stmt = null;
    try {
      stmt = createStatement();
      for(Map.Entry<String,StringBuilder> e : data.entrySet()) {
               
                StringBuilder sb = new StringBuilder(256);
                sb.append("sparql define output:format '_JAVA_' DELETE FROM <");
                sb.append(e.getKey());
                sb.append("> { ");
                sb.append(e.getValue().toString());
                  sb.append(" }");

          stmt.execute(sb.toString());
      }
    }
    catch (Exception e) {
        throw new RepositoryException(e);
    }
    finally {
      try {
          if (stmt!=null)
              stmt.close();
      } catch (Exception e) {}
    }
  }

 
  private void removeContext(Resource subject, URI predicate, Value object, Resource context) throws RepositoryException {
    String S = "?s";
    String P = "?p";
    String O = "?o";

    try {

        if (subject == null && predicate == null && object == null && context != null) {
      String  query = "sparql clear graph iri(??)";

      PreparedStatement ps = prepareStatement(query);
      ps.setString(1, context.toString());
      ps.execute();
      ps.close();

        } else if (subject != null && predicate != null && object != null && context != null) {

          PreparedStatement ps = prepareStatement(VirtuosoRepositoryConnection.S_DELETE);

      ps.setString(1, context.toString());
      bindResource(ps, 2, subject);
      bindURI(ps, 3, predicate);
      bindValue(ps, 4, object);
      ps.execute();
      ps.close();

        } else {

            if (context == null)
               throw new RepositoryException("Context can't be NULL");

      if (subject != null)
        S = stringForResource(subject);

      if (predicate != null)
        P = stringForURI(predicate);

      if (object != null)
        O = stringForValue(object);

      // s = s.replaceAll("'", "''");
      // p = p.replaceAll("'", "''");
      // o = o.replaceAll("'", "''");
         
          // context should not be null at this point, at the least, it will be a wildcard
            String query = "sparql delete from graph <"+context+
          "> { "+S+" "+P+" "+O+" } from <"+context+
          "> where { "+S+" "+P+" "+O+" }";

          java.sql.Statement stmt = createStatement();
          stmt.execute(query);
          stmt.close();
        }
    }
    catch (Exception e) {
        throw new RepositoryException(e);
    }
  }

 
  private void bindResource(PreparedStatement ps, int col, Resource n) throws SQLException {
    if (n == null)
      return;
    ps.setString(col, n.toString());
  }

 
  private void bindURI(PreparedStatement ps, int col, URI n) throws SQLException {
    if (n == null)
      return;
    ps.setString(col, n.toString());
  }

 
  private void bindValue(PreparedStatement ps, int col, Value n) throws SQLException {
    if (n == null)
      return;
    if (n instanceof URI) {
      ps.setInt(col, 1);
      ps.setString(col+1, n.toString());
      ps.setNull(col+2, java.sql.Types.VARCHAR);
    }
    else if (n instanceof BNode) {
      ps.setInt(col, 1);
      ps.setString(col+1, n.toString());
      ps.setNull(col+2, java.sql.Types.VARCHAR);
    }
    else if (n instanceof Literal) {
      Literal lit = (Literal) n;
      if (lit.getLanguage() != null) {
        ps.setInt(col, 5);
        ps.setString(col+1, lit.getLabel());
        ps.setString(col+2, lit.getLanguage());
      }
      else if (lit.getDatatype() != null) {
        ps.setInt(col, 4);
        ps.setString(col+1, lit.getLabel());
        ps.setString(col+2, lit.getDatatype().toString());
       }
       else {
        ps.setInt(col, 3);
        ps.setString(col+1, lit.getLabel());
        ps.setNull(col+2, java.sql.Types.VARCHAR);
      
    }
    else {
      ps.setInt(col, 3);
      ps.setString(col+1, n.toString());
      ps.setNull(col+2, java.sql.Types.VARCHAR);
    }
  }
 

  private String stringForResource(Resource nthrows RepositoryException {
    StringBuilder sb = new StringBuilder(256);
    append(n, sb);
    return sb.toString();
  }

 
  private String stringForURI(URI nthrows RepositoryException {
    StringBuilder sb = new StringBuilder(256);
    append(n, sb);
    return sb.toString();
  }

 
  private String stringForValue(Value nthrows RepositoryException {
    StringBuilder sb = new StringBuilder(256);
    append(n, sb);
    return sb.toString();
  }

 
  private Value castValue(Object val) throws RepositoryException {
    if (val == null)
      return null;
    if (val instanceof ExtendedString) {
      ExtendedString ves = (ExtendedString) val;
      String valueString = ves.toString();
      if (ves.getIriType() == ExtendedString.IRI && (ves.getStrType() & 0x01)==0x01) {
        if (valueString.startsWith("_:")) {
          valueString = valueString.substring(2);
          return getRepository().getValueFactory().createBNode(valueString);
        }
        try {
          if (valueString.indexOf(':') < 0)
            return getRepository().getValueFactory().createURI(":" + valueString);
          else
            return getRepository().getValueFactory().createURI(valueString);
        }
        catch (IllegalArgumentException iaex) {
          throw new RepositoryException("VirtuosoRepositoryConnection().castValue() Invalid value from Virtuoso: \"" + valueString + "\"", iaex);
        }
      }
      else if (ves.getIriType() == ExtendedString.BNODE) {
        try {
          valueString = valueString.substring(9); // "nodeID://"
          return getRepository().getValueFactory().createBNode(valueString);
        }
        catch (IllegalArgumentException iaex) {
          throw new RepositoryException("VirtuosoRepositoryConnection().castValue() Invalid value from Virtuoso: \"" + valueString + "\"", iaex);
        }
      }
      else {
        try {
          return getRepository().getValueFactory().createLiteral(valueString);
        }
        catch (IllegalArgumentException iaex) {
          throw new RepositoryException("VirtuosoRepositoryConnection().castValue() Invalid value from Virtuoso: \"" + valueString + "\", STRTYPE = " + ves.getIriType(), iaex);
        }
      }
    }
    else if (val instanceof RdfBox) {
      RdfBox rb = (RdfBox) val;
      if (rb.getLang() != null) {
        return getRepository().getValueFactory().createLiteral(rb.toString(), rb.getLang());
      }
      else if (rb.getType() != null) {
        return getRepository().getValueFactory().createLiteral(rb.toString(), this.getRepository().getValueFactory().createURI(rb.getType()));
      }
      else {
        return getRepository().getValueFactory().createLiteral(rb.toString());
      }
    }
    else if (val instanceof java.lang.Long) {
      return getRepository().getValueFactory().createLiteral(((Long) val).longValue());
    }
    else if (val instanceof java.lang.Integer) {
      return getRepository().getValueFactory().createLiteral(((Integer) val).intValue());
    }
    else if (val instanceof java.lang.Short) {
      return getRepository().getValueFactory().createLiteral(((Short) val).intValue());
    }
    else if (val instanceof java.lang.Float) {
      return getRepository().getValueFactory().createLiteral(((Float) val).floatValue());
    }
    else if (val instanceof java.lang.Double) {
      return getRepository().getValueFactory().createLiteral(((Double) val).doubleValue());
    }
    else if (val instanceof java.math.BigDecimal) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#decimal");
      return getRepository().getValueFactory().createLiteral(val.toString(), type);
    }
    else if (val instanceof java.sql.Blob) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#hexBinary");
      return getRepository().getValueFactory().createLiteral(val.toString(), type);
    }
    else if (val instanceof java.sql.Date) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#date");
      return getRepository().getValueFactory().createLiteral(val.toString(), type);
    }
    else if (val instanceof java.sql.Timestamp) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#dateTime");
      return getRepository().getValueFactory().createLiteral(Timestamp2String((java.sql.Timestamp)val), type);
    }
    else if (val instanceof java.sql.Time) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#time");
      return getRepository().getValueFactory().createLiteral(val.toString(), type);
    }
    else if (val instanceof VirtuosoDate) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#date");
      return getRepository().getValueFactory().createLiteral(((VirtuosoDate)val).toXSD_String(), type);
    }
    else if (val instanceof VirtuosoTimestamp) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#dateTime");
      return getRepository().getValueFactory().createLiteral(((VirtuosoTimestamp)val).toXSD_String(), type);
    }
    else if (val instanceof VirtuosoTime) {
      URI type = getRepository().getValueFactory().createURI("http://www.w3.org/2001/XMLSchema#time");
      return getRepository().getValueFactory().createLiteral(((VirtuosoTime)val).toXSD_String(), type);
    }
    else { // if(val instanceof String) {
      try {
        return getRepository().getValueFactory().createLiteral(val.toString());
      }
      catch (IllegalArgumentException iaex2) {
        throw new RepositoryException("VirtuosoRepositoryConnection().castValue() Could not parse resource: " + val, iaex2);
      }
    }
  }


  /**
   * Creates a RepositoryResult for the supplied element set.
   */
  protected <E> RepositoryResult<E> createRepositoryResult(Iterable<? extends E> elements) {
    return new RepositoryResult<E>(new CloseableIteratorIteration<E, RepositoryException>(elements.iterator()));
  }


  private void verifyIsOpen() throws RepositoryException {
    try {
      if (this.getQuadStoreConnection().isClosed())
        throw new IllegalStateException("Connection has been closed");
    }
    catch (SQLException e) {
      throw new RepositoryException(e);
    }
  }


  protected void verifyNotTxnActive(String msg)
    throws RepositoryException
  {
    if (!isAutoCommit()) {
      throw new RepositoryException(msg);
    }
  }

/**
  protected void verifyTxnActive()
    throws StoreException
  {
    if (isAutoCommit()) {
      throw new RepositoryException("Connection does not have an active transaction");
    }
  }
**/

        public abstract class CloseableIterationBase<E, X extends Exception> implements CloseableIteration<E, X> {
                                          

    E    v_row;
    boolean    v_finished = false;
    boolean    v_prefetched = false;
    Resource  subject;
    URI       predicate;
    Value     object;
    ResultSet v_rs;
    java.sql.Statement v_stmt;

          public CloseableIterationBase(java.sql.Statement stmt, ResultSet rs, Resource subject, URI predicate, Value object)
          {
            v_stmt = stmt;
            v_rs = rs;
            this.subject = subject;
            this.predicate = predicate;
            this.object = object; 
          }


          protected abstract X createException(Exception e);

    public boolean hasNext() throws X
    {
             if (!v_finished && !v_prefetched)
               moveForward();
      return !v_finished;
    }

    public E next() throws X
    {
            if (!v_finished && !v_prefetched)
          moveForward();

            v_prefetched = false;

            if (v_finished)
                throw new NoSuchElementException();

            return v_row;
    }

    public void remove() throws X
    {
      throw new UnsupportedOperationException();
    }

    public void close() throws X
    {
      if (!v_finished)
      {
        try
        {
            v_rs.close();
            v_stmt.close();
        }
        catch (SQLException e)
        {
            throw createException(e);
        }
      }
      v_finished = true;
    }

    protected void finalize() throws Throwable
    {
      if (!v_finished)
        try {
            close();
        } catch (Exception e) {}
    }

    protected void moveForward() throws X
    {
      try
      {
          if (!v_finished && v_rs.next())
          {
        extractRow();
        v_prefetched = true;
          }
          else
        close();
      }
      catch (Exception e)
      {
          throw createException(e);
      }
    }

    protected abstract void extractRow() throws Exception;
  }


        public class CloseableIterationStmt extends CloseableIterationBase<Statement, RepositoryException> {
                                          
                int col_g = -1;
                int col_s = -1;
                int col_p = -1;
                int col_o = -1;

          public CloseableIterationStmt(java.sql.Statement stmt, ResultSet rs, Resource subject, URI predicate, Value object) throws RepositoryException
          {
            super(stmt, rs, subject, predicate, object);
            try {
          ResultSetMetaData rsmd = rs.getMetaData();
         for (int i = 1; i <= rsmd.getColumnCount(); i++) {
      String label = rsmd.getColumnName(i);
      if (label.equalsIgnoreCase("g"))
        col_g = i;
      else if (label.equalsIgnoreCase("s"))
        col_s = i;
      else if (label.equalsIgnoreCase("p"))
        col_p = i;
      else if (label.equalsIgnoreCase("o"))
        col_o = i;
         }
      } catch (Exception e) {
         throw createException(e);
      }
          }

          protected RepositoryException createException(Exception e) {
            return new RepositoryException(e);
          }

    protected void extractRow() throws Exception
    {
      Resource _graph = null;
      Resource _subject = subject;
      URI _predicate = predicate;
      Value _object = object;
      Object val = null;

      try {
              if (col_g != -1) {
          val = v_rs.getObject(col_g);
          _graph = (Resource) castValue(val);
        }
      }
      catch (ClassCastException ccex) {
        throw new RepositoryException("Unexpected resource type encountered. Was expecting Resource: " + val, ccex);
      }

      if (_subject == null && col_s != -1)
        try {
        val = v_rs.getObject(col_s);
        _subject = (Resource) castValue(val);
        }
        catch (ClassCastException ccex) {
        throw new RepositoryException("Unexpected resource type encountered. Was expecting Resource: " + val, ccex);
        }

      if (_predicate == null && col_p != -1)
        try {
        val = v_rs.getObject(col_p);
        _predicate = (URI) castValue(val);
        }
        catch (ClassCastException ccex) {
        throw new RepositoryException("Unexpected resource type encountered. Was expecting URI: " + val, ccex);
        }

      if (_object == null && col_o != -1)
        _object = castValue(v_rs.getObject(col_o));

      v_row = new ContextStatementImpl(_subject,_predicate,_object,_graph);
    }
  }

       

        public class CloseableIterationBindingSet extends CloseableIterationBase<BindingSet, QueryEvaluationException> {
                                          
     ResultSetMetaData rsmd;

          public CloseableIterationBindingSet(java.sql.Statement stmt, ResultSet rs) throws QueryEvaluationException
          {
            super(stmt, rs, null, null, null);
            try {
         rsmd = rs.getMetaData();
      } catch (Exception e) {
         throw createException(e);
      }
          }

          protected QueryEvaluationException createException(Exception e) {
            return new QueryEvaluationException(e);
          }

    protected void extractRow() throws Exception
    {
      v_row = new QueryBindingSet();
      for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        String col = rsmd.getColumnName(i);
        Object val = v_rs.getObject(i);
        Value v = castValue(val);
        ((QueryBindingSet)v_row).setBinding(col, v);
      }
    }
  }


        public class CloseableIterationGraphResult extends CloseableIterationBase<Statement, QueryEvaluationException> {
                                          
                int col_g = -1;
                int col_s = -1;
                int col_p = -1;
                int col_o = -1;

          public CloseableIterationGraphResult(java.sql.Statement stmt, ResultSet rs) throws QueryEvaluationException
          {
            super(stmt, rs, null, null, null);

            try {
         ResultSetMetaData rsmd = rs.getMetaData();

        // begin at onset one
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
          String label = rsmd.getColumnName(i);
          if (label.equalsIgnoreCase("G"))
            col_g = i;
          else if (label.equalsIgnoreCase("S"))
            col_s = i;
          else if (label.equalsIgnoreCase("P"))
            col_p = i;
          else if (label.equalsIgnoreCase("O"))
            col_o = i;
      }
      } catch (Exception e) {
         throw createException(e);
      }
          }

          protected QueryEvaluationException createException(Exception e) {
            return new QueryEvaluationException(e);
          }

    protected void extractRow() throws Exception
    {
      Resource sval = null;
      URI pval = null;
      Value oval = null;
      Resource gval = null;

      if (col_s != -1)
        sval = (Resource) castValue(v_rs.getObject(col_s));
       
      if (col_p != -1)
        pval = (URI) castValue(v_rs.getObject(col_p));
       
      if (col_o != -1)
        oval = castValue(v_rs.getObject(col_o));
       
      if (col_g != -1)
        gval = (Resource) castValue(v_rs.getObject(col_g));

      v_row = new ContextStatementImpl(sval,pval,oval,gval);
    }
  }


      private String Timestamp2String(java.sql.Timestamp v)
      {
        GregorianCalendar cal = new GregorianCalendar();
        int timezone = cal.get(Calendar.ZONE_OFFSET)/60000; //min

        StringBuilder sb = new StringBuilder();
        DateFormat formatter= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        String nanosString;
        String timeZoneString = null;
        String zeros = "000000000";
        int nanos = v.getNanos();

        sb.append(formatter.format(v));

        if (nanos == 0) {
            nanosString = "000";
        } else {
            nanosString = Integer.toString(nanos);

            // Add leading zeros
            nanosString = zeros.substring(0, (9-nanosString.length())) +
                    nanosString;

            // Truncate trailing zeros
            char[] nanosChar = new char[nanosString.length()];
            nanosString.getChars(0, nanosString.length(), nanosChar, 0);
            int truncIndex = 8;
            while (nanosChar[truncIndex] == '0') {
                truncIndex--;
            }

            nanosString = new String(nanosChar, 0, truncIndex + 1);
        }

        sb.append(".");
        sb.append(nanosString);
        sb.append(timezone>0?'+':'-');

        int tz = Math.abs(timezone);
        int tzh = tz/60;
        int tzm = tz%60;

        if (tzh < 10)
            sb.append('0');

        sb.append(tzh);
        sb.append(':');

        if (tzm < 10)
            sb.append('0');

        sb.append(tzm);
        return sb.toString();
      }
}
TOP

Related Classes of virtuoso.sesame2.driver.VirtuosoRepositoryConnection

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.