Statistics
| Revision:

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

History | View | Annotate | Download (7.1 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.exceptions.DataException;
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.impl.DefaultFeatureIndexes;
18
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
19
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
20
import org.gvsig.tools.exception.BaseException;
21
import org.gvsig.tools.observer.WeakReferencingObservable;
22
import org.gvsig.tools.observer.Observer;
23
import org.gvsig.tools.visitor.Visitor;
24

    
25
public class DefaultFeatureSet implements FeatureSet, Observer {
26

    
27

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

    
38
        private boolean modified = false;
39
        DefaultFeatureStore store;
40
        private List featureTypes;
41
        FeatureQuery query;
42
        FeatureSetProvider provider;
43
        private long size = -1;
44
        private int iteratorMode = NO_CHECKED;
45
        List orderedData = null;
46

    
47

    
48
        public DefaultFeatureSet(DefaultFeatureStore store, FeatureQuery query)
49
                        throws DataException {
50
                this.store = store;
51
                this.query = query;
52
                this.featureTypes = new ArrayList();
53
                this.featureTypes.add(this.query.getFeatureType());
54
                if (query.hasFilter()) {
55
                        this.provider = ((DefaultFeatureIndexes) store.getIndexes())
56
                                        .getFeatureSet(query.getFilter());
57
                }
58
                if (this.provider == null) {
59
                        this.provider = this.store.getProvider().createSet(query);
60
                }
61
        }
62

    
63
        public FeatureType getDefaultFeatureType() {
64
                return this.query.getFeatureType();
65
        }
66

    
67
        public List getFeatureTypes() {
68
                return Collections.unmodifiableList(this.featureTypes);
69
        }
70

    
71
        public long getSize() throws DataException {
72
                if (size < 0) {
73
                        size = calculateSize();
74
                }
75
                return size;
76
        }
77

    
78
        private long calculateSize() throws DataException {
79
                int mode = this.getIteratorMode();
80
                if ((mode & FILTERED) == FILTERED) {
81
                        long mySize =0;
82
                        Iterator iter = this.fastIterator();
83
                        try{
84
                                while (true) {
85
                                        iter.next();
86
                                        mySize++;
87
                                }
88
                        } catch (NoSuchElementException e){
89
                                return mySize;
90
                        }
91
                } else if ((mode & EDITED) == EDITED) {
92
                        return provider.getSize()
93
                                        + store.getFeatureManager().getDeltaSize();
94
                }
95
                return provider.getSize();
96
        }
97

    
98
        public void dispose() {
99

    
100
        }
101

    
102
        public boolean isFromStore(DataStore store) {
103
                return this.store.equals(store);
104
        }
105

    
106
        public void update(WeakReferencingObservable obsevable, Object notification) {
107
                if (modified) {
108
                        return;
109
                }
110
                String type = ((FeatureStoreNotification) notification).getType();
111
                if (type.equalsIgnoreCase(FeatureStoreNotification.AFTER_INSERT)
112
                                || type.equalsIgnoreCase(FeatureStoreNotification.AFTER_DELETE)
113
                                || type
114
                                                .equalsIgnoreCase(FeatureStoreNotification.RESOURCE_CHANGED)) {
115
                        modified = true;
116
                }
117
        }
118

    
119
        public void accept(Visitor visitor) throws BaseException {
120
                Iterator iterator = iterator();
121

    
122
                while (iterator.hasNext()) {
123
                        Feature feature = (Feature) iterator.next();
124
                        visitor.visit(feature);
125
                }
126
        }
127

    
128
        protected void checkModified() {
129
                if (modified) {
130
                        throw new ConcurrentModificationException(
131
                                        "FeatureCollection modified");
132
                }
133
        }
134

    
135
        public boolean isEmpty() throws DataException {
136
                checkModified();
137
                if (this.store.isEditing()) {
138
                        if (this.store.getFeatureManager().hasNews()) {
139
                                return false;
140
                        }
141
                        if (this.provider.isEmpty()) {
142
                                return true;
143
                        }
144
                        return this.provider.getSize()
145
                                        + this.store.getFeatureManager().getDeltaSize() == 0;
146
                }
147
                return this.provider.isEmpty();
148
        }
149
        public Iterator fastIterator() throws DataException {
150
                return this.fastIterator(0);
151
        }
152

    
153
        public Iterator fastIterator(long index) throws DataException {
154
                if (index < 0) {
155
                        throw new IndexOutOfBoundsException("The index (" + index
156
                                        + ") is less than 0");
157
                }
158
                int mode = this.getIteratorMode();
159

    
160
                switch (mode) {
161
                case DEFAULT:
162
                        return new FastDefaultIterator(this, index);
163

    
164
                case FILTERED:
165
                        return new FastFilteredIterator(this, index);
166

    
167
                case ORDERED_FILTERED:
168
                        return new FastOrderedIterator(this, new FastDefaultIterator(this,
169
                                        0),
170
                                        index);
171

    
172
                case EDITED:
173
                        return new FastEditedIterator(this, index);
174

    
175
                case EDITED_FILTERED:
176
                        return new FastEditedFilteredIterator(this, index);
177

    
178
                case ORDERD_EDITED:
179
                        return new FastOrderedIterator(this,
180
                                        new FastEditedIterator(this, 0), index);
181

    
182
                case ORDERED_EDITED_FILTER:
183
                        return new FastOrderedIterator(this,
184
                                        new FastEditedFilteredIterator(this, 0), index);
185

    
186
                default:
187
                        throw new IllegalArgumentException();
188
                }
189
        }
190

    
191
        public Iterator iterator() throws DataException {
192
                return this.iterator(0);
193
        }
194

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

    
202
                switch (mode) {
203
                case DEFAULT:
204
                        return new DefaultIterator(this, index);
205

    
206
                case FILTERED:
207
                        return new FilteredIterator(this, index);
208

    
209
                case ORDERED_FILTERED:
210
                        return new OrderedIterator(this, new DefaultIterator(this, 0),
211
                                        index);
212

    
213
                case EDITED:
214
                        return new EditedIterator(this, index);
215

    
216
                case EDITED_FILTERED:
217
                        return new EditedFilteredIterator(this, index);
218

    
219
                case ORDERD_EDITED:
220
                        return new OrderedIterator(this,
221
                                        new EditedIterator(this, 0), index);
222

    
223
                case ORDERED_EDITED_FILTER:
224
                        return new OrderedIterator(this,
225
                                        new EditedFilteredIterator(this, 0), index);
226

    
227
                default:
228
                        throw new IllegalArgumentException();
229
                }
230

    
231
        }
232

    
233
        private boolean providerCanOrder() {
234
                return this.provider.canOrder();
235
        }
236

    
237
        private boolean providerCanFilter() {
238
                return this.provider.canFilter();
239
        }
240

    
241
        private int getIteratorMode() {
242

    
243
                if (this.iteratorMode != NO_CHECKED) {
244
                        return this.iteratorMode;
245
                }
246

    
247
                if (store.isEditing() && store.getFeatureManager().hasChanges()) {
248
                        if (this.query.hasOrder()) { // En edicion siempre ordeno yo.
249
                                if (this.query.hasFilter()) {
250
                                        return ORDERED_EDITED_FILTER;
251
                                } else {
252
                                        return ORDERD_EDITED;
253
                                }
254
                        } else {
255
                                if (this.query.hasFilter()) {
256
                                        return EDITED_FILTERED;
257
                                } else {
258
                                        return EDITED;
259
                                }
260
                        }
261
                } else {
262
                        boolean useMyFilter = this.query.hasFilter();
263
                        boolean useMyOrder = this.query.hasOrder();
264
                        if (this.providerCanOrder()) {
265
                                useMyOrder = false;
266
                        }
267
                        if (this.providerCanFilter()) {
268
                                useMyFilter = false;
269
                        }
270

    
271
                        if (useMyOrder) {
272
                                if (useMyFilter) {
273
                                        return ORDERED_FILTERED;// ORDERED_FILTERED;
274
                                } else {
275
                                        return ORDERED;// ORDERED;
276
                                }
277
                        } else {
278
                                if (useMyFilter) {
279
                                        return FILTERED;// FILTERED;
280
                                } else {
281
                                        return DEFAULT;// DEFAULT;
282
                                }
283
                        }
284
                }
285

    
286
        }
287

    
288
}