Statistics
| Revision:

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

History | View | Annotate | Download (23.4 KB)

1 27525 jmvivo
/* 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 28784 jmvivo
import java.security.InvalidParameterException;
34 27571 jmvivo
import java.sql.Connection;
35 28784 jmvivo
import java.sql.PreparedStatement;
36 27525 jmvivo
import java.sql.ResultSet;
37
import java.sql.SQLException;
38 27571 jmvivo
import java.sql.Statement;
39 27525 jmvivo
import java.util.ArrayList;
40 31022 cordinyana
import java.util.Collections;
41 27571 jmvivo
import java.util.Iterator;
42 27525 jmvivo
import java.util.List;
43
44 28784 jmvivo
import org.cresques.cts.IProjection;
45
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47
import org.gvsig.fmap.dal.DataServerExplorer;
48 32880 jjdelcerro
import org.gvsig.fmap.dal.DataStore;
49 28784 jmvivo
import org.gvsig.fmap.dal.DataStoreNotification;
50
import org.gvsig.fmap.dal.DataTypes;
51 27672 jmvivo
import org.gvsig.fmap.dal.exception.CloseException;
52 27525 jmvivo
import org.gvsig.fmap.dal.exception.DataException;
53 28784 jmvivo
import org.gvsig.fmap.dal.exception.InitializeException;
54
import org.gvsig.fmap.dal.exception.OpenException;
55
import org.gvsig.fmap.dal.exception.ReadException;
56
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
57
import org.gvsig.fmap.dal.feature.EditableFeatureType;
58 27571 jmvivo
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59 28784 jmvivo
import org.gvsig.fmap.dal.feature.FeatureQuery;
60 27672 jmvivo
import org.gvsig.fmap.dal.feature.FeatureType;
61 27525 jmvivo
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
62 29289 jmvivo
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
63 28784 jmvivo
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
64
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
65 31022 cordinyana
import org.gvsig.fmap.dal.resource.ResourceAction;
66
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
67 27571 jmvivo
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
68 29326 jmvivo
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
69 32880 jjdelcerro
import org.gvsig.fmap.dal.store.db.DBHelper;
70
import org.gvsig.fmap.dal.store.db.FeatureTypeHelper;
71 28785 jmvivo
import org.gvsig.fmap.dal.store.jdbc.exception.InvalidResultSetIdException;
72
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
73
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
74 28784 jmvivo
import org.gvsig.fmap.geom.Geometry;
75
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
76
import org.gvsig.fmap.geom.primitive.Envelope;
77 32880 jjdelcerro
import org.gvsig.metadata.MetadataLocator;
78
import org.gvsig.metadata.MetadataManager;
79 29326 jmvivo
import org.gvsig.tools.dynobject.DynObject;
80 32880 jjdelcerro
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
81 28784 jmvivo
import org.gvsig.tools.exception.BaseException;
82 27672 jmvivo
import org.slf4j.Logger;
83
import org.slf4j.LoggerFactory;
84 27525 jmvivo
85
86
/**
87
 * @author jmvivo
88
 *
89
 */
90 28784 jmvivo
public class JDBCStoreProvider extends AbstractFeatureStoreProvider
91
                implements JDBCHelperUser {
92 27525 jmvivo
93 27672 jmvivo
        final static private Logger logger = LoggerFactory
94
                        .getLogger(JDBCStoreProvider.class);
95
96 32880 jjdelcerro
        private List<ResultSetInfo> resulsetList;
97 27525 jmvivo
98 29289 jmvivo
        public static String NAME = "JDBC";
99 28784 jmvivo
        public static String DESCRIPTION = "JDBC source";
100
101 32880 jjdelcerro
        public static final String METADATA_DEFINITION_NAME = NAME;
102
103 28630 jmvivo
        private long mlsecondsToZombie = 1000 * 60 * 10; // 10 Min
104 27525 jmvivo
105 28784 jmvivo
        protected JDBCHelper helper;
106 28630 jmvivo
107 28784 jmvivo
        protected boolean directSQLMode;
108
109
        private Long totalCount = null;
110
111 29326 jmvivo
        public JDBCStoreProvider(JDBCStoreParameters params,
112
                        DataStoreProviderServices storeServices) throws InitializeException {
113 32880 jjdelcerro
                this(
114
                                params,
115
                                storeServices,
116
                                DBHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
117
                );
118 27525 jmvivo
        }
119
120 29326 jmvivo
        protected JDBCStoreProvider(JDBCStoreParameters params,
121
                        DataStoreProviderServices storeServices, DynObject metadata)
122 28784 jmvivo
                        throws InitializeException {
123 29326 jmvivo
                super(params, storeServices, metadata);
124
125 32880 jjdelcerro
                resulsetList = new ArrayList<ResultSetInfo>(10);
126 29326 jmvivo
127
                helper = createHelper();
128
                if (params.getSQL() != null && (params.getSQL()).trim().length() > 0) {
129
                        directSQLMode = true;
130
                }
131
132
                this.initFeatureType();
133 28784 jmvivo
        }
134 27525 jmvivo
135 32880 jjdelcerro
        public Object getDynValue(String name) throws DynFieldNotFoundException {
136
                try {
137
                        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
138
                                Envelope env = this.getEnvelope();
139
                                if( env != null ) {
140
                                        return env;
141
                                }
142
                        } else if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
143
                                IProjection proj;
144
                                proj = this.getFeatureStore().getDefaultFeatureType().getDefaultSRS();
145
                                if( proj != null ) {
146
                                        return proj;
147
                                }
148
                        }
149
                } catch (DataException e) {
150
                        throw new RuntimeException(e);
151
                }
