Statistics
| Revision:

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

History | View | Annotate | Download (9.93 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

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

    
226
                case ORDERED_FILTERED:
227
                        return new FastOrderedIterator(this, new FastFilteredIterator(this,
228
                                        0),
229
                                        index);
230

    
231
                case EDITED:
232
                        return new FastEditedIterator(this, index);
233

    
234
                case EDITED_FILTERED:
235
                        return new FastEditedFilteredIterator(this, index);
236

    
237
                case ORDERD_EDITED:
238
                        return new FastOrderedIterator(this,
239
                                        new FastEditedIterator(this, 0), index);
240

    
241
                case ORDERED_EDITED_FILTER:
242
                        return new FastOrderedIterator(this,
243
                                        new FastEditedFilteredIterator(this, 0), index);
244

    
245
                default:
246
                        throw new IllegalArgumentException();
247
                }
248
        }
249

    
250
        public Iterator iterator() throws DataException {
251
                return this.iterator(0);
252
        }
253

    
254
        public Iterator iterator(long index) throws DataException {
255
                if (index < 0) {
256
                                throw new IndexOutOfBoundsException("The index (" + index
257
                                                + ") is less than 0");
258
                }
259
                int mode = this.getIteratorMode();
260

    
261
                switch (mode) {
262
                case DEFAULT:
263
                        return new DefaultIterator(this, index);
264

    
265
                case FILTERED:
266
                        return new FilteredIterator(this, index);
267

    
268
                case ORDERED:
269
                        return new OrderedIterator(this, new DefaultIterator(this, 0),
270
                                        index);
271

    
272
                case ORDERED_FILTERED:
273
                        return new OrderedIterator(this, new FilteredIterator(this, 0),
274
                                        index);
275

    
276
                case EDITED:
277
                        return new EditedIterator(this, index);
278

    
279
                case EDITED_FILTERED:
280
                        return new EditedFilteredIterator(this, index);
281

    
282
                case ORDERD_EDITED:
283
                        return new OrderedIterator(this,
284
                                        new EditedIterator(this, 0), index);
285

    
286
                case ORDERED_EDITED_FILTER:
287
                        return new OrderedIterator(this,
288
                                        new EditedFilteredIterator(this, 0), index);
289

    
290
                default:
291
                        throw new IllegalArgumentException();
292
                }
293

    
294
        }
295

    
296
        private boolean providerCanOrder() {
297
                return this.provider.canOrder();
298
        }
299

    
300
        private boolean providerCanFilter() {
301
                return this.provider.canFilter();
302
        }
303

    
304
        private int getIteratorMode() {
305

    
306
                if (this.iteratorMode != NO_CHECKED) {
307
                        return this.iteratorMode;
308
                }
309

    
310
                // TODO Tener en cuenta las transformaciones ???
311

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

    
336
                        if (useMyOrder) {
337
                                if (useMyFilter) {
338
                                        return ORDERED_FILTERED;// ORDERED_FILTERED;
339
                                } else {
340
                                        return ORDERED;// ORDERED;
341
                                }
342
                        } else {
343
                                if (useMyFilter) {
344
                                        return FILTERED;// FILTERED;
345
                                } else {
346
                                        return DEFAULT;// DEFAULT;
347
                                }
348
                        }
349
                }
350

    
351
        }
352

    
353
        public void delete(Feature feature) throws DataException {
354
                this.featureToIgnoreNotification = feature;
355
                this.store.delete(feature);
356
                if (this.size > 0) {
357
                        this.size--;
358
                }
359
                this.featureToIgnoreNotification = null;
360
        }
361

    
362
        public void insert(EditableFeature feature) throws DataException {
363
                this.featureToIgnoreNotification = feature;
364
                this.store.insert(feature);
365
                if (this.size >= 0) {
366
                        this.size++;
367
                }
368
                this.featureToIgnoreNotification = null;
369
        }
370

    
371
        public void update(EditableFeature feature) throws DataException {
372
                this.featureToIgnoreNotification = feature;
373
                this.store.update(feature);
374
                this.featureToIgnoreNotification = null;
375
        }
376

    
377
}