Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc / JDBCStoreProvider.java @ 40559

History | View | Annotate | Download (24.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/* gvSIG. Geographic Information System of the Valencian Government
25
*
26
* Copyright (C) 2007-2008 Infrastructures and Transports Department
27
* of the Valencian Government (CIT)
28
*
29
* This program is free software; you can redistribute it and/or
30
* modify it under the terms of the GNU General Public License
31
* as published by the Free Software Foundation; either version 2
32
* of the License, or (at your option) any later version.
33
*
34
* This program is distributed in the hope that it will be useful,
35
* but WITHOUT ANY WARRANTY; without even the implied warranty of
36
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
* GNU General Public License for more details.
38
*
39
* You should have received a copy of the GNU General Public License
40
* along with this program; if not, write to the Free Software
41
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
42
* MA  02110-1301, USA.
43
*
44
*/
45

    
46
/*
47
* AUTHORS (In addition to CIT):
48
* 2009 IVER T.I   {{Task}}
49
*/
50

    
51
/**
52
 *
53
 */
54
package org.gvsig.fmap.dal.store.jdbc;
55

    
56
import java.security.InvalidParameterException;
57
import java.sql.Connection;
58
import java.sql.PreparedStatement;
59
import java.sql.ResultSet;
60
import java.sql.SQLException;
61
import java.sql.Statement;
62
import java.util.ArrayList;
63
import java.util.Collections;
64
import java.util.Iterator;
65
import java.util.List;
66

    
67
import org.cresques.cts.IProjection;
68
import org.gvsig.fmap.dal.DALLocator;
69
import org.gvsig.fmap.dal.DataManager;
70
import org.gvsig.fmap.dal.DataServerExplorer;
71
import org.gvsig.fmap.dal.DataStore;
72
import org.gvsig.fmap.dal.DataStoreNotification;
73
import org.gvsig.fmap.dal.DataTypes;
74
import org.gvsig.fmap.dal.exception.CloseException;
75
import org.gvsig.fmap.dal.exception.DataException;
76
import org.gvsig.fmap.dal.exception.InitializeException;
77
import org.gvsig.fmap.dal.exception.OpenException;
78
import org.gvsig.fmap.dal.exception.ReadException;
79
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
80
import org.gvsig.fmap.dal.feature.EditableFeatureType;
81
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
82
import org.gvsig.fmap.dal.feature.FeatureQuery;
83
import org.gvsig.fmap.dal.feature.FeatureType;
84
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
85
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
86
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
87
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
88
import org.gvsig.fmap.dal.resource.ResourceAction;
89
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
90
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
91
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
92
import org.gvsig.fmap.dal.store.db.DBHelper;
93
import org.gvsig.fmap.dal.store.db.FeatureTypeHelper;
94
import org.gvsig.fmap.dal.store.jdbc.exception.InvalidResultSetIdException;
95
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
96
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
97
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
98
import org.gvsig.fmap.geom.Geometry;
99
import org.gvsig.fmap.geom.GeometryLocator;
100
import org.gvsig.fmap.geom.GeometryManager;
101
import org.gvsig.fmap.geom.primitive.Envelope;
102
import org.gvsig.tools.dynobject.DynObject;
103
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
104
import org.gvsig.tools.exception.BaseException;
105
import org.slf4j.Logger;
106
import org.slf4j.LoggerFactory;
107

    
108

    
109
/**
110
 * @author jmvivo
111
 *
112
 */
113
public class JDBCStoreProvider extends AbstractFeatureStoreProvider
114
                implements JDBCHelperUser {
115

    
116
        final static private Logger logger = LoggerFactory
117
                        .getLogger(JDBCStoreProvider.class);
118

    
119
        private List<ResultSetInfo> resulsetList;
120

    
121
        public static String NAME = "JDBC";
122
        public static String DESCRIPTION = "JDBC source";
123

    
124
        public static final String METADATA_DEFINITION_NAME = NAME;
125

    
126
        private long mlsecondsToZombie = 1000 * 60 * 10; // 10 Min
127

    
128
        protected JDBCHelper helper;
129

    
130
        protected boolean directSQLMode;
131

    
132
        private Long totalCount = null;
133
        private GeometryManager geomManager = null;
134

    
135
        public JDBCStoreProvider(JDBCStoreParameters params,
136
                        DataStoreProviderServices storeServices) throws InitializeException {
137
                this(
138
                                params, 
139
                                storeServices,
140
                                DBHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
141
                );
142
        }
143

    
144
        protected JDBCStoreProvider(JDBCStoreParameters params,
145
                        DataStoreProviderServices storeServices, DynObject metadata)
146
                        throws InitializeException {
147
                super(params, storeServices, metadata);
148
                geomManager = GeometryLocator.getGeometryManager();
149
                
150
                resulsetList = new ArrayList<ResultSetInfo>(10);
151

    
152
                helper = createHelper();
153
                if (params.getSQL() != null && (params.getSQL()).trim().length() > 0) {
154
                        directSQLMode = true;
155
                }
156

    
157
                this.initFeatureType();
158
        }
159

    
160
        public Object getDynValue(String name) throws DynFieldNotFoundException {
161
                try {
162
                        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
163
                                Envelope env = this.getEnvelope();
164
                                if( env != null ) {
165
                                        return env;
166
                                }
167
                        } else if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
168
                                IProjection proj;
169
                                proj = this.getFeatureStore().getDefaultFeatureType().getDefaultSRS();
170
                                if( proj != null ) {
171
                                        return proj;
172
                                }
173
                        }
174
                } catch (DataException e) {
175
                        throw new RuntimeException(e);
176
                }
177
                return super.getDynValue(name);
178
        }
