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 @ 46485

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