Package org.openrdf.repository.http

Source Code of org.openrdf.repository.http.HTTPRepository

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2006-2007.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.repository.http;

import static org.openrdf.http.protocol.Protocol.MIN_TIME_OUT;
import static org.openrdf.http.protocol.Protocol.TIME_OUT_UNITS;

import java.io.File;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.openrdf.http.client.ConnectionClient;
import org.openrdf.http.client.NamespaceClient;
import org.openrdf.http.client.RepositoryClient;
import org.openrdf.http.client.SesameClient;
import org.openrdf.http.client.connections.HTTPConnectionPool;
import org.openrdf.http.protocol.Protocol;
import org.openrdf.model.LiteralFactory;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.URIFactory;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.BNodeFactoryImpl;
import org.openrdf.model.impl.LiteralFactoryImpl;
import org.openrdf.model.impl.URIFactoryImpl;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.query.resultio.TupleQueryResultFormat;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryMetaData;
import org.openrdf.repository.http.helpers.CachedNamespaceResult;
import org.openrdf.repository.http.helpers.RepositoryCache;
import org.openrdf.result.NamespaceResult;
import org.openrdf.result.impl.NamespaceResultImpl;
import org.openrdf.rio.RDFFormat;
import org.openrdf.store.StoreException;

/**
* A repository that serves as a proxy for a remote repository on a Sesame
* server. Methods in this class may throw the specific StoreException
* subclasses UnautorizedException and NotAllowedException, the semantics of
* which are defined by the HTTP protocol.
*
* @see org.openrdf.http.protocol.UnauthorizedException
* @see org.openrdf.http.protocol.NotAllowedException
* @author Arjohn Kampman
* @author jeen
* @author Herko ter Horst
*/
public class HTTPRepository implements Repository {

  /*------------*
   * Attributes *
   *------------*/

  final Logger logger = LoggerFactory.getLogger(HTTPRepository.class);

  private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

  private final URIFactory uf = new URIFactoryImpl();

  private final LiteralFactory lf = new LiteralFactoryImpl();
 
  private final HTTPConnectionPool pool;

  /**
   * The HTTP client that takes care of the client-server communication.
   */
  private final RepositoryClient client;

  private final RepositoryCache cache;

  private CachedNamespaceResult namespaces;

  private File dataDir;

  private boolean initialized = false;

  private RepositoryMetaData metadata;

  private boolean readOnly;

  /*--------------*
   * Constructors *
   *--------------*/

  public HTTPRepository(String serverURL, String repositoryID) {
    ValueFactory vf = new ValueFactoryImpl(new BNodeFactoryImpl(), uf, lf);
    pool = new HTTPConnectionPool(serverURL, vf);
    client = new SesameClient(pool).repositories().slash(repositoryID);
    cache = new RepositoryCache(client);
  }

  public HTTPRepository(String repositoryURL) {
    ValueFactory vf = new ValueFactoryImpl(new BNodeFactoryImpl(), uf, lf);
    String serverURL = Protocol.getServerLocation(repositoryURL);
    if (serverURL != null) {
      pool = new HTTPConnectionPool(serverURL, vf).location(repositoryURL);
    }
    else {
      pool = new HTTPConnectionPool(repositoryURL, vf);
    }
    client = new RepositoryClient(pool);
    cache = new RepositoryCache(client);
  }

  /*---------*
   * Methods *
   *---------*/

  public void setDataDir(File dataDir) {
    this.dataDir = dataDir;
  }

  public File getDataDir() {
    return dataDir;
  }

  public boolean isReadOnly() {
    return readOnly;
  }

  public void setReadOnly(boolean readOnly) {
    this.readOnly = readOnly;
  }

  public void setSubjectSpace(Set<String> uriSpace) {
    cache.setSubjectSpace(uriSpace);
  }

  public void initialize()
    throws StoreException
  {
    initialized = true;
  }

  public RepositoryMetaData getMetaData()
    throws StoreException
  {
    if (metadata == null) {
      metadata = HTTPRepositoryMetaData.create(this, client.metadata().get());
    }
    return metadata;
  }

  public void shutDown()
    throws StoreException
  {
    initialized = false;
    pool.shutdown();
    executor.shutdown();
  }

  public URIFactory getURIFactory() {
    return uf;
  }

  public LiteralFactory getLiteralFactory() {
    return lf;
  }

  public ValueFactory getValueFactory() {
    return new ValueFactoryImpl(uf, lf);
  }

  public RepositoryConnection getConnection()
    throws StoreException
  {
    final ConnectionClient connection = client.connections().post();
    final HTTPRepositoryConnection con = new HTTPRepositoryConnection(this, connection);
    executor.scheduleAtFixedRate(new Runnable() {

      public void run() {
        try {
          if (con.isOpen()) {
            connection.ping();
          }
          else {
            throw new RuntimeException("connection already closed");
          }
        }
        catch (StoreException e) {
          logger.warn(e.toString());
          throw new RuntimeException(e);
        }
      }
    }, MIN_TIME_OUT, MIN_TIME_OUT, TIME_OUT_UNITS);
    return con;
  }

