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 / featureset / DefaultFeatureSet.java

History | View | Annotate | Download (24.9 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
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
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.featureset;
25
26
import java.util.ArrayList;
27
import java.util.Collections;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.NoSuchElementException;
31
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34 44753 omartinez
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
35 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureIndexes;
37
import org.gvsig.fmap.dal.feature.FeatureQuery;
38
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
39 43026 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
40 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
43
import org.gvsig.fmap.dal.feature.FeatureType;
44
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
45
import org.gvsig.fmap.dal.feature.exception.FeatureSetInitializeException;
46
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
47
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStoreTransforms;
48 44753 omartinez
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureType;
49 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
50
import org.gvsig.tools.dispose.DisposableIterator;
51 44113 jjdelcerro
import org.gvsig.tools.dispose.DisposeUtils;
52 40435 jjdelcerro
import org.gvsig.tools.evaluator.Evaluator;
53
import org.gvsig.tools.observer.Observable;
54
import org.gvsig.tools.observer.Observer;
55
56 43089 jjdelcerro
public class DefaultFeatureSet extends AbstractFeatureSet implements
57 40435 jjdelcerro
    FeatureSet, Observer {
58 46485 fdiaz
59 44113 jjdelcerro
    protected static final int NO_CHECKED = -1;
60
    protected static final int DEFAULT = 0;
61
    protected static final int FILTERED = 1;
62
    protected static final int ORDERED = 2;
63
    protected static final int ORDERED_FILTERED = 3;
64
    protected static final int EDITED = 4;
65
    protected static final int EDITED_FILTERED = 5;
66
    protected static final int ORDERD_EDITED = 6;
67
    protected static final int ORDERED_EDITED_FILTER = 7;
68 40435 jjdelcerro
69 45425 jjdelcerro
    protected Throwable sourceStoreModifiedCause;
70 44113 jjdelcerro
    protected boolean sourceStoreModified;
71
    protected boolean ownFeaturesModified;
72
    protected DefaultFeatureStore store;
73
    protected List featureTypes;
74
    protected FeatureQuery query;
75
    protected FeatureSetProvider provider;
76
    protected long size;
77
    protected int iteratorMode;
78
    protected List orderedData;
79
    protected Feature featureToIgnoreNotification;
80
    protected DefaultFeatureStoreTransforms transform;
81
    protected FeatureQuery queryForProvider;
82 44753 omartinez
    protected FeatureType defaultFeatureType;
83 44113 jjdelcerro
    protected FeatureType defatulFeatureTypeForProvider;
84
    protected boolean ignoreChanges;
85 45195 omartinez
    private boolean disposed = false;
86 40435 jjdelcerro
87
    public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
88
        throws DataException {
89 45195 omartinez
        DisposeUtils.bind(this);
90 40435 jjdelcerro
        this.featureToIgnoreNotification = null;
91
        this.iteratorMode = NO_CHECKED;
92
        this.sourceStoreModified = false;
93
        this.ownFeaturesModified = false;
94
        this.size = -1;
95
        this.orderedData = null;
96
        this.store = store;
97 45425 jjdelcerro
        DisposeUtils.bind(this.store);
98 40435 jjdelcerro
        if (this.store.isEditing()) {
99
            this.transform = this.store.getFeatureTypeManager().getTransforms();
100
        } else {
101
            this.transform =
102
                (DefaultFeatureStoreTransforms) store.getTransforms();
103
        }
104
        this.query = query;
105
        try {
106
            this.queryForProvider = (FeatureQuery) query.clone();
107
        } catch (CloneNotSupportedException e) {
108
            throw new FeatureSetInitializeException(e);
109
        }
110
111
        this.featureTypes = new ArrayList();
112
        if (this.query.getFeatureTypeId() == null
113
            && this.query.getAttributeNames() == null) {
114 44753 omartinez
            this.defaultFeatureType = this.store.getDefaultFeatureType();
115 40435 jjdelcerro
            this.featureTypes.addAll(this.store.getFeatureTypes());
116
        } else {
117 44753 omartinez
            this.defaultFeatureType = this.store.getFeatureType(this.query);
118
            List<EditableFeatureAttributeDescriptor> cols = this.query.getExtraColumn().getColumns();
119
            if (this.query!=null && cols!=null && !cols.isEmpty()) {
120
                DefaultFeatureType featureTypeExtraCols = (DefaultFeatureType) this.defaultFeatureType.getCopy();
121
                featureTypeExtraCols.setExtraColumn(this.query.getExtraColumn());
122
                this.defaultFeatureType = featureTypeExtraCols;
123
            }
124
            this.featureTypes.add(this.defaultFeatureType);
125 40435 jjdelcerro
        }
126
        if (this.transform != null && !this.transform.isEmpty()) {
127
            this.fixQueryForProvider(this.queryForProvider, this.transform);
128
        } else {
129 44753 omartinez
            this.defatulFeatureTypeForProvider = this.defaultFeatureType;
130 40435 jjdelcerro
        }
131
132
        FeatureIndexes indexes = store.getIndexes();
133
        if (this.queryForProvider.hasFilter() && indexes != null
134
            && indexes.areValid()) {
135
            this.provider =
136
                (FeatureSetProvider) indexes
137
                    .getFeatureSet(this.queryForProvider.getFilter());
138
        }
139
        if (this.provider == null) {
140
            this.provider =
141
                this.store.getProvider().createSet(this.queryForProvider,
142 47436 fdiaz
                    this.defatulFeatureTypeForProvider, this.defaultFeatureType);
143 40435 jjdelcerro
        }
144
        this.store.addObserver(this);
145
    }
146
147
    private void fixQueryForProvider(FeatureQuery theQueryForProvider,
148
        DefaultFeatureStoreTransforms transformsToUse) throws DataException {
149 42975 jjdelcerro
        theQueryForProvider.clearAttributeNames();
150 40435 jjdelcerro
        FeatureType ftype =
151 44753 omartinez
            transformsToUse.getSourceFeatureTypeFrom(this.defaultFeatureType);
152 40435 jjdelcerro
        theQueryForProvider.setFeatureTypeId(ftype.getId());
153
        this.defatulFeatureTypeForProvider = ftype;
154 44854 omartinez
155 40435 jjdelcerro
        if (transformsToUse.isTransformsOriginalValues()) {
156 42975 jjdelcerro
            theQueryForProvider.clearFilter();
157 40435 jjdelcerro
            FeatureQueryOrder fqo = theQueryForProvider.getOrder();
158
            if (fqo != null) {
159
                fqo.clear();
160
            }
161
            return;
162
163
        }
164
165
        // Filter
166
        Evaluator filter = theQueryForProvider.getFilter();
167
        if (filter != null) {
168 44113 jjdelcerro
            boolean canUseFilter;
169 40435 jjdelcerro
            if (filter.getFieldsInfo() == null) {
170
                canUseFilter = false;
171
            } else {
172
                canUseFilter = areEvaluatorFieldsInAttributes(filter, ftype);
173
            }
174
175
            if (!canUseFilter) {
176 42975 jjdelcerro
                theQueryForProvider.clearFilter();
177 40435 jjdelcerro
            }
178
179
        }
180
181
        // Order
182
        if (theQueryForProvider.hasOrder()) {
183
            boolean canUseOrder = true;
184
            Iterator iter = theQueryForProvider.getOrder().iterator();
185
            FeatureQueryOrderMember item;
186
            while (iter.hasNext()) {
187
                item = (FeatureQueryOrderMember) iter.next();
188
                if (item.hasEvaluator()) {
189
                    if (!areEvaluatorFieldsInAttributes(item.getEvaluator(),
190
                        ftype)) {
191
                        canUseOrder = false;
192
                        break;
193
                    }
194
                } else {
195
                    if (ftype.get(item.getAttributeName()) == null) {
196
                        canUseOrder = false;
197
                        break;
198
                    }
199
                }
200
            }
201
202
            if (!canUseOrder) {
203
                theQueryForProvider.getOrder().clear();
204
            }
205
        }
206
207
    }
208
209
    private boolean areEvaluatorFieldsInAttributes(Evaluator evaluator,
210
        FeatureType fType) {
211
        if (evaluator.getFieldsInfo() == null) {
212
            return false;
213
        }
214
        String[] fieldNames = evaluator.getFieldsInfo().getFieldNames();
215
        if (fieldNames.length == 0) {
216
            return false;
217
        } else {
218 44113 jjdelcerro
            for (String fieldName : fieldNames) {
219
                if (fType.get(fieldName) == null) {
220 40435 jjdelcerro
                    return false;
221
                }
222
            }
223
        }
224
        return true;
225
    }
226
227 44854 omartinez
    @Override
228 40435 jjdelcerro
    public FeatureType getDefaultFeatureType() {
229 44753 omartinez
        return this.defaultFeatureType;
230 40435 jjdelcerro
    }
231
232 44854 omartinez
    @Override
233 40435 jjdelcerro
    public List getFeatureTypes() {
234
        return Collections.unmodifiableList(this.featureTypes);
235
    }
236
237 44854 omartinez
    @Override
238 40435 jjdelcerro
    public long getSize() throws DataException {
239
        this.checkSourceStoreModified();
240
        if (size < 0) {
241
            size = calculateSize();
242
        }
243
        return size;
244
    }
245
246
    private long calculateSize() throws DataException {
247 46277 jjdelcerro
        boolean hasLimit = this.query.hasLimit();
248 44202 jjdelcerro
        long limit = this.query.getLimit();
249 46505 fdiaz
        if(hasLimit && limit == 0){
250
            return 0;
251
        }
252 44202 jjdelcerro
        long mySize = 0;
253
254 40435 jjdelcerro
        int mode = this.getIteratorMode();
255 45530 fdiaz
        DisposableIterator iter = null;
256 44202 jjdelcerro
        switch (mode) {
257
        case DEFAULT:
258
        case ORDERED:
259 40435 jjdelcerro
            if (this.provider.isEmpty()) {
260
                return 0;
261
            }
262 44202 jjdelcerro
            mySize = provider.getSize();
263 46277 jjdelcerro
            return (hasLimit && mySize>limit)? limit:mySize;
264 44202 jjdelcerro
265
        case FILTERED:
266
        case ORDERED_FILTERED:
267 40435 jjdelcerro
            try {
268
                iter = this.fastIterator();
269 46277 jjdelcerro
                while ((hasLimit && (mySize<limit)) || !hasLimit ) {
270 40435 jjdelcerro
                    iter.next();
271
                    mySize++;
272
                }
273
            } catch (NoSuchElementException e) {
274 44202 jjdelcerro
275 40435 jjdelcerro
            } finally {
276 44113 jjdelcerro
                DisposeUtils.disposeQuietly(iter);
277 40435 jjdelcerro
            }
278 46277 jjdelcerro
            return (limit>=0 && mySize>limit)? limit:mySize;
279 44202 jjdelcerro
280
        case EDITED:
281
        case ORDERD_EDITED:
282
            mySize = provider.getSize()
283 43983 jjdelcerro
                + store.getFeatureManager().getDeltaSize();
284 46277 jjdelcerro
            return (hasLimit && mySize>limit)? limit:mySize;
285 44202 jjdelcerro
286 45530 fdiaz
        case EDITED_FILTERED:
287
        case ORDERED_EDITED_FILTER:
288
            try {
289
                iter = this.fastIterator();
290 46277 jjdelcerro
                while ((hasLimit && (mySize<limit)) || !hasLimit ) {
291 45530 fdiaz
                    iter.next();
292
                    mySize++;
293
                }
294
            } catch (NoSuchElementException e) {
295
296
            } finally {
297
                DisposeUtils.disposeQuietly(iter);
298
            }
299 46277 jjdelcerro
            return (hasLimit && mySize>limit)? limit:mySize;
300 45530 fdiaz
301 44202 jjdelcerro
        default:
302
            throw new IllegalArgumentException();
303 43983 jjdelcerro
        }
304 40435 jjdelcerro
    }
305 45195 omartinez
306
    @Override
307
    public synchronized final void dispose() {
308
        // Check if we have already been disposed, and don't do it again
309
        if (!disposed) {
310
            if (DisposeUtils.release(this)) {
311
                try {
312
                    doDispose();
313
                } catch (Exception ex) {
314
                    LOG.error("Error performing dispose", ex);
315
                } finally {
316
                    disposed = true;
317
                }
318
            }
319
        }
320
    }
321 40435 jjdelcerro
322 45195 omartinez
    public void doDispose() {
323 44669 jjdelcerro
        if( this.store!=null ) {
324
            this.store.deleteObserver(this);
325 45425 jjdelcerro
            DisposeUtils.dispose(this.store);
326 44669 jjdelcerro
            this.store = null;
327
        }
328
        if( this.provider!=null ) {
329
            this.provider.dispose();
330
            this.provider = null;
331
        }
332 40435 jjdelcerro
        if (orderedData != null) {
333
            orderedData.clear();
334 44669 jjdelcerro
            this.orderedData = null;
335 40435 jjdelcerro
        }
336 44669 jjdelcerro
        this.featureToIgnoreNotification = null;
337 40435 jjdelcerro
        this.transform = null;
338
        this.query = null;
339
        this.queryForProvider = null;
340
        this.featureTypes = null;
341 44753 omartinez
        this.defaultFeatureType = null;
342 40435 jjdelcerro
        this.defatulFeatureTypeForProvider = null;
343
    }
344
345
    public void update(Observable obsevable, Object notification) {
346
        if (sourceStoreModified) {
347
            return;
348
        }
349
350
        String type = ((FeatureStoreNotification) notification).getType();
351
352
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
353
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
354
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE)) {
355
            if (this.featureToIgnoreNotification == ((FeatureStoreNotification) notification)
356
                .getFeature()) {
357
                return;
358
            }
359
            sourceStoreModified = true;
360 45425 jjdelcerro
            sourceStoreModifiedCause = new Throwable();
361 40435 jjdelcerro
            return;
362
        }
363
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE_TYPE)
364
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REDO)
365
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UNDO)
366
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH)
367 45425 jjdelcerro
            || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