152
                return super.getDynValue(name);
153
        }
154
155 27525 jmvivo
156 29326 jmvivo
        protected JDBCStoreParameters getJDBCParameters() {
157
                return (JDBCStoreParameters) this.getParameters();
158
        }
159
160
161 27571 jmvivo
        /**
162
         * Load data form a resulset.<br>
163
         *
164
         * <strong>Note:</strong><br>
165
         * this method have to perform <code>resouceBegin</code> at the begining and
166
         * <code>resourceEnd</code> at the end of execution.
167
         *
168
         *
169
         * @param data
170
         * @param resulsetID
171
         *
172
         * @return
173
         * @throws DataException
174
         */
175 31022 cordinyana
        public void loadFeatureProvider(final FeatureProvider data, final int resultsetID)
176 27571 jmvivo
                        throws DataException {
177 31022 cordinyana
                getResource().execute(new ResourceAction() {
178
                        public Object run() throws Exception {
179
                                ResultSet rs = getResultSet(resultsetID);
180
                                FeatureAttributeDescriptor attr;
181 32880 jjdelcerro
                                Iterator<FeatureAttributeDescriptor> iter = FeatureTypeHelper.iterator(data.getType());
182 31022 cordinyana
                                while (iter.hasNext()) {
183 32880 jjdelcerro
                                        attr = iter.next();
184 31022 cordinyana
                                        loadFeatureProviderValue(data, rs, attr);
185
                                }
186
                                return null;
187 27571 jmvivo
                        }
188 31022 cordinyana
                });
189 27525 jmvivo
        }
190
191 29292 jmvivo
        protected void loadFeatureProviderValue(FeatureProvider data, ResultSet rs,
192 27571 jmvivo
                        FeatureAttributeDescriptor attr) throws DataException {
193 33331 jjdelcerro
                if (attr.getType() == DataTypes.GEOMETRY) {
194 28784 jmvivo
                        byte[] buffer;
195
                        try {
196
                                buffer = rs.getBytes(attr.getIndex() + 1);
197
                                if (buffer == null) {
198
                                        data.set(attr.getIndex(), null);
199
                                } else {
200
                                        data.set(attr.getIndex(), this.helper.getGeometry(buffer));
201
                                }
202
                        } catch (SQLException e) {
203
                                throw new JDBCSQLException(e);
204
                        } catch (BaseException e) {
205 33717 jjdelcerro
                                throw new ReadException(getProviderName(), e);
206 28784 jmvivo
                        }
207 27571 jmvivo
208 28784 jmvivo
                } else {
209
                        try {
210
                                data.set(attr.getIndex(), rs.getObject(attr.getIndex() + 1));
211
                        } catch (SQLException e) {
212
                                throw new JDBCSQLException(e);
213
                        }
214 27571 jmvivo
                }
215
        }
216
217 28630 jmvivo
        public long getTimeToResulSetZombie() {
218
                return mlsecondsToZombie;
219
        }
220
221
        public void setTimeToResulSetZombie(long mlSeconds) {
222
                mlsecondsToZombie = mlSeconds;
223
        }
