Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / editing / memory / FeatureManager.java @ 44434

History | View | Annotate | Download (11.5 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18 40559 jjdelcerro
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 40435 jjdelcerro
 *
21 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24 43840 jjdelcerro
package org.gvsig.fmap.dal.feature.impl.editing.memory;
25 40435 jjdelcerro
26
import java.util.Collection;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.LinkedHashMap;
30
import java.util.LinkedHashSet;
31
import java.util.Map;
32
import java.util.NoSuchElementException;
33
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureReference;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39 43840 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.DefaultFeature;
40
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureReference;
41 40435 jjdelcerro
42
43
public class FeatureManager {
44 42639 dmartinezizquierdo
45 43840 jjdelcerro
    private int deltaSize;
46 43838 jjdelcerro
    private final ExpansionAdapter expansionAdapter;
47 43840 jjdelcerro
    private final Collection<FeatureReference> deleted;
48
    private final Map<FeatureReference, Integer> added;
49
    private final Map<FeatureReference, Integer> addedAndDeleted;
50
    private final Map<FeatureReference, Integer> modifiedFromOriginal;
51 43838 jjdelcerro
52 43840 jjdelcerro
    public FeatureManager() {
53
        deltaSize = 0;
54
        expansionAdapter = new MemoryExpansionAdapter();
55
        deleted = new LinkedHashSet<>();
56
        added = new LinkedHashMap<>();
57
        addedAndDeleted = new LinkedHashMap<>();
58
        modifiedFromOriginal = new HashMap<>();
59 40435 jjdelcerro
    }
60
61 43838 jjdelcerro
    /**
62
     * Deletes feature from this manager.
63
     *
64
     * @param id
65
     * @return The deleted feature or null if the feature had not been edited or
66
     * previously added in the editing session
67
     */
68 40435 jjdelcerro
    public Feature delete(FeatureReference id) {
69
        deleted.add(id);
70 43838 jjdelcerro
        Integer num = added.remove(id);
71
        Feature feature = null;
72
        if (num == null || num == -1) {
73
            num = modifiedFromOriginal.remove(id);
74 40435 jjdelcerro
            if (num != null) {
75 43838 jjdelcerro
                feature = (Feature) expansionAdapter.getObject(num);
76 40435 jjdelcerro
            }
77
            // if num is null here, method returns null
78 43838 jjdelcerro
        } else {
79
            feature = (Feature) expansionAdapter.getObject(num);
80
            addedAndDeleted.put(id, num);
81
        }
82 40435 jjdelcerro
        deltaSize--;
83
        return feature;
84
    }
85
86
    public void add(Feature feature) {
87
        int pos = expansionAdapter.addObject(feature);
88 43838 jjdelcerro
        added.put(feature.getReference(), pos);
89 40435 jjdelcerro
        deleted.remove(feature.getReference());
90
        deltaSize++;
91
    }
92
93
    public Feature deleteLastFeature() {
94
        expansionAdapter.deleteLastObject();
95 43838 jjdelcerro
        Feature feature = (Feature) expansionAdapter.getObject(expansionAdapter.getSize() - 1);
96 40435 jjdelcerro
        added.remove(feature.getReference());
97
        modifiedFromOriginal.remove(feature.getReference());
98
        deltaSize--;
99
        return feature;
100
    }
101
102
    /**
103
     * Returns a Feature of the default type.
104
     *
105 43838 jjdelcerro
     * @param id the feature reference
106
     * @param store the store to get the feature from
107 40435 jjdelcerro
     * @return a Feature with the given reference
108 43838 jjdelcerro
     * @throws DataException if there is an error getting the Feature
109 40435 jjdelcerro
     */
110
    public Feature get(FeatureReference id, FeatureStore store)
111
            throws DataException {
112
        return get(id, store, null);
113
    }
114
115
    /**
116
     * Returns a Feature of the given type.
117
     *
118 43838 jjdelcerro
     * @param id the feature reference
119
     * @param store the store to get the feature from
120
     * @param featureType the type of the feature to return
121 40435 jjdelcerro
     * @return a Feature with the given reference
122 43838 jjdelcerro
     * @throws DataException if there is an error getting the Feature
123 40435 jjdelcerro
     */
124
    public Feature get(FeatureReference id, FeatureStore store,
125 43838 jjdelcerro
            FeatureType featureType) throws DataException {
126
        // FIXME: y si el featuretype que paso esta modificado.
127
        //        Deberia buscarlo en el featuretypemanager ?
128
        //
129
        //        Si no existe feature con ese id... ? retorna null ?
130
        //        en EditedDefaultIterator se hace uso de ese comportamiento.
131
        //
132
        Integer intNum = (added.get(id));
133
        if (intNum == null) {
134
            intNum = (modifiedFromOriginal.get(id));
135
            if (intNum == null) {
136
                //If the feature has been added and deleted
137
                intNum = addedAndDeleted.get(id);
138
                if (intNum == null) {
139
                    return null;
140
                }
141
            }
142 40435 jjdelcerro
        }
143 43838 jjdelcerro
        int num = intNum;
144
        if (num == -1) {
145
            return null;
146
        }
147
        Feature feature = (Feature) expansionAdapter.getObject(num);
148
        if (featureType == null) {
149
            featureType = store.getDefaultFeatureType();
150
        }
151 43729 fdiaz
        return new DefaultFeature(featureType, feature);
152 40435 jjdelcerro
    }
153
154
    public int update(Feature feature, Feature oldFeature) {
155 43838 jjdelcerro
        int oldNum = -1;
156 40435 jjdelcerro
        int num = expansionAdapter.addObject(feature);
157 43838 jjdelcerro
        FeatureReference id = feature.getReference();
158
        if (added.containsKey(id)) {
159
            oldNum = (added.get(id));
160
            added.put(id, num);
161
        } else {
162
            if (modifiedFromOriginal.get(id) != null) {
163
                oldNum = (modifiedFromOriginal.get(id));
164
            }
165
            modifiedFromOriginal.put(id, num);
166 40435 jjdelcerro
        }
167
        return oldNum;
168
    }
169
170
    public void restore(FeatureReference id) {
171
        deleted.remove(id);
172
        deltaSize++;
173
    }
174 43838 jjdelcerro
175
    public void restore(FeatureReference id, int num) {
176
        if (added.containsKey(id)) {
177
            added.put(id, num);
178
        } else {
179
            modifiedFromOriginal.put(id, num);
180 40435 jjdelcerro
        }
181
    }
182
183 43838 jjdelcerro
    public boolean isDeleted(Feature feature) {
184
        return deleted.contains(feature.getReference());
185 40435 jjdelcerro
    }
186
187
    public boolean isDeleted(FeatureReference featureID) {
188 43838 jjdelcerro
        return deleted.contains(featureID);
189
    }
190 40435 jjdelcerro
191 43838 jjdelcerro
    public void clear() {
192
        added.clear();
193
        modifiedFromOriginal.clear();
194
        expansionAdapter.close();
195
        deleted.clear();
196
        addedAndDeleted.clear();
197
        deltaSize = 0;
198
    }
199 40435 jjdelcerro
200 43838 jjdelcerro
    public boolean hasChanges() {
201
        return added.size() > 0 || modifiedFromOriginal.size() > 0 || deleted.size() > 0;
202
    }
203 40435 jjdelcerro
204 43838 jjdelcerro
    public Iterator getDeleted() {
205
        return new DeletedIterator();
206 40435 jjdelcerro
207 43838 jjdelcerro
    }
208 40435 jjdelcerro
209 44111 jjdelcerro
    public long getPendingChangesCount() {
210
        long count = 0;
211
        if( this.added!=null ) {
212
            count += this.added.size();
213
        }
214
        if( this.deleted!=null ) {
215
            count += this.deleted.size();
216
        }
217
        if( this.modifiedFromOriginal!=null ) {
218
            count += this.modifiedFromOriginal.size();
219
        }
220
        return count;
221
    }
222
223 43838 jjdelcerro
    private class DeletedIterator implements Iterator {
224 40435 jjdelcerro
225 43838 jjdelcerro
        private Boolean hasnext = null;
226
        private final Iterator iter;
227
        private DefaultFeatureReference obj;
228 40435 jjdelcerro
229 43838 jjdelcerro
        public DeletedIterator() {
230
            iter = deleted.iterator();
231
        }
232 40435 jjdelcerro
233 43838 jjdelcerro
        @Override
234
        public boolean hasNext() {
235
            if (hasnext != null) {
236
                return hasnext;
237
            }
238
            hasnext = false;
239
            while (iter.hasNext()) {
240
                obj = (DefaultFeatureReference) iter.next();
241
                if (obj.isNewFeature()) {
242
                    continue;
243
                }
244 44434 jjdelcerro
                hasnext = true;
245 43838 jjdelcerro
                break;
246
            }
247
            return hasnext;
248
        }
249 40435 jjdelcerro
250 43838 jjdelcerro
        @Override
251
        public Object next() {
252
            if (!hasNext()) {
253
                throw new NoSuchElementException();
254
            }
255
            hasnext = null;
256
            return obj;
257
        }
258 40435 jjdelcerro
259 43838 jjdelcerro
        @Override
260
        public void remove() {
261
            throw new UnsupportedOperationException();
262
        }
263 40435 jjdelcerro
264 43838 jjdelcerro
    }
265 40435 jjdelcerro
266 43838 jjdelcerro
    public Iterator getInserted() {
267
        return new InsertedIterator();
268
    }
269 40435 jjdelcerro
270 43838 jjdelcerro
    private class InsertedIterator implements Iterator {
271 40435 jjdelcerro
272 43838 jjdelcerro
        private final Iterator addedIter;
273
        private DefaultFeature obj;
274
        private Boolean hasnext = null;
275 40435 jjdelcerro
276 43838 jjdelcerro
        public InsertedIterator() {
277
            addedIter = added.values().iterator();
278
        }
279 40435 jjdelcerro
280 43838 jjdelcerro
        @Override
281
        public boolean hasNext() {
282
            if (hasnext != null) {
283
                return hasnext;
284
            }
285
            hasnext = false;
286
            int pos;
287
            while (addedIter.hasNext()) {
288
                pos = ((Integer) addedIter.next());
289
                obj = (DefaultFeature) expansionAdapter.getObject(pos);
290
                if (!deleted.contains(obj.getReference())) {
291
                    hasnext = true;
292
                    break;
293
                }
294
            }
295
            return hasnext;
296
        }
297 40435 jjdelcerro
298 43838 jjdelcerro
        @Override
299
        public Object next() {
300
            if (!hasNext()) {
301
                throw new NoSuchElementException();
302
            }
303
            hasnext = null;
304
            return obj.getData();
305
        }
306 40435 jjdelcerro
307 43838 jjdelcerro
        @Override
308
        public void remove() {
309
            addedIter.remove();
310
        }
311 40435 jjdelcerro
312 43838 jjdelcerro
    }
313 40435 jjdelcerro
314 43838 jjdelcerro
    public Iterator getUpdated() {
315
        return new UpdatedIterator();
316
    }
317 40435 jjdelcerro
318 43838 jjdelcerro
    private class UpdatedIterator implements Iterator {
319 40435 jjdelcerro
320 43838 jjdelcerro
        private Boolean hasnext = null;
321
        private final Iterator iter;
322
        private DefaultFeature obj;
323
        private int pos;
324 40435 jjdelcerro
325 43838 jjdelcerro
        public UpdatedIterator() {
326
            iter = expansionAdapter.iterator();
327
            pos = -1;
328
        }
329 40435 jjdelcerro
330 43838 jjdelcerro
        @Override
331
        public boolean hasNext() {
332
            if (hasnext != null) {
333
                return hasnext;
334
            }
335
            hasnext = false;
336
            while (iter.hasNext()) {
337
                pos++;
338
                obj = (DefaultFeature) iter.next();
339
                if (deleted.contains(obj.getReference())) {
340
                    continue;
341
                } else if (!modifiedFromOriginal.containsValue(pos)) {
342
                    continue;
343
                } else {
344
                    hasnext = true;
345
                    break;
346
                }
347
            }
348
            return hasnext;
349
        }
350 40435 jjdelcerro
351 43838 jjdelcerro
        @Override
352
        public Object next() {
353
            if (!hasNext()) {
354
                throw new NoSuchElementException();
355
            }
356
            hasnext = null;
357
            return obj.getData();
358
        }
359 40435 jjdelcerro
360 43838 jjdelcerro
        @Override
361
        public void remove() {
362
            throw new UnsupportedOperationException();
363 40435 jjdelcerro
364 43838 jjdelcerro
        }
365
    }
366 40435 jjdelcerro
367 43838 jjdelcerro
    public boolean hasNews() {
368
        return !added.isEmpty();
369
    }
370 42639 dmartinezizquierdo
371 43838 jjdelcerro
    public long getDeltaSize() {
372
        return deltaSize;
373
    }
374
375 42639 dmartinezizquierdo
    /**
376
     * Indicates if any operation has comprimised the selected features.
377 43838 jjdelcerro
     *
378 42639 dmartinezizquierdo
     * @return
379
     */
380
    public boolean isSelectionCompromised() {
381
        //Only deleted features can change order, as added features are added at the end.
382 43838 jjdelcerro
        return deleted.size() > 0;
383 42639 dmartinezizquierdo
    }
384 40435 jjdelcerro
}