368
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
369
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
370 40435 jjdelcerro
            || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)) {
371
            sourceStoreModified = true;
372 45425 jjdelcerro
            sourceStoreModifiedCause = new Throwable();
373 40435 jjdelcerro
            return;
374
        }
375 44097 omartinez
        if (type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)) {
376
            if(!this.ignoreChanges) {
377
                sourceStoreModified = true;
378 45425 jjdelcerro
                sourceStoreModifiedCause = new Throwable();
379 44097 omartinez
                return;
380
            }
381 40435 jjdelcerro
        }
382 44097 omartinez
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)) {
383
            if (ownFeaturesModified) {
384
                sourceStoreModified = true;
385 45425 jjdelcerro
                sourceStoreModifiedCause = new Throwable();
386 44097 omartinez
                return;
387
            }
388
        }
389 40435 jjdelcerro
    }
390 43358 jjdelcerro
391 40435 jjdelcerro
    protected void checkSourceStoreModified() {
392
        if (sourceStoreModified) {
393 46485 fdiaz
            LOG.debug("ConcurrentDataModification in featureSet "+this.hashCode()+" of store '"+(store == null ? "": store.getName())+"'");
394 45425 jjdelcerro
            ConcurrentDataModificationException ex = new ConcurrentDataModificationException(
395
                    store == null ? "": store.getName()
396
            );
397
            ex.initCause(sourceStoreModifiedCause);
398
            throw ex;
399 40435 jjdelcerro
        }
400
    }
