Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / featureset / DefaultFeatureSet.java @ 25994

History | View | Annotate | Download (9.52 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.ConcurrentModificationException;
6
import java.util.Iterator;
7
import java.util.List;
8
import java.util.NoSuchElementException;
9

    
10
import org.gvsig.fmap.dal.DataStore;
11
import org.gvsig.fmap.dal.exception.DataException;
12
import org.gvsig.fmap.dal.feature.EditableFeature;
13
import org.gvsig.fmap.dal.feature.Feature;
14
import org.gvsig.fmap.dal.feature.FeatureQuery;
15
import org.gvsig.fmap.dal.feature.FeatureSet;
16
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
17
import org.gvsig.fmap.dal.feature.FeatureType;
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
        }
82

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

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

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

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

    
119
        public void dispose() {
120

    
121
        }
122

    
123
        public boolean isFromStore(DataStore store) {
124
                return this.store.equals(store);
125
        }
126

    
127
        public void update(Observable obsevable, Object notification) {
128
                if (modified) {
129
                        return;
130
                }
131

    
132
                String type = ((FeatureStoreNotification) notification).getType();
133

    
134
                if (
135
                           type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
136
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
137
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE)
138
                        ) {
139
                        if( this.featureToIgnoreNotification == ((FeatureStoreNotification) notification).getFeature() ) {
140
                                return;
141
                        }
142
                        modified = true;
143
                        return;
144
                }
145
                if (
146
                           type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UPDATE_TYPE)
147
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REDO)
148
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_UNDO)
149
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CANCELEDITING)
150
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_REFRESH)
151
                        || type.equalsIgnoreCase(FeatureStoreNotification.COMPLEX_NOTIFICATION)
152
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_CLOSE)
153
                        || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DISPOSE)
154
                        || type.equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)
155
                        || type.equalsIgnoreCase(FeatureStoreNotification.TRANSFORM_CHANGE)
156
                        ) {
157
                        modified = true;
158
                        return;
159
                }
160
        }
161

    
162
        public void accept(Visitor visitor) throws BaseException {
163
                Iterator iterator = iterator();
164

    
165
                while (iterator.hasNext()) {
166
                        Feature feature = (Feature) iterator.next();
167
                        visitor.visit(feature);
168
                }
169
        }
170

    
171
        protected void checkModified() {
172
                if (modified) {
173
                        throw new ConcurrentModificationException(
174
                                        "FeatureSet modified");
175
                }
176
        }
177

    
178
        public boolean isEmpty() throws DataException {
179
                checkModified();
180
                if (this.store.isEditing()) {
181
                        if (this.store.getFeatureManager().hasNews()) {
182
                                return false;
183
                        }
184
                        if (this.provider.isEmpty()) {
185
                                return true;
186
                        }
187
                        return this.provider.getSize()
188
                                        + this.store.getFeatureManager().getDeltaSize() == 0;
189
                }
190
                return this.provider.isEmpty();
191
        }
192

    
193
        public Iterator fastIterator() throws DataException {
194
                return this.fastIterator(0);
195
        }
196

    
197
        public Iterator fastIterator(long index) throws DataException {
198
                if (index < 0) {
199
                        throw new IndexOutOfBoundsException("The index (" + index
200
                                        + ") is less than 0");
201
                }
202
                int mode = this.getIteratorMode();
203

    
204
                switch (mode) {
205
                case DEFAULT:
206
                        return new FastDefaultIterator(this, index);
207

    
208
                case FILTERED:
209
                        return new FastFilteredIterator(this, index);
210

    
211
                case ORDERED_FILTERED:
212
                        return new FastOrderedIterator(this, new FastDefaultIterator(this,
213
                                        0),
214
                                        index);
215

    
216
                case EDITED:
217
                        return new FastEditedIterator(this, index);
218

    
219
                case EDITED_FILTERED:
220
                        return new FastEditedFilteredIterator(this, index);
221

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

    
226
                case ORDERED_EDITED_FILTER:
227
                        return new FastOrderedIterator(this,
228
                                        new FastEditedFilteredIterator(this, 0), index);
229

    
230
                default:
231
                        throw new IllegalArgumentException();
232
                }
233
        }
