001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.repository.dataset;
007:
008: import java.io.IOException;
009: import java.io.InputStream;
010: import java.net.URL;
011: import java.net.URLConnection;
012: import java.util.Map;
013: import java.util.concurrent.ConcurrentHashMap;
014:
015: import org.openrdf.model.URI;
016: import org.openrdf.repository.Repository;
017: import org.openrdf.repository.RepositoryConnection;
018: import org.openrdf.repository.RepositoryException;
019: import org.openrdf.repository.base.RepositoryWrapper;
020: import org.openrdf.repository.sail.SailRepository;
021: import org.openrdf.rio.RDFFormat;
022: import org.openrdf.rio.RDFParseException;
023: import org.openrdf.rio.RDFParserRegistry;
024:
025: public class DatasetRepository extends RepositoryWrapper {
026:
027: private Map<URL, Long> lastModified = new ConcurrentHashMap<URL, Long>();
028:
029: public DatasetRepository() {
030: super ();
031: }
032:
033: public DatasetRepository(SailRepository delegate) {
034: super (delegate);
035: }
036:
037: @Override
038: public void setDelegate(Repository delegate) {
039: if (delegate instanceof SailRepository) {
040: super .setDelegate(delegate);
041: } else {
042: throw new IllegalArgumentException(
043: "delegate must be a SailRepository, is: "
044: + delegate.getClass());
045: }
046: }
047:
048: @Override
049: public SailRepository getDelegate() {
050: return (SailRepository) super .getDelegate();
051: }
052:
053: @Override
054: public RepositoryConnection getConnection()
055: throws RepositoryException {
056: return new DatasetRepositoryConnection(this , getDelegate()
057: .getConnection());
058: }
059:
060: public void loadDataset(URL url, URI context)
061: throws RepositoryException {
062: try {
063: Long since = lastModified.get(url);
064: URLConnection urlCon = url.openConnection();
065: if (since != null) {
066: urlCon.setIfModifiedSince(since);
067: }
068: if (since == null || since < urlCon.getLastModified()) {
069: load(url, urlCon, context);
070: }
071: } catch (RDFParseException e) {
072: throw new RepositoryException(e);
073: } catch (IOException e) {
074: throw new RepositoryException(e);
075: }
076: }
077:
078: private synchronized void load(URL url, URLConnection urlCon,
079: URI context) throws RepositoryException, RDFParseException,
080: IOException {
081: long modified = urlCon.getLastModified();
082: if (lastModified.containsKey(url)
083: && lastModified.get(url) >= modified) {
084: return;
085: }
086:
087: // Try to determine the data's MIME type
088: String mimeType = urlCon.getContentType();
089: int semiColonIdx = mimeType.indexOf(';');
090: if (semiColonIdx >= 0) {
091: mimeType = mimeType.substring(0, semiColonIdx);
092: }
093: RDFFormat format = RDFParserRegistry.getInstance()
094: .getFileFormatForMIMEType(mimeType);
095:
096: // Fall back to using file name extensions
097: if (format == null) {
098: format = RDFParserRegistry.getInstance()
099: .getFileFormatForFileName(url.getFile());
100: }
101:
102: InputStream stream = urlCon.getInputStream();
103: try {
104: RepositoryConnection repCon = super .getConnection();
105: try {
106: repCon.setAutoCommit(false);
107: repCon.clear(context);
108: repCon.add(stream, url.toExternalForm(), format,
109: context);
110: repCon.commit();
111: lastModified.put(url, modified);
112: } finally {
113: repCon.close();
114: }
115: } finally {
116: stream.close();
117: }
118: }
119: }
|