401
402 43358 jjdelcerro
    @Override
403 40435 jjdelcerro
    public DisposableIterator fastIterator(long index) throws DataException {
404 43358 jjdelcerro
        return fastIterator(index, 0);
405
    }
406
407
    @Override
408
    public DisposableIterator fastIterator(long index, long elements) throws DataException {
409 40435 jjdelcerro
        if (index < 0) {
410
            throw new IndexOutOfBoundsException("The index (" + index
411
                + ") is less than 0");
412
        }
413 43913 jjdelcerro
        DisposableIterator it;
414 40435 jjdelcerro
        int mode = this.getIteratorMode();
415
416
        switch (mode) {
417
        case DEFAULT:
418 43913 jjdelcerro
            it = new FastDefaultIterator(this, index, elements);
419
            break;
420 40435 jjdelcerro
421
        case FILTERED:
422 45989 fdiaz
            it = new FastFilteredIterator(this, index, elements);
423 43913 jjdelcerro
            break;
424 40435 jjdelcerro
425
        case ORDERED:
426 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canIterateFromIndex()){
427
                it = new FastDefaultIterator(this, index, elements);
428 40435 jjdelcerro
            } else {
429 45989 fdiaz
                if (this.orderedData != null) {
430
                    it = new FastOrderedIterator(this, index);
431
                } else {
432
                    it = new FastOrderedIterator(this, new FastDefaultIterator(this, 0, -1), index);
433
                }
434 40435 jjdelcerro
            }
435 43913 jjdelcerro
            break;
436
437 40435 jjdelcerro
        case ORDERED_FILTERED:
438 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex()){
439
                it = new FastFilteredIterator(this, index, elements);
440 40435 jjdelcerro
            } else {
441 45989 fdiaz
                if (this.orderedData != null) {
442
                    it = new FastOrderedIterator(this, index);
443
                } else {
444
                    it = new FastOrderedIterator(this, new FastFilteredIterator(
445
                        this, 0, -1), index);
446
                }
447 40435 jjdelcerro
            }