224
225
        private class ResultSetInfo{
226
                private ResultSet resultSet = null;
227
                private long lastUse = 0;
228
229
                public ResultSetInfo(ResultSet resulSet) {
230
                        this.resultSet = resulSet;
231
                        used();
232
                }
233
234
                private void used() {
235
                        lastUse = System.currentTimeMillis();
236
                }
237
238
239
                public ResultSet get() {
240
                        used();
241
                        return resultSet;
242
                }
243
244
                public boolean isZombie() {
245
                        return System.currentTimeMillis() - lastUse > mlsecondsToZombie;
246
                }
247
        }
248
249 31128 cordinyana
        public final int createResultSet(String sql, int fetchSize)
250 27571 jmvivo
                        throws DataException {
251 31128 cordinyana
                return createResultSet(sql, null, -1);
252 27571 jmvivo
        }
253
254 31128 cordinyana
        public final int createResultSet(final String sql, final Object[] values,
255
                        final int fetchSize)
256 27571 jmvivo
                        throws DataException {
257 27672 jmvivo
                synchronized (this) {
258 28630 jmvivo
                        checksResulsets();
259 31022 cordinyana
                        return ((Integer) getResource().execute(new ResourceAction() {
260
                                public Object run() throws Exception {
261
                                        ResultSetInfo newRs =
262 31128 cordinyana
                                                        new ResultSetInfo(createNewResultSet(sql, values,
263
                                                                        fetchSize));
264 31022 cordinyana
                                        int newId = getNewId();
265
                                        if (newId < 0) {
266
                                                newId = resulsetList.size();
267
                                                resulsetList.add(newRs);
268
                                        } else {
269
                                                resulsetList.set(newId, newRs);
270
                                        }
271
                                        if (logger.isDebugEnabled()) {
272
                                                logger.debug(" id: {} (total {})", newId,
273
                                                                getResultsetOpenCount());
274
                                        }
275
276
                                        return Integer.valueOf(newId);
277 27672 jmvivo
                                }
278 31022 cordinyana
                        })).intValue();
279 27525 jmvivo
                }
280
        }
281
282
        private int getNewId() {
283
                int newId;
284
                if (resulsetList.size() < 1) {
285
                        return -1;
286
                }
287
                for (newId = 0; newId < resulsetList.size(); newId++) {
288
                        if (resulsetList.get(newId) == null) {
289
                                return newId;
290
                        }
291
                }
292
                return -1;
293
        }
294
295 27672 jmvivo
        protected final void forceCloseAllResultSet()
296 31022 cordinyana
                        throws ResourceExecuteException,
297 28191 jmvivo
                        JDBCException {
298 27672 jmvivo
                synchronized (this) {
299 32880 jjdelcerro
                        // FIXME: Esto no deberia funcionar.
300 27672 jmvivo
                        Iterator iter = resulsetList.iterator();
301
                        Integer rsID = null;
302
                        while (iter.hasNext()) {
303
                                rsID = (Integer) iter.next();
304
                                if (rsID != null) {
305
                                        try {
306 28630 jmvivo
                                                forceCloseResultSet(rsID.intValue());
307 27672 jmvivo
                                        } catch (InvalidResultSetIdException e) {
308
                                                continue;
309
                                        }
310
                                }
311
                                iter.remove();
312
                        }
313
314
                }
315 28630 jmvivo
        }
316 32880 jjdelcerro
317 28630 jmvivo
        protected final void forceCloseResultSet(int rsID)
318 31022 cordinyana
                        throws ResourceExecuteException, JDBCException,
319 28630 jmvivo
                        InvalidResultSetIdException {
320
                logger.warn("Close forced of resultSet ({})", rsID);
321
                closeResulset(rsID);
322 27672 jmvivo
        }
323
324 27525 jmvivo
        protected final ResultSet getResultSet(int resultsetID)
325
                        throws InvalidResultSetIdException {
326
                if (resultsetID >= resulsetList.size()) {
327
                        throw new InvalidResultSetIdException(resultsetID);
328
                }
329 32880 jjdelcerro
                ResultSetInfo rsInfo = resulsetList.get(resultsetID);
330 28630 jmvivo
                if (rsInfo == null) {
331 27525 jmvivo
                        throw new InvalidResultSetIdException(resultsetID);
332
                }
333 28630 jmvivo
                return rsInfo.get();
334 27525 jmvivo
335
        }
336
337 27672 jmvivo
        private ResultSet dropResultSet(int resultsetID)
