Statistics
| Revision:

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

History | View | Annotate | Download (10.2 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.gvsig.tools.exception.BaseException;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

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

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

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

    
68
        protected List resultSetIDReferenced;
69

    
70
        private JDBCHelper helper = null;
71

    
72
        private int defaultFetchSize = 1000;
73

    
74
        private long limit = -1l;
75

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

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

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

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

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

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

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

    
127
                List values = new ArrayList();
128

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

    
138
                }
139

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

    
147
                return filterString;
148
        }
149

    
150

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

    
158

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

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

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

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

    
195

    
196

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

    
226

    
227

    
228
                                }
229

    
230
                                return true;
231
                        }
232

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

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

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

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

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

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

    
303
        }
304

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

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

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

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

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

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

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

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

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

    
385
        private class EmptyJDBCIterator extends JDBCIterator {
386

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

    
391
                @Override
392
                protected boolean internalHasNext() {
393
                        return false;
394
                }
395

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

    
401
                @Override
402
                protected void doDispose() throws BaseException {
403
                        // nothing to do
404
                }
405

    
406
        }
407

    
408
}