001: /*
002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004,
003: * Refractions Research Inc. This library is free software; you can redistribute it and/or modify it
004: * under the terms of the GNU Lesser General Public License as published by the Free Software
005: * Foundation; version 2.1 of the License. This library is distributed in the hope that it will be
006: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
007: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
008: */
009: package net.refractions.udig.project.internal.commands.edit;
010:
011: import java.util.Collections;
012:
013: import net.refractions.udig.core.IBlockingProvider;
014: import net.refractions.udig.core.StaticFeatureCollection;
015: import net.refractions.udig.project.command.MapCommand;
016: import net.refractions.udig.project.command.UndoableMapCommand;
017: import net.refractions.udig.project.command.provider.EditFeatureProvider;
018: import net.refractions.udig.project.command.provider.EditLayerFeatureStoreProvider;
019: import net.refractions.udig.project.internal.Messages;
020: import net.refractions.udig.project.internal.ProjectPlugin;
021:
022: import org.eclipse.core.runtime.IProgressMonitor;
023: import org.eclipse.core.runtime.SubProgressMonitor;
024: import org.geotools.data.FeatureStore;
025: import org.geotools.feature.Feature;
026: import org.geotools.feature.FeatureCollection;
027: import org.geotools.feature.FeatureIterator;
028: import org.geotools.feature.FeatureType;
029: import org.geotools.filter.FidFilter;
030: import org.geotools.filter.FilterFactory;
031: import org.geotools.filter.FilterFactoryFinder;
032:
033: /**
034: * Compares the editFeature with the corresponding feature in the data store (The feature with the
035: * same fid) and replaces the old feature with the edit feature. If the feature is a new feature
036: * then the feature is added to the datastore.
037: *
038: * @author jeichar
039: * @since 0.3
040: */
041: public class WriteFeatureChangesCommand extends AbstractEditCommand
042: implements UndoableMapCommand {
043: private IBlockingProvider<Feature> featureProvider;
044: private IBlockingProvider<FeatureStore> storeProvider;
045: private FeatureStore store;
046: private FidFilter filter;
047: private boolean added = false;
048: private boolean noChange = false;
049: private Feature editFeature;
050:
051: public WriteFeatureChangesCommand() {
052: this (null, null);
053: }
054:
055: public WriteFeatureChangesCommand(
056: IBlockingProvider<Feature> feature,
057: IBlockingProvider<FeatureStore> featureStore) {
058: if (feature == null) {
059: this .featureProvider = new EditFeatureProvider(this );
060: } else {
061: this .featureProvider = feature;
062: }
063: if (featureStore == null) {
064: this .storeProvider = new EditLayerFeatureStoreProvider(this );
065: } else {
066: this .storeProvider = featureStore;
067: }
068: }
069:
070: /**
071: * @see net.refractions.udig.project.internal.command.MapCommand#run()
072: */
073: @SuppressWarnings("deprecation")
074: public void run(IProgressMonitor monitor) throws Exception {
075: monitor.beginTask(Messages.WriteFeatureChangesCommand_runTask,
076: 3);
077: SubProgressMonitor subProgressMonitor = new SubProgressMonitor(
078: monitor, 1);
079: editFeature = featureProvider.get(subProgressMonitor);
080: subProgressMonitor.done();
081: store = storeProvider.get(subProgressMonitor);
082: if (editFeature == null || store == null) {
083: noChange = true;
084: return;
085: }
086:
087: FeatureType featureType = editFeature.getFeatureType();
088: FilterFactory factory = FilterFactoryFinder
089: .createFilterFactory();
090: subProgressMonitor = new SubProgressMonitor(monitor, 1);
091: subProgressMonitor.done();
092: filter = factory.createFidFilter(editFeature.getID());
093: FeatureCollection results = store.getFeatures(filter);
094:
095: FeatureIterator reader = results.features();
096: try {
097: if (reader.hasNext()) {
098: try {
099: store.modifyFeatures(featureType
100: .getAttributeTypes(), editFeature
101: .getAttributes(new Object[featureType
102: .getAttributeCount()]), filter);
103: } catch (Exception e) {
104: ProjectPlugin.log("", e); //$NON-NLS-1$
105: noChange = true;
106: }
107:
108: } else {
109: added = true;
110: store
111: .addFeatures(new StaticFeatureCollection(
112: Collections.singleton(editFeature),
113: featureType));
114: }
115: } finally {
116: if (reader != null)
117: reader.close();
118: }
119: }
120:
121: /**
122: * @see net.refractions.udig.project.internal.command.MapCommand#copy()
123: */
124: public MapCommand copy() {
125: return new WriteFeatureChangesCommand();
126: }
127:
128: /**
129: * @see net.refractions.udig.project.command.MapCommand#getName()
130: */
131: public String getName() {
132: return Messages.WriteFeatureChangesCommand_commandName;
133: }
134:
135: public void rollback(IProgressMonitor monitor) throws Exception {
136: if (noChange)
137: return;
138: monitor.beginTask(
139: Messages.WriteFeatureChangesCommand_rollbackTask,
140: IProgressMonitor.UNKNOWN);
141: if (added) {
142: store.removeFeatures(filter);
143: } else {
144: FeatureType featureType = this .editFeature.getFeatureType();
145: store.modifyFeatures(featureType.getAttributeTypes(),
146: this .editFeature
147: .getAttributes(new Object[featureType
148: .getAttributeCount()]), filter);
149: }
150: }
151:
152: }
|