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

History | View | Annotate | Download (25 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
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
 * as published by the Free Software Foundation; either version 3
9
 * 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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
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
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
35
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
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
40
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
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureType;
49
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.dispose.DisposableIterator;
52
import org.gvsig.tools.dispose.DisposeUtils;
53
import org.gvsig.tools.evaluator.Evaluator;
54
import org.gvsig.tools.exception.BaseException;
55
import org.gvsig.tools.observer.Observable;
56
import org.gvsig.tools.observer.Observer;
57

    
58
public class DefaultFeatureSet extends AbstractFeatureSet implements
59
    FeatureSet, Observer {
60
    
61
    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

    
71
    protected Throwable sourceStoreModifiedCause;
72
    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
    protected FeatureType defaultFeatureType;
85
    protected FeatureType defatulFeatureTypeForProvider;
86
    protected boolean ignoreChanges;
87
    private boolean disposed = false;
88

    
89
    public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
90
        throws DataException {
91
        DisposeUtils.bind(this);
92
        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
        DisposeUtils.bind(this.store);
100
        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
            this.defaultFeatureType = this.store.getDefaultFeatureType();
117
            this.featureTypes.addAll(this.store.getFeatureTypes());
118
        } else {
119
            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
        }
128
        if (this.transform != null && !this.transform.isEmpty()) {
129
            this.fixQueryForProvider(this.queryForProvider, this.transform);
130
        } else {
131
            this.defatulFeatureTypeForProvider = this.defaultFeatureType;
132
        }
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
        theQueryForProvider.clearAttributeNames();
152
        FeatureType ftype =
153
            transformsToUse.getSourceFeatureTypeFrom(this.defaultFeatureType);
154
        theQueryForProvider.setFeatureTypeId(ftype.getId());
155
        this.defatulFeatureTypeForProvider = ftype;
156
        
157
        if (transformsToUse.isTransformsOriginalValues()) {
158
            theQueryForProvider.clearFilter();
159
            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
            boolean canUseFilter;
171
            if (filter.getFieldsInfo() == null) {
172
                canUseFilter = false;
173
            } else {
174
                canUseFilter = areEvaluatorFieldsInAttributes(filter, ftype);
175
            }
176

    
177
            if (!canUseFilter) {
178
                theQueryForProvider.clearFilter();
179
            }
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
            for (String fieldName : fieldNames) {
221
                if (fType.get(fieldName) == null) {
222
                    return false;
223
                }
224
            }
225
        }
226
        return true;
227
    }
228

    
229
    @Override
230
    public FeatureType getDefaultFeatureType() {
231
        return this.defaultFeatureType;
232
    }
233

    
234
    @Override
235
    public List getFeatureTypes() {
236
        return Collections.unmodifiableList(this.featureTypes);
237
    }
238

    
239
    @Override
240
    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
        boolean hasLimit = this.query.hasLimit();
250
        long limit = this.query.getLimit();
251
        if(hasLimit && limit == 0){
252
            return 0;
253
        }
254
        long mySize = 0;
255
        
256
        int mode = this.getIteratorMode();
257
        DisposableIterator iter = null;
258
        switch (mode) {
259
        case DEFAULT:
260
        case ORDERED:
261
            if (this.provider.isEmpty()) {
262
                return 0;
263
            }
264
            mySize = provider.getSize();
265
            return (hasLimit && mySize>limit)? limit:mySize;
266

    
267
        case FILTERED:
268
        case ORDERED_FILTERED:
269
            try {
270
                iter = this.fastIterator();
271
                while ((hasLimit && (mySize<limit)) || !hasLimit ) {
272
                    iter.next();
273
                    mySize++;
274
                }
275
            } catch (NoSuchElementException e) {
276

    
277
            } finally {
278
                DisposeUtils.disposeQuietly(iter);
279
            }
280
            return (limit>=0 && mySize>limit)? limit:mySize;
281

    
282
        case EDITED:
283
        case ORDERD_EDITED:
284
            mySize = provider.getSize()
285
                + store.getFeatureManager().getDeltaSize();
286
            return (hasLimit && mySize>limit)? limit:mySize;
287

    
288
        case EDITED_FILTERED:
289
        case ORDERED_EDITED_FILTER:
290
            try {
291
                iter = this.fastIterator();
292
                while ((hasLimit && (mySize<limit)) || !hasLimit ) {
293
                    iter.next();
294
                    mySize++;
295
                }
296
            } catch (NoSuchElementException e) {
297

    
298
            } finally {
299
                DisposeUtils.disposeQuietly(iter);
300
            }
301
            return (hasLimit && mySize>limit)? limit:mySize;
302
            
303
        default:
304
            throw new IllegalArgumentException();
305
        }
306
    }