448 45989 fdiaz
449 43913 jjdelcerro
            break;
450 40435 jjdelcerro
451
        case EDITED:
452 45989 fdiaz
            it = new FastEditedIterator(this, index, elements);
453 43913 jjdelcerro
            break;
454 40435 jjdelcerro
455
        case EDITED_FILTERED:
456 45989 fdiaz
            it = new FastEditedFilteredIterator(this, index, elements);
457 43913 jjdelcerro
            break;
458 40435 jjdelcerro
459
        case ORDERD_EDITED:
460 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
461
                it = new FastEditedIterator(this, index, elements);
462 40435 jjdelcerro
            } else {
463 45989 fdiaz
                if (this.orderedData != null) {
464
                    it = new FastOrderedIterator(this, index);
465
                } else {
466
                    it = new FastOrderedIterator(this, new FastEditedIterator(
467
                        this, 0, -1), index);
468
                }
469 40435 jjdelcerro
            }
470 43913 jjdelcerro
            break;
471 40435 jjdelcerro
472
        case ORDERED_EDITED_FILTER:
473 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
474
                it = new FastEditedFilteredIterator(this, index, elements);
475 40435 jjdelcerro
            } else {
476 45989 fdiaz
                if (this.orderedData != null) {
477
                    it = new FastOrderedIterator(this, index);
478
                } else {
479
                    it = new FastOrderedIterator(this,
480
                        new FastEditedFilteredIterator(this, 0, -1), index);
481
                }
482 40435 jjdelcerro
            }
