Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / jdbc / JDBCSetProvider.java @ 28909

History | View | Annotate | Download (9.94 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
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 2
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
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.jdbc;
32

    
33
import java.util.ArrayList;
34
import java.util.Arrays;
35
import java.util.Iterator;
36
import java.util.List;
37
import java.util.NoSuchElementException;
38

    
39
import org.gvsig.fmap.dal.DataTypes;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.DisposableIterator;
42
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
43
import org.gvsig.fmap.dal.feature.FeatureQuery;
44
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
45
import org.gvsig.fmap.dal.feature.FeatureType;
46
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
47
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
48
import org.gvsig.tools.evaluator.Evaluator;
49
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
50
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
/**
55
 * @author jmvivo
56
 *
57
 */
58
public class JDBCSetProvider implements FeatureSetProvider {
59

    
60
        final static private Logger logger = LoggerFactory
61
                        .getLogger(JDBCSetProvider.class);
62

    
63

    
64

    
65
        protected JDBCStoreProvider store;
66
        protected FeatureQuery query;
67
        protected FeatureType featureType;
68
        protected String filter;
69
        protected String order;
70
        protected Long size = null;
71
        protected Boolean isEmpty = null;
72

    
73
        protected List resultSetIDReferenced;
74

    
75
        private JDBCHelper helper = null;
76

    
77
        public JDBCSetProvider(JDBCStoreProvider store, FeatureQuery query,
78
                        FeatureType featureType) throws DataException {
79
                this.store = store;
80
                this.query = query;
81
                this.featureType = featureType;
82
                this.resultSetIDReferenced = new ArrayList();
83

    
84
                if (query.hasFilter() && this.canFilter()) {
85
                        setFilter(query.getFilter());
86
                } else {
87
                        setFilter(null);
88
                }
89

    
90
                if (query.hasOrder() && canOrder()) {
91
                        setOrder(query.getOrder());
92
                } else {
93
                        setOrder(null);
94
                }
95
        }
96

    
97
        protected String getSqlForEvaluator(Evaluator filter) {
98
                if (filter == null) {
99
                        return null;
100
                }
101
                EvaluatorFieldsInfo info = filter.getFieldsInfo();
102
                String filterString = filter.getCQL();
103
                if (info == null) {
104
                        return filterString;
105
                }
106
                String[] filterNames = info.getFieldNames();
107
                String[] finalNames = new String[filterNames.length];
108
                EvaluatorFieldValue[] fValues;
109

    
110
                List values = new ArrayList();
111

    
112
                FeatureAttributeDescriptor attr;
113
                for (int i = 0; i < filterNames.length; i++) {
114
                        attr = featureType.getAttributeDescriptor(filterNames[i]);
115
                        if (attr == null) {
116
                                finalNames[i] = filterNames[i];
117
                                continue;
118
                        }
119
                        finalNames[i] = getEscapedFieldName(attr.getName());
120

    
121
                }
122

    
123
                for (int i = 0; i < filterNames.length; i++) {
124
                        if (!filterNames[i].equals(finalNames[i])) {
125
                                filterString.replaceAll("\\b" + filterNames[i] + "\\b",
126
                                                finalNames[i]);
127
                        }
128
                }
129

    
130
                return filterString;
131
        }
132

    
133

    
134
        protected String getEscapedFieldName(String fieldName) {
135
                if (helper == null) {
136
                        helper = (store).getHelper();
137
                }
138
                return helper.escapeFieldName(fieldName);
139
        }
140

    
141

    
142
        protected void setOrder(FeatureQueryOrder order) {
143
                if (order == null || order.size() == 0) {
144
                        this.order = null;
145
                        return;
146
                }
147

    
148
                StringBuilder buffer = new StringBuilder();
149
                Iterator iter = order.iterator();
150
                FeatureQueryOrderMember menber;
151
                while (true) {
152
                        menber = (FeatureQueryOrderMember) iter.next();
153
                        if (menber.hasEvaluator()) {
154
                                buffer.append(getSqlForEvaluator(menber.getEvaluator()));
155
                        } else {
156
                                buffer.append(getEscapedFieldName(menber.getAttributeName()));
157
                        }
158
                        if (menber.getAscending()) {
159
                                buffer.append(" ASC");
160
                        } else {
161
                                buffer.append(" DESC");
162
                        }
163
                        if (iter.hasNext()) {
164
                                buffer.append(", ");
165
                        } else {
166
                                buffer.append(' ');
167
                                break;
168
                        }
169
                }
170

    
171
                this.order = buffer.toString();
172
        }
173

    
174
        protected void setFilter(Evaluator filter) {
175
                this.filter = getSqlForEvaluator(filter);
176
        }
177

    
178

    
179

    
180
        /* (non-Javadoc)
181
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canFilter()
182
         */
183
        public boolean canFilter() {
184
                Evaluator filter = query.getFilter();
185
                if (filter != null) {
186
                        if (filter.getCQL() == null || filter.getCQL().length() == 0) {
187
                                return false;
188
                        } else {
189
                                // TODO Check Geom fields if
190
                                EvaluatorFieldsInfo fInfo = filter.getFieldsInfo();
191
                                if (fInfo == null || fInfo.getFieldNames() == null) {
192
                                        return true;
193
                                }
194
                                Iterator names = Arrays.asList(fInfo.getFieldNames())
195
                                                .iterator();
196
                                String name;
197
                                int type;
198
                                while (names.hasNext()) {
199
                                        name = (String) names.next();
200
                                        type = this.featureType.getAttributeDescriptor(name)
201
                                                        .getDataType();
202
                                        if (type == DataTypes.GEOMETRY
203
                                                        && !this.helper.hasGeometrySupport()) {
204
                                                return false;
205
                                        }
206

    
207

    
208

    
209
                                }
210

    
211
                                return true;
212
                        }
213

    
214
                } else{
215
                        return false;
216
                }
217
        }
218

    
219
        /* (non-Javadoc)
220
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canIterateFromIndex()
221
         */
222
        public boolean canIterateFromIndex() {
223
                return helper.supportOffset();
224
        }
225

    
226
        /* (non-Javadoc)
227
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canOrder()
228
         */
229
        public boolean canOrder() {
230
                // TODO Check Geom fields if postgis not are available
231
                if (query.hasOrder()) {
232
                        Iterator iter = query.getOrder().iterator();
233
                        FeatureQueryOrderMember menber;
234
                        String cql;
235
                        while (iter.hasNext()){
236
                                menber = (FeatureQueryOrderMember) iter.next();
237
                                if (menber.hasEvaluator()){
238
                                        cql =menber.getEvaluator().getCQL();
239
                                        if (cql == null || cql.length() == 0) {
240
                                                return false;
241
                                        }
242
                                }
243
                        }
244
                }
245
                return true;
246
        }
247

    
248
        public void dispose() {
249
                if (resultSetIDReferenced != null) {
250
                        Iterator iter = resultSetIDReferenced.iterator();
251
                        Integer resID;
252
                        while (iter.hasNext()) {
253
                                resID = (Integer) iter.next();
254
                                if (resID != null) {
255
                                        logger.warn(
256
                                                "ResultSet (ID {}) not closed on dispose, will close",
257
                                                resID);
258
                                        try {
259
                                                this.store.closeResulset(resID.intValue());
260
                                        } catch (DataException e) {
261
                                                logger.error("Close resulset Exception", e);
262
                                        }
263
                                }
264
                                iter.remove();
265
                        }
266
                }
267
                resultSetIDReferenced = null;
268
                store = null;
269
                query = null;
270
                featureType = null;
271
                filter = null;
272
                order = null;
273
                size = null;
274
                isEmpty = null;
275
        }
276

    
277

    
278
        /*
279
         * (non-Javadoc)
280
         *
281
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#fastIterator()
282
         */
283
        public DisposableIterator fastIterator() throws DataException {
284
                return this.fastIterator(0);
285
        }
286

    
287
        /*
288
         * (non-Javadoc)
289
         *
290
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#fastIterator(long)
291
         */
292
        public DisposableIterator fastIterator(long index) throws DataException {
293
                if (isEmpty != null && isEmpty.booleanValue()) {
294
                        return new EmptyJDBCIterator();
295
                }
296
                JDBCIterator iter = createFastIterartor(index);
297
                return iter;
298
        }
299

    
300
        protected String getSQL(long fromIndex) throws DataException {
301
                return store.compoundSelect(featureType, filter, order, 0, fromIndex);
302

    
303
        }
304

    
305
        protected JDBCIterator createFastIterartor(long index) throws DataException {
306
                int rsID = store.createResultSet(getSQL(index));
307
                return createDefaultFastIterartor(rsID);
308
        }
309

    
310
        protected JDBCIterator createIterator(long index) throws DataException {
311
                int rsID = store.createResultSet(getSQL(index));
312
                return createDefaultIterartor(rsID);
313
        }
314
        protected JDBCIterator createDefaultFastIterartor(int resultSetID)
315
                        throws DataException {
316
                return new JDBCFastIterator(store, this, featureType, resultSetID);
317
        }
318

    
319
        /* (non-Javadoc)
320
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#getSize()
321
         */
322
        public long getSize() throws DataException {
323
                if (size == null) {
324
                        size = new Long(store.getCount(filter));
325
                }
326
                return size.longValue();
327
        }
328

    
329
        /* (non-Javadoc)
330
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#isEmpty()
331
         */
332
        public boolean isEmpty() throws DataException {
333
                if (isEmpty == null) {
334
                        if (size == null) {
335
                                String sql = store
336
                                                .compoundSelect(featureType, filter, null, 1,
337
                                                0);
338
                                int rsID = store.createResultSet(sql);
339
                                isEmpty = new Boolean(store.resulsetNext(rsID));
340
                                store.closeResulset(rsID);
341
                        } else {
342
                                isEmpty = new Boolean(size.longValue() < 1);
343
                        }
344
                }
345
                return isEmpty.booleanValue();
346
        }
347

    
348
        /* (non-Javadoc)
349
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#iterator()
350
         */
351
        public DisposableIterator iterator() throws DataException {
352
                return iterator(0);
353
        }
354

    
355
        /* (non-Javadoc)
356
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#iterator(long)
357
         */
358
        public DisposableIterator iterator(long index) throws DataException {
359
                if (isEmpty != null && isEmpty.booleanValue()) {
360
                        return new EmptyJDBCIterator();
361
                }
362

    
363
                JDBCIterator iter = createIterator(index);
364
                return iter;
365
        }
366

    
367

    
368
        protected JDBCIterator createDefaultIterartor(int resultSetID)
369
                        throws DataException {
370
                return new JDBCIterator(store, this, featureType, resultSetID);
371
        }
372

    
373
        private class EmptyJDBCIterator extends JDBCIterator {
374

    
375
                protected EmptyJDBCIterator() throws DataException {
376
                        super(null, null, null, -1);
377
                }
378

    
379
                public boolean hasNext() {
380
                        return false;
381
                }
382

    
383
                public Object next() {
384
                        throw new NoSuchElementException();
385
                }
386

    
387
                public void dispose() {
388

    
389
                }
390

    
391
        }
392

    
393
        public void addResulsetReference(int resulsetID) {
394
                this.resultSetIDReferenced.add(new Integer(resulsetID));
395
        }
396

    
397
        public void removeResulsetReference(int resulsetID) {
398
                this.resultSetIDReferenced.remove(new Integer(resulsetID));
399
        }
400

    
401

    
402
}