307
    
308
    @Override
309
    public synchronized final void dispose() {
310
        // Check if we have already been disposed, and don't do it again
311
        if (!disposed) {
312
            if (DisposeUtils.release(this)) {
313
                try {
314
                    doDispose();
315
                } catch (Exception ex) {
316
                    LOG.error("Error performing dispose", ex);
317
                } finally {
318
                    disposed = true;
319
                }
320
            }
321
        }
322
    }
323

    
324
    public void doDispose() {
325
        if( this.store!=null ) {
326
            this.store.deleteObserver(this);
327
            DisposeUtils.dispose(this.store);
328
            this.store = null;
329
        }
330
        if( this.provider!=null ) {
331
            this.provider.dispose();
332
            this.provider = null;
333
        }
334
        if (orderedData != null) {
335
            orderedData.clear();
336
            this.orderedData = null;
337
        }
338
        this.featureToIgnoreNotification = null;
339
        this.transform = null;
340
        this.query = null;
341
        this.queryForProvider = null;
342
        this.featureTypes = null;
343
        this.defaultFeatureType = null;
344
        this.defatulFeatureTypeForProvider = null;
345
    }
346

    
347
    public void update(Observable obsevable, Object notification) {
348
        if (sourceStoreModified) {
349
            return;
350
        }
351

    
352
        String type = ((FeatureStoreNotification) notification).getType();
353

    
354
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
355
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
356
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE)) {
357
            if (this.featureToIgnoreNotification == ((FeatureStoreNotification) notification)
358
                .getFeature()) {
359
                return;
360
            }
361
            sourceStoreModified = true;
362
            sourceStoreModifiedCause = new Throwable();
363
            return;
364
        }
365
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE_TYPE)
366
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REDO)
367
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UNDO)
368
            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH)
369
            || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
370
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
371
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
372
            || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)) {
373
            sourceStoreModified = true;
374
            sourceStoreModifiedCause = new Throwable();
375
            return;
376
        }
377
        if (type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)) {
378
            if(!this.ignoreChanges) {
379
                sourceStoreModified = true;
380
                sourceStoreModifiedCause = new Throwable();
381
                return;
382
            }
383
        }
384
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)) {
385
            if (ownFeaturesModified) {
386
                sourceStoreModified = true;
387
                sourceStoreModifiedCause = new Throwable();
388
                return;
389
            }
390
        }
391
    }
392
  
393
    protected void checkSourceStoreModified() {
394
        if (sourceStoreModified) {
395
            LOG.debug("ConcurrentDataModification in featureSet "+this.hashCode()+" of store '"+(store == null ? "": store.getName())+"'");
396
            ConcurrentDataModificationException ex = new ConcurrentDataModificationException(
397
                    store == null ? "": store.getName()
398
            );
399
            ex.initCause(sourceStoreModifiedCause);
400
            throw ex;
401
        }
402
    }
403

    
404
    @Override
405
    public DisposableIterator fastIterator(long index) throws DataException {
406
        return fastIterator(index, 0);
407
    }
408
    
409
    @Override
