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 / AbstractFeatureSet.java @ 47436

History | View | Annotate | Download (9.29 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.Iterator;
27
import javax.json.Json;
28
import javax.json.JsonArray;
29
import javax.json.JsonArrayBuilder;
30
import javax.json.JsonObject;
31
import org.apache.commons.lang3.mutable.MutableInt;
32
import org.gvsig.expressionevaluator.Expression;
33
import org.gvsig.expressionevaluator.ExpressionBuilder;
34
import org.gvsig.expressionevaluator.ExpressionUtils;
35
import org.gvsig.fmap.dal.DataStore;
36
import org.gvsig.fmap.dal.exception.DataException;
37
import org.gvsig.fmap.dal.feature.DisposableFeatureSetIterable;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
40
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.dal.feature.impl.DefaultFeature;
44
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectSetFeatureSetFacade;
45
import org.gvsig.tools.dispose.DisposableIterator;
46
import org.gvsig.tools.dispose.DisposeUtils;
47
import org.gvsig.tools.dynobject.DynObjectSet;
48
import org.gvsig.tools.exception.BaseException;
49
import org.gvsig.tools.visitor.VisitCanceledException;
50
import org.gvsig.tools.visitor.Visitor;
51
import org.gvsig.tools.visitor.impl.AbstractIndexedVisitable;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

    
55

    
56
@SuppressWarnings("UseSpecificCatch")
57
public abstract class AbstractFeatureSet 
58
    extends AbstractIndexedVisitable 
59
    implements FeatureSet {
60

    
61
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFeatureSet.class);
62
    
63
    private static class DisposableFeatureSetIterableImpl implements DisposableFeatureSetIterable {
64

    
65
        private final FeatureSet fset;
66
        private final DisposableIterator it;
67

    
68
        public DisposableFeatureSetIterableImpl(FeatureSet fset, DisposableIterator it) {
69
            this.fset = fset;
70
            // No se debe de hacer el bind. DisposeUtils.bind(fset);
71
            this.it = it;
72
        }
73
        
74
        @Override
75
        public boolean hasNext() {
76
            return this.it.hasNext();
77
        }
78

    
79
        @Override
80
        public Feature next() {
81
            return (Feature) this.it.next();
82
        }
83

    
84
        @Override
85
        public Iterator<Feature> iterator() {
86
            return this.it;
87
        }
88

    
89
        @Override
90
        public void dispose() {
91
            DisposeUtils.disposeQuietly(this.it);
92
            DisposeUtils.disposeQuietly(this.fset);
93
        }
94

    
95
        @Override
96
        public boolean isEmpty() {
97
            return this.fset.isEmpty();
98
        }
99

    
100
        @Override
101
        public long size64() {
102
            return this.fset.size64();
103
        }
104

    
105
        @Override
106
        public FeatureSet getFeatureSet() {
107
            return this.fset;
108
        }
109
        
110
        
111
    } 
112
    
113
    protected static final Logger LOG = LoggerFactory.getLogger(AbstractFeatureSet.class);
114

    
115
    @Override
116
    public abstract FeatureStore getFeatureStore();
117
    
118
    @Override
119
    public final void accept(Visitor visitor, long firstValueIndex, long elements) throws BaseException {
120
        try {
121
            doAccept(visitor, firstValueIndex, elements);
122
        } catch (VisitCanceledException ex) {
123
            // The visit has been cancelled by the visitor, so we finish here.
124
            LOG.debug("The visit, beggining on position {}, has been cancelled "
125
                    + "by the visitor: {}", firstValueIndex,
126
                    visitor);
127
        }
128
    }
129
    
130
    @Override
131
    protected void doAccept(Visitor visitor, long firstValueIndex)
132
        throws VisitCanceledException, BaseException {
133
        doAccept(visitor, firstValueIndex, 0);
134
    }
135

    
136
    protected void doAccept(Visitor visitor, long firstValueIndex, long elements)
137
        throws VisitCanceledException, BaseException {
138
        DisposableIterator iterator = fastIterator(firstValueIndex, elements);
139

    
140
        try {
141
            while (iterator.hasNext()) {
142
                Feature feature = (Feature) iterator.next();
143
                visitor.visit(feature);
144
            }
145
        } finally {
146
            iterator.dispose();
147
        }
148
    }
149
      
150
    @Override
151
    public Feature first() {
152
        DisposableIterator it = null;
153
        try {
154
            it = this.iterator();
155
            if( it == null ) {
156
                return null;
157
            }
158
            if( it.hasNext() ) {
159
                Feature f = (Feature) it.next();
160
                return f;
161
            }
162
            return null;
163
        } finally {
164
            DisposeUtils.disposeQuietly(it);
165
        }
166
    }
167

    
168
    @Override
169
    public boolean isEmpty() {
170
        return this.size64() == 0;
171
    }
172

    
173
    @Override
174
    public DisposableIterator fastIterator() throws DataException {
175
        return this.fastIterator(0);
176
    }   
177

    
178
    @Override
179
    public DisposableIterator iterator() {
180
        try {
181
            return this.fastIterator(0);
182
        } catch (DataException ex) {
183
            throw new RuntimeException("Can't obtain iterator.",ex);
184
        }
185
    }
186

    
187
    @Override
188
    public DisposableFeatureSetIterable iterable() {
189
        return iterable(true);
190
    }
191
    
192
    @Override
193
    public DisposableFeatureSetIterable iterable(boolean disposeFeatureSet) {
194
        if (!disposeFeatureSet) {
195
            DisposeUtils.bind(this);
196
        }
197
        return new DisposableFeatureSetIterableImpl(this, this.iterator());
198
    }
199
    @Override
200
    public DynObjectSet getDynObjectSet() {
201
        return this.getDynObjectSet(true);
202
    }
203

    
204
    @Override
205
    public DynObjectSet getDynObjectSet(boolean fast) {
206
        return new DynObjectSetFeatureSetFacade(this, this.getFeatureStore(), fast);
207
    }
208

    
209
    @Override
210
    public boolean isFromStore(DataStore store) {
211
        return this.getFeatureStore().equals(store);
212
    }    
213

    
214
    @Override
215
    public long size64() {
216
        try {
217
            return this.getSize();
218
        } catch (DataException ex) {
219
            throw new RuntimeException("Can't get size",ex);
220
        }
221
    }
222

    
223
    @Override
224
    public int size() {
225
        try {
226
            long sz = this.getSize();
227
            if( sz > Integer.MAX_VALUE ) {
228
                return Integer.MAX_VALUE;
229
            }
230
            return (int) sz;
231
        } catch (DataException ex) {
232
            throw new RuntimeException("Can't get size",ex);
233
        }
234
    }
235

    
236
    @Override
237
    public JsonArray toJson() {
238
        JsonArrayBuilder builder = this.toJsonBuilder();
239
        return builder.build();
240
    }
241

    
242
    @Override
243
    public JsonArrayBuilder toJsonBuilder() {
244
        // TODO: estaria bien hacer una implementacion alternativa que devolviese
245
        // un JsonArray basado en el FeatureSet/FeaturePagingHelper, asi no 
246
        // tendria que construirse en memoria el JSON entero.
247
        try {
248
            JsonArrayBuilder builder = Json.createArrayBuilder();
249
            this.accept((Object obj) -> {
250
                DefaultFeature f = (DefaultFeature) obj;
251
                JsonObject fjson = f.toJson();
252
                builder.add(fjson);
253
            });
254
            return builder;        
255
        } catch (Exception ex) {
256
            throw new RuntimeException("Can't create JSON array.",ex);
257
        }
258
    }
259
    
260
    @Deprecated
261
    @Override
262
    public JsonArray toJSON() {
263
        return this.toJson();
264
    }
265

    
266
    @Override
267
    public Expression makeFilter(int maxfeatures) {
268
        try {
269
            FeatureType ftype = this.getDefaultFeatureType();
270
            if( !ftype.hasPrimaryKey() ) {
271
                return null;
272
            }
273
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
274
            final MutableInt counter = new MutableInt(0);
275
            this.accept((Object obj) -> {
276
                if( counter.getAndIncrement()>=maxfeatures ) {
277
                    throw new VisitCanceledException();
278
                }
279
                Feature feature = (Feature) obj;
280
                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
281
                    builder.or(
282
                            builder.eq(
283
                                    builder.column(attrdesc.getName()),
284
                                    builder.constant(feature.get(attrdesc.getName()))
285
                            )
286
                    );
287
                }
288
            });
289
            Expression filter = ExpressionUtils.createExpression(builder.toString());
290
            return filter;
291
        } catch (Exception ex) {
292
            LOGGER.warn("Can't build filter expression.", ex);
293
            return null;
294
        }
295
    }
296
        
297
}