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

History | View | Annotate | Download (24.9 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.dispose.DisposableIterator;
51
import org.gvsig.tools.dispose.DisposeUtils;
52
import org.gvsig.tools.evaluator.Evaluator;
53
import org.gvsig.tools.observer.Observable;
54
import org.gvsig.tools.observer.Observer;
55

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

    
69
    protected Throwable sourceStoreModifiedCause;
70
    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
    protected FeatureType defaultFeatureType;
83
    protected FeatureType defatulFeatureTypeForProvider;
84
    protected boolean ignoreChanges;
85
    private boolean disposed = false;
86

    
87
    public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
88
        throws DataException {
89
        DisposeUtils.bind(this);
90
        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
        DisposeUtils.bind(this.store);
98
        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
            this.defaultFeatureType = this.store.getDefaultFeatureType();
115
            this.featureTypes.addAll(this.store.getFeatureTypes());
116
        } else {
117
            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
        }
126
        if (this.transform != null && !this.transform.isEmpty()) {
127
            this.fixQueryForProvider(this.queryForProvider, this.transform);
128
        } else {
129
            this.defatulFeatureTypeForProvider = this.defaultFeatureType;
130
        }
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
                    this.defatulFeatureTypeForProvider, this.defaultFeatureType);
143
        }
144
        this.store.addObserver(this);
145
    }
146

    
147
    private void fixQueryForProvider(FeatureQuery theQueryForProvider,
148
        DefaultFeatureStoreTransforms transformsToUse) throws DataException {
149
        theQueryForProvider.clearAttributeNames();
150
        FeatureType ftype =
151
            transformsToUse.getSourceFeatureTypeFrom(this.defaultFeatureType);
152
        theQueryForProvider.setFeatureTypeId(ftype.getId());
153
        this.defatulFeatureTypeForProvider = ftype;
154
        
155
        if (transformsToUse.isTransformsOriginalValues()) {
156
            theQueryForProvider.clearFilter();
157
            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
            boolean canUseFilter;
169
            if (filter.getFieldsInfo() == null) {
170
                canUseFilter = false;
171
            } else {
172
                canUseFilter = areEvaluatorFieldsInAttributes(filter, ftype);
173
            }
174

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

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

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

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

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

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

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

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

    
296
            } finally {
297
                DisposeUtils.disposeQuietly(iter);
298
            }
299
            return (hasLimit && mySize>limit)? limit:mySize;
300
            
301
        default:
302
            throw new IllegalArgumentException();
303
        }
304
    }
305
    
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

    
322
    public void doDispose() {
323
        if( this.store!=null ) {
324
            this.store.deleteObserver(this);
325
            DisposeUtils.dispose(this.store);
326
            this.store = null;
327
        }
328
        if( this.provider!=null ) {
329
            this.provider.dispose();
330
            this.provider = null;
331
        }
332
        if (orderedData != null) {
333
            orderedData.clear();
334
            this.orderedData = null;
335
        }
336
        this.featureToIgnoreNotification = null;
337
        this.transform = null;
338
        this.query = null;
339
        this.queryForProvider = null;
340
        this.featureTypes = null;
341
        this.defaultFeatureType = null;
342
        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
            sourceStoreModifiedCause = new Throwable();
361
            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
            || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
368
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
369
//            || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
370
            || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)) {
371
            sourceStoreModified = true;
372
            sourceStoreModifiedCause = new Throwable();
373
            return;
374
        }
375
        if (type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)) {
376
            if(!this.ignoreChanges) {
377
                sourceStoreModified = true;
378
                sourceStoreModifiedCause = new Throwable();
379
                return;
380
            }
381
        }
382
        if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)) {
383
            if (ownFeaturesModified) {
384
                sourceStoreModified = true;
385
                sourceStoreModifiedCause = new Throwable();
386
                return;
387
            }
388
        }
389
    }
390
  
391
    protected void checkSourceStoreModified() {
392
        if (sourceStoreModified) {
393
            LOG.debug("ConcurrentDataModification in featureSet "+this.hashCode()+" of store '"+(store == null ? "": store.getName())+"'");
394
            ConcurrentDataModificationException ex = new ConcurrentDataModificationException(
395
                    store == null ? "": store.getName()
396
            );
397
            ex.initCause(sourceStoreModifiedCause);
398
            throw ex;
399
        }
400
    }
401

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

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

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

    
425
        case ORDERED:
426
            if(this.provider.canOrder() && this.provider.canIterateFromIndex()){
427
                it = new FastDefaultIterator(this, index, elements);
428
            } else {
429
                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
            }
435
            break;
436
            
437
        case ORDERED_FILTERED:
438
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex()){
439
                it = new FastFilteredIterator(this, index, elements);
440
            } else {
441
                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
            }
448

    
449
            break;
450

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

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

    
459
        case ORDERD_EDITED:
460
            if(this.provider.canOrder() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
461
                it = new FastEditedIterator(this, index, elements);
462
            } else {
463
                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
            }
470
            break;
471

    
472
        case ORDERED_EDITED_FILTER:
473
            if(this.provider.canOrder() && this.provider.canFilter() && this.provider.canIterateFromIndex() && !this.store.getFeatureManager().hasDeleteds()){
474
                it = new FastEditedFilteredIterator(this, index, elements);
475
            } else {
476
                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
            }
483
            break;
484
            
485
        default:
486
            throw new IllegalArgumentException();
487
        }
488
        if( this.query!=null && this.query.getLimit()>0 ) {
489
            it = new LimitIterator(it,this.query.getLimit());
490
        }
491
        return it;
492
    }
493

    
494
    private class LimitIterator implements DisposableIterator {
495

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

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

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

    
558
        case ORDERED:
559
            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

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

    
571
        case ORDERED_FILTERED:
572
            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
            break;
582

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

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

    
591
        case ORDERD_EDITED:
592
            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
            break;
603

    
604
        case ORDERED_EDITED_FILTER:
605
            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
            break;
616

    
617
        default:
618
            throw new IllegalArgumentException();
619
        }
620

    
621
        if( this.query!=null && this.query.getLimit()>0 ) {
622
            it = new LimitIterator(it,this.query.getLimit());
623
        }
624
        return it;
625
    }
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
        if (store.isEditing() && (store.getFeatureTypeManager().hasChanges() || store.getFeatureManager().hasChanges())) {
644
            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
                    return ORDERED_FILTERED;
670
                } else {
671
                    return ORDERED;
672
                }
673
            } else {
674
                if (useMyFilter) {
675
                    return FILTERED;
676
                } else {
677
                    return DEFAULT;
678
                }
679
            }
680
        }
681

    
682
    }
683

    
684
    @Override
685
    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
    @Override
696
    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
    @Override
707
    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
    
714
    @Override
715
    public void commitChanges() throws DataException {
716
        this.ignoreChanges = true;
717
        this.store.commitChanges();
718
        this.ignoreChanges = false;
719
        
720
    }
721

    
722
    @Override
723
    public FeatureStore getFeatureStore() {
724
        return store;
725
    }
726

    
727
}