338 27571 jmvivo
                        throws InvalidResultSetIdException {
339
                if (resultsetID >= resulsetList.size()) {
340
                        throw new InvalidResultSetIdException(resultsetID);
341
                }
342 28630 jmvivo
                ResultSetInfo rsInfo = (ResultSetInfo) resulsetList.get(resultsetID);
343
                if (rsInfo == null) {
344 27571 jmvivo
                        throw new InvalidResultSetIdException(resultsetID);
345
                }
346
                if (resultsetID == resulsetList.size() - 1) {
347
                        resulsetList.remove(resultsetID);
348
                } else {
349
                        resulsetList.set(resultsetID, null);
350
                }
351 28630 jmvivo
                return rsInfo.get();
352 27571 jmvivo
        }
353
354
355 31022 cordinyana
        public final boolean resulsetNext(final int resultsetID)
356
                        throws JDBCException,
357
                        InvalidResultSetIdException, ResourceExecuteException {
358
                return ((Boolean) getResource().execute(new ResourceAction() {
359
                        public Object run() throws Exception {
360
                                return Boolean.valueOf(getResultSet(resultsetID).next());
361
                        }
362
                })).booleanValue();
363 27525 jmvivo
        }
364
365 31022 cordinyana
        public final void closeResulset(final int resultsetID)
366 28191 jmvivo
                        throws JDBCException,
367 31022 cordinyana
                        InvalidResultSetIdException, ResourceExecuteException {
368 27672 jmvivo
                synchronized (this) {
369 31022 cordinyana
                        getResource().execute(new ResourceAction() {
370
                                public Object run() throws Exception {
371
                                        ResultSet rs = dropResultSet(resultsetID);
372
                                        closeResulset(rs);
373
                                        return null;
374 27672 jmvivo
                                }
375 31022 cordinyana
                        });
376
                        if (logger.isDebugEnabled()) {
377
                                logger.debug(" id: " + resultsetID + " (total "
378
                                                + getResultsetOpenCount() + ")");
379
                        }
380 28630 jmvivo
                        checksResulsets();
381
                }
382
        }
383 27672 jmvivo
384 28630 jmvivo
        public final void checksResulsets() throws JDBCException,
385 31022 cordinyana
                        InvalidResultSetIdException, ResourceExecuteException {
386 28630 jmvivo
                synchronized (this) {
387 31022 cordinyana
                        getResource().execute(new ResourceAction() {
388
                                public Object run() throws Exception {
389
                                        ResultSetInfo rsInfo;
390
                                        for (int i = 0; i < resulsetList.size(); i++) {
391
                                                rsInfo = (ResultSetInfo) resulsetList.get(i);
392
                                                if (rsInfo == null) {
393
                                                        continue;
394
                                                }
395
                                                if (rsInfo.isZombie()) {
396
                                                        forceCloseResultSet(i);
397
                                                }
398 28630 jmvivo
                                        }
399 31022 cordinyana
                                        return null;
400 28630 jmvivo
                                }
401 31022 cordinyana
                        });
402 27525 jmvivo
                }
403
        }
404
405 31022 cordinyana
        protected void closeResulset(final ResultSet rs) throws JDBCException,
406
                        ResourceExecuteException {
407
                getResource().execute(new ResourceAction() {
408
                        public Object run() throws Exception {
409
                                Statement st = rs.getStatement();
410
                                Connection con = st.getConnection();
411
                                try {
412
                                        rs.close();
413
                                } finally {
414
                                        // TODO revisar esto
415
                                        try{ st.close();  } catch (Exception ex){ };
416
                                        try{ con.close(); } catch (Exception ex){ };
417
                                }
418
                                return null;
419 27571 jmvivo
                        }
420 31022 cordinyana
                });
421 27571 jmvivo
        }
422
423 32880 jjdelcerro
        private int getResultsetOpenCount() {
424
                int count = 0;
425
                Iterator<ResultSetInfo> iter = resulsetList.iterator();
426
                while (iter.hasNext()) {
427
                        if (iter.next() != null) {
428
                                count++;
429
                        }
430
                }
431
                return count;
432
        }
433
434 27571 jmvivo
        protected final int openResulsetCount() {
435
                int count = 0;
436 32880 jjdelcerro
                Iterator<ResultSetInfo> iter = resulsetList.iterator();
437 27571 jmvivo
                while (iter.hasNext()) {
438
                        if (iter.next() != null) {
439
                                count++;
440
                        }
441
                }
442
                return count;
443
        }
444
445
        public boolean closeResourceRequested(ResourceProvider resource) {
446
                try {
447 28630 jmvivo
                        checksResulsets();
448 27571 jmvivo
                        return openResulsetCount() == 0 && closeResource(resource);
449 28630 jmvivo
                } catch (DataException e) {
450
                        logger.error("Exception throws", e);
451 27571 jmvivo
                        return false;
452
                }
453
        }