483 43913 jjdelcerro
            break;
484
485 40435 jjdelcerro
        default:
486
            throw new IllegalArgumentException();
487
        }
488 43913 jjdelcerro
        if( this.query!=null && this.query.getLimit()>0 ) {
489
            it = new LimitIterator(it,this.query.getLimit());
490
        }
491
        return it;
492 40435 jjdelcerro
    }
493
494 43913 jjdelcerro
    private class LimitIterator implements DisposableIterator {
495 40435 jjdelcerro
496 43913 jjdelcerro
        private final DisposableIterator it;
497
        private final long limit;
498
        private int count;
499
500
        private LimitIterator(DisposableIterator it, long limit) {
501
            this.it = it;
502
            this.limit = limit;
503
            this.count = 0;
504
        }
505
506
        @Override
507
        public void dispose() {
508
            this.it.dispose();
509
        }
510
511
        @Override
512
        public boolean hasNext() {
513
            if( this.count>=this.limit ) {
514
                return false;
515
            }
516
            return this.it.hasNext();
517
        }
518
519
        @Override
520
        public Object next() {
521
            if( this.count>=this.limit ) {
522
                return null;
523
            }
524
            this.count++;
525
            return this.it.next();
526
        }
527
528
        @Override
529
        public void remove() {
530
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
531
        }
532
533
    }
