Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / featureset / DefaultFeatureSet.java @ 26029

History | View | Annotate | Download (9.83 KB)

1
package org.gvsig.fmap.dal.feature.impl.featureset;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.NoSuchElementException;
8

    
9
import org.gvsig.fmap.dal.DataStore;
10
import org.gvsig.fmap.dal.exception.DataException;
11
import org.gvsig.fmap.dal.feature.EditableFeature;
12
import org.gvsig.fmap.dal.feature.Feature;
13
import org.gvsig.fmap.dal.feature.FeatureQuery;
14
import org.gvsig.fmap.dal.feature.FeatureSet;
15
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
16
import org.gvsig.fmap.dal.feature.FeatureType;
17
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
18
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
19
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStoreTransforms;
20
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
21
import org.gvsig.tools.exception.BaseException;
22
import org.gvsig.tools.observer.Observable;
23
import org.gvsig.tools.observer.Observer;
24
import org.gvsig.tools.visitor.Visitor;
25

    
26
public class DefaultFeatureSet implements FeatureSet, Observer {
27

    
28

    
29
        private static final int NO_CHECKED = -1;
30
        private static final int DEFAULT = 0;
31
        private static final int FILTERED = 1;
32
        private static final int ORDERED = 2;
33
        private static final int ORDERED_FILTERED = 3;
34
        private static final int EDITED = 4;
35
        private static final int EDITED_FILTERED = 5;
36
        private static final int ORDERD_EDITED = 6;
37
        private static final int ORDERED_EDITED_FILTER = 7;
38

    
39
        private boolean modified;
40
        DefaultFeatureStore store;
41
        private List featureTypes;
42
        FeatureQuery query;
43
        FeatureSetProvider provider;
44
        private long size;
45
        private int iteratorMode;
46
        List orderedData;
47
        private Feature featureToIgnoreNotification;
48
        private List providerFeatureTypes;
49
        DefaultFeatureStoreTransforms transform;
50
        private FeatureQuery queryForProvider;
51

    
52

    
53
        public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
54
                        throws DataException {
55
                this.featureToIgnoreNotification = null;
56
                this.iteratorMode = NO_CHECKED;
57
                this.modified = false;
58
                this.size = -1;
59
                this.orderedData = null;
60
                this.store = store;
61
                this.transform = (DefaultFeatureStoreTransforms) store.getTransforms();
62
                this.query = query;
63
                this.queryForProvider = query.getCopy();
64
                this.featureTypes = new ArrayList();
65
                this.featureTypes.add(this.query.getFeatureType());
66
                if (!this.transform.isEmpty()) {
67
                        this.queryForProvider.setAttributeNames(null);
68
                        this.queryForProvider.setFeatureType(this.transform
69
                                        .getSourceFeatureTypeFrom(this.query.getFeatureType()));
70
                        this.queryForProvider.setFilter(null);
71
                }
72

    
73
                if (query.hasFilter() && store.getIndexes() != null) {
74
                        this.provider = (FeatureSetProvider) store.getIndexes()
75
                                        .getFeatureSet(this.queryForProvider.getFilter());
76
                }
77
                if (this.provider == null) {
78
                        this.provider = this.store.getProvider().createSet(
79
                                        this.queryForProvider);
80
                }
81
                this.store.addObserver(this);
82
        }
83

    
84
        public FeatureType getDefaultFeatureType() {
85
                return this.query.getFeatureType();
86
        }
87

    
88
        public List getFeatureTypes() {
89
                return Collections.unmodifiableList(this.featureTypes);
90
        }
91

    
92
        public long getSize() throws DataException {
93
                this.checkModified();
94
                if (size < 0) {
95
                        size = calculateSize();
96
                }
97
                return size;
98
        }
99

    
100
        private long calculateSize() throws DataException {
101
                int mode = this.getIteratorMode();
102
                if ((mode & FILTERED) == FILTERED) {
103
                        long mySize =0;
104
                        Iterator iter = this.fastIterator();
105
                        try{
106
                                while (true) {
107
                                        iter.next();
108
                                        mySize++;
109
                                }
110
                        } catch (NoSuchElementException e){
111
                                return mySize;
112
                        }
113
                } else if ((mode & EDITED) == EDITED) {
114
                        return provider.getSize()
115
                                        + store.getFeatureManager().getDeltaSize();
116
                }
117
                return provider.getSize();
118
        }
119

    
120
        public void dispose() {
121
                this.store.deleteObserver(this);
122
                this.provider = null;
123

    
124
                this.featureToIgnoreNotification = null;
125
                this.orderedData = null;
126
                this.store = null;
127
                this.transform = null;
128
                this.query = null;
129
                this.queryForProvider = null;
130
                this.featureTypes = null;
131

    
132
        }
133

    
134
        public boolean isFromStore(DataStore store) {
135
                return this.store.equals(store);
136
        }
137

    
138
        public void update(Observable obsevable, Object notification) {
139
                if (modified) {
140
                        return;
141
                }
142

    
143
                String type = ((FeatureStoreNotification) notification).getType();
144

    
145
                if (
146
                           type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
147
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
148
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE)
149
                        ) {
150
                        if( this.featureToIgnoreNotification == ((FeatureStoreNotification) notification).getFeature() ) {
151
                                return;
152
                        }
153
                        modified = true;
154
                        return;
155
                }
156
                if (
157
                           type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE_TYPE)
158
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REDO)
159
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UNDO)
160
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)
161
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH)
162
                        || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
