Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / jdbc / JDBCSetProvider.java @ 31128

History | View | Annotate | Download (10.1 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.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureQuery;
43
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
44
import org.gvsig.fmap.dal.feature.FeatureType;
45
import org.gvsig.fmap.dal.feature.FeatureQueryOrder.FeatureQueryOrderMember;
46
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureSetProvider;
47
import org.gvsig.tools.evaluator.Evaluator;
48
import org.gvsig.tools.evaluator.EvaluatorFieldValue;
49
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

    
53
/**
54
 * @author jmvivo
55
 *
56
 */
57
public class JDBCSetProvider extends AbstractFeatureSetProvider {
58

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

    
62
        protected String filter;
63
        protected String order;
64
        protected Long size = null;
65
        protected Boolean isEmpty = null;
66

    
67
        protected List resultSetIDReferenced;
68

    
69
        private JDBCHelper helper = null;
70

    
71
        private int defaultFetchSize = 1000;
72

    
73
        private long limit = -1l;
74

    
75
        public JDBCSetProvider(JDBCStoreProvider store, FeatureQuery query,
76
                        FeatureType featureType) throws DataException {
77
                super(store, query, featureType);
78
                this.helper = store.getHelper();
79
                this.resultSetIDReferenced = new ArrayList();
80

    
81
                if (query.hasFilter() && this.canFilter()) {
82
                        setFilter(query.getFilter());
83
                } else {
84
                        setFilter(null);
85
                }
86

    
87
                if (query.hasOrder() && canOrder()) {
88
                        setOrder(query.getOrder());
89
                } else {
90
                        setOrder(null);
91
                }
92

    
93
                if (query != null) {
94
                        limit = query.getLimit();
95
                }
96
        }
97

    
98
        /**
99
         * @return the defaultFetchSize
100
         */
101
        public int getDefaultFetchSize() {
102
                return defaultFetchSize;
103
        }
104

    
105
        /**
106
         * @param defaultFetchSize
107
         *            the defaultFetchSize to set
108
         */
109
        public void setDefaultFetchSize(int defaultFetchSize) {
110
                this.defaultFetchSize = defaultFetchSize;
111
        }
112

    
113
        protected String getSqlForEvaluator(Evaluator filter) {
114
                if (filter == null) {
115
                        return null;
116
                }
117
                EvaluatorFieldsInfo info = filter.getFieldsInfo();
118
                String filterString = filter.getCQL();
119
                if (info == null) {
120
                        return filterString;
121
                }
122
                String[] filterNames = info.getFieldNames();
123
                String[] finalNames = new String[filterNames.length];
124
                EvaluatorFieldValue[] fValues;
125

    
126
                List values = new ArrayList();
127

    
128
                FeatureAttributeDescriptor attr;
129
                for (int i = 0; i < filterNames.length; i++) {
130
                        attr = getFeatureType().getAttributeDescriptor(filterNames[i]);
131
                        if (attr == null) {
132
                                finalNames[i] = filterNames[i];
133
                                continue;
134
                        }
135
                        finalNames[i] = getEscapedFieldName(attr.getName());
136

    
137
                }
138

    
139
                for (int i = 0; i < filterNames.length; i++) {
140
                        if (!filterNames[i].equals(finalNames[i])) {
141
                                filterString.replaceAll("\\b" + filterNames[i] + "\\b",
142
                                                finalNames[i]);
143
                        }
144
                }
145

    
146
                return filterString;
147
        }
148

    
149

    
150
        protected String getEscapedFieldName(String fieldName) {
151
                if (helper == null) {
152
                        helper = getJDBCStoreProvider().getHelper();
153
                }
154
                return helper.escapeFieldName(fieldName);
155
        }
156

    
157

    
158
        protected void setOrder(FeatureQueryOrder order) {
159
                if (order == null || order.size() == 0) {
160
                        this.order = null;
161
                        return;
162
                }
163

    
164
                StringBuilder buffer = new StringBuilder();
165
                Iterator iter = order.iterator();
166
                FeatureQueryOrderMember menber;
167
                while (true) {
168
                        menber = (FeatureQueryOrderMember) iter.next();
169
                        if (menber.hasEvaluator()) {
170
                                buffer.append(getSqlForEvaluator(menber.getEvaluator()));
171
                        } else {
172
                                buffer.append(getEscapedFieldName(menber.getAttributeName()));
173
                        }
174
                        if (menber.getAscending()) {
175
                                buffer.append(" ASC");
176
                        } else {
177
                                buffer.append(" DESC");
178
                        }
179
                        if (iter.hasNext()) {
180
                                buffer.append(", ");
181
                        } else {
182
                                buffer.append(' ');
183
                                break;
184
                        }
185
                }
186

    
187
                this.order = buffer.toString();
188
        }
189

    
190
        protected void setFilter(Evaluator filter) {
191
                this.filter = getSqlForEvaluator(filter);
192
        }
193

    
194

    
195

    
196
        /* (non-Javadoc)
197
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canFilter()
198
         */
199
        public boolean canFilter() {
200
                Evaluator filter = getQuery().getFilter();
201
                if (filter != null) {
202
                        if (filter.getCQL() == null || filter.getCQL().length() == 0) {
203
                                return false;
204
                        } else {
205
                                // TODO Check Geom fields if
206
                                EvaluatorFieldsInfo fInfo = filter.getFieldsInfo();
207
                                if (fInfo == null || fInfo.getFieldNames() == null) {
208
                                        return true;
209
                                }
210
                                Iterator names = Arrays.asList(fInfo.getFieldNames())
211
                                                .iterator();
212
                                String name;
213
                                int type;
214
                                while (names.hasNext()) {
215
                                        name = (String) names.next();
216
                                        type =
217
                                                        this.getFeatureType()
218
                                                                        .getAttributeDescriptor(name)
219
                                                        .getDataType();
220
                                        if (type == DataTypes.GEOMETRY
221
                                                        && !this.helper.hasGeometrySupport()) {
222
                                                return false;
223
                                        }
224

    
225

    
226

    
227
                                }
228

    
229
                                return true;
230
                        }
231

    
232
                } else{
233
                        return false;
234
                }
235
        }
236

    
237
        /* (non-Javadoc)
238
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canIterateFromIndex()
239
         */
240
        public boolean canIterateFromIndex() {
241
                return helper.supportOffset();
242
        }
243

    
244
        /* (non-Javadoc)
245
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#canOrder()
246
         */
247
        public boolean canOrder() {
248
                // TODO Check Geom fields if postgis not are available
249
                FeatureQuery query = getQuery();
250
                if (query.hasOrder()) {
251
                        Iterator iter = query.getOrder().iterator();
252
                        FeatureQueryOrderMember menber;
253
                        String cql;
254
                        while (iter.hasNext()){
255
                                menber = (FeatureQueryOrderMember) iter.next();
256
                                if (menber.hasEvaluator()){
257
                                        cql =menber.getEvaluator().getCQL();
258
                                        if (cql == null || cql.length() == 0) {
259
                                                return false;
260
                                        }
261
                                }
262
                        }
263
                }
264
                return true;
265
        }
266

    
267
        private JDBCStoreProvider getJDBCStoreProvider() {
268
                return (JDBCStoreProvider) getStore();
269
        }
270

    
271
        public void dispose() {
272
                if (resultSetIDReferenced != null) {
273
                        Iterator iter = resultSetIDReferenced.iterator();
274
                        Integer resID;
275
                        while (iter.hasNext()) {
276
                                resID = (Integer) iter.next();
277
                                if (resID != null) {
278
                                        logger.warn(
279
                                                "ResultSet (ID {}) not closed on dispose, will close",
280
                                                resID);
281
                                        try {
282
                                                getJDBCStoreProvider().closeResulset(resID.intValue());
283
                                        } catch (DataException e) {
284
                                                logger.error("Close resulset Exception", e);
285
                                        }
286
                                }
287
                                iter.remove();
288
                        }
289
                }
290
                resultSetIDReferenced = null;
291
                filter = null;
292
                order = null;
293
                size = null;
294
                isEmpty = null;
295
        }
296

    
297
        protected String getSQL(long fromIndex) throws DataException {
298
                return getJDBCStoreProvider().compoundSelect(getFeatureType(), filter,
299
                                order, limit, fromIndex);
300

    
301
        }
302

    
303
        /* (non-Javadoc)
304
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#getSize()
305
         */
306
        public long getSize() throws DataException {
307
                if (size == null) {
308
                        size = new Long(getJDBCStoreProvider().getCount(filter));
309
                }
310
                return size.longValue();
311
        }
312

    
313
        /* (non-Javadoc)
314
         * @see org.gvsig.fmap.dal.feature.spi.FeatureSetProvider#isEmpty()
315
         */
316
        public boolean isEmpty() throws DataException {
317
                JDBCStoreProvider store = getJDBCStoreProvider();
318
                if (isEmpty == null) {
319
                        if (size == null) {
320
                                String sql =
321
                                                store.compoundSelect(getFeatureType(), filter, null, 1,
322
                                                                0);
323
                                int rsID = store.createResultSet(sql, getFetchSize());
324
                                isEmpty = new Boolean(store.resulsetNext(rsID));
325
                                store.closeResulset(rsID);
326
                        } else {
327
                                isEmpty = new Boolean(size.longValue() < 1);
328
                        }
329
                }
330
                return isEmpty.booleanValue();
331
        }
332

    
333
        protected int getFetchSize() {
334
                long pageSize = -1;
335
                if (getQuery() != null) {
336
                        pageSize = getQuery().getPageSize();
337
                        pageSize =
338
                                        pageSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : pageSize;
339
                }
340
                return (pageSize > 0 ? (int) pageSize : defaultFetchSize);
341
        }
342

    
343
        protected JDBCIterator createFastIterator(long index) throws DataException {
344
                if (isEmpty != null && isEmpty.booleanValue()) {
345
                        return new EmptyJDBCIterator();
346
                }
347
                int rsID =
348
                                getJDBCStoreProvider().createResultSet(getSQL(index),
349
                                                getFetchSize());
350
                return createDefaultFastIterator(rsID);
351
        }
352

    
353
        protected JDBCIterator createDefaultFastIterator(int resultSetID)
354
                        throws DataException {
355
                return new JDBCFastIterator(getJDBCStoreProvider(), this,
356
                                getFeatureType(), resultSetID);
357
        }
358

    
359
        protected JDBCIterator createIterator(long index) throws DataException {
360
                if (isEmpty != null && isEmpty.booleanValue()) {
361
                        return new EmptyJDBCIterator();
362
                }
363
                int rsID =
364
                                getJDBCStoreProvider().createResultSet(getSQL(index),
365
                                                getFetchSize());
366
                return createDefaultIterator(rsID);
367
        }
368

    
369
        protected JDBCIterator createDefaultIterator(int resultSetID)
370
                        throws DataException {
371
                return new JDBCIterator(getJDBCStoreProvider(), this, getFeatureType(),
372
                                resultSetID);
373
        }
374

    
375
        public void addResulsetReference(int resulsetID) {
376
                this.resultSetIDReferenced.add(new Integer(resulsetID));
377
        }
378

    
379
        public void removeResulsetReference(int resulsetID) {
380
                this.resultSetIDReferenced.remove(new Integer(resulsetID));
381
        }
382

    
383
        private class EmptyJDBCIterator extends JDBCIterator {
384

    
385
                protected EmptyJDBCIterator() throws DataException {
386
                        super(null, null, null, -1);
387
                }
388

    
389
                @Override
390
                protected boolean internalHasNext() {
391
                        return false;
392
                }
393

    
394
                @Override
395
                protected Object internalNext() {
396
                        throw new NoSuchElementException();
397
                }
398

    
399
                @Override
400
                protected void internalDispose() {
401
                        // nothing to do
402
                }
403

    
404
        }
405

    
406
}