/* * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ package com.mysema.rdfbean.virtuoso; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.sql.SQLException; import java.util.Collection; import java.util.Collections; import java.util.Map; import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import virtuoso.jdbc4.VirtuosoDataSource; import com.mysema.commons.lang.Assert; import com.mysema.commons.lang.CloseableIterator; import com.mysema.rdfbean.Namespaces; import com.mysema.rdfbean.model.*; import com.mysema.rdfbean.model.io.RDFSource; import com.mysema.rdfbean.model.io.RDFWriter; import com.mysema.rdfbean.model.io.WriterUtils; import com.mysema.rdfbean.xsd.ConverterRegistryImpl; /** * @author tiwe * */ public class VirtuosoRepository implements Repository { private static final String RDFBEAN_NIL = "rdfbean:nil"; private static final Logger logger = LoggerFactory.getLogger(VirtuosoRepository.class); private final VirtuosoDataSource ds = new VirtuosoDataSource(); private final String host; private final Converter converter = new Converter(new ConverterRegistryImpl()); @Nullable private RDFSource[] sources; @Nullable private File dataDir; private static final String charset = "UTF-8"; private final UID defGraph; private Collection<UID> allowedGraphs = Collections.emptySet(); private int prefetchSize = 200; private boolean initialized = false; @Nullable private Integer initialPoolSize, minPoolSize, maxPoolSize; @Nullable private IdSequence idSequence; public VirtuosoRepository(String hostlist, String user, String password) { this(hostlist, user, password, RDFBEAN_NIL); } public VirtuosoRepository(String host, int port, String user, String password) { this(host, port, user, password, RDFBEAN_NIL); } public VirtuosoRepository(String hostlist, String user, String password, String defGraph) { this(hostlist, 1111, user, password, defGraph); } public VirtuosoRepository(String host, int port, String user, String password, String defGraph) { this.defGraph = new UID(defGraph); this.host = host; ds.setServerName(host); ds.setPortNumber(port); ds.setUser(user); ds.setPassword(password); ds.setCharset(charset); } @Override public void close() { initialized = false; } @Override public <RT> RT execute(RDFConnectionCallback<RT> operation) { RDFConnection connection = openConnection(); try { try { RDFBeanTransaction tx = connection.beginTransaction(false, RDFBeanTransaction.TIMEOUT, RDFBeanTransaction.ISOLATION); try { RT retVal = operation.doInConnection(connection); tx.commit(); return retVal; } catch (IOException io) { tx.rollback(); throw io; } } finally { connection.close(); } } catch (IOException io) { throw new RepositoryException(io); } } @Override public void export(Format format, Map<String, String> ns2prefix, UID context, OutputStream out) { RDFWriter writer = WriterUtils.createWriter(format, out, ns2prefix); RDFConnection conn = openConnection(); try { CloseableIterator<STMT> stmts = conn.findStatements(null, null, null, context, false); try { writer.begin(); while (stmts.hasNext()) { writer.handle(stmts.next()); } writer.end(); } finally { stmts.close(); } } finally { conn.close(); } } @Override public void export(Format format, UID context, OutputStream out) { export(format, Namespaces.DEFAULT, context, out); } public VirtuosoRepositoryConnection openConnection() { try { java.sql.Connection connection = ds.getConnection(); return new VirtuosoRepositoryConnection(idSequence, converter, prefetchSize, defGraph, allowedGraphs, connection); } catch (SQLException e) { logger.error("Connection to " + host + " FAILED."); throw new RepositoryException(e); } } public File getDataDir() { return this.dataDir; } public int getFetchSize() { return this.prefetchSize; } public void initialize() { if (!initialized) { if (dataDir != null) { idSequence = new FileIdSequence(new File(dataDir, "lastLocalId")); } else { idSequence = new MemoryIdSequence(); } try { ds.setLogWriter(new PrintWriter(System.err)); } catch (SQLException e) { throw new RepositoryException(e); } VirtuosoRepositoryConnection connection = openConnection(); RDFBeanTransaction tx = connection.beginTransaction(false, RDFBeanTransaction.TIMEOUT, RDFBeanTransaction.ISOLATION); try { if (sources != null) { for (RDFSource source : sources) { if (source.getResource() != null) { logger.info("loading " + source.getResource()); } UID context = new UID(source.getContext()); InputStream is = source.openStream(); try { connection.load(source.getFormat(), is, context, false); } finally { is.close(); } } } tx.commit(); } catch (Exception e) { tx.rollback(); throw new RepositoryException(e); } finally { connection.close(); } initialized = true; } } @Override public void load(Format format, InputStream is, UID context, boolean replace) { VirtuosoRepositoryConnection connection = openConnection(); try { try { connection.load(format, is, context, replace); } finally { is.close(); } } catch (SQLException e) { throw new RepositoryException(e); } catch (IOException e) { throw new RepositoryException(e); } finally { connection.close(); } } public boolean isInitialized() { return initialized; } public void setDataDir(File dataDir) { this.dataDir = Assert.notNull(dataDir, "dataDir"); } public void setFetchSize(int sz) { this.prefetchSize = sz; } public void setSources(RDFSource... sources) { this.sources = sources; } public void setAllowedGraphs(Collection<UID> allowedGraphs) { this.allowedGraphs = Assert.notNull(allowedGraphs, "allowedGraphs"); } public void setInitialPoolSize(int initialPoolSize) { this.initialPoolSize = initialPoolSize; } public void setMinPoolSize(int minPoolSize) { this.minPoolSize = minPoolSize; } public void setMaxPoolSize(int maxPoolSize) { this.maxPoolSize = maxPoolSize; } }