410
    public DisposableIterator fastIterator(long index, long elements) throws DataException {
411
        if (index < 0) {
412
            throw new IndexOutOfBoundsException("The index (" + index
413
                + ") is less than 0");
414
        }
415
        DisposableIterator it;
416
        int mode = this.getIteratorMode();
417

    
418
        switch (mode) {
419
        case DEFAULT:
420
            it = new FastDefaultIterator(this, index, elements);
421
            break;
422

    
423
        case FILTERED:
424
            it = new FastFilteredIterator(this, index, elements);
425
            break;
426

    
427
        case ORDERED:
428
            if(this.provider.canOrder() && this.provider.canIterateFromIndex()){
429
                it = new FastDefaultIterator(this, index, elements);
430
            } else {
431
                if (this.orderedData != null) {
432
                    it = new FastOrderedIterator(this, index);
433
                } else {
434
                    it = new FastOrderedIterator(this, new FastDefaultIterator(this, 0, -1), index);
435
                }
436
            }
437
            break;
438
            
439
        case ORDERED_FILTERED:
440
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex()){
441
                it = new FastFilteredIterator(this, index, elements);
442
            } else {
443
                if (this.orderedData != null) {
444
                    it = new FastOrderedIterator(this, index);
445
                } else {
446
                    it = new FastOrderedIterator(this, new FastFilteredIterator(
447
                        this, 0, -1), index);
448
                }
449
            }
450

    
451
            break;
452

    
453
        case EDITED:
454
            it = new FastEditedIterator(this, index, elements);
455
            break;
456

    
457
        case EDITED_FILTERED:
458
            it = new FastEditedFilteredIterator(this, index, elements);
459
            break;
460

    
461
        case ORDERD_EDITED:
462
            if(this.provider.canOrder() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
463
                it = new FastEditedIterator(this, index, elements);
464
            } else {
465
                if (this.orderedData != null) {
466
                    it = new FastOrderedIterator(this, index);
467
                } else {
468
                    it = new FastOrderedIterator(this, new FastEditedIterator(
469
                        this, 0, -1), index);
470
                }
471
            }
472
            break;
473

    
474
        case ORDERED_EDITED_FILTER:
475
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
476
                it = new FastEditedFilteredIterator(this, index, elements);
477
            } else {
478
                if (this.orderedData != null) {
479
                    it = new FastOrderedIterator(this, index);
480
                } else {
481
                    it = new FastOrderedIterator(this,
482
                        new FastEditedFilteredIterator(this, 0, -1), index);
483
                }
484
            }
485
            break;
486
            
487
        default:
488
            throw new IllegalArgumentException();
489
        }
490
        if( this.query!=null && this.query.getLimit()>0 ) {
491
            it = new LimitIterator(it,this.query.getLimit());
492
        }
493
        return it;
494
    }
495

    
496
    private class LimitIterator implements DisposableIterator {
497

    
498
        private final DisposableIterator it;
499
        private final long limit;
500
        private int count;
501

    
502
        private LimitIterator(DisposableIterator it, long limit) {
503
            this.it = it;
504
            this.limit = limit;
505
            this.count = 0;
506
        }
507

    
508
        @Override
509
        public void dispose() {
510
            this.it.dispose();
511
        }
512

    
513
        @Override
514
        public boolean hasNext() {
515
            if( this.count>=this.limit ) {
516
                return false;
517
            }
518
            return this.it.hasNext();
519
        }
520

    
521
        @Override
522
        public Object next() {
523
            if( this.count>=this.limit ) {
524
                return null;
525
            }
526
            this.count++;
527
            return this.it.next();
528
        }
529

    
530
        @Override
531
        public void remove() {
532
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
533
        }
534
        
535
    }
536

    
537
    @Override
538
    public DisposableIterator iterator(long index) throws DataException {
539
        return iterator(index,0);
540
    }
541
    
542
    @Override
543
    public DisposableIterator iterator(long index, long elements) throws DataException {        
544
        if (index < 0) {
545
            throw new IndexOutOfBoundsException("The index (" + index
546
                + ") is less than 0");
547
        }
548
        DisposableIterator it;
549
        int mode = this.getIteratorMode();
550

    
551
        switch (mode) {
552
        case DEFAULT:
553
            it = new DefaultIterator(this, index, elements);
554
            break;
555

    
556
        case FILTERED:
557
            it = new FilteredIterator(this, index, elements);
558
            break;
559

    
560
        case ORDERED:
561
            if(this.provider.canOrder() && this.provider.canIterateFromIndex()){
562
                it = new DefaultIterator(this, index, elements);
563
            } else {
564
                if (orderedData != null) {
565
                    it = new OrderedIterator(this, index);
566

    
567
                } else {
568
                    it = new OrderedIterator(this, new DefaultIterator(this, 0, elements),index);
569
                }
570
            }
571
            break;
572

    
573
        case ORDERED_FILTERED:
574
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex()){
575
                it = new FilteredIterator(this, index, elements);
576
            } else {
577
                if (orderedData != null) {
578
                    it = new OrderedIterator(this, index);
579
                } else {
580
                    it = new OrderedIterator(this, new FilteredIterator(this, 0, -1),index);
581
                }
582
            }
583
            break;
584

    
585
        case EDITED:
586
            it = new EditedIterator(this, index, elements);
587
            break;
588

    
589
        case EDITED_FILTERED:
590
            it = new EditedFilteredIterator(this, index, elements);
591
            break;
592

    
593
        case ORDERD_EDITED:
594
            if(this.provider.canOrder() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
595
                it = new EditedIterator(this, index, elements);
596
            } else {
597
                if (orderedData != null) {
598
                    it = new OrderedIterator(this, index);
599
                } else {
600
                    it = new OrderedIterator(this,
601
                        new EditedIterator(this, 0, -1), index);
602
                }
603
            }
604
            break;
605

    
606
        case ORDERED_EDITED_FILTER:
607
            if(this.provider.canOrder() && this.providerCanFilter() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
608
                it = new EditedFilteredIterator(this, index, elements);
609
            } else {
610
                if (orderedData != null) {
611
                    it = new OrderedIterator(this, index);
612
                } else {
613
                    it = new OrderedIterator(this,
614
                        new EditedFilteredIterator(this, 0, -1), index);
615
                }
616
            }
617
            break;
618

    
619
        default:
620
            throw new IllegalArgumentException();
621
        }
