Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / featureset / DefaultFeatureSet.java @ 26252

History | View | Annotate | Download (10.2 KB)

1 24507 jmvivo
package org.gvsig.fmap.dal.feature.impl.featureset;
2 23820 jjdelcerro
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.NoSuchElementException;
8
9 24496 jmvivo
import org.gvsig.fmap.dal.DataStore;
10 24505 jmvivo
import org.gvsig.fmap.dal.exception.DataException;
11 24684 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
12 24496 jmvivo
import org.gvsig.fmap.dal.feature.Feature;
13
import org.gvsig.fmap.dal.feature.FeatureQuery;
14
import org.gvsig.fmap.dal.feature.FeatureSet;
15
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
16
import org.gvsig.fmap.dal.feature.FeatureType;
17 26029 jmvivo
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
18 24496 jmvivo
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
19 25917 jmvivo
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStoreTransforms;
20 24496 jmvivo
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
21 23820 jjdelcerro
import org.gvsig.tools.exception.BaseException;
22 24794 jmvivo
import org.gvsig.tools.observer.Observable;
23 24683 jjdelcerro
import org.gvsig.tools.observer.Observer;
24 23820 jjdelcerro
import org.gvsig.tools.visitor.Visitor;
25
26 23842 jjdelcerro
public class DefaultFeatureSet implements FeatureSet, Observer {
27 23820 jjdelcerro
28
29
        private static final int NO_CHECKED = -1;
30
        private static final int DEFAULT = 0;
31
        private static final int FILTERED = 1;
32
        private static final int ORDERED = 2;
33
        private static final int ORDERED_FILTERED = 3;
34
        private static final int EDITED = 4;
35
        private static final int EDITED_FILTERED = 5;
36
        private static final int ORDERD_EDITED = 6;
37
        private static final int ORDERED_EDITED_FILTER = 7;
38
39 24684 jjdelcerro
        private boolean modified;
40 23820 jjdelcerro
        DefaultFeatureStore store;
41
        private List featureTypes;
42
        FeatureQuery query;
43
        FeatureSetProvider provider;
44 24684 jjdelcerro
        private long size;
45
        private int iteratorMode;
46
        List orderedData;
47
        private Feature featureToIgnoreNotification;
48 25917 jmvivo
        private List providerFeatureTypes;
49
        DefaultFeatureStoreTransforms transform;
50
        private FeatureQuery queryForProvider;
51 23820 jjdelcerro
52
53
        public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
54 26252 jmvivo
        throws DataException {
55 24684 jjdelcerro
                this.featureToIgnoreNotification = null;
56
                this.iteratorMode = NO_CHECKED;
57
                this.modified = false;
58
                this.size = -1;
59
                this.orderedData = null;
60 23820 jjdelcerro
                this.store = store;
61 26252 jmvivo
                if (this.store.isEditing()) {
62
                        this.transform = this.store.getFeatureTypeManager().getTransforms();
63
                } else {
64
                        this.transform = (DefaultFeatureStoreTransforms) store
65
                                .getTransforms();
66
                }
67 23820 jjdelcerro
                this.query = query;
68 25917 jmvivo
                this.queryForProvider = query.getCopy();
69 23820 jjdelcerro
                this.featureTypes = new ArrayList();
70
                this.featureTypes.add(this.query.getFeatureType());
71 25917 jmvivo
                if (!this.transform.isEmpty()) {
72
                        this.queryForProvider.setAttributeNames(null);
73
                        this.queryForProvider.setFeatureType(this.transform
74
                                        .getSourceFeatureTypeFrom(this.query.getFeatureType()));
75
                        this.queryForProvider.setFilter(null);
76 26252 jmvivo
                        // TODO Habria que comprobar si todos los campos que usan el filtro
77
                        // son del provider. Si esto se cumple, no eliminamos el filtro.
78 25917 jmvivo
                }
79
80 25176 jmvivo
                if (query.hasFilter() && store.getIndexes() != null) {
81 25747 jiyarza
                        this.provider = (FeatureSetProvider) store.getIndexes()
82 26252 jmvivo
                        .getFeatureSet(this.queryForProvider.getFilter());
83 24017 jjdelcerro
                }
84 23894 jjdelcerro
                if (this.provider == null) {
85 25917 jmvivo
                        this.provider = this.store.getProvider().createSet(
86
                                        this.queryForProvider);
87 23894 jjdelcerro
                }
88 26029 jmvivo
                this.store.addObserver(this);
89 23820 jjdelcerro
        }
90
91
        public FeatureType getDefaultFeatureType() {
92
                return this.query.getFeatureType();
93
        }
94
95
        public List getFeatureTypes() {
96
                return Collections.unmodifiableList(this.featureTypes);
97
        }
98
99
        public long getSize() throws DataException {
100 25994 jmvivo
                this.checkModified();
101 23820 jjdelcerro
                if (size < 0) {
102
                        size = calculateSize();
103
                }
104
                return size;
105
        }
106
107
        private long calculateSize() throws DataException {
108
                int mode = this.getIteratorMode();
109
                if ((mode & FILTERED) == FILTERED) {
110
                        long mySize =0;
111
                        Iterator iter = this.fastIterator();
112
                        try{
113
                                while (true) {
114
                                        iter.next();
115
                                        mySize++;
116
                                }
117
                        } catch (NoSuchElementException e){
118
                                return mySize;
119
                        }
120
                } else if ((mode & EDITED) == EDITED) {
121
                        return provider.getSize()
122 26252 jmvivo
                        + store.getFeatureManager().getDeltaSize();
123 23820 jjdelcerro
                }
124
                return provider.getSize();
125
        }
126
127
        public void dispose() {
128 26029 jmvivo
                this.store.deleteObserver(this);
129
                this.provider = null;
130 23820 jjdelcerro
131 26029 jmvivo
                this.featureToIgnoreNotification = null;
132
                this.orderedData = null;
133
                this.store = null;
134
                this.transform = null;
135
                this.query = null;
136
                this.queryForProvider = null;
137
                this.featureTypes = null;
138
139 23820 jjdelcerro
        }
140
141
        public boolean isFromStore(DataStore store) {
142
                return this.store.equals(store);
143
        }
144
145 24794 jmvivo
        public void update(Observable obsevable, Object notification) {
146 23820 jjdelcerro
                if (modified) {
147
                        return;
148
                }
149 24684 jjdelcerro
150 23820 jjdelcerro
                String type = ((FeatureStoreNotification) notification).getType();
151 24684 jjdelcerro
152
                if (
153 26252 jmvivo
                                type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
154
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
155
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE)
156
                ) {
157 24684 jjdelcerro
                        if( this.featureToIgnoreNotification == ((FeatureStoreNotification) notification).getFeature() ) {
158
                                return;
159
                        }
160 23820 jjdelcerro
                        modified = true;
161 24684 jjdelcerro
                        return;
162 23820 jjdelcerro
                }
163 24684 jjdelcerro
                if (
164 26252 jmvivo
                                type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE_TYPE)
165
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REDO)
166
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UNDO)
167
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)
168
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH)
169
                                || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
