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 / FeatureManager.java @ 43838

History | View | Annotate | Download (11 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
package org.gvsig.fmap.dal.feature.impl;
25
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
import org.gvsig.fmap.dal.feature.impl.expansionadapter.ExpansionAdapter;
40
41
42
public class FeatureManager {
43 42639 dmartinezizquierdo
44 43838 jjdelcerro
    private int deltaSize = 0;
45
    private final ExpansionAdapter expansionAdapter;
46
    private final Collection<FeatureReference> deleted = new LinkedHashSet();
47
    private final Map<FeatureReference, Integer> added = new LinkedHashMap();
48
    private final Map<FeatureReference, Integer> addedAndDeleted = new LinkedHashMap();
49
    private final Map<FeatureReference, Integer> modifiedFromOriginal = new HashMap();
50
51
    public FeatureManager(ExpansionAdapter expansionAdapter) {
52
        this.expansionAdapter = expansionAdapter;
53 40435 jjdelcerro
    }
54
55 43838 jjdelcerro
    /**
56
     * Deletes feature from this manager.
57
     *
58
     * @param id
59
     * @return The deleted feature or null if the feature had not been edited or
60
     * previously added in the editing session
61
     */
62 40435 jjdelcerro
    public Feature delete(FeatureReference id) {
63
        deleted.add(id);
64 43838 jjdelcerro
        Integer num = added.remove(id);
65
        Feature feature = null;
66
        if (num == null || num == -1) {
67
            num = modifiedFromOriginal.remove(id);
68 40435 jjdelcerro
            if (num != null) {
69 43838 jjdelcerro
                feature = (Feature) expansionAdapter.getObject(num);
70 40435 jjdelcerro
            }
71
            // if num is null here, method returns null
72 43838 jjdelcerro
        } else {
73
            feature = (Feature) expansionAdapter.getObject(num);
74
            addedAndDeleted.put(id, num);
75
        }
76 40435 jjdelcerro
        deltaSize--;
77
        return feature;
78
    }
79
80
    public void add(Feature feature) {
81
        int pos = expansionAdapter.addObject(feature);
82 43838 jjdelcerro
        added.put(feature.getReference(), pos);
83 40435 jjdelcerro
        deleted.remove(feature.getReference());
84
        deltaSize++;
85
    }
86
87
    public Feature deleteLastFeature() {
88
        expansionAdapter.deleteLastObject();
89 43838 jjdelcerro
        Feature feature = (Feature) expansionAdapter.getObject(expansionAdapter.getSize() - 1);
90 40435 jjdelcerro
        added.remove(feature.getReference());
91
        modifiedFromOriginal.remove(feature.getReference());
92
        deltaSize--;
93
        return feature;
94
    }
95
96
    /**
97
     * Returns a Feature of the default type.
98
     *
99 43838 jjdelcerro
     * @param id the feature reference
100
     * @param store the store to get the feature from
101 40435 jjdelcerro
     * @return a Feature with the given reference
102 43838 jjdelcerro
     * @throws DataException if there is an error getting the Feature
103 40435 jjdelcerro
     */
104
    public Feature get(FeatureReference id, FeatureStore store)
105
            throws DataException {
106
        return get(id, store, null);
107
    }
108
109
    /**
110
     * Returns a Feature of the given type.
111
     *
112 43838 jjdelcerro
     * @param id the feature reference
113
     * @param store the store to get the feature from
114
     * @param featureType the type of the feature to return
115 40435 jjdelcerro
     * @return a Feature with the given reference
116 43838 jjdelcerro
     * @throws DataException if there is an error getting the Feature
117 40435 jjdelcerro
     */
118
    public Feature get(FeatureReference id, FeatureStore store,
119 43838 jjdelcerro
            FeatureType featureType) throws DataException {
120
        // FIXME: y si el featuretype que paso esta modificado.
121
        //        Deberia buscarlo en el featuretypemanager ?
122
        //
123
        //        Si no existe feature con ese id... ? retorna null ?
124
        //        en EditedDefaultIterator se hace uso de ese comportamiento.
125
        //
126
        Integer intNum = (added.get(id));
127
        if (intNum == null) {
128
            intNum = (modifiedFromOriginal.get(id));
129
            if (intNum == null) {
130
                //If the feature has been added and deleted
131
                intNum = addedAndDeleted.get(id);
132
                if (intNum == null) {
133
                    return null;
134
                }
135
            }
136 40435 jjdelcerro
        }
137 43838 jjdelcerro
        int num = intNum;
138
        if (num == -1) {
139
            return null;
140
        }
141
        Feature feature = (Feature) expansionAdapter.getObject(num);
142
        if (featureType == null) {
143
            featureType = store.getDefaultFeatureType();
144
        }
145 43729 fdiaz
        return new DefaultFeature(featureType, feature);
146 40435 jjdelcerro
    }
147
148
    public int update(Feature feature, Feature oldFeature) {
149 43838 jjdelcerro
        int oldNum = -1;
150 40435 jjdelcerro
        int num = expansionAdapter.addObject(feature);
151 43838 jjdelcerro
        FeatureReference id = feature.getReference();
152
        if (added.containsKey(id)) {
153
            oldNum = (added.get(id));
154
            added.put(id, num);
155
        } else {
156
            if (modifiedFromOriginal.get(id) != null) {
157
                oldNum = (modifiedFromOriginal.get(id));
158
            }
159
            modifiedFromOriginal.put(id, num);
160 40435 jjdelcerro
        }
161
        return oldNum;
162
    }
163
164
    public void restore(FeatureReference id) {
165
        deleted.remove(id);
166
        deltaSize++;
167
    }
168 43838 jjdelcerro
169
    public void restore(FeatureReference id, int num) {
170
        if (added.containsKey(id)) {
171
            added.put(id, num);
172
        } else {
173
            modifiedFromOriginal.put(id, num);
174 40435 jjdelcerro
        }
175
    }
176
177 43838 jjdelcerro
    public boolean isDeleted(Feature feature) {
178
        return deleted.contains(feature.getReference());
179 40435 jjdelcerro
    }
180
181
    public boolean isDeleted(FeatureReference featureID) {
182 43838 jjdelcerro
        return deleted.contains(featureID);
183
    }
184 40435 jjdelcerro
185 43838 jjdelcerro
    public void clear() {
186
        added.clear();
187
        modifiedFromOriginal.clear();
188
        expansionAdapter.close();
189
        deleted.clear();
190
        addedAndDeleted.clear();
191
        deltaSize = 0;
192
    }
193 40435 jjdelcerro
194 43838 jjdelcerro
    public boolean hasChanges() {
195
        return added.size() > 0 || modifiedFromOriginal.size() > 0 || deleted.size() > 0;
196
    }
197 40435 jjdelcerro
198 43838 jjdelcerro
    public Iterator getDeleted() {
199
        return new DeletedIterator();
200 40435 jjdelcerro
201 43838 jjdelcerro
    }
202 40435 jjdelcerro
203 43838 jjdelcerro
    private class DeletedIterator implements Iterator {
204 40435 jjdelcerro
205 43838 jjdelcerro
        private Boolean hasnext = null;
206
        private final Iterator iter;
207
        private DefaultFeatureReference obj;
208 40435 jjdelcerro
209 43838 jjdelcerro
        public DeletedIterator() {
210
            iter = deleted.iterator();
211
        }
212 40435 jjdelcerro
213 43838 jjdelcerro
        @Override
214
        public boolean hasNext() {
215
            if (hasnext != null) {
216
                return hasnext;
217
            }
218
            hasnext = false;
219
            while (iter.hasNext()) {
220
                obj = (DefaultFeatureReference) iter.next();
221
                if (obj.isNewFeature()) {
222
                    continue;
223
                }
224
                hasnext = false;
225
                break;
226
            }
227
            return hasnext;
228
        }
229 40435 jjdelcerro
230 43838 jjdelcerro
        @Override
231
        public Object next() {
232
            if (!hasNext()) {
233
                throw new NoSuchElementException();
234
            }
235
            hasnext = null;
236
            return obj;
237
        }
238 40435 jjdelcerro
239 43838 jjdelcerro
        @Override
240
        public void remove() {
241
            throw new UnsupportedOperationException();
242
        }
243 40435 jjdelcerro
244 43838 jjdelcerro
    }
245 40435 jjdelcerro
246 43838 jjdelcerro
    public Iterator getInserted() {
247
        return new InsertedIterator();
248
    }
249 40435 jjdelcerro
250 43838 jjdelcerro
    private class InsertedIterator implements Iterator {
251 40435 jjdelcerro
252 43838 jjdelcerro
        private final Iterator addedIter;
253
        private DefaultFeature obj;
254
        private Boolean hasnext = null;
255 40435 jjdelcerro
256 43838 jjdelcerro
        public InsertedIterator() {
257
            addedIter = added.values().iterator();
258
        }
259 40435 jjdelcerro
260 43838 jjdelcerro
        @Override
261
        public boolean hasNext() {
262
            if (hasnext != null) {
263
                return hasnext;
264
            }
265
            hasnext = false;
266
            int pos;
267
            while (addedIter.hasNext()) {
268
                pos = ((Integer) addedIter.next());
269
                obj = (DefaultFeature) expansionAdapter.getObject(pos);
270
                if (!deleted.contains(obj.getReference())) {
271
                    hasnext = true;
272
                    break;
273
                }
274
            }
275
            return hasnext;
276
        }
277 40435 jjdelcerro
278 43838 jjdelcerro
        @Override
279
        public Object next() {
280
            if (!hasNext()) {
281
                throw new NoSuchElementException();
282
            }
283
            hasnext = null;
284
            return obj.getData();
285
        }
286 40435 jjdelcerro
287 43838 jjdelcerro
        @Override
288
        public void remove() {
289
            addedIter.remove();
290
        }
291 40435 jjdelcerro
292 43838 jjdelcerro
    }
293 40435 jjdelcerro
294 43838 jjdelcerro
    public Iterator getUpdated() {
295
        return new UpdatedIterator();
296
    }
297 40435 jjdelcerro
298 43838 jjdelcerro
    private class UpdatedIterator implements Iterator {
299 40435 jjdelcerro
300 43838 jjdelcerro
        private Boolean hasnext = null;
301
        private final Iterator iter;
302
        private DefaultFeature obj;
303
        private int pos;
304 40435 jjdelcerro
305 43838 jjdelcerro
        public UpdatedIterator() {
306
            iter = expansionAdapter.iterator();
307
            pos = -1;
308
        }
309 40435 jjdelcerro
310 43838 jjdelcerro
        @Override
311
        public boolean hasNext() {
312
            if (hasnext != null) {
313
                return hasnext;
314
            }
315
            hasnext = false;
316
            while (iter.hasNext()) {
317
                pos++;
318
                obj = (DefaultFeature) iter.next();
319
                if (deleted.contains(obj.getReference())) {
320
                    continue;
321
                } else if (!modifiedFromOriginal.containsValue(pos)) {
322
                    continue;
323
                } else {
324
                    hasnext = true;
325
                    break;
326
                }
327
            }
328
            return hasnext;
329
        }
330 40435 jjdelcerro
331 43838 jjdelcerro
        @Override
332
        public Object next() {
333
            if (!hasNext()) {
334
                throw new NoSuchElementException();
335
            }
336
            hasnext = null;
337
            return obj.getData();
338
        }
339 40435 jjdelcerro
340 43838 jjdelcerro
        @Override
341
        public void remove() {
342
            throw new UnsupportedOperationException();
343 40435 jjdelcerro
344 43838 jjdelcerro
        }
345
    }
346 40435 jjdelcerro
347 43838 jjdelcerro
    public boolean hasNews() {
348
        return !added.isEmpty();
349
    }
350 42639 dmartinezizquierdo
351 43838 jjdelcerro
    public long getDeltaSize() {
352
        return deltaSize;
353
    }
354
355 42639 dmartinezizquierdo
    /**
356
     * Indicates if any operation has comprimised the selected features.
357 43838 jjdelcerro
     *
358 42639 dmartinezizquierdo
     * @return
359
     */
360
    public boolean isSelectionCompromised() {
361
        //Only deleted features can change order, as added features are added at the end.
362 43838 jjdelcerro
        return deleted.size() > 0;
363 42639 dmartinezizquierdo
    }
364 40435 jjdelcerro
}