163
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
164
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
165
                        || type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)
166
                        || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)
167
                        ) {
168
                        modified = true;
169
                        return;
170
                }
171
        }
172

    
173
        public void accept(Visitor visitor) throws BaseException {
174
                Iterator iterator = iterator();
175

    
176
                while (iterator.hasNext()) {
177
                        Feature feature = (Feature) iterator.next();
178
                        visitor.visit(feature);
179
                }
180
        }
181

    
182
        protected void checkModified() {
183
                if (modified) {
184
                        throw new ConcurrentDataModificationException(store.getName());
185
                }
186
        }
187

    
188
        public boolean isEmpty() throws DataException {
189
                checkModified();
190
                if (this.store.isEditing()) {
191
                        if (this.store.getFeatureManager().hasNews()) {
192
                                return false;
193
                        }
194
                        if (this.provider.isEmpty()) {
195
                                return true;
196
                        }
197
                        return this.provider.getSize()
198
                                        + this.store.getFeatureManager().getDeltaSize() == 0;
199
                }
200
                return this.provider.isEmpty();
201
        }
202

    
203
        public Iterator fastIterator() throws DataException {
204
                return this.fastIterator(0);
205
        }
206

    
207
        public Iterator fastIterator(long index) throws DataException {
208
                if (index < 0) {
209
                        throw new IndexOutOfBoundsException("The index (" + index
210
                                        + ") is less than 0");
211
                }
212
                int mode = this.getIteratorMode();
213

    
214
                switch (mode) {
215
                case DEFAULT:
216
                        return new FastDefaultIterator(this, index);
217

    
218
                case FILTERED:
219
                        return new FastFilteredIterator(this, index);
220

    
221
                case ORDERED_FILTERED:
222
                        return new FastOrderedIterator(this, new FastDefaultIterator(this,
223
                                        0),
224
                                        index);
225

    
226
                case EDITED:
227
                        return new FastEditedIterator(this, index);
228

    
229
                case EDITED_FILTERED:
230
                        return new FastEditedFilteredIterator(this, index);
231

    
232
                case ORDERD_EDITED:
233
                        return new FastOrderedIterator(this,
234
                                        new FastEditedIterator(this, 0), index);
235

    
236
                case ORDERED_EDITED_FILTER:
237
                        return new FastOrderedIterator(this,
238
                                        new FastEditedFilteredIterator(this, 0), index);
239

    
240
                default:
241
                        throw new IllegalArgumentException();
242
                }
243
        }
244

    
245
        public Iterator iterator() throws DataException {
246
                return this.iterator(0);
247
        }
