package org.neo4j.rdf.sail; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.rdf.sail.utils.MutatingLogger; import org.neo4j.rdf.store.RdfStore; import org.neo4j.rdf.util.TemporaryLogger; import org.openrdf.model.ValueFactory; import org.openrdf.model.impl.ValueFactoryImpl; import org.openrdf.sail.Sail; import org.openrdf.sail.SailChangedListener; import org.openrdf.sail.SailConnection; import org.openrdf.sail.SailException; /** * Author: josh * Date: Apr 25, 2008 * Time: 5:32:22 PM */ public class GraphDatabaseSail implements Sail { // TODO: is there such thing as a read-only NeoSail? private static final boolean IS_WRITABLE = true; private final GraphDatabaseService graphDb; private final RdfStore store; private final ValueFactory valueFactory = new ValueFactoryImpl(); private final Set<SailChangedListener> listeners = new HashSet<SailChangedListener>(); private final AtomicInteger connectionCounter = new AtomicInteger(); private final Map<Integer, GraphDatabaseSailConnectionImpl> activeConnections = Collections.synchronizedMap( new HashMap<Integer, GraphDatabaseSailConnectionImpl>() ); public GraphDatabaseSail(final GraphDatabaseService graphDb, final RdfStore store) { this.graphDb = graphDb; this.store = store; } public void setDataDir(final File file) { // Not used. } public File getDataDir() { // Not used. return null; } public void initialize() throws SailException { // Not used. } public void shutDown() throws SailException { TemporaryLogger.getLogger().info( getClass().getName() + " shutDown called", new Exception() ); printActiveConnections(); // System.out.println( "Number of history connections: " + // connectionCounter.get() ); store.shutDown(); } private void printActiveConnections() { for ( Map.Entry<Integer, GraphDatabaseSailConnectionImpl> entry : this.activeConnections.entrySet() ) { String logString = entry.getValue().getClass().getSimpleName() + "[" + entry.getKey() + "] still open when shutting down sail, closing"; TemporaryLogger.getLogger().warn( logString ); MutatingLogger.getLogger().warn( logString ); try { entry.getValue().close(); } catch ( Exception e ) { TemporaryLogger.getLogger().warn( e ); MutatingLogger.getLogger().warn( e ); } } } public boolean isWritable() throws SailException { return IS_WRITABLE; } public SailConnection getConnection() throws SailException { connectionCounter.incrementAndGet(); GraphDatabaseSailConnectionImpl connection = new GraphDatabaseSailConnectionImpl(graphDb, store, this, valueFactory, listeners); this.activeConnections.put( connection.getIdentifier(), connection ); return connection; } void connectionEnded( int identifier, GraphDatabaseSailConnectionImpl connection ) { this.activeConnections.remove( identifier ); } public ValueFactory getValueFactory() { return valueFactory; } public void addSailChangedListener(final SailChangedListener listener) { listeners.add(listener); } public void removeSailChangedListener(final SailChangedListener listener) { listeners.remove(listener); } }