454
455
456 28784 jmvivo
        protected String fixFilter(String filter) {
457
                if (filter == null) {
458
                        return null;
459
                }
460
461
                return filter;
462 27672 jmvivo
        }
463
464 28784 jmvivo
        protected JDBCHelper createHelper() throws InitializeException {
465 29326 jmvivo
                return new JDBCHelper(this, getJDBCParameters());
466 28784 jmvivo
        }
467
468
        protected JDBCHelper getHelper() {
469
                return helper;
470
        }
471
472
        protected void resetCount() {
473
                totalCount = null;
474
        }
475
476
        /**
477
         * Get feature count for a <code>filter</code>.<br>
478
         *
479
         * <code>filter</code> can be <code>null</code>.<br>
480
         *
481
         * <strong>Note:</strong><br>
482
         * this method have to perform <code>resouceBegin</code> at the begining and
483
         * <code>resourceEnd</code> at the end of execution.
484
         *
485
         *
486
         * @param filter
487
         * @return
488
         * @throws DataException
489
         */
490 31128 cordinyana
        protected long getCount(String filter)
491
                        throws DataException {
492 28784 jmvivo
                this.open();
493
                if (filter == null && totalCount != null) {
494
                        return totalCount.longValue();
495
                }
496 31022 cordinyana
                final String sql = compoundCountSelect(filter);
497 31128 cordinyana
498 31022 cordinyana
                long count = ((Long) getResource().execute(new ResourceAction() {
499
                        public Object run() throws Exception {
500
                                long count = 0;
501 31128 cordinyana
                                ResultSet rs = createNewResultSet(sql, null, 1);
502 31022 cordinyana
                                try {
503
                                        if (rs.next()) {
504
                                                count = rs.getLong(1);
505
                                        }
506
                                } catch (SQLException e) {
507
                                        throw new JDBCSQLException(e);
508
                                } finally {
509
                                        closeResulset(rs);
510 28784 jmvivo
                                }
511 31022 cordinyana
                                return Long.valueOf(count);
512 28784 jmvivo
                        }
513 31022 cordinyana
                })).longValue();
514 31128 cordinyana
515 28784 jmvivo
                if (filter == null) {
516
                        totalCount = new Long(count);
517
                }
518
                return count;
519
        }
520
521 27672 jmvivo
        public void close() throws CloseException {
522 28784 jmvivo
                helper.close();
523
        }
524
525
        public void open() throws OpenException {
526
                helper.open();
527
        }
528
529 31022 cordinyana
        @Override
530
        protected FeatureProvider internalGetFeatureProviderByReference(
531 28784 jmvivo
                        FeatureReferenceProviderServices reference) throws DataException {
532 31022 cordinyana
                return internalGetFeatureProviderByReference(reference,
533
                                getFeatureStore()
534 28784 jmvivo
                                .getDefaultFeatureType());
535
        }
536
537 31022 cordinyana
        @Override
538
        protected FeatureProvider internalGetFeatureProviderByReference(
539 31128 cordinyana
                        FeatureReferenceProviderServices reference,
540
                        FeatureType featureType)
541 28784 jmvivo
                        throws DataException {
542 31022 cordinyana
                StringBuilder filter = new StringBuilder();
543
                FeatureAttributeDescriptor[] pk =
544
                                getFeatureStore().getFeatureType(featureType.getId())
545
                                                .getPrimaryKey();
546 28784 jmvivo
547 32880 jjdelcerro
                List<Object> values = new ArrayList<Object>();
548 28784 jmvivo
549 31022 cordinyana
                int i;
550
                for (i = 0; i < pk.length - 1; i++) {
551 32880 jjdelcerro
                        values.add(
552
                                        helper.dalValueToJDBC(pk[i],
553 31022 cordinyana
                                        reference.getKeyValue(pk[i].getName())));
554 28784 jmvivo
                        filter.append(helper.getSqlFieldName(pk[i]));
555 31022 cordinyana
                        filter.append(" = ? AND ");
556
                }
557
                values.add(helper.dalValueToJDBC(pk[i],
558
                                reference.getKeyValue(pk[i].getName())));
559
                filter.append(helper.getSqlFieldName(pk[i]));
560
                filter.append(" = ? ");
561 28784 jmvivo
562 31022 cordinyana
                String sql = compoundSelect(featureType, filter.toString(), null, 1, 0);
563 28784 jmvivo
564 31022 cordinyana
                FeatureProvider data;
565 31128 cordinyana
                int rsId = createResultSet(sql, values.toArray(), 1);
566 31022 cordinyana
                try {
567
                        if (!resulsetNext(rsId)) {
568
                                throw new RuntimeException("Reference Not found");
569 28784 jmvivo
                        }
570 31022 cordinyana
                        data = createFeatureProvider(featureType);
571
                        loadFeatureProvider(data, rsId);
572 28784 jmvivo
                } finally {
573 31022 cordinyana
                        closeResulset(rsId);
574 27672 jmvivo
                }
575 28784 jmvivo
576 31022 cordinyana
                return data;
577 28784 jmvivo
        }