170
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
171
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
172
                                || type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)
173
                                || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)
174
                ) {
175 24684 jjdelcerro
                        modified = true;
176
                        return;
177
                }
178 23820 jjdelcerro
        }
179
180
        public void accept(Visitor visitor) throws BaseException {
181
                Iterator iterator = iterator();
182
183
                while (iterator.hasNext()) {
184
                        Feature feature = (Feature) iterator.next();
185
                        visitor.visit(feature);
186
                }
187
        }
188
189
        protected void checkModified() {
190
                if (modified) {
191 26029 jmvivo
                        throw new ConcurrentDataModificationException(store.getName());
192 23820 jjdelcerro
                }
193
        }
194
195
        public boolean isEmpty() throws DataException {
196
                checkModified();
197
                if (this.store.isEditing()) {
198
                        if (this.store.getFeatureManager().hasNews()) {
199
                                return false;
200
                        }
201
                        if (this.provider.isEmpty()) {
202
                                return true;
203
                        }
204
                        return this.provider.getSize()
205 26252 jmvivo
                        + this.store.getFeatureManager().getDeltaSize() == 0;
206 23820 jjdelcerro
                }
207
                return this.provider.isEmpty();
208
        }
209 24684 jjdelcerro
210 23894 jjdelcerro
        public Iterator fastIterator() throws DataException {
211 23820 jjdelcerro
                return this.fastIterator(0);
212
        }
213
214 23894 jjdelcerro
        public Iterator fastIterator(long index) throws DataException {
215 23820 jjdelcerro
                if (index < 0) {
216
                        throw new IndexOutOfBoundsException("The index (" + index
217
                                        + ") is less than 0");
218
                }
219
                int mode = this.getIteratorMode();
220
221
                switch (mode) {
222
                case DEFAULT:
223
                        return new FastDefaultIterator(this, index);
224
225
                case FILTERED:
226
                        return new FastFilteredIterator(this, index);
227
228 26061 jmvivo
229
                case ORDERED:
230
                        return new FastOrderedIterator(this, new FastDefaultIterator(this,
231
                                        0), index);
232
233 23820 jjdelcerro
                case ORDERED_FILTERED:
234 26061 jmvivo
                        return new FastOrderedIterator(this, new FastFilteredIterator(this,
235 23820 jjdelcerro
                                        0),
236
                                        index);
237
238
                case EDITED:
239
                        return new FastEditedIterator(this, index);
240
241
                case EDITED_FILTERED:
242
                        return new FastEditedFilteredIterator(this, index);
243
244
                case ORDERD_EDITED:
245
                        return new FastOrderedIterator(this,
246
                                        new FastEditedIterator(this, 0), index);
247
248
                case ORDERED_EDITED_FILTER:
249
                        return new FastOrderedIterator(this,
250
                                        new FastEditedFilteredIterator(this, 0), index);
251
252
                default:
253
                        throw new IllegalArgumentException();
254
                }
255
        }