534
535 43358 jjdelcerro
    @Override
536 40435 jjdelcerro
    public DisposableIterator iterator(long index) throws DataException {
537 43358 jjdelcerro
        return iterator(index,0);
538
    }
539
540
    @Override
541
    public DisposableIterator iterator(long index, long elements) throws DataException {
542 40435 jjdelcerro
        if (index < 0) {
543
            throw new IndexOutOfBoundsException("The index (" + index
544
                + ") is less than 0");
545
        }
546 43913 jjdelcerro
        DisposableIterator it;
547 40435 jjdelcerro
        int mode = this.getIteratorMode();
548
549
        switch (mode) {
550
        case DEFAULT:
551 43913 jjdelcerro
            it = new DefaultIterator(this, index, elements);
552
            break;
553 40435 jjdelcerro
554
        case FILTERED:
555 45989 fdiaz
            it = new FilteredIterator(this, index, elements);
556 43913 jjdelcerro
            break;
557 40435 jjdelcerro
558
        case ORDERED:
559 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canIterateFromIndex()){
560
                it = new DefaultIterator(this, index, elements);
561
            } else {
562
                if (orderedData != null) {
563
                    it = new OrderedIterator(this, index);
564 40435 jjdelcerro
565 45989 fdiaz
                } else {
566
                    it = new OrderedIterator(this, new DefaultIterator(this, 0, elements),index);
567
                }
568 40435 jjdelcerro
            }
569 43913 jjdelcerro
            break;
570 40435 jjdelcerro
571
        case ORDERED_FILTERED:
572 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex()){
573
                it = new FilteredIterator(this, index, elements);
574
            } else {
575
                if (orderedData != null) {
576
                    it = new OrderedIterator(this, index);
577
                } else {
578
                    it = new OrderedIterator(this, new FilteredIterator(this, 0, -1),index);
579
                }
580
            }
581 43913 jjdelcerro
            break;
582 40435 jjdelcerro
583
        case EDITED:
584 45989 fdiaz
            it = new EditedIterator(this, index, elements);
585 43913 jjdelcerro
            break;
586 40435 jjdelcerro
587
        case EDITED_FILTERED:
588 45989 fdiaz
            it = new EditedFilteredIterator(this, index, elements);
589 43913 jjdelcerro
            break;
590 40435 jjdelcerro
591
        case ORDERD_EDITED:
592 45989 fdiaz
            if(this.provider.canOrder() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
593
                it = new EditedIterator(this, index, elements);
594
            } else {
595
                if (orderedData != null) {
596
                    it = new OrderedIterator(this, index);
597
                } else {
598
                    it = new OrderedIterator(this,
599
                        new EditedIterator(this, 0, -1), index);
600
                }
601
            }
602 43913 jjdelcerro
            break;
603 40435 jjdelcerro
604
        case ORDERED_EDITED_FILTER:
605 45989 fdiaz
            if(this.provider.canOrder() && this.providerCanFilter() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
606
                it = new EditedFilteredIterator(this, index, elements);
607
            } else {
608
                if (orderedData != null) {
609
                    it = new OrderedIterator(this, index);
610
                } else {
611
                    it = new OrderedIterator(this,
612
                        new EditedFilteredIterator(this, 0, -1), index);
613
                }
614
            }