234

    
235
        public Iterator iterator() throws DataException {
236
                return this.iterator(0);
237
        }
238

    
239
        public Iterator iterator(long index) throws DataException {
240
                if (index < 0) {
241
                                throw new IndexOutOfBoundsException("The index (" + index
242
                                                + ") is less than 0");
243
                }
244
                int mode = this.getIteratorMode();
245

    
246
                switch (mode) {
247
                case DEFAULT:
248
                        return new DefaultIterator(this, index);
249

    
250
                case FILTERED:
251
                        return new FilteredIterator(this, index);
252

    
253
                case ORDERED:
254
                        return new OrderedIterator(this, new DefaultIterator(this, 0),
255
                                        index);
256

    
257
                case ORDERED_FILTERED:
258
                        return new OrderedIterator(this, new FilteredIterator(this, 0),
259
                                        index);
260

    
261
                case EDITED:
262
                        return new EditedIterator(this, index);
263

    
264
                case EDITED_FILTERED:
265
                        return new EditedFilteredIterator(this, index);
266

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

    
271
                case ORDERED_EDITED_FILTER:
272
                        return new OrderedIterator(this,
273
                                        new EditedFilteredIterator(this, 0), index);
274

    
275
                default:
276
                        throw new IllegalArgumentException();
277
                }
278

    
279
        }
280

    
281
        private boolean providerCanOrder() {
282
                return this.provider.canOrder();
283
        }
284

    
285
        private boolean providerCanFilter() {
286
                return this.provider.canFilter();
287
        }
288

    
289
        private int getIteratorMode() {
290

    
291
                if (this.iteratorMode != NO_CHECKED) {
292
                        return this.iteratorMode;
293
                }
294

    
295
                // TODO Tener en cuenta las transformaciones ???
296

    
297
                if (store.isEditing() && store.getFeatureManager().hasChanges()) {
298
                        if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
299
                                if (this.query.hasFilter()) {
300
                                        return ORDERED_EDITED_FILTER;
301
                                } else {
302
                                        return ORDERD_EDITED;
303
                                }
304
                        } else {
305
                                if (this.query.hasFilter()) {
306
                                        return EDITED_FILTERED;
307
                                } else {
308
                                        return EDITED;
309
                                }
310
                        }
311
                } else {
312
                        boolean useMyFilter = this.query.hasFilter();
313
                        boolean useMyOrder = this.query.hasOrder();
314
                        if (this.providerCanOrder() && this.transform.isEmpty()) {
315
                                useMyOrder = false;
316
                        }
317
                        if (this.providerCanFilter() && this.transform.isEmpty()) {
318
                                useMyFilter = false;
319
                        }
320

    
321
                        if (useMyOrder) {
322
                                if (useMyFilter) {
323
                                        return ORDERED_FILTERED;// ORDERED_FILTERED;
324
                                } else {
325
                                        return ORDERED;// ORDERED;
326
                                }
327
                        } else {
328
                                if (useMyFilter) {
329
                                        return FILTERED;// FILTERED;
330
                                } else {
331
                                        return DEFAULT;// DEFAULT;
332
                                }
333
                        }
334
                }
335

    
336
        }
337

    
338
        public void delete(Feature feature) throws DataException {
339
                this.featureToIgnoreNotification = feature;
340
                this.store.delete(feature);
341
                if (this.size > 0) {
342
                        this.size--;
343
                }
344
                this.featureToIgnoreNotification = null;
345
        }
346

    
347
        public void insert(EditableFeature feature) throws DataException {
348
                this.featureToIgnoreNotification = feature;
349
                this.store.insert(feature);
350
                if (this.size >= 0) {
351
                        this.size++;
352
                }
353
                this.featureToIgnoreNotification = null;
354
        }
355

    
356
        public void update(EditableFeature feature) throws DataException {
357
                this.featureToIgnoreNotification = feature;
358
                this.store.update(feature);
359
                this.featureToIgnoreNotification = null;
360
        }
361

    
362
}