  public boolean isWritable()
    throws StoreException
  {
    if (!initialized) {
      throw new IllegalStateException("HTTPRepository not initialized.");
    }
    return !getMetaData().isReadOnly();
  }

  /**
   * Sets the preferred serialization format for tuple query results to the
   * supplied {@link TupleQueryResultFormat}, overriding the default
   * preference. Setting this parameter is not necessary in most cases as the
   * default indicates a preference for the most compact and efficient format
   * available.
   *
   * @param format
   *        the preferred {@link TupleQueryResultFormat}. If set to 'null' no
   *        explicit preference will be stated.
   */
  public void setPreferredTupleQueryResultFormat(TupleQueryResultFormat format) {
    pool.setPreferredTupleQueryResultFormat(format);
  }

  /**
   * Indicates the current preferred {@link TupleQueryResultFormat}.
   *
   * @return The preferred format, of 'null' if no explicit preference is
   *         defined.
   */
  public TupleQueryResultFormat getPreferredTupleQueryResultFormat() {
    return pool.getPreferredTupleQueryResultFormat();
  }

  /**
   * Sets the preferred serialization format for RDF to the supplied
   * {@link RDFFormat}, overriding the default preference. Setting this
   * parameter is not necessary in most cases as the default indicates a
   * preference for the most compact and efficient format available.
   * <p>
   * Use with caution: if set to a format that does not support context
   * serialization any context info contained in the query result will be lost.
   *
   * @param format
   *        the preferred {@link RDFFormat}. If set to 'null' no explicit
   *        preference will be stated.
   */
  public void setPreferredRDFFormat(RDFFormat format) {
    pool.setPreferredRDFFormat(format);
  }

  /**
   * Indicates the current preferred {@link RDFFormat}.
   *
   * @return The preferred format, of 'null' if no explicit preference is
   *         defined.
   */
  public RDFFormat getPreferredRDFFormat() {
    return pool.getPreferredRDFFormat();
  }

  /**
   * Set the username and password to use for authenticating with the remote
   * repository.
   *
   * @param username
   *        the username. Setting this to null will disable authentication.
   * @param password
   *        the password. Setting this to null will disable authentication.
   */
  public void setUsernameAndPassword(String username, String password) {
    pool.setUsernameAndPassword(username, password);
  }

  @Override
  public String toString() {
    return client.toString();
  }

  /**
   * Indicates that the cache needs validation.
   */
  void modified() {
    cache.stale();
    if (namespaces != null) {
      namespaces.stale();
    }
  }

  boolean hasStatement(Resource subj, URI pred, Value obj, boolean includeInferred, Resource[] contexts)
    throws StoreException
  {
    return cache.hasStatement(subj, pred, obj, includeInferred, contexts);
  }

  /**
   * Will never connect to the remote server.
   *
   * @return if this statement cannot be stored in the remote server
   */
  boolean isIllegal(Resource subj, URI pred, Value obj, Resource... contexts) {
    return cache.isIllegal(subj, pred, obj, contexts);
  }

  /**
   * Will never connect to the remote server.
   *
   * @return if it is known that this pattern (or super set) has no matches.
   */
  boolean noMatch(Resource subj, URI pred, Value obj, boolean includeInferred, Resource... contexts)
    throws StoreException
  {
    return cache.noMatch(subj, pred, obj, includeInferred, contexts);
  }

  /**
   * Uses cache of given pattern or super patterns before loading size.
   */
  long size(Resource subj, URI pred, Value obj, boolean includeInferred, Resource... contexts)
    throws StoreException
  {
    return cache.size(subj, pred, obj, includeInferred, contexts);
  }

  NamespaceResult getNamespaces()
    throws StoreException
  {
    return new NamespaceResultImpl(getNamespaceMap());
  }

  String getNamespace(String prefix)
    throws StoreException
  {
    return getNamespaceMap().get(prefix);
  }

  private Map<String, String> getNamespaceMap()
    throws StoreException
  {
    long now = System.currentTimeMillis();
    if (namespaces == null || !namespaces.isFresh(now)) {
      NamespaceClient client = this.client.namespaces();
      if (namespaces != null) {
        client.ifNoneMatch(namespaces.getETag());
      }
      NamespaceResult result = client.list();
      if (result == null) {
        assert namespaces != null;
        namespaces.refreshed(now, client.getMaxAge());
      }
      else {
        namespaces = new CachedNamespaceResult(result.asMap(), client.getETag());
      }
    }
    return namespaces.getNamespaces();
  }
}
TOP

Related Classes of org.openrdf.repository.http.HTTPRepository

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.