256
257 23894 jjdelcerro
        public Iterator iterator() throws DataException {
258 23820 jjdelcerro
                return this.iterator(0);
259
        }
260
261 23894 jjdelcerro
        public Iterator iterator(long index) throws DataException {
262 23820 jjdelcerro
                if (index < 0) {
263 26252 jmvivo
                        throw new IndexOutOfBoundsException("The index (" + index
264
                                        + ") is less than 0");
265 23820 jjdelcerro
                }
266
                int mode = this.getIteratorMode();
267
268
                switch (mode) {
269
                case DEFAULT:
270
                        return new DefaultIterator(this, index);
271
272
                case FILTERED:
273
                        return new FilteredIterator(this, index);
274
275 24766 jmvivo
                case ORDERED:
276 23820 jjdelcerro
                        return new OrderedIterator(this, new DefaultIterator(this, 0),
277
                                        index);
278
279 24766 jmvivo
                case ORDERED_FILTERED:
280
                        return new OrderedIterator(this, new FilteredIterator(this, 0),
281
                                        index);
282
283 23820 jjdelcerro
                case EDITED:
284
                        return new EditedIterator(this, index);
285
286
                case EDITED_FILTERED:
287
                        return new EditedFilteredIterator(this, index);
288
289
                case ORDERD_EDITED:
290
                        return new OrderedIterator(this,
291
                                        new EditedIterator(this, 0), index);
292
293
                case ORDERED_EDITED_FILTER:
294
                        return new OrderedIterator(this,
295
                                        new EditedFilteredIterator(this, 0), index);
296
297
                default:
298
                        throw new IllegalArgumentException();
299
                }
300
301
        }
302
303 23894 jjdelcerro
        private boolean providerCanOrder() {
304
                return this.provider.canOrder();
305
        }
306
307
        private boolean providerCanFilter() {
308
                return this.provider.canFilter();
309
        }
310
311 23820 jjdelcerro
        private int getIteratorMode() {
312
313
                if (this.iteratorMode != NO_CHECKED) {
314
                        return this.iteratorMode;
315
                }
316
317 25917 jmvivo
                // TODO Tener en cuenta las transformaciones ???
318
319 23820 jjdelcerro
                if (store.isEditing() && store.getFeatureManager().hasChanges()) {
320
                        if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
321
                                if (this.query.hasFilter()) {
322
                                        return ORDERED_EDITED_FILTER;
323
                                } else {
324
                                        return ORDERD_EDITED;
325
                                }
326
                        } else {
327
                                if (this.query.hasFilter()) {
328
                                        return EDITED_FILTERED;
329
                                } else {
330
                                        return EDITED;
331
                                }
332
                        }
333
                } else {
334
                        boolean useMyFilter = this.query.hasFilter();
335
                        boolean useMyOrder = this.query.hasOrder();
336 25917 jmvivo
                        if (this.providerCanOrder() && this.transform.isEmpty()) {
337 23820 jjdelcerro
                                useMyOrder = false;
338
                        }
339 25917 jmvivo
                        if (this.providerCanFilter() && this.transform.isEmpty()) {
340 23820 jjdelcerro
                                useMyFilter = false;
341
                        }
342
343
                        if (useMyOrder) {
344
                                if (useMyFilter) {
345
                                        return ORDERED_FILTERED;// ORDERED_FILTERED;
346
                                } else {
347
                                        return ORDERED;// ORDERED;
348
                                }
349
                        } else {
350
                                if (useMyFilter) {
351
                                        return FILTERED;// FILTERED;
352
                                } else {
353
                                        return DEFAULT;// DEFAULT;
354
                                }
355
                        }
356
                }
357
358
        }
359
360 24684 jjdelcerro
        public void delete(Feature feature) throws DataException {
361
                this.featureToIgnoreNotification = feature;
362
                this.store.delete(feature);
363 25994 jmvivo
                if (this.size > 0) {
364
                        this.size--;
365
                }
366 24684 jjdelcerro
                this.featureToIgnoreNotification = null;
367
        }
368
369
        public void insert(EditableFeature feature) throws DataException {
370
                this.featureToIgnoreNotification = feature;
371
                this.store.insert(feature);
372 25994 jmvivo
                if (this.size >= 0) {
373
                        this.size++;
374
                }
375 24684 jjdelcerro
                this.featureToIgnoreNotification = null;
376
        }
377
378
        public void update(EditableFeature feature) throws DataException {
379
                this.featureToIgnoreNotification = feature;
380
                this.store.update(feature);
381
                this.featureToIgnoreNotification = null;
382
        }
383
384 23820 jjdelcerro
}