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.IOException;
019: import java.util.Collections;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.Set;
023:
024: import org.geotools.feature.AttributeType;
025: import org.geotools.feature.Feature;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.feature.IllegalAttributeException;
028: import org.geotools.feature.SimpleFeature;
029: import org.opengis.filter.Filter;
030:
031: /**
032: * This is a starting point for providing your own FeatureStore implementation.
033: *
034: * @author Jody Garnett, Refractions Research
035: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/AbstractFeatureStore.java $
036: */
037: public abstract class AbstractFeatureStore extends
038: AbstractFeatureSource implements FeatureStore {
039: /** Current Transaction this FeatureSource is opperating against */
040: protected Transaction transaction = Transaction.AUTO_COMMIT;
041:
042: public AbstractFeatureStore() {
043: // just to keep the default constructor around
044: }
045:
046: /**
047: * This constructors allows to set the supported hints
048: * @param hints
049: */
050: public AbstractFeatureStore(Set hints) {
051: super (hints);
052: }
053:
054: /**
055: * Retrieve the Transaction this FeatureSource is opperating against.
056: *
057: * @return Transaction FeatureSource is operating against
058: */
059: public Transaction getTransaction() {
060: return transaction;
061: }
062:
063: //
064: // FeatureStore implementation against DataStore API
065: //
066:
067: /**
068: * Modifies features matching <code>filter</code>.
069: *
070: * <p>
071: * Equivelent to:
072: * </p>
073: * <pre><code>
074: * FeatureWriter writer = dataStore.getFeatureWriter( typeName, filter, transaction );
075: * while( writer.hasNext() ){
076: * feature = writer.next();
077: * feature.setAttribute( type.getName(), value );
078: * writer.write();
079: * }
080: * writer.close();
081: * </code>
082: * </pre>
083: *
084: * <p>
085: * Subclasses may override this method to perform the appropriate
086: * optimization for this result.
087: * </p>
088: *
089: * @param type Attribute to modify
090: * @param value Modification being made to type
091: * @param filter Identifies features to modify
092: *
093: * @throws IOException If modification could not be made
094: */
095: public void modifyFeatures(AttributeType type, Object value,
096: Filter filter) throws IOException {
097: modifyFeatures(new AttributeType[] { type, },
098: new Object[] { value, }, filter);
099: }
100:
101: /**
102: * Modifies features matching <code>filter</code>.
103: *
104: * <p>
105: * Equivelent to:
106: * </p>
107: * <pre><code>
108: * FeatureWriter writer = dataStore.getFeatureWriter( typeName, filter, transaction );
109: * Feature feature;
110: * while( writer.hasNext() ){
111: * feature = writer.next();
112: * feature.setAttribute( type[0].getName(), value[0] );
113: * feature.setAttribute( type[1].getName(), value[1] );
114: * ...
115: * feature.setAttribute( type[N].getName(), value[N] );
116: * writer.write();
117: * }
118: * writer.close();
119: * </code>
120: * </pre>
121: *
122: * <p>
123: * Subclasses may override this method to perform the appropriate
124: * optimization for this result.
125: * </p>
126: *
127: * @param type Attributes to modify
128: * @param value Modifications being made to type
129: * @param filter Identifies features to modify
130: *
131: * @throws IOException If we could not modify Feature
132: * @throws DataSourceException See IOException
133: */
134: public void modifyFeatures(AttributeType[] type, Object[] value,
135: Filter filter) throws IOException {
136: String typeName = getSchema().getTypeName();
137: FeatureWriter writer = getDataStore().getFeatureWriter(
138: typeName, filter, getTransaction());
139: Feature feature;
140:
141: try {
142: while (writer.hasNext()) {
143: feature = writer.next();
144:
145: for (int i = 0; i < type.length; i++) {
146: try {
147: feature.setAttribute(type[i].getName(),
148: value[i]);
149: } catch (IllegalAttributeException e) {
150: throw new DataSourceException(
151: "Could not update feature "
152: + feature.getID() + " with "
153: + type[i].getName() + "="
154: + value[i], e);
155: }
156: }
157:
158: writer.write();
159: }
160: } finally {
161: writer.close();
162: }
163: }
164:
165: /**
166: * Add Features from reader to this FeatureStore.
167: *
168: * <p>
169: * Equivelent to:
170: * </p>
171: * <pre><code>
172: * Set set = new HashSet();
173: * FeatureWriter writer = dataStore.getFeatureWriter( typeName, true, transaction );
174: * Featrue feature, newFeature;
175: * while( reader.hasNext() ){
176: * feature = reader.next();
177: * newFeature = writer.next();
178: * newFeature.setAttributes( feature.getAttribtues( null ) );
179: * writer.write();
180: * set.add( newfeature.getID() );
181: * }
182: * reader.close();
183: * writer.close();
184: *
185: * return set;
186: * </code>
187: * </pre>
188: *
189: * <p>
190: * (If you don't have a FeatureReader handy DataUtilities.reader() may be
191: * able to help out)
192: * </p>
193: *
194: * <p>
195: * Subclasses may override this method to perform the appropriate
196: * optimization for this result.
197: * </p>
198: *
199: * @param reader
200: *
201: * @return The Set of FeatureIDs added
202: *
203: * @throws IOException If we encounter a problem encounter writing content
204: * @throws DataSourceException See IOException
205: *
206: * @see org.geotools.data.FeatureStore#addFeatures(org.geotools.data.FeatureReader)
207: */
208: public Set addFeatures(FeatureReader reader) throws IOException {
209: Set addedFids = new HashSet();
210: String typeName = getSchema().getTypeName();
211: Feature feature = null;
212: SimpleFeature newFeature;
213: FeatureWriter writer = getDataStore().getFeatureWriterAppend(
214: typeName, getTransaction());
215:
216: try {
217: while (reader.hasNext()) {
218: try {
219: feature = reader.next();
220: } catch (Exception e) {
221: throw new DataSourceException(
222: "Could not add Features, problem with provided reader",
223: e);
224: }
225:
226: newFeature = (SimpleFeature) writer.next();
227:
228: try {
229: newFeature.setAttributes(feature
230: .getAttributes(null));
231: } catch (IllegalAttributeException writeProblem) {
232: throw new DataSourceException("Could not create "
233: + typeName + " out of provided feature: "
234: + feature.getID(), writeProblem);
235: }
236:
237: writer.write();
238: addedFids.add(newFeature.getID());
239: }
240: } finally {
241: reader.close();
242: writer.close();
243: }
244:
245: return addedFids;
246: }
247:
248: public Set addFeatures(FeatureCollection collection)
249: throws IOException {
250: Set addedFids = new HashSet();
251: String typeName = getSchema().getTypeName();
252: Feature feature = null;
253: SimpleFeature newFeature;
254: FeatureWriter writer = getDataStore().getFeatureWriterAppend(
255: typeName, getTransaction());
256:
257: Iterator iterator = collection.iterator();
258: try {
259:
260: while (iterator.hasNext()) {
261: feature = (Feature) iterator.next();
262: newFeature = (SimpleFeature) writer.next();
263: try {
264: newFeature.setAttributes(feature
265: .getAttributes(null));
266: } catch (IllegalAttributeException writeProblem) {
267: throw new DataSourceException("Could not create "
268: + typeName + " out of provided feature: "
269: + feature.getID(), writeProblem);
270: }
271:
272: writer.write();
273: addedFids.add(newFeature.getID());
274: }
275: } finally {
276: collection.close(iterator);
277: writer.close();
278: }
279: return addedFids;
280: }
281:
282: /**
283: * Removes features indicated by provided filter.
284: *
285: * <p>
286: * Equivelent to:
287: * </p>
288: * <pre><code>
289: * FeatureWriter writer = dataStore.getFeatureWriter( typeName, filter, transaction );
290: * Feature feature;
291: * while( writer.hasNext() ){
292: * feature = writer.next();
293: * writer.remove();
294: * }
295: * writer.close();
296: * </code>
297: * </pre>
298: *
299: * <p>
300: * Subclasses may override this method to perform the appropriate
301: * optimization for this result.
302: * </p>
303: *
304: * @param filter Identifies features to remove
305: *
306: * @throws IOException
307: */
308: public void removeFeatures(Filter filter) throws IOException {
309: String typeName = getSchema().getTypeName();
310: FeatureWriter writer = getDataStore().getFeatureWriter(
311: typeName, filter, getTransaction());
312:
313: try {
314: while (writer.hasNext()) {
315: writer.next();
316: writer.remove();
317: }
318: } finally {
319: writer.close();
320: }
321: }
322:
323: /**
324: * Replace with contents of reader.
325: *
326: * <p>
327: * Equivelent to:
328: * </p>
329: * <pre><code>
330: * FeatureWriter writer = dataStore.getFeatureWriter( typeName, false, transaction );
331: * Feature feature, newFeature;
332: * while( writer.hasNext() ){
333: * feature = writer.next();
334: * writer.remove();
335: * }
336: * while( reader.hasNext() ){
337: * newFeature = reader.next();
338: * feature = writer.next();
339: * newFeature.setAttributes( feature.getAttributes( null ) );
340: * writer.write();
341: * }
342: * reader.close();
343: * writer.close();
344: * </code>
345: * </pre>
346: *
347: * <p>
348: * Subclasses may override this method to perform the appropriate
349: * optimization for this result.
350: * </p>
351: *
352: * @param reader Contents to replace with
353: *
354: * @throws IOException if anything goes wrong during replacement
355: * @throws DataSourceException See IOException
356: */
357: public void setFeatures(FeatureReader reader) throws IOException {
358: String typeName = getSchema().getTypeName();
359: FeatureWriter writer = getDataStore().getFeatureWriter(
360: typeName, getTransaction());
361: Feature feature;
362: SimpleFeature newFeature;
363:
364: try {
365: while (writer.hasNext()) {
366: feature = writer.next();
367: writer.remove();
368: }
369:
370: while (reader.hasNext()) {
371: try {
372: feature = reader.next();
373: } catch (Exception readProblem) {
374: throw new DataSourceException(
375: "Could not add Features, problem with provided reader",
376: readProblem);
377: }
378:
379: newFeature = (SimpleFeature) writer.next();
380:
381: try {
382: newFeature.setAttributes(feature
383: .getAttributes(null));
384: } catch (IllegalAttributeException writeProblem) {
385: throw new DataSourceException("Could not create "
386: + typeName + " out of provided feature: "
387: + feature.getID(), writeProblem);
388: }
389:
390: writer.write();
391: }
392: } finally {
393: reader.close();
394: writer.close();
395: }
396: }
397:
398: public void setTransaction(Transaction transaction) {
399: if (transaction == null) {
400: throw new IllegalArgumentException(
401: "Transaction cannot be null, did you mean Transaction.AUTO_COMMIT?");
402: }
403:
404: this.transaction = transaction;
405: }
406: }
|