179
        
180

    
181
        protected JDBCStoreParameters getJDBCParameters() {
182
                return (JDBCStoreParameters) this.getParameters();
183
        }
184

    
185

    
186
        /**
187
         * Load data form a resulset.<br>
188
         *
189
         * <strong>Note:</strong><br>
190
         * this method have to perform <code>resouceBegin</code> at the begining and
191
         * <code>resourceEnd</code> at the end of execution.
192
         *
193
         *
194
         * @param data
195
         * @param resulsetID
196
         *
197
         * @return
198
         * @throws DataException
199
         */
200
        public void loadFeatureProvider(final FeatureProvider data, final int resultsetID)
201
                        throws DataException {
202
                getResource().execute(new ResourceAction() {
203
                        public Object run() throws Exception {
204
                                ResultSet rs = getResultSet(resultsetID);
205
                                FeatureAttributeDescriptor attr;
206
                                Iterator<FeatureAttributeDescriptor> iter = FeatureTypeHelper.iterator(data.getType());
207
                                while (iter.hasNext()) {
208
                                        attr = iter.next();
209
                                        loadFeatureProviderValue(data, rs, attr);
210
                                }
211
                                return null;
212
                        }
213
                });
214
        }
215

    
216
        protected void loadFeatureProviderValue(FeatureProvider data, ResultSet rs,
217
                        FeatureAttributeDescriptor attr) throws DataException {
218
                if (attr.getType() == DataTypes.GEOMETRY) {
219
                        byte[] buffer;
220
                        try {
221
                                buffer = rs.getBytes(attr.getIndex() + 1);
222
                                if (buffer == null) {
223
                                        data.set(attr.getIndex(), null);
224
                                } else {
225
                                        data.set(attr.getIndex(), this.helper.getGeometry(buffer));
226
                                }
227
                        } catch (SQLException e) {
228
                                throw new JDBCSQLException(e);
229
                        } catch (BaseException e) {
230
                                throw new ReadException(getProviderName(), e);
231
                        }
232

    
233
                } else {
234
                        try {
235
                                data.set(attr.getIndex(), rs.getObject(attr.getIndex() + 1));
236
                        } catch (SQLException e) {
237
                                throw new JDBCSQLException(e);
238
                        }
239
                }
240
        }