615 43913 jjdelcerro
            break;
616 40435 jjdelcerro
617
        default:
618
            throw new IllegalArgumentException();
619
        }
620
621 43913 jjdelcerro
        if( this.query!=null && this.query.getLimit()>0 ) {
622
            it = new LimitIterator(it,this.query.getLimit());
623
        }
624
        return it;
625 40435 jjdelcerro
    }
626
627
    private boolean providerCanOrder() {
628
        return this.provider.canOrder();
629
    }
630
631
    private boolean providerCanFilter() {
632
        return this.provider.canFilter();
633
    }
634
635
    private int getIteratorMode() {
636
637
        if (this.iteratorMode != NO_CHECKED) {
638
            return this.iteratorMode;
639
        }
640
641
        // TODO Tener en cuenta las transformaciones ???
642
643 43981 omartinez
        if (store.isEditing() && (store.getFeatureTypeManager().hasChanges() || store.getFeatureManager().hasChanges())) {
644 40435 jjdelcerro
            if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
645
                if (this.query.hasFilter()) {
646
                    return ORDERED_EDITED_FILTER;
647
                } else {
648
                    return ORDERD_EDITED;
649
                }
650
            } else {
651
                if (this.query.hasFilter()) {
652
                    return EDITED_FILTERED;
653
                } else {
654
                    return EDITED;
655
                }
656
            }
657
        } else {
658
            boolean useMyFilter = this.query.hasFilter();
659
            boolean useMyOrder = this.query.hasOrder();
660
            if (this.providerCanOrder() && this.transform.isEmpty()) {
661
                useMyOrder = false;
662
            }
663
            if (this.providerCanFilter() && this.transform.isEmpty()) {
664
                useMyFilter = false;
665
            }
666
667
            if (useMyOrder) {
668
                if (useMyFilter) {
669 44191 jjdelcerro
                    return ORDERED_FILTERED;
670 40435 jjdelcerro
                } else {
671 44191 jjdelcerro
                    return ORDERED;
672 40435 jjdelcerro
                }
673
            } else {
674
                if (useMyFilter) {
675 44191 jjdelcerro
                    return FILTERED;
676 40435 jjdelcerro
                } else {
677 44191 jjdelcerro
                    return DEFAULT;
678 40435 jjdelcerro
                }
679
            }
680
        }
681
682
    }
683
684 44854 omartinez
    @Override
685 40435 jjdelcerro
    public void delete(Feature feature) throws DataException {
686
        this.featureToIgnoreNotification = feature;
687
        this.store.delete(feature);
688
        if (this.size > 0) {
689
            this.size--;
690
        }
691
        this.featureToIgnoreNotification = null;
692
        this.ownFeaturesModified = true;
693
    }
694
695 44854 omartinez
    @Override
696 40435 jjdelcerro
    public void insert(EditableFeature feature) throws DataException {
697
        this.featureToIgnoreNotification = feature;
698
        this.store.insert(feature);
699
        if (this.size >= 0) {
700
            this.size++;
701
        }
702
        this.featureToIgnoreNotification = null;
703
        this.ownFeaturesModified = true;
704
    }
705
706 44854 omartinez
    @Override
707 40435 jjdelcerro
    public void update(EditableFeature feature) throws DataException {
708
        this.featureToIgnoreNotification = feature;
709
        this.store.update(feature);
710
        this.featureToIgnoreNotification = null;
711
        this.ownFeaturesModified = true;
712
    }
713 44097 omartinez
714 44854 omartinez
    @Override
715 44097 omartinez
    public void commitChanges() throws DataException {
716
        this.ignoreChanges = true;
717
        this.store.commitChanges();
718
        this.ignoreChanges = false;
719
720
    }
721 40435 jjdelcerro
722 44854 omartinez
    @Override
723 40435 jjdelcerro
    public FeatureStore getFeatureStore() {
724
        return store;
725
    }
726 43358 jjdelcerro
727 40435 jjdelcerro
}