package com.vividsolutions.jump.workbench.datastore; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.vividsolutions.jump.datastore.DataStoreConnection; import com.vividsolutions.jump.datastore.DataStoreDriver; import com.vividsolutions.jump.datastore.DataStoreException; import com.vividsolutions.jump.datastore.DataStoreMetadata; import com.vividsolutions.jump.datastore.Query; import com.vividsolutions.jump.io.FeatureInputStream; import com.vividsolutions.jump.util.Blackboard; import com.vividsolutions.jump.workbench.WorkbenchContext; import com.vividsolutions.jump.workbench.ui.plugin.PersistentBlackboardPlugIn; /** * Reuses existing connections where possible. */ public class ConnectionManager { public interface Listener { void connectionDescriptorAdded(ConnectionDescriptor connectionDescriptor); void connectionDescriptorRemoved( ConnectionDescriptor connectionDescriptor); } private WorkbenchContext context; /** * @param connectionDescriptors * a collection that is kept up to date by the ConnectionManager */ private ConnectionManager(WorkbenchContext context, final Collection connectionDescriptors) { this.context = context; for (Iterator i = connectionDescriptors.iterator(); i.hasNext();) { ConnectionDescriptor connectionDescriptor = (ConnectionDescriptor) i .next(); connectionDescriptorToConnectionMap.put(connectionDescriptor, DUMMY_CONNECTION); } addListener(new Listener() { public void connectionDescriptorAdded( ConnectionDescriptor connectionDescriptor) { updateConnectionDescriptors(); } public void connectionDescriptorRemoved( ConnectionDescriptor connectionDescriptor) { updateConnectionDescriptors(); } private void updateConnectionDescriptors() { connectionDescriptors.clear(); connectionDescriptors .addAll(connectionDescriptorToConnectionMap.keySet()); } }); } private Map connectionDescriptorToConnectionMap = new HashMap(); public DataStoreConnection getOpenConnection( ConnectionDescriptor connectionDescriptor) throws Exception { if (getConnection(connectionDescriptor).isClosed()) { connectionDescriptorToConnectionMap.put(connectionDescriptor, connectionDescriptor.createConnection( getDriver(connectionDescriptor.getDataStoreDriverClassName()))); } return getConnection(connectionDescriptor); } public DataStoreDriver getDriver(String driverClassName) { DataStoreDriver driver = findDriverRegistryEntry(driverClassName); if (driver == null) throw new RuntimeException("Can't find DataStoreDriver: " + driverClassName); return driver; } private DataStoreDriver findDriverRegistryEntry(String driverClassName) { List drivers = context.getRegistry().getEntries(DataStoreDriver.REGISTRY_CLASSIFICATION); for (Iterator i = drivers.iterator(); i.hasNext(); ) { DataStoreDriver driver = (DataStoreDriver) i.next(); if (driver.getClass().getName().equals(driverClassName)) return driver; } return null; } private static final DataStoreConnection DUMMY_CONNECTION = new DataStoreConnection() { public DataStoreMetadata getMetadata() { throw new UnsupportedOperationException(); } public FeatureInputStream execute(Query query) { throw new UnsupportedOperationException(); } public void close() throws DataStoreException { throw new UnsupportedOperationException(); } public boolean isClosed() throws DataStoreException { return true; } }; /** * @return a connection, possibly closed, never null */ public DataStoreConnection getConnection( ConnectionDescriptor connectionDescriptor) { if (!connectionDescriptorToConnectionMap .containsKey(connectionDescriptor)) { connectionDescriptorToConnectionMap.put(connectionDescriptor, DUMMY_CONNECTION); fireConnectionDescriptorAdded(connectionDescriptor); } return (DataStoreConnection) connectionDescriptorToConnectionMap .get(connectionDescriptor); } public Collection getConnectionDescriptors() { return Collections .unmodifiableCollection(connectionDescriptorToConnectionMap .keySet()); } /** * Removes the ConnectionDescriptor and closes its associated * DataStoreConnection. */ public void deleteConnectionDescriptor( ConnectionDescriptor connectionDescriptor) throws DataStoreException { if (!getConnection(connectionDescriptor).isClosed()) { getConnection(connectionDescriptor).close(); } connectionDescriptorToConnectionMap.remove(connectionDescriptor); fireConnectionDescriptorRemoved(connectionDescriptor); } private void fireConnectionDescriptorAdded( ConnectionDescriptor connectionDescriptor) { for (Iterator i = listeners.iterator(); i.hasNext();) { Listener listener = (Listener) i.next(); listener.connectionDescriptorAdded(connectionDescriptor); } } private void fireConnectionDescriptorRemoved( ConnectionDescriptor connectionDescriptor) { for (Iterator i = listeners.iterator(); i.hasNext();) { Listener listener = (Listener) i.next(); listener.connectionDescriptorRemoved(connectionDescriptor); } } public static ConnectionManager instance(WorkbenchContext context) { Blackboard blackboard = context.getBlackboard(); String INSTANCE_KEY = ConnectionManager.class.getName() + " - INSTANCE"; if (blackboard.get(INSTANCE_KEY) == null) { // If the blackboard has an associated PersistentBlackboard, // that will be used to persist the DataStoreDrivers. // [Jon Aquino 2005-03-11] blackboard.put(INSTANCE_KEY, new ConnectionManager( context, (Collection) PersistentBlackboardPlugIn.get(blackboard) .get( ConnectionManager.class.getName() + " - CONNECTION DESCRIPTORS", new ArrayList()))); } return (ConnectionManager) blackboard.get(INSTANCE_KEY); } private List listeners = new ArrayList(); public void addListener(Listener listener) { listeners.add(listener); } public void closeConnections() throws DataStoreException { for (Iterator i = getConnectionDescriptors().iterator(); i.hasNext();) { ConnectionDescriptor connectionDescriptor = (ConnectionDescriptor) i .next(); if (!getConnection(connectionDescriptor).isClosed()) { getConnection(connectionDescriptor).close(); } } } }