578
579 29289 jmvivo
        public int getOIDType() {
580 28784 jmvivo
                return DataTypes.UNKNOWN;
581
        }
582
583
        protected void initFeatureType() throws InitializeException {
584
585
                EditableFeatureType edFType = null;
586 27672 jmvivo
                try {
587 29326 jmvivo
                        edFType = this.getStoreServices().createFeatureType();
588 28784 jmvivo
589 29326 jmvivo
                        helper.loadFeatureType(edFType, getJDBCParameters());
590 28784 jmvivo
591 27672 jmvivo
                } catch (DataException e) {
592 33717 jjdelcerro
                        throw new InitializeException(this.getProviderName(), e);
593 28784 jmvivo
                }
594
595
                FeatureType defaultType = edFType.getNotEditableCopy();
596 32880 jjdelcerro
                List<FeatureType> types = Collections.singletonList(defaultType);
597 29326 jmvivo
                this.getStoreServices().setFeatureTypes(types, defaultType);
598 28784 jmvivo
        }
599
600 31022 cordinyana
        protected ResultSet createNewResultSet(final String sql,
601 31128 cordinyana
                        final Object[] values, final int fetchSize)
602
                        throws DataException {
603 28784 jmvivo
                this.open();
604 31022 cordinyana
                return (ResultSet) getResource().execute(new ResourceAction() {
605
                        public Object run() throws Exception {
606
                                Connection conn = null;
607
                                PreparedStatement st = null;
608
                                ResultSet rs = null;
609
                                try {
610 28784 jmvivo
611 31022 cordinyana
                                        conn = helper.getConnection();
612 31128 cordinyana
                                        conn.setAutoCommit(false);
613 31022 cordinyana
                                        st = conn.prepareStatement(sql);
614
615
                                        if (values != null) {
616
                                                Object value;
617
                                                for (int i = 0; i < values.length; i++) {
618
                                                        value = values[i];
619
                                                        if (value instanceof Geometry) {
620
                                                                byte[] bytes;
621
                                                                try {
622
                                                                        bytes =
623
                                                                                        (byte[]) ((Geometry) value).invokeOperation(
624
                                                                                                        ToWKB.CODE, null);
625
                                                                } catch (BaseException e) {
626
                                                                        throw new InvalidParameterException();
627
                                                                }
628
                                                                st.setBytes(i + 1, bytes);
629
                                                        }
630
                                                        st.setObject(i + 1, value);
631 28784 jmvivo
                                                }
632
                                        }
633 31022 cordinyana
634 31128 cordinyana
                                        if (fetchSize > 0) {
635
                                                st.setFetchSize(fetchSize);
636
                                        }
637 31022 cordinyana
                                        rs = st.executeQuery();
638 31128 cordinyana
                                        if (fetchSize > 0) {
639
                                                rs.setFetchSize(fetchSize);
640
                                        }
641 31022 cordinyana
                                        return rs;
642
                                } catch (SQLException e) {
643
                                        try {
644
                                                rs.close();
645
                                        } catch (Exception e1) {
646
                                        }
647
                                        try {
648
                                                st.close();
649
                                        } catch (Exception e1) {
650
                                        }
651
                                        try {
652
                                                conn.close();
653
                                        } catch (Exception e1) {
654
                                        }
655
                                        throw new JDBCSQLException(e);
656 28784 jmvivo
                                }
657
                        }
658 31022 cordinyana
                });
659 27672 jmvivo
        }
660
661 28784 jmvivo
        protected boolean closeResource(ResourceProvider resource) {
662
                try {
663
                        this.helper.close();
664
                } catch (CloseException e) {
665
                        logger.error("Exception in close Request", e);
666
                }
667
                return !this.helper.isOpen();
668
        }