248

    
249
        public Iterator iterator(long index) throws DataException {
250
                if (index < 0) {
251
                                throw new IndexOutOfBoundsException("The index (" + index
252
                                                + ") is less than 0");
253
                }
254
                int mode = this.getIteratorMode();
255

    
256
                switch (mode) {
257
                case DEFAULT:
258
                        return new DefaultIterator(this, index);
259

    
260
                case FILTERED:
261
                        return new FilteredIterator(this, index);
262

    
263
                case ORDERED:
264
                        return new OrderedIterator(this, new DefaultIterator(this, 0),
265
                                        index);
266

    
267
                case ORDERED_FILTERED:
268
                        return new OrderedIterator(this, new FilteredIterator(this, 0),
269
                                        index);
270

    
271
                case EDITED:
272
                        return new EditedIterator(this, index);
273

    
274
                case EDITED_FILTERED:
275
                        return new EditedFilteredIterator(this, index);
276

    
277
                case ORDERD_EDITED:
278
                        return new OrderedIterator(this,
279
                                        new EditedIterator(this, 0), index);
280

    
281
                case ORDERED_EDITED_FILTER:
282
                        return new OrderedIterator(this,
283
                                        new EditedFilteredIterator(this, 0), index);
284

    
285
                default:
286
                        throw new IllegalArgumentException();
287
                }
288

    
289
        }
290

    
291
        private boolean providerCanOrder() {
292
                return this.provider.canOrder();
293
        }
294

    
295
        private boolean providerCanFilter() {
296
                return this.provider.canFilter();
297
        }
298

    
299
        private int getIteratorMode() {
300

    
301
                if (this.iteratorMode != NO_CHECKED) {
302
                        return this.iteratorMode;
303
                }
304

    
305
                // TODO Tener en cuenta las transformaciones ???
306

    
307
                if (store.isEditing() && store.getFeatureManager().hasChanges()) {
308
                        if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
309
                                if (this.query.hasFilter()) {
310
                                        return ORDERED_EDITED_FILTER;
311
                                } else {
312
                                        return ORDERD_EDITED;
313
                                }
314
                        } else {
315
                                if (this.query.hasFilter()) {
316
                                        return EDITED_FILTERED;
317
                                } else {
318
                                        return EDITED;
319
                                }
320
                        }
321
                } else {
322
                        boolean useMyFilter = this.query.hasFilter();
323
                        boolean useMyOrder = this.query.hasOrder();
324
                        if (this.providerCanOrder() && this.transform.isEmpty()) {
325
                                useMyOrder = false;
326
                        }
327
                        if (this.providerCanFilter() && this.transform.isEmpty()) {
328
                                useMyFilter = false;
329
                        }
330

    
331
                        if (useMyOrder) {
332
                                if (useMyFilter) {
333
                                        return ORDERED_FILTERED;// ORDERED_FILTERED;
334
                                } else {
335
                                        return ORDERED;// ORDERED;
336
                                }
337
                        } else {
338
                                if (useMyFilter) {
339
                                        return FILTERED;// FILTERED;
340
                                } else {
341
                                        return DEFAULT;// DEFAULT;
342
                                }
343
                        }
344
                }
345

    
346
        }
347

    
348
        public void delete(Feature feature) throws DataException {
349
                this.featureToIgnoreNotification = feature;
350
                this.store.delete(feature);
351
                if (this.size > 0) {
352
                        this.size--;
353
                }
354
                this.featureToIgnoreNotification = null;
355
        }
356

    
357
        public void insert(EditableFeature feature) throws DataException {
358
                this.featureToIgnoreNotification = feature;
359
                this.store.insert(feature);
360
                if (this.size >= 0) {
361
                        this.size++;
362
                }
363
                this.featureToIgnoreNotification = null;
364
        }
365

    
366
        public void update(EditableFeature feature) throws DataException {
367
                this.featureToIgnoreNotification = feature;
368
                this.store.update(feature);
369
                this.featureToIgnoreNotification = null;
370
        }
371

    
372
}