241

    
242
        public long getTimeToResulSetZombie() {
243
                return mlsecondsToZombie;
244
        }
245

    
246
        public void setTimeToResulSetZombie(long mlSeconds) {
247
                mlsecondsToZombie = mlSeconds;
248
        }
249

    
250
        private class ResultSetInfo{
251
                private ResultSet resultSet = null;
252
                private long lastUse = 0;
253

    
254
                public ResultSetInfo(ResultSet resulSet) {
255
                        this.resultSet = resulSet;
256
                        used();
257
                }
258

    
259
                private void used() {
260
                        lastUse = System.currentTimeMillis();
261
                }
262

    
263

    
264
                public ResultSet get() {
265
                        used();
266
                        return resultSet;
267
                }
268

    
269
                public boolean isZombie() {
270
                        return System.currentTimeMillis() - lastUse > mlsecondsToZombie;
271
                }
272
        }
273

    
274
        public final int createResultSet(String sql, int fetchSize)
275
                        throws DataException {
276
        return createResultSet(sql, null, fetchSize);
277
        }
278

    
279
        public final int createResultSet(final String sql, final Object[] values,
280
                        final int fetchSize)
281
                        throws DataException {
282
                logger.debug("Creating resultSet with sql: {}", sql);
283
                synchronized (this) {
284
                        checksResulsets();
285
                        return ((Integer) getResource().execute(new ResourceAction() {
286
                                public Object run() throws Exception {
287
                                        ResultSetInfo newRs =
288
                                                        new ResultSetInfo(createNewResultSet(sql, values,
289
                                                                        fetchSize));
290
                                        int newId = getNewId();
291
                                        if (newId < 0) {
292
                                                newId = resulsetList.size();
293
                                                resulsetList.add(newRs);
294
                                        } else {
295
                                                resulsetList.set(newId, newRs);
296
                                        }
297
                                        logger.debug("Created resultset id: {} (total open: {})",
298
                                                        newId, getResultsetOpenCount());
299

    
300
                                        return Integer.valueOf(newId);
301
                                }
302
                        })).intValue();
303
                }
304
        }
305

    
306
        private int getNewId() {
307
                int newId;
308
                if (resulsetList.size() < 1) {
309
                        return -1;
310
                }
311
                for (newId = 0; newId < resulsetList.size(); newId++) {
312
                        if (resulsetList.get(newId) == null) {
313
                                return newId;
314
                        }
315
                }
316
                return -1;
317
        }
318

    
319
        protected final void forceCloseAllResultSet()
320
                        throws ResourceExecuteException,
321
                        JDBCException {
322
                synchronized (this) {
323
                        // FIXME: Esto no deberia funcionar. 
324
                        Iterator iter = resulsetList.iterator();
325
                        Integer rsID = null;
326
                        while (iter.hasNext()) {
327
                                rsID = (Integer) iter.next();
328
                                if (rsID != null) {
329
                                        try {
330
                                                forceCloseResultSet(rsID.intValue());
331
                                        } catch (InvalidResultSetIdException e) {
332
                                                continue;
333
                                        }
334
                                }
335
                                iter.remove();
336
                        }
337

    
338
                }
339
        }
340
        
341
        protected final void forceCloseResultSet(int rsID)
342
                        throws ResourceExecuteException, JDBCException,
343
                        InvalidResultSetIdException {
344
                logger.warn("Close forced of resultSet ({})", rsID);
345
                closeResulset(rsID);
346
        }
347

    
348
        protected final ResultSet getResultSet(int resultsetID)
349
                        throws InvalidResultSetIdException {
350
                if (resultsetID >= resulsetList.size()) {
351
                        throw new InvalidResultSetIdException(resultsetID);
352
                }
353
                ResultSetInfo rsInfo = resulsetList.get(resultsetID);
354
                if (rsInfo == null) {
355
                        throw new InvalidResultSetIdException(resultsetID);
356
                }
357
                return rsInfo.get();
358

    
359
        }