669
670
        protected String compoundCountSelect(String filter) {
671
                if (this.directSQLMode) {
672
                        return null;
673
                }
674
                // Select
675
                StringBuilder sql = new StringBuilder();
676
                sql.append("Select count(");
677 29326 jmvivo
                String[] pkFields = getJDBCParameters().getPkFields();
678 28784 jmvivo
                if (pkFields != null && pkFields.length == 1) {
679
                        sql.append(helper.escapeFieldName(pkFields[0]));
680
                } else {
681
                        sql.append('*');
682
683
                }
684
                sql.append(") ");
685
686
                sql.append("from ");
687
688 29326 jmvivo
                sql.append(getJDBCParameters().tableID());
689 28784 jmvivo
                sql.append(' ');
690
691
                appendWhere(sql, filter);
692
693
                return sql.toString();
694
        }
695
696
        protected void appendWhere(StringBuilder sql, String filter) {
697
                filter = fixFilter(filter);
698 32880 jjdelcerro
                String initialFilter = getJDBCParameters().getBaseFilter();
699 28784 jmvivo
                if ((initialFilter != null && initialFilter.length() != 0)
700
                                || (filter != null && filter.length() != 0)) {
701
                        sql.append("where (");
702
703
                        if (initialFilter != null && initialFilter.length() != 0
704
                                        && filter != null && filter.length() != 0) {
705
                                // initialFilter + filter
706
                                sql.append('(');
707
                                sql.append(initialFilter);
708
                                sql.append(") and (");
709
                                sql.append(filter);
710
                                sql.append(')');
711
                        } else if (initialFilter != null && initialFilter.length() != 0) {
712
                                // initialFilter only
713
                                sql.append(initialFilter);
714
                        } else {
715
                                // filter only
716
                                sql.append(filter);
717
                        }
718
                        sql.append(") ");
719
                }
720
        }
721
722
        public void closeDone() throws DataException {
723 32880 jjdelcerro
                // Do nothing
724 28784 jmvivo
        }
725
726
        public void opendDone() throws DataException {
727
                // Nothing to do
728
        }
729
730
        public Envelope getEnvelope() throws DataException {
731
                this.open();
732 32880 jjdelcerro
                String defaultGeometryAttributeName;
733
                defaultGeometryAttributeName = this.getFeatureStore()
734
                        .getDefaultFeatureType()
735
                                .getDefaultGeometryAttributeName();
736
                if( defaultGeometryAttributeName != null ) {
737
                        return this.helper.getFullEnvelopeOfField(
738
                                        this.getJDBCParameters(),
739
                                        defaultGeometryAttributeName,
740
                                        this.getJDBCParameters().getWorkingArea()
741
                                );
742
                }
743
                return null;
744 28784 jmvivo
        }
745
746
        public void resourceChanged(ResourceProvider resource) {
747 29326 jmvivo
                this.getStoreServices().notifyChange(
748
                                DataStoreNotification.RESOURCE_CHANGED,
749 28784 jmvivo
                                resource);
750
        }
751
752
        public boolean allowAutomaticValues() {
753 28948 jmvivo
                return this.helper.allowAutomaticValues();
754 28784 jmvivo
        }
755
756
        public DataServerExplorer getExplorer() throws ReadException {
757
                DataManager manager = DALLocator.getDataManager();
758
                JDBCServerExplorerParameters exParams;
759 29326 jmvivo
                JDBCStoreParameters params = getJDBCParameters();
760 28784 jmvivo
                try {
761
                        exParams = (JDBCServerExplorerParameters) manager
762
                                        .createServerExplorerParameters(JDBCServerExplorer.NAME);
763
                        exParams.setHost(params.getHost());
764
                        exParams.setPort(params.getPort());
765
                        exParams.setDBName(params.getDBName());
766
                        exParams.setUser(params.getUser());
767
                        exParams.setPassword(params.getPassword());
768 28909 jmvivo
                        exParams.setUrl(params.getUrl());
769 28784 jmvivo
                        exParams.setCatalog(params.getCatalog());
770
                        exParams.setSchema(params.getSchema());
771
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
772
773 32880 jjdelcerro
                        return manager.openServerExplorer(JDBCServerExplorer.NAME,exParams);
774 28784 jmvivo
                } catch (DataException e) {
775 33717 jjdelcerro
                        throw new ReadException(this.getProviderName(), e);
776 28784 jmvivo
                } catch (ValidateDataParametersException e) {
777 33717 jjdelcerro
                        throw new ReadException(this.getProviderName(), e);
778 28784 jmvivo
                }
779
        }
