001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020: import java.io.FileNotFoundException;
021: import java.io.IOException;
022: import java.text.ParseException;
023: import java.util.Arrays;
024: import java.util.Collections;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.Map;
029: import java.util.Properties;
030: import java.util.Set;
031: import java.util.SortedMap;
032: import java.util.SortedSet;
033: import java.util.TreeMap;
034: import java.util.TreeSet;
035:
036: import org.geotools.feature.FeatureType;
037:
038: /**
039: * Quick hack of a DataRepository allows me to bridge the existing DataStore
040: * API with these experiments for a Opperations api.
041: *
042: * I have used the old DefaultCatalaog as a starting point.
043: *
044: * This also serves as a reminder that we need CrossDataStore functionality
045: * - at least for Locks. And possibly for "Query".
046: *
047: * @author Jody Garnett
048: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/DefaultRepository.java $
049: */
050: public class DefaultRepository implements Repository {
051:
052: private static final Map definition(String definition)
053: throws ParseException {
054: Map map = new HashMap();
055:
056: String[] params = definition.split(",");
057: int offset = 0;
058: for (int i = 0; i < params.length; i++) {
059: String[] vals = params[i].split("=");
060: if (vals.length == 2) {
061: map.put(vals[0].trim(), vals[1].trim());
062: } else {
063: throw new ParseException("Could not interpret "
064: + params[i], offset);
065: }
066: offset += params[i].length();
067: }
068: return map;
069: }
070:
071: /**
072: * Load a quick datastore definition from a properties file.
073: * <p>
074: * This is useful for test cases.
075: * </p>
076: * @throws IOException
077: * @throws FileNotFoundException
078: */
079: public void load(File propertiesFile) throws Exception {
080: Properties properties = new Properties();
081: properties.load(new FileInputStream(propertiesFile));
082:
083: for (Iterator i = properties.entrySet().iterator(); i.hasNext();) {
084: Map.Entry entry = (Map.Entry) i.next();
085: String dataStoreId = (String) entry.getKey();
086: String definition = (String) entry.getValue();
087: Map params = definition(definition);
088:
089: DataStore dataStore = DataStoreFinder.getDataStore(params);
090: register(dataStoreId, dataStore);
091: }
092: }
093:
094: /** Map of DataStore by dataStoreId */
095: protected SortedMap datastores = new TreeMap();
096:
097: /* (non-Javadoc)
098: * @see org.geotools.data.Repository#getTypes()
099: */
100: public SortedMap getFeatureSources() {
101: SortedMap map = new TreeMap();
102: for (Iterator i = datastores.entrySet().iterator(); i.hasNext();) {
103: Map.Entry entry = (Map.Entry) i.next();
104: String id = (String) entry.getKey();
105: DataStore ds = (DataStore) entry.getValue();
106: String typeNames[];
107: try {
108: typeNames = ds.getTypeNames();
109: for (int j = 0; j < typeNames.length; j++) {
110: String typeName = typeNames[j];
111: try {
112: map.put(id + ":" + typeName, ds
113: .getFeatureSource(typeName));
114: } catch (IOException e) {
115: // type was not available after all
116: }
117: }
118: } catch (IOException e1) {
119: // apparently this datastores is not working
120: }
121: }
122: return map;
123: }
124:
125: /**
126: * Retrieve prefix set.
127: *
128: * @see org.geotools.data.Catalog#getPrefixes()
129: *
130: * @return Set of namespace prefixes
131: * @throws IOException
132: */
133: public Set getPrefixes() throws IOException {
134: Set prefix = new HashSet();
135: for (Iterator i = datastores.values().iterator(); i.hasNext();) {
136: DataStore ds = (DataStore) i.next();
137: for (Iterator t = types(ds).values().iterator(); t
138: .hasNext();) {
139: FeatureType schema = (FeatureType) t.next();
140: prefix.add(schema.getNamespace().toString());
141: }
142: }
143: return prefix;
144: }
145:
146: private SortedSet typeNames(DataStore ds) throws IOException {
147: return new TreeSet(Arrays.asList(ds.getTypeNames()));
148: }
149:
150: private SortedMap types(DataStore ds) throws IOException {
151: SortedMap map = new TreeMap();
152: String typeNames[] = ds.getTypeNames();
153: for (int i = 0; i < typeNames.length; i++) {
154: try {
155: map.put(typeNames[i], ds.getSchema(typeNames[i]));
156: } catch (IOException ignore) {
157: // ignore broken featureType
158: }
159: }
160: return map;
161: }
162:
163: /** All FeatureTypes by dataStoreId:typeName
164: * @throws IOException*/
165: public SortedMap types() throws IOException {
166: SortedMap map = new TreeMap();
167: for (Iterator i = datastores.entrySet().iterator(); i.hasNext();) {
168: Map.Entry entry = (Map.Entry) i.next();
169: String id = (String) entry.getKey();
170: DataStore ds = (DataStore) entry.getValue();
171: for (Iterator t = types(ds).values().iterator(); t
172: .hasNext();) {
173: FeatureType schema = (FeatureType) t.next();
174: map.put(id + ":" + schema.getTypeName(), schema);
175: }
176: }
177: return map;
178: }
179:
180: /**
181: * Implement lockExists.
182: *
183: * @see org.geotools.data.Catalog#lockExists(java.lang.String)
184: *
185: * @param lockID
186: */
187: public boolean lockExists(String lockID) {
188: if (lockID == null)
189: return false;
190: DataStore store;
191: LockingManager lockManager;
192:
193: for (Iterator i = datastores.values().iterator(); i.hasNext();) {
194: store = (DataStore) i.next();
195: lockManager = store.getLockingManager();
196: if (lockManager == null)
197: continue; // did not support locking
198: if (lockManager.exists(lockID)) {
199: return true;
200: }
201: }
202: return false;
203: }
204:
205: /**
206: * Implement lockRefresh.
207: * <p>
208: * Currently it is an error if the lockID is not found. Because if
209: * we can't find it we cannot refresh it.
210: * </p>
211: * <p>
212: * Since locks are time sensitive it is impossible to check
213: * if a lockExists and then be sure it will still exist when you try to
214: * refresh it. Nothing we do can protect client code from this fact, they
215: * will need to do with the IOException when (not if) this situation
216: * occurs.
217: * </p>
218: * @see org.geotools.data.Catalog#lockRefresh(java.lang.String, org.geotools.data.Transaction)
219: *
220: * @param lockID Authorizataion of lock to refresh
221: * @param transaction Transaction used to authorize refresh
222: * @throws IOException If opperation encounters problems, or lock not found
223: * @throws IllegalArgumentException if lockID is <code>null</code>
224: */
225: public boolean lockRefresh(String lockID, Transaction transaction)
226: throws IOException {
227: if (lockID == null) {
228: throw new IllegalArgumentException("lockID required");
229: }
230: if (transaction == null
231: || transaction == Transaction.AUTO_COMMIT) {
232: throw new IllegalArgumentException(
233: "Tansaction required (with authorization for "
234: + lockID + ")");
235: }
236:
237: DataStore store;
238: LockingManager lockManager;
239:
240: boolean refresh = false;
241: for (Iterator i = datastores.values().iterator(); i.hasNext();) {
242: store = (DataStore) i.next();
243: lockManager = store.getLockingManager();
244: if (lockManager == null)
245: continue; // did not support locking
246:
247: if (lockManager.release(lockID, transaction)) {
248: refresh = true;
249: }
250: }
251: return refresh;
252: }
253:
254: /**
255: * Implement lockRelease.
256: * <p>
257: * Currently it is <b>not</b> and error if the lockID is not found, it may
258: * have expired. Since locks are time sensitive it is impossible to check
259: * if a lockExists and then be sure it will still exist when you try to
260: * release it.
261: * </p>
262: * @see org.geotools.data.Catalog#lockRefresh(java.lang.String, org.geotools.data.Transaction)
263: *
264: * @param lockID Authorizataion of lock to refresh
265: * @param transaction Transaction used to authorize refresh
266: * @throws IOException If opperation encounters problems
267: * @throws IllegalArgumentException if lockID is <code>null</code>
268: */
269: public boolean lockRelease(String lockID, Transaction transaction)
270: throws IOException {
271: if (lockID == null) {
272: throw new IllegalArgumentException("lockID required");
273: }
274: if (transaction == null
275: || transaction == Transaction.AUTO_COMMIT) {
276: throw new IllegalArgumentException(
277: "Tansaction required (with authorization for "
278: + lockID + ")");
279: }
280:
281: DataStore store;
282: LockingManager lockManager;
283:
284: boolean release = false;
285: for (Iterator i = datastores.values().iterator(); i.hasNext();) {
286: store = (DataStore) i.next();
287: lockManager = store.getLockingManager();
288: if (lockManager == null)
289: continue; // did not support locking
290:
291: if (lockManager.release(lockID, transaction)) {
292: release = true;
293: }
294: }
295: return release;
296: }
297:
298: /**
299: * Implement registerDataStore.
300: * <p>
301: * Description ...
302: * </p>
303: * @see org.geotools.data.Catalog#registerDataStore(org.geotools.data.DataStore)
304: *
305: * @param dataStore
306: * @throws IOException
307: */
308: public void register(String id, DataStore dataStore)
309: throws IOException {
310: if (datastores.containsKey(id)) {
311: throw new IOException("ID already registered");
312: }
313: if (datastores.containsValue(dataStore)) {
314: throw new IOException("dataStore already registered");
315: }
316: datastores.put(id, dataStore);
317: }
318:
319: /**
320: * Implement getDataStores.
321: * <p>
322: * Description ...
323: * </p>
324: * @see org.geotools.data.Catalog#getDataStores(java.lang.String)
325: *
326: * @param id a String giving the name of the DataStore
327: *
328: * @return the DataStore with the given name
329: */
330: public DataStore datastore(String id) {
331: return (DataStore) datastores.get(id);
332: }
333:
334: /**
335: * Access to the set of registered DataStores.
336: * <p>
337: * The provided Set may not be modified :-)
338: * </p>
339: * @see org.geotools.data.Catalog#getDataStores(java.lang.String)
340: *
341: *
342: *
343: */
344: public Map getDataStores() {
345: return Collections.unmodifiableMap(datastores);
346: }
347:
348: public FeatureSource source(String dataStoreId, String typeName)
349: throws IOException {
350: DataStore ds = datastore(dataStoreId);
351: return ds.getFeatureSource(typeName);
352: }
353: }
|