001: package com.vividsolutions.jump.workbench.datastore;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Collections;
006: import java.util.HashMap;
007: import java.util.Iterator;
008: import java.util.List;
009: import java.util.Map;
010:
011: import com.vividsolutions.jump.datastore.DataStoreConnection;
012: import com.vividsolutions.jump.datastore.DataStoreDriver;
013: import com.vividsolutions.jump.datastore.DataStoreException;
014: import com.vividsolutions.jump.datastore.DataStoreMetadata;
015: import com.vividsolutions.jump.datastore.Query;
016: import com.vividsolutions.jump.io.FeatureInputStream;
017: import com.vividsolutions.jump.util.Blackboard;
018: import com.vividsolutions.jump.workbench.WorkbenchContext;
019: import com.vividsolutions.jump.workbench.ui.plugin.PersistentBlackboardPlugIn;
020:
021: /**
022: * Reuses existing connections where possible.
023: */
024: public class ConnectionManager {
025:
026: public interface Listener {
027: void connectionDescriptorAdded(
028: ConnectionDescriptor connectionDescriptor);
029:
030: void connectionDescriptorRemoved(
031: ConnectionDescriptor connectionDescriptor);
032: }
033:
034: private WorkbenchContext context;
035:
036: /**
037: * @param connectionDescriptors
038: * a collection that is kept up to date by the ConnectionManager
039: */
040: private ConnectionManager(WorkbenchContext context,
041: final Collection connectionDescriptors) {
042: this .context = context;
043: for (Iterator i = connectionDescriptors.iterator(); i.hasNext();) {
044: ConnectionDescriptor connectionDescriptor = (ConnectionDescriptor) i
045: .next();
046: connectionDescriptorToConnectionMap.put(
047: connectionDescriptor, DUMMY_CONNECTION);
048: }
049: addListener(new Listener() {
050: public void connectionDescriptorAdded(
051: ConnectionDescriptor connectionDescriptor) {
052: updateConnectionDescriptors();
053: }
054:
055: public void connectionDescriptorRemoved(
056: ConnectionDescriptor connectionDescriptor) {
057: updateConnectionDescriptors();
058: }
059:
060: private void updateConnectionDescriptors() {
061: connectionDescriptors.clear();
062: connectionDescriptors
063: .addAll(connectionDescriptorToConnectionMap
064: .keySet());
065: }
066: });
067: }
068:
069: private Map connectionDescriptorToConnectionMap = new HashMap();
070:
071: public DataStoreConnection getOpenConnection(
072: ConnectionDescriptor connectionDescriptor) throws Exception {
073: if (getConnection(connectionDescriptor).isClosed()) {
074: connectionDescriptorToConnectionMap
075: .put(
076: connectionDescriptor,
077: connectionDescriptor
078: .createConnection(getDriver(connectionDescriptor
079: .getDataStoreDriverClassName())));
080: }
081: return getConnection(connectionDescriptor);
082: }
083:
084: public DataStoreDriver getDriver(String driverClassName) {
085: DataStoreDriver driver = findDriverRegistryEntry(driverClassName);
086: if (driver == null)
087: throw new RuntimeException("Can't find DataStoreDriver: "
088: + driverClassName);
089: return driver;
090: }
091:
092: private DataStoreDriver findDriverRegistryEntry(
093: String driverClassName) {
094: List drivers = context.getRegistry().getEntries(
095: DataStoreDriver.REGISTRY_CLASSIFICATION);
096: for (Iterator i = drivers.iterator(); i.hasNext();) {
097: DataStoreDriver driver = (DataStoreDriver) i.next();
098: if (driver.getClass().getName().equals(driverClassName))
099: return driver;
100: }
101: return null;
102: }
103:
104: private static final DataStoreConnection DUMMY_CONNECTION = new DataStoreConnection() {
105: public DataStoreMetadata getMetadata() {
106: throw new UnsupportedOperationException();
107: }
108:
109: public FeatureInputStream execute(Query query) {
110: throw new UnsupportedOperationException();
111: }
112:
113: public void close() throws DataStoreException {
114: throw new UnsupportedOperationException();
115: }
116:
117: public boolean isClosed() throws DataStoreException {
118: return true;
119: }
120: };
121:
122: /**
123: * @return a connection, possibly closed, never null
124: */
125: public DataStoreConnection getConnection(
126: ConnectionDescriptor connectionDescriptor) {
127: if (!connectionDescriptorToConnectionMap
128: .containsKey(connectionDescriptor)) {
129: connectionDescriptorToConnectionMap.put(
130: connectionDescriptor, DUMMY_CONNECTION);
131: fireConnectionDescriptorAdded(connectionDescriptor);
132: }
133: return (DataStoreConnection) connectionDescriptorToConnectionMap
134: .get(connectionDescriptor);
135: }
136:
137: public Collection getConnectionDescriptors() {
138: return Collections
139: .unmodifiableCollection(connectionDescriptorToConnectionMap
140: .keySet());
141: }
142:
143: /**
144: * Removes the ConnectionDescriptor and closes its associated
145: * DataStoreConnection.
146: */
147: public void deleteConnectionDescriptor(
148: ConnectionDescriptor connectionDescriptor)
149: throws DataStoreException {
150: if (!getConnection(connectionDescriptor).isClosed()) {
151: getConnection(connectionDescriptor).close();
152: }
153: connectionDescriptorToConnectionMap
154: .remove(connectionDescriptor);
155: fireConnectionDescriptorRemoved(connectionDescriptor);
156: }
157:
158: private void fireConnectionDescriptorAdded(
159: ConnectionDescriptor connectionDescriptor) {
160: for (Iterator i = listeners.iterator(); i.hasNext();) {
161: Listener listener = (Listener) i.next();
162: listener.connectionDescriptorAdded(connectionDescriptor);
163: }
164: }
165:
166: private void fireConnectionDescriptorRemoved(
167: ConnectionDescriptor connectionDescriptor) {
168: for (Iterator i = listeners.iterator(); i.hasNext();) {
169: Listener listener = (Listener) i.next();
170: listener.connectionDescriptorRemoved(connectionDescriptor);
171: }
172: }
173:
174: public static ConnectionManager instance(WorkbenchContext context) {
175: Blackboard blackboard = context.getBlackboard();
176: String INSTANCE_KEY = ConnectionManager.class.getName()
177: + " - INSTANCE";
178: if (blackboard.get(INSTANCE_KEY) == null) {
179: // If the blackboard has an associated PersistentBlackboard,
180: // that will be used to persist the DataStoreDrivers.
181: // [Jon Aquino 2005-03-11]
182: blackboard.put(INSTANCE_KEY, new ConnectionManager(context,
183: (Collection) PersistentBlackboardPlugIn.get(
184: blackboard).get(
185: ConnectionManager.class.getName()
186: + " - CONNECTION DESCRIPTORS",
187: new ArrayList())));
188: }
189: return (ConnectionManager) blackboard.get(INSTANCE_KEY);
190: }
191:
192: private List listeners = new ArrayList();
193:
194: public void addListener(Listener listener) {
195: listeners.add(listener);
196: }
197:
198: public void closeConnections() throws DataStoreException {
199: for (Iterator i = getConnectionDescriptors().iterator(); i
200: .hasNext();) {
201: ConnectionDescriptor connectionDescriptor = (ConnectionDescriptor) i
202: .next();
203: if (!getConnection(connectionDescriptor).isClosed()) {
204: getConnection(connectionDescriptor).close();
205: }
206: }
207: }
208:
209: }
|