780
781 31284 cordinyana
        @Override
782
        protected void doDispose() throws BaseException {
783 28784 jmvivo
                this.close();
784
                resulsetList = null;
785
                this.helper.dispose();
786 31890 cordinyana
                super.doDispose();
787 28784 jmvivo
        }
788
789
        public Object createNewOID() {
790
                return null;
791
        }
792
793
        public String compoundSelect(FeatureType type, String filter, String order,
794
                        long limit, long offset) throws DataException {
795
                StringBuilder sql = new StringBuilder();
796 29326 jmvivo
                JDBCStoreParameters params = getJDBCParameters();
797 28784 jmvivo
                if (directSQLMode) {
798
                        if (filter != null || order != null) {
799
                                throw new UnsupportedOperationException();
800
                        }
801
                        sql.append(params.getSQL());
802
                        sql.append(' ');
803
                } else {
804
                        FeatureAttributeDescriptor[] fields = type
805
                                        .getAttributeDescriptors();
806
807
                        // Select
808
                        sql.append("Select ");
809
                        for (int i = 0; i < fields.length - 1; i++) {
810
                                sql.append(helper.getSqlFieldName(fields[i]));
811
                                sql.append(", ");
812
                        }
813
                        sql.append(helper.getSqlFieldName(fields[fields.length - 1]));
814
                        sql.append(' ');
815
816 29326 jmvivo
                        FeatureAttributeDescriptor[] pkFields = getStoreServices()
817 28784 jmvivo
                                        .getProviderFeatureType(type.getId()).getPrimaryKey();
818
819
                        if (pkFields != null && pkFields.length > 0) {
820
                                // checks for pk fields are in select
821
                                boolean toAdd;
822
                                for (int i = 0; i < pkFields.length; i++) {
823
                                        toAdd = true;
824
                                        for (int j = 0; j < fields.length; j++) {
825
                                                if (pkFields[i].getName().equals(fields[j].getName())) {
826
                                                        toAdd = false;
827
                                                        break;
828
                                                }
829
                                                if (toAdd) {
830
                                                        sql.append(", ");
831
                                                        sql.append(helper.getSqlFieldName(pkFields[i]));
832
                                                }
833
                                        }
834
                                }
835
                                sql.append(' ');
836
                        }
837
838
                        // table
839
                        sql.append("from ");
840
                        sql.append(params.tableID());
841
                        sql.append(' ');
842
843
                        // Where
844
                        appendWhere(sql, filter);
845
846
                        // Order
847 32880 jjdelcerro
                        if ((params.getBaseOrder() != null && params.getBaseOrder()
848 28784 jmvivo
                                        .length() != 0)
849
                                        || (order != null && order.length() != 0)) {
850
                                sql.append("order by ");
851
852
                                if (order != null && order.length() != 0) {
853
                                        // order
854
                                        sql.append(order);
855
                                } else {
856
                                        // initial order
857 32880 jjdelcerro
                                        sql.append(params.getBaseOrder());
858 28784 jmvivo
                                }
859
                                sql.append(' ');
860
                        }
861
                }
862
                // limit offset
863 31128 cordinyana
                if (limit > 0 || offset > 0) {
864 28784 jmvivo
                        sql.append(helper.compoundLimitAndOffset(limit,offset));
865
                }
866
                return sql.toString();
867
        }
868
869
        public long getFeatureCount() throws DataException {
870
                return getCount(null);
871
        }
872
873 33717 jjdelcerro
        public String getProviderName() {
874 28784 jmvivo
                return NAME;
875
        }
876
877 29289 jmvivo
        public boolean hasGeometrySupport() {
878 28784 jmvivo
                return false;
879
        }
880
881
        public FeatureSetProvider createSet(FeatureQuery query,
882
                        FeatureType featureType) throws DataException {
883
884
                return new JDBCSetProvider(this, query, featureType);
885
        }
886
887
        public Object getSourceId() {
888 29326 jmvivo
                return this.getJDBCParameters().getSourceId();
889 28784 jmvivo
        }
890 33717 jjdelcerro
891
        public String getName() {
892
                return this.getJDBCParameters().tableID();
893
        }
894 31022 cordinyana
895 33717 jjdelcerro
        public String getFullName() {
896
                return this.getJDBCParameters().getHost()+":"+this.getJDBCParameters().getDBName()+":"+this.getJDBCParameters().tableID();
897
        }
898
899
900 31022 cordinyana
        public ResourceProvider getResource() {
901
                return getHelper().getResource();
902
        }
903
}