622

    
623
        if( this.query!=null && this.query.getLimit()>0 ) {
624
            it = new LimitIterator(it,this.query.getLimit());
625
        }
626
        return it;
627
    }
628

    
629
    private boolean providerCanOrder() {
630
        return this.provider.canOrder();
631
    }
632

    
633
    private boolean providerCanFilter() {
634
        return this.provider.canFilter();
635
    }
636

    
637
    private int getIteratorMode() {
638

    
639
        if (this.iteratorMode != NO_CHECKED) {
640
            return this.iteratorMode;
641
        }
642

    
643
        // TODO Tener en cuenta las transformaciones ???
644

    
645
        if (store.isEditing() && (store.getFeatureTypeManager().hasChanges() || store.getFeatureManager().hasChanges())) {
646
            if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
647
                if (this.query.hasFilter()) {
648
                    return ORDERED_EDITED_FILTER;
649
                } else {
650
                    return ORDERD_EDITED;
651
                }
652
            } else {
653
                if (this.query.hasFilter()) {
654
                    return EDITED_FILTERED;
655
                } else {
656
                    return EDITED;
657
                }
658
            }
659
        } else {
660
            boolean useMyFilter = this.query.hasFilter();
661
            boolean useMyOrder = this.query.hasOrder();
662
            if (this.providerCanOrder() && this.transform.isEmpty()) {
663
                useMyOrder = false;
664
            }
665
            if (this.providerCanFilter() && this.transform.isEmpty()) {
666
                useMyFilter = false;
667
            }
668

    
669
            if (useMyOrder) {
670
                if (useMyFilter) {
671
                    return ORDERED_FILTERED;
672
                } else {
673
                    return ORDERED;
674
                }
675
            } else {
676
                if (useMyFilter) {
677
                    return FILTERED;
678
                } else {
679
                    return DEFAULT;
680
                }
681
            }
682
        }
683

    
684
    }
685

    
686
    @Override
687
    public void delete(Feature feature) throws DataException {
688
        this.featureToIgnoreNotification = feature;
689
        this.store.delete(feature);
690
        if (this.size > 0) {
691
            this.size--;
692
        }
693
        this.featureToIgnoreNotification = null;
694
        this.ownFeaturesModified = true;
695
    }
696

    
697
    @Override
698
    public void insert(EditableFeature feature) throws DataException {
699
        this.featureToIgnoreNotification = feature;
700
        this.store.insert(feature);
701
        if (this.size >= 0) {
702
            this.size++;
703
        }
704
        this.featureToIgnoreNotification = null;
705
        this.ownFeaturesModified = true;
706
    }
707

    
708
    @Override
709
    public void update(EditableFeature feature) throws DataException {
710
        this.featureToIgnoreNotification = feature;
711
        this.store.update(feature);
712
        this.featureToIgnoreNotification = null;
713
        this.ownFeaturesModified = true;
714
    }
715
    
716
    @Override
717
    public void commitChanges() throws DataException {
718
        this.ignoreChanges = true;
719
        this.store.commitChanges();
720
        this.ignoreChanges = false;
721
        
722
    }
723

    
724
    @Override
725
    public FeatureStore getFeatureStore() {
726
        return store;
727
    }
728

    
729
}