360

    
361
        private ResultSet dropResultSet(int resultsetID)
362
                        throws InvalidResultSetIdException {
363
                if (resultsetID >= resulsetList.size()) {
364
                        throw new InvalidResultSetIdException(resultsetID);
365
                }
366
                ResultSetInfo rsInfo = (ResultSetInfo) resulsetList.get(resultsetID);
367
                if (rsInfo == null) {
368
                        throw new InvalidResultSetIdException(resultsetID);
369
                }
370
                if (resultsetID == resulsetList.size() - 1) {
371
                        resulsetList.remove(resultsetID);
372
                } else {
373
                        resulsetList.set(resultsetID, null);
374
                }
375
                return rsInfo.get();
376
        }
377

    
378

    
379
        public final boolean resulsetNext(final int resultsetID)
380
                        throws JDBCException,
381
                        InvalidResultSetIdException, ResourceExecuteException {
382
                return ((Boolean) getResource().execute(new ResourceAction() {
383
                        public Object run() throws Exception {
384
                            boolean bool = getResultSet(resultsetID).next();
385
                                return Boolean.valueOf(bool);
386
                        }
387
                })).booleanValue();
388
        }
389

    
390
        public final void closeResulset(final int resultsetID)
391
                        throws JDBCException,
392
                        InvalidResultSetIdException, ResourceExecuteException {
393
                synchronized (this) {
394
                        getResource().execute(new ResourceAction() {
395
                                public Object run() throws Exception {
396
                                        ResultSet rs = dropResultSet(resultsetID);
397
                                        closeResulset(rs);
398
                                        return null;
399
                                }
400
                        });
401
                        if (logger.isDebugEnabled()) {
402
                                logger.debug(" id: " + resultsetID + " (total "
403
                                                + getResultsetOpenCount() + ")");
404
                        }
405
                        checksResulsets();
406
                }
407
        }
408

    
409
        public final void checksResulsets() throws JDBCException,
410
                        InvalidResultSetIdException, ResourceExecuteException {
411
                synchronized (this) {
412
                        getResource().execute(new ResourceAction() {
413
                                public Object run() throws Exception {
414
                                        ResultSetInfo rsInfo;
415
                                        for (int i = 0; i < resulsetList.size(); i++) {
416
                                                rsInfo = (ResultSetInfo) resulsetList.get(i);
417
                                                if (rsInfo == null) {
418
                                                        continue;
419
                                                }
420
                                                if (rsInfo.isZombie()) {
421
                                                        forceCloseResultSet(i);
422
                                                }
423
                                        }
424
                                        return null;
425
                                }
426
                        });
427
                }
428
        }
429

    
430
        protected void closeResulset(final ResultSet rs) throws JDBCException,
431
                        ResourceExecuteException {
432
                getResource().execute(new ResourceAction() {
433
                        public Object run() throws Exception {
434
                                Statement st = rs.getStatement();
435
                                Connection con = st.getConnection();
436
                                try {
437
                                        rs.close();
438
                                } finally {
439
                                        // TODO revisar esto
440
                                        try{ st.close();  } catch (Exception ex){ };
441
                                        try{ con.close(); } catch (Exception ex){ };
442
                                }
443
                                return null;
444
                        }
445
                });
446
        }
447

    
448
        private int getResultsetOpenCount() {
449
                int count = 0;
450
                Iterator<ResultSetInfo> iter = resulsetList.iterator();
451
                while (iter.hasNext()) {
452
                        if (iter.next() != null) {
453
                                count++;
454
                        }
455
                }
456
                return count;
457
        }
458

    
459
        protected final int openResulsetCount() {
460
                int count = 0;
461
                Iterator<ResultSetInfo> iter = resulsetList.iterator();
462
                while (iter.hasNext()) {
463
                        if (iter.next() != null) {
464
                                count++;
465
                        }
466
                }
467
                return count;
468
        }
469

    
470
        public boolean closeResourceRequested(ResourceProvider resource) {
471
                try {
472
                        checksResulsets();
473
                        return openResulsetCount() == 0 && closeResource(resource);
474
                } catch (DataException e) {
475
                        logger.error("Exception throws", e);
476
                        return false;
477
                }
478
        }
479

    
480

    
481
        protected String fixFilter(String filter) {
482
                if (filter == null) {
483
                        return null;
484
                }
485

    
486
                return filter;
487
        }
488

    
489
        protected JDBCHelper createHelper() throws InitializeException {
490
                return new JDBCHelper(this, getJDBCParameters());
491
        }
492

    
493
        protected JDBCHelper getHelper() {
494
                return helper;
495
        }
496

    
497
        protected void resetCount() {
498
                totalCount = null;
499
        }
500

    
501
        /**
502
         * Get feature count for a <code>filter</code>.<br>
503
         *
504
         * <code>filter</code> can be <code>null</code>.<br>
505
         *
506
         * <strong>Note:</strong><br>
507
         * this method have to perform <code>resouceBegin</code> at the begining and
508
         * <code>resourceEnd</code> at the end of execution.
509
         *
510
         *
511
         * @param filter
512
         * @return
513
         * @throws DataException
514
         */
515
        protected long getCount(String filter)
516
                        throws DataException {
517
                this.open();
518
                if (filter == null && totalCount != null) {
519
                        return totalCount.longValue();
520
                }
521
                final String sql = compoundCountSelect(filter);
522

    
523
                long count = ((Long) getResource().execute(new ResourceAction() {
524
                        public Object run() throws Exception {
525
                                long count = 0;
526
                                ResultSet rs = createNewResultSet(sql, null, 1);
527
                                try {
528
                                        if (rs.next()) {
529
                                                count = rs.getLong(1);
530
                                        }
531
                                } catch (SQLException e) {
532
                                        throw new JDBCSQLException(e);
533
                                } finally {
534
                                        closeResulset(rs);
535
                                }
536
                                return Long.valueOf(count);
537
                        }
538
                })).longValue();
539

    
540
                if (filter == null) {
541
                        totalCount = new Long(count);
542
                }
543
                return count;
544
        }
545

    
546
        public void close() throws CloseException {
547
                helper.close();
548
        }
549

    
550
        public void open() throws OpenException {
551
                helper.open();
552
        }
553

    
554
        @Override
555
        protected FeatureProvider internalGetFeatureProviderByReference(
556
                        FeatureReferenceProviderServices reference) throws DataException {
557
                return internalGetFeatureProviderByReference(reference,
558
                                getFeatureStore()
559
                                .getDefaultFeatureType());
560
        }
561

    
562
        @Override
563
        protected FeatureProvider internalGetFeatureProviderByReference(
564
                        FeatureReferenceProviderServices reference,
565
                        FeatureType featureType)
566
                        throws DataException {
567
                StringBuilder filter = new StringBuilder();
568
                FeatureAttributeDescriptor[] pk =
569
                                getFeatureStore().getFeatureType(featureType.getId())
570
                                                .getPrimaryKey();
571

    
572
                List<Object> values = new ArrayList<Object>();
573

    
574
                int i;
575
                for (i = 0; i < pk.length - 1; i++) {
576
                        values.add(
577
                                        helper.dalValueToJDBC(pk[i],
578
                                        reference.getKeyValue(pk[i].getName())));
579
                        filter.append(helper.getSqlFieldName(pk[i]));
580
                        filter.append(" = ? AND ");
581
                }
582
                values.add(helper.dalValueToJDBC(pk[i],
583
                                reference.getKeyValue(pk[i].getName())));
584
                filter.append(helper.getSqlFieldName(pk[i]));
585
                filter.append(" = ? ");
586

    
587
                String sql = compoundSelect(featureType, filter.toString(), null, 1, 0);
588

    
589
                FeatureProvider data;
590
                int rsId = createResultSet(sql, values.toArray(), 1);
591
                try {
592
                        if (!resulsetNext(rsId)) {
593
                                throw new RuntimeException("Reference Not found");
594
                        }
595
                        data = createFeatureProvider(featureType);
596
                        loadFeatureProvider(data, rsId);
597
                } finally {
598
                        closeResulset(rsId);
599
                }
600

    
601
                return data;
602
        }
603

    
604
        public int getOIDType() {
605
                return DataTypes.UNKNOWN;
606
        }
607

    
608
        protected void initFeatureType() throws InitializeException {
609

    
610
                EditableFeatureType edFType = null;
611
                try {
612
                        edFType = this.getStoreServices().createFeatureType();
613

    
614
                        helper.loadFeatureType(edFType, getJDBCParameters());
615

    
616
                } catch (DataException e) {
617
                        throw new InitializeException(this.getProviderName(), e);
618
                }
619

    
620
                FeatureType defaultType = edFType.getNotEditableCopy();
621
                List<FeatureType> types = Collections.singletonList(defaultType);
622
                this.getStoreServices().setFeatureTypes(types, defaultType);
623
        }
624

    
625
        protected ResultSet createNewResultSet(final String sql,
626
                        final Object[] values, final int fetchSize)
627
                        throws DataException {
628
                this.open();
629
                return (ResultSet) getResource().execute(new ResourceAction() {
630
                        public Object run() throws Exception {
631
                                Connection conn = null;
632
                                PreparedStatement st = null;
633
                                ResultSet rs = null;
634
                                try {
635

    
636
                                        conn = helper.getConnection();
637
                                        conn.setAutoCommit(false);
638
                                        st = conn.prepareStatement(sql);
639

    
640
                                        if (values != null) {
641
                                                Object value;
642
                                                for (int i = 0; i < values.length; i++) {
643
                                                        value = values[i];
644
                                                        if (value instanceof Geometry) {
645
                                                                byte[] bytes;
646
                                                                try {
647
                                                                        bytes = ((Geometry) value).convertToWKB();
648
                                                                } catch (BaseException e) {
649
                                                                        throw new InvalidParameterException();
650
                                                                }
651
                                                                st.setBytes(i + 1, bytes);
652
                                                        }
653
                                                        st.setObject(i + 1, value);
654
                                                }
655
                                        }
656

    
657
                                        if (fetchSize > 0) {
658
                                                st.setFetchSize(fetchSize);
659
                                        }
660
                                        rs = st.executeQuery();
661
                                        if (fetchSize > 0) {
662
                                                rs.setFetchSize(fetchSize);
663
                                        }
664
                                        return rs;
665
                                } catch (SQLException e) {
666
                                        try {
667
                                                rs.close();
668
                                        } catch (Exception e1) {
669
                                        }
670
                                        try {
671
                                                st.close();
672
                                        } catch (Exception e1) {
673
                                        }
674
                                        try {
675
                                                conn.close();
676
                                        } catch (Exception e1) {
677
                                        }
678
                                        throw new JDBCExecutePreparedSQLException(sql,values,e);
679
                                }
680
                        }
681
                });
682
        }
683

    
684
        protected boolean closeResource(ResourceProvider resource) {
685
                try {
686
                        this.helper.close();
687
                } catch (CloseException e) {
688
                        logger.error("Exception in close Request", e);
689
                }
690
                return !this.helper.isOpen();
691
        }
692

    
693
        protected String compoundCountSelect(String filter) {
694
                if (this.directSQLMode) {
695
                        return null;
696
                }
697
                // Select
698
                StringBuilder sql = new StringBuilder();
699
                sql.append("Select count(");
700
                String[] pkFields = getJDBCParameters().getPkFields();
701
                if (pkFields != null && pkFields.length == 1) {
702
                        sql.append(helper.escapeFieldName(pkFields[0]));
703
                } else {
704
                        sql.append('*');
705

    
706
                }
707
                sql.append(") ");
708

    
709
                sql.append("from ");
710

    
711
                sql.append(getJDBCParameters().tableID());
712
                sql.append(' ');
713

    
714
                appendWhere(sql, filter);
715

    
716
                return sql.toString();
717
        }
718

    
719
        protected void appendWhere(StringBuilder sql, String filter) {
720
                filter = fixFilter(filter);
721
                String initialFilter = getJDBCParameters().getBaseFilter();
722
                if ((initialFilter != null && initialFilter.length() != 0)
723
                                || (filter != null && filter.length() != 0)) {
724
                        sql.append("where (");
725

    
726
                        if (initialFilter != null && initialFilter.length() != 0
727
                                        && filter != null && filter.length() != 0) {
728
                                // initialFilter + filter
729
                                sql.append('(');
730
                                sql.append(initialFilter);
731
                                sql.append(") and (");
732
                                sql.append(filter);
733
                                sql.append(')');
734
                        } else if (initialFilter != null && initialFilter.length() != 0) {
735
                                // initialFilter only
736
                                sql.append(initialFilter);
737
                        } else {
738
                                // filter only
739
                                sql.append(filter);
740
                        }
741
                        sql.append(") ");
742
                }
743
        }
744

    
745
        public void closeDone() throws DataException {
746
                // Do nothing
747
        }
748

    
749
        public void opendDone() throws DataException {
750
                // Nothing to do
751
        }
752

    
753
        public Envelope getEnvelope() throws DataException {
754
                this.open();
755
                String defaultGeometryAttributeName;
756
                defaultGeometryAttributeName = this.getFeatureStore()
757
                        .getDefaultFeatureType()
758
                                .getDefaultGeometryAttributeName();
759
                if( defaultGeometryAttributeName != null ) {
760
                        return this.helper.getFullEnvelopeOfField(
761
                                        this.getJDBCParameters(),
762
                                        defaultGeometryAttributeName, 
763
                                        this.getJDBCParameters().getWorkingArea()
764
                                );
765
                }
766
                return null;
767
        }
768

    
769
        public void resourceChanged(ResourceProvider resource) {
770
                this.getStoreServices().notifyChange(
771
                                DataStoreNotification.RESOURCE_CHANGED,
772
                                resource);
773
        }
774

    
775
        public boolean allowAutomaticValues() {
776
                return this.helper.allowAutomaticValues();
777
        }
778

    
779
        public DataServerExplorer getExplorer() throws ReadException {
780
                DataManager manager = DALLocator.getDataManager();
781
                JDBCServerExplorerParameters exParams;
782
                JDBCStoreParameters params = getJDBCParameters();
783
                try {
784
                        exParams = (JDBCServerExplorerParameters) manager
785
                                        .createServerExplorerParameters(JDBCServerExplorer.NAME);
786
                        exParams.setHost(params.getHost());
787
                        exParams.setPort(params.getPort());
788
                        exParams.setDBName(params.getDBName());
789
                        exParams.setUser(params.getUser());
790
                        exParams.setPassword(params.getPassword());
791
                        exParams.setUrl(params.getUrl());
792
                        exParams.setCatalog(params.getCatalog());
793
                        exParams.setSchema(params.getSchema());
794
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
795

    
796
                        return manager.openServerExplorer(JDBCServerExplorer.NAME,exParams);
797
                } catch (DataException e) {
798
                        throw new ReadException(this.getProviderName(), e);
799
                } catch (ValidateDataParametersException e) {
800
                        throw new ReadException(this.getProviderName(), e);
801
                }
802
        }
803

    
804
        @Override
805
        protected void doDispose() throws BaseException {
806
                this.close();
807
                resulsetList = null;
808
                this.helper.dispose();
809
                super.doDispose();
810
        }
811

    
812
        public Object createNewOID() {
813
                return null;
814
        }
815

    
816
        public String compoundSelect(FeatureType type, String filter, String order,
817
                        long limit, long offset) throws DataException {
818
                StringBuilder sql = new StringBuilder();
819
                JDBCStoreParameters params = getJDBCParameters();
820
                if (directSQLMode) {
821
                        sql.append(params.getSQL());
822
                        sql.append(' ');
823
                } else {
824
                        FeatureAttributeDescriptor[] fields = type
825
                                        .getAttributeDescriptors();
826

    
827
                        // Select
828
                        sql.append("Select ");
829
                        for (int i = 0; i < fields.length - 1; i++) {
830
                                sql.append(helper.getSqlFieldName(fields[i]));
831
                                sql.append(", ");
832
                        }
833
                        sql.append(helper.getSqlFieldName(fields[fields.length - 1]));
834
                        sql.append(' ');
835

    
836
                        FeatureAttributeDescriptor[] pkFields = getStoreServices()
837
                                        .getProviderFeatureType(type.getId()).getPrimaryKey();
838

    
839
                        if (pkFields != null && pkFields.length > 0) {
840
                                // checks for pk fields are in select
841
                                boolean toAdd;
842
                                for (int i = 0; i < pkFields.length; i++) {
843
                                        toAdd = true;
844
                                        for (int j = 0; j < fields.length; j++) {
845
                                                if (pkFields[i].getName().equals(fields[j].getName())) {
846
                                                        toAdd = false;
847
                                                        break;
848
                                                }
849
                                                if (toAdd) {
850
                                                        sql.append(", ");
851
                                                        sql.append(helper.getSqlFieldName(pkFields[i]));
852
                                                }
853
                                        }
854
                                }
855
                                sql.append(' ');
856
                        }
857

    
858
                        // table
859
                        sql.append("from ");
860
                        sql.append(params.tableID());
861
                        sql.append(' ');
862

    
863
                        // Where
864
                        appendWhere(sql, filter);
865

    
866
                        // Order
867
                        if ((params.getBaseOrder() != null && params.getBaseOrder()
868
                                        .length() != 0)
869
                                        || (order != null && order.length() != 0)) {
870
                                sql.append("order by ");
871

    
872
                                if (order != null && order.length() != 0) {
873
                                        // order
874
                                        sql.append(order);
875
                                } else {
876
                                        // initial order
877
                                        sql.append(params.getBaseOrder());
878
                                }
879
                                sql.append(' ');
880
                        }
881
                }
882
                // limit offset
883
                if (limit > 0 || offset > 0) {
884
                        sql.append(helper.compoundLimitAndOffset(limit,offset));
885
                }
886
                return sql.toString();
887
        }
888

    
889
        public long getFeatureCount() throws DataException {
890
                return getCount(null);
891
        }
892

    
893
        public String getProviderName() {
894
                return NAME;
895
        }
896

    
897
        public boolean hasGeometrySupport() {
898
                return false;
899
        }
900

    
901
        public FeatureSetProvider createSet(FeatureQuery query,
902
                        FeatureType featureType) throws DataException {
903

    
904
                return new JDBCSetProvider(this, query, featureType);
905
        }
906

    
907
        public Object getSourceId() {
908
                return this.getJDBCParameters().getSourceId();
909
        }
910
        
911
        public String getName() {
912
                return this.getJDBCParameters().tableID();
913
        }
914
        
915
        public String getFullName() {
916
                return this.getJDBCParameters().getHost()+":"+this.getJDBCParameters().getDBName()+":"+this.getJDBCParameters().tableID();
917
        }
918
        
919

    
920
        public ResourceProvider getResource() {
921
                return getHelper().getResource();
922
        }
923
        
924
        protected boolean isDirectSQLMode(){
925
            return directSQLMode;
926
        }
927
}