Statistics
| Revision:

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

History | View | Annotate | Download (24.5 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.security.InvalidParameterException;
34
import java.sql.Connection;
35
import java.sql.PreparedStatement;
36
import java.sql.ResultSet;
37
import java.sql.SQLException;
38
import java.sql.Statement;
39
import java.util.ArrayList;
40
import java.util.Iterator;
41
import java.util.List;
42

    
43
import org.cresques.cts.IProjection;
44
import org.gvsig.fmap.dal.DALLocator;
45
import org.gvsig.fmap.dal.DataManager;
46
import org.gvsig.fmap.dal.DataServerExplorer;
47
import org.gvsig.fmap.dal.DataStoreNotification;
48
import org.gvsig.fmap.dal.DataTypes;
49
import org.gvsig.fmap.dal.exception.CloseException;
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.exception.InitializeException;
52
import org.gvsig.fmap.dal.exception.OpenException;
53
import org.gvsig.fmap.dal.exception.ReadException;
54
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
55
import org.gvsig.fmap.dal.feature.EditableFeatureType;
56
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.FeatureQuery;
58
import org.gvsig.fmap.dal.feature.FeatureStore;
59
import org.gvsig.fmap.dal.feature.FeatureType;
60
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
61
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
62
import org.gvsig.fmap.dal.feature.spi.FeatureData;
63
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
64
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
65
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
66
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
67
import org.gvsig.fmap.dal.resource.Resource;
68
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
69
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
70
import org.gvsig.fmap.dal.store.jdbc.exception.InvalidResultSetIdException;
71
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
72
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
73
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
74
import org.gvsig.fmap.geom.Geometry;
75
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
76
import org.gvsig.fmap.geom.primitive.Envelope;
77
import org.gvsig.tools.ToolsLocator;
78
import org.gvsig.tools.dynobject.DelegatedDynObject;
79
import org.gvsig.tools.dynobject.DynClass;
80
import org.gvsig.tools.dynobject.DynObjectManager;
81
import org.gvsig.tools.exception.BaseException;
82
import org.gvsig.tools.persistence.PersistenceException;
83
import org.gvsig.tools.persistence.PersistentState;
84
import org.slf4j.Logger;
85
import org.slf4j.LoggerFactory;
86

    
87

    
88
/**
89
 * @author jmvivo
90
 *
91
 */
92
public class JDBCStoreProvider extends AbstractFeatureStoreProvider
93
                implements JDBCHelperUser {
94

    
95
        final static private Logger logger = LoggerFactory
96
                        .getLogger(JDBCStoreProvider.class);
97

    
98
        private List resulsetList;
99

    
100
        public static String NAME = "JDBCStore";
101
        private static final String DYNCLASS_NAME = "JDBCStore";
102
        public static String DESCRIPTION = "JDBC source";
103
        private static DynClass DYNCLASS = null;
104

    
105
        private long mlsecondsToZombie = 1000 * 60 * 10; // 10 Min
106

    
107
        protected JDBCStoreParameters params;
108
        protected JDBCHelper helper;
109

    
110
        protected boolean directSQLMode;
111

    
112
        private Long totalCount = null;
113

    
114

    
115
        public JDBCStoreProvider() {
116
                super();
117
                resulsetList = new ArrayList(10);
118
        }
119

    
120
        public JDBCStoreProvider(JDBCStoreParameters params)
121
                        throws InitializeException {
122
                this();
123
                this.init(params);
124
        }
125

    
126

    
127
        protected static void registerDynClass() {
128
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
129
                DynClass dynClass;
130
                if (DYNCLASS == null) {
131
                        dynClass = dynman.add(DYNCLASS_NAME, DESCRIPTION);
132

    
133
                        dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
134
                        DYNCLASS = dynClass;
135
                }
136
        }
137

    
138
        /**
139
         * Load data form a resulset.<br>
140
         *
141
         * <strong>Note:</strong><br>
142
         * this method have to perform <code>resouceBegin</code> at the begining and
143
         * <code>resourceEnd</code> at the end of execution.
144
         *
145
         *
146
         * @param data
147
         * @param resulsetID
148
         *
149
         * @return
150
         * @throws DataException
151
         */
152
        public void loadFeatureData(FeatureData data, int resultsetID)
153
                        throws DataException {
154
                this.resourceBegin();
155
                try {
156
                        ResultSet rs = getResultSet(resultsetID);
157
                        FeatureAttributeDescriptor attr;
158
                        Iterator iter = data.getType().iterator();
159
                        while (iter.hasNext()) {
160
                                attr = (FeatureAttributeDescriptor) iter.next();
161
                                loadFeatureDataValue(data, rs, attr);
162
                        }
163
                } finally {
164
                        this.resourceEnd();
165
                }
166

    
167

    
168

    
169
        }
170

    
171

    
172
        protected void loadFeatureDataValue(FeatureData data, ResultSet rs,
173
                        FeatureAttributeDescriptor attr) throws DataException {
174
                if (attr.getDataType() == DataTypes.GEOMETRY) {
175
                        byte[] buffer;
176
                        try {
177
                                buffer = rs.getBytes(attr.getIndex() + 1);
178
                                if (buffer == null) {
179
                                        data.set(attr.getIndex(), null);
180
                                } else {
181
                                        data.set(attr.getIndex(), this.helper.getGeometry(buffer));
182
                                }
183
                        } catch (SQLException e) {
184
                                throw new JDBCSQLException(e);
185
                        } catch (BaseException e) {
186
                                throw new ReadException(getName(), e);
187
                        }
188

    
189
                } else {
190
                        try {
191
                                data.set(attr.getIndex(), rs.getObject(attr.getIndex() + 1));
192
                        } catch (SQLException e) {
193
                                throw new JDBCSQLException(e);
194
                        }
195
                }
196
        }
197

    
198
        public long getTimeToResulSetZombie() {
199
                return mlsecondsToZombie;
200
        }
201

    
202
        public void setTimeToResulSetZombie(long mlSeconds) {
203
                mlsecondsToZombie = mlSeconds;
204
        }
205

    
206
        private class ResultSetInfo{
207
                private ResultSet resultSet = null;
208
                private long lastUse = 0;
209

    
210
                public ResultSetInfo(ResultSet resulSet) {
211
                        this.resultSet = resulSet;
212
                        used();
213
                }
214

    
215
                private void used() {
216
                        lastUse = System.currentTimeMillis();
217
                }
218

    
219

    
220
                public ResultSet get() {
221
                        used();
222
                        return resultSet;
223
                }
224

    
225
                public boolean isZombie() {
226
                        return System.currentTimeMillis() - lastUse > mlsecondsToZombie;
227
                }
228
        }
229

    
230
        public final int createResultSet(String sql)
231
                        throws DataException {
232
                return createResultSet(sql, null);
233
        }
234

    
235
        public final int createResultSet(String sql, Object[] values)
236
                        throws DataException {
237
                synchronized (this) {
238
                        checksResulsets();
239
                        resourceBegin();
240
                        try {
241
                                ResultSetInfo newRs = new ResultSetInfo(createNewResultSet(sql,
242
                                                values));
243
                                int newId = getNewId();
244
                                if (newId < 0) {
245
                                        newId = resulsetList.size();
246
                                        resulsetList.add(newRs);
247
                                } else {
248
                                        resulsetList.set(newId, newRs);
249
                                }
250
                                if (logger.isDebugEnabled()) {
251
                                        logger.debug(" id: {} (total {})", newId,
252
                                                        getResultsetOpenCount());
253
                                }
254

    
255
                                return newId;
256
                        } finally {
257
                                resourceEnd();
258
                        }
259

    
260
                }
261
        }
262

    
263
        private int getNewId() {
264
                int newId;
265
                if (resulsetList.size() < 1) {
266
                        return -1;
267
                }
268
                for (newId = 0; newId < resulsetList.size(); newId++) {
269
                        if (resulsetList.get(newId) == null) {
270
                                return newId;
271
                        }
272
                }
273
                return -1;
274
        }
275

    
276
        protected final void forceCloseAllResultSet()
277
                        throws ResourceBeginException,
278
                        JDBCException {
279
                synchronized (this) {
280
                        Iterator iter = resulsetList.iterator();
281
                        Integer rsID = null;
282
                        while (iter.hasNext()) {
283
                                rsID = (Integer) iter.next();
284
                                if (rsID != null) {
285
                                        try {
286
                                                forceCloseResultSet(rsID.intValue());
287
                                        } catch (InvalidResultSetIdException e) {
288
                                                continue;
289
                                        }
290
                                }
291
                                iter.remove();
292
                        }
293

    
294
                }
295
        }
296

    
297
        protected final void forceCloseResultSet(int rsID)
298
                        throws ResourceBeginException, JDBCException,
299
                        InvalidResultSetIdException {
300
                logger.warn("Close forced of resultSet ({})", rsID);
301
                closeResulset(rsID);
302
        }
303

    
304
        protected final ResultSet getResultSet(int resultsetID)
305
                        throws InvalidResultSetIdException {
306
                if (resultsetID >= resulsetList.size()) {
307
                        throw new InvalidResultSetIdException(resultsetID);
308
                }
309
                ResultSetInfo rsInfo = (ResultSetInfo) resulsetList.get(resultsetID);
310
                if (rsInfo == null) {
311
                        throw new InvalidResultSetIdException(resultsetID);
312
                }
313
                return rsInfo.get();
314

    
315
        }
316

    
317
        private ResultSet dropResultSet(int resultsetID)
318
                        throws InvalidResultSetIdException {
319
                if (resultsetID >= resulsetList.size()) {
320
                        throw new InvalidResultSetIdException(resultsetID);
321
                }
322
                ResultSetInfo rsInfo = (ResultSetInfo) resulsetList.get(resultsetID);
323
                if (rsInfo == null) {
324
                        throw new InvalidResultSetIdException(resultsetID);
325
                }
326
                if (resultsetID == resulsetList.size() - 1) {
327
                        resulsetList.remove(resultsetID);
328
                } else {
329
                        resulsetList.set(resultsetID, null);
330
                }
331
                return rsInfo.get();
332
        }
333

    
334

    
335
        public final boolean resulsetNext(int resultsetID) throws JDBCException,
336
                        InvalidResultSetIdException, ResourceBeginException {
337
                ResultSet rs = getResultSet(resultsetID);
338
                resourceBegin();
339
                try {
340
                        return rs.next();
341
                } catch (SQLException e) {
342
                        throw new JDBCSQLException(e);
343
                } finally {
344
                        resourceEnd();
345
                }
346
        }
347

    
348
        public final void closeResulset(int resultsetID)
349
                        throws JDBCException,
350
                        InvalidResultSetIdException, ResourceBeginException {
351
                synchronized (this) {
352
                        resourceBegin();
353
                        try {
354
                                ResultSet rs = dropResultSet(resultsetID);
355
                                closeResulset(rs);
356
                                if (logger.isDebugEnabled()) {
357
                                        logger.debug(" id: " + resultsetID + " (total "
358
                                                        + getResultsetOpenCount() + ")");
359
                                }
360

    
361
                        } finally {
362
                                resourceEnd();
363
                        }
364
                        checksResulsets();
365
                }
366
        }
367

    
368
        public final void checksResulsets() throws JDBCException,
369
                        InvalidResultSetIdException, ResourceBeginException {
370
                synchronized (this) {
371
                        resourceBegin();
372
                        try {
373
                                ResultSetInfo rsInfo;
374
                                for (int i = 0; i < resulsetList.size(); i++) {
375
                                        rsInfo = (ResultSetInfo) resulsetList.get(i);
376
                                        if (rsInfo == null) {
377
                                                continue;
378
                                        }
379
                                        if (rsInfo.isZombie()) {
380
                                                forceCloseResultSet(i);
381
                                        }
382
                                }
383

    
384
                        } finally {
385
                                resourceEnd();
386
                        }
387

    
388
                }
389
        }
390

    
391

    
392
        private int getResultsetOpenCount() {
393
                int count = 0;
394
                Iterator iter = resulsetList.iterator();
395
                while (iter.hasNext()) {
396
                        if (iter.next() != null) {
397
                                count++;
398
                        }
399
                }
400
                return count;
401
        }
402

    
403
        protected void closeResulset(ResultSet rs) throws JDBCException,
404
                        ResourceBeginException {
405
                resourceBegin();
406
                try {
407
                        Statement st = rs.getStatement();
408
                        Connection con = st.getConnection();
409
                        try {
410
                                rs.close();
411
                        } finally {
412
                                // TODO revisar esto
413
                                try{ st.close();  } catch (Exception ex){ };
414
                                try{ con.close(); } catch (Exception ex){ };
415
                        }
416
                } catch (SQLException e) {
417
                        throw new JDBCSQLException(e);
418
                } finally {
419
                        resourceEnd();
420
                }
421

    
422
        }
423

    
424
        protected final int openResulsetCount() {
425
                int count = 0;
426
                Iterator iter = resulsetList.iterator();
427
                while (iter.hasNext()) {
428
                        if (iter.next() != null) {
429
                                count++;
430
                        }
431
                }
432
                return count;
433
        }
434

    
435
        public boolean closeResourceRequested(ResourceProvider resource) {
436
                try {
437
                        checksResulsets();
438
                        return openResulsetCount() == 0 && closeResource(resource);
439
                } catch (DataException e) {
440
                        logger.error("Exception throws", e);
441
                        return false;
442
                }
443
        }
444

    
445

    
446
        protected String fixFilter(String filter) {
447
                if (filter == null) {
448
                        return null;
449
                }
450

    
451
                return filter;
452
        }
453

    
454
        public void init(JDBCStoreParameters params) throws InitializeException {
455
                this.params = params;
456
                helper = createHelper();
457
                if (params.getSQL() != null && (params.getSQL()).trim().length() > 0) {
458
                        directSQLMode = true;
459
                }
460

    
461
                this.dynObject = (DelegatedDynObject) ToolsLocator
462
                                .getDynObjectManager().createDynObject(DYNCLASS);
463

    
464
                this.dynObject.setDynValue("DefaultSRS", null);
465
                this.dynObject.setDynValue("Envelope", null);
466

    
467
        }
468

    
469
        protected JDBCHelper createHelper() throws InitializeException {
470
                return new JDBCHelper(this, params);
471
        }
472

    
473
        protected JDBCHelper getHelper() {
474
                return helper;
475
        }
476

    
477
        protected void resetCount() {
478
                totalCount = null;
479
        }
480

    
481
        /**
482
         * Get feature count for a <code>filter</code>.<br>
483
         *
484
         * <code>filter</code> can be <code>null</code>.<br>
485
         *
486
         * <strong>Note:</strong><br>
487
         * this method have to perform <code>resouceBegin</code> at the begining and
488
         * <code>resourceEnd</code> at the end of execution.
489
         *
490
         *
491
         * @param filter
492
         * @return
493
         * @throws DataException
494
         */
495
        protected long getCount(String filter) throws DataException {
496
                this.open();
497
                if (filter == null && totalCount != null) {
498
                        return totalCount.longValue();
499
                }
500
                long count = 0;
501
                String sql = compoundCountSelect(filter);
502
                resourceBegin();
503
                try {
504
                        ResultSet rs = createNewResultSet(sql, null);
505
                        try {
506
                                if (rs.next()) {
507
                                        count = rs.getLong(1);
508
                                }
509
                        } catch (SQLException e) {
510
                                throw new JDBCSQLException(e);
511
                        } finally {
512
                                closeResulset(rs);
513
                        }
514
                } finally {
515
                        resourceEnd();
516
                }
517
                if (filter == null) {
518
                        totalCount = new Long(count);
519
                }
520
                return count;
521
        }
522

    
523
        public void close() throws CloseException {
524
                helper.close();
525
        }
526

    
527
        public void open() throws OpenException {
528
                helper.open();
529
        }
530

    
531

    
532
        public FeatureData getFeatureDataByReference(
533
                        FeatureReferenceProviderServices reference) throws DataException {
534
                return getFeatureDataByReference(reference, store
535
                                .getDefaultFeatureType());
536
        }
537

    
538
        public FeatureData getFeatureDataByReference(
539
                        FeatureReferenceProviderServices reference, FeatureType featureType)
540
                        throws DataException {
541
                open();
542
                resourceBegin();
543
                try {
544
                        StringBuilder filter = new StringBuilder();
545
                        FeatureAttributeDescriptor[] pk = store.getFeatureType(
546
                                        featureType.getId()).getPrimaryKey();
547

    
548
                        List values = new ArrayList();
549

    
550
                        int i;
551
                        for (i = 0; i < pk.length - 1; i++) {
552
                                values.add(helper.dalValueToJDBC(pk[i], reference
553
                                                .getKeyValue(pk[i].getName())));
554
                                filter.append(helper.getSqlFieldName(pk[i]));
555
                                filter.append(" = ? AND ");
556
                        }
557
                        values.add(helper.dalValueToJDBC(pk[i], reference.getKeyValue(pk[i]
558
                                        .getName())));
559
                        filter.append(helper.getSqlFieldName(pk[i]));
560
                        filter.append(" = ? ");
561

    
562
                        String sql = compoundSelect(featureType, filter.toString(), null,
563
                                        1, 0);
564

    
565
                        FeatureData data;
566
                        int rsId = createResultSet(sql, values.toArray());
567
                        try {
568
                                if (!resulsetNext(rsId)) {
569
                                        // FIXME Exception
570
                                        throw new RuntimeException("Reference Not found");
571
                                }
572
                                data = createFeatureData(featureType);
573
                                loadFeatureData(data, rsId);
574
                        } finally {
575
                                closeResulset(rsId);
576
                        }
577

    
578
                        return data;
579

    
580
                } finally {
581
                        resourceEnd();
582
                }
583

    
584
        }
585

    
586
        public int getFeatureReferenceOIDType() {
587
                return DataTypes.UNKNOWN;
588
        }
589

    
590
        protected void initFeatureType() throws InitializeException {
591

    
592
                EditableFeatureType edFType = null;
593
                try {
594
                        edFType = this.store.createFeatureType();
595

    
596
                        helper.loadFeatureType(edFType, params);
597

    
598
                } catch (DataException e) {
599
                        throw new InitializeException(this.getName(), e);
600
                }
601

    
602
                FeatureType defaultType = edFType.getNotEditableCopy();
603
                List types = new ArrayList(1);
604
                types.add(defaultType);
605
                this.store.setFeatureTypes(types, defaultType);
606
                try {
607
                        loadMetadata();
608
                } catch (DataException e) {
609
                        throw new InitializeException(e);
610
                }
611
        }
612

    
613
        protected ResultSet createNewResultSet(String sql, Object[] values)
614
                        throws DataException {
615
                this.open();
616
                Connection conn = null;
617
                PreparedStatement st = null;
618
                ResultSet rs = null;
619
                this.resourceBegin();
620
                try {
621
                        conn = this.helper.getConnection();
622
                        st = conn.prepareStatement(sql);
623

    
624
                        if (values != null) {
625
                                Object value;
626
                                for (int i = 0; i < values.length; i++) {
627
                                        value = values[i];
628
                                        if (value instanceof Geometry) {
629
                                                byte[] bytes;
630
                                                try {
631
                                                        bytes = (byte[]) ((Geometry) value)
632
                                                                        .invokeOperation(ToWKB.CODE, null);
633
                                                } catch (BaseException e) {
634
                                                        // FIXME
635
                                                        throw new InvalidParameterException();
636
                                                }
637
                                                st.setBytes(i + 1, bytes);
638
                                        }
639
                                        st.setObject(i + 1, value);
640
                                }
641

    
642
                        }
643

    
644
                        try {
645
                                rs = st.executeQuery();
646
                        } catch (SQLException e1) {
647
                                try {st.close();} catch (Exception e2) {};
648
                                try {conn.close();} catch (Exception e2) {}        ;
649
                                throw new JDBCExecuteSQLException(sql, e1);
650
                        }
651
                        rs.setFetchSize(5000); // TODO add to params?
652
                        return rs;
653
                } catch (SQLException e) {
654
                        // TODO throw exception ???
655
                        try {rs.close();} catch (Exception e1) {};
656
                        try {st.close();} catch (Exception e1) {};
657
                        try {conn.close();} catch (Exception e1) {};
658
                        throw new JDBCSQLException(e);
659
                } finally {
660
                        this.resourceEnd();
661
                }
662
        }
663

    
664
        /**
665
         * Permform a {@link Resource#begin()} to the current provider resources.
666
         *
667
         */
668

    
669
        protected void resourceBegin() throws ResourceBeginException {
670
                this.helper.begin();
671

    
672
        }
673

    
674
        /**
675
         * Permform a {@link Resource#end()} to the current provider resources.
676
         */
677

    
678
        protected void resourceEnd() {
679
                this.helper.end();
680
        }
681

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

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

    
704
                }
705
                sql.append(") ");
706

    
707
                sql.append("from ");
708

    
709
                sql.append(params.tableID());
710
                sql.append(' ');
711

    
712
                appendWhere(sql, filter);
713

    
714
                return sql.toString();
715
        }
716

    
717
        protected void appendWhere(StringBuilder sql, String filter) {
718
                filter = fixFilter(filter);
719
                String initialFilter = params.getInitialFilter();
720
                if ((initialFilter != null && initialFilter.length() != 0)
721
                                || (filter != null && filter.length() != 0)) {
722
                        sql.append("where (");
723

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

    
743
        protected void loadMetadata() throws DataException {
744
                IProjection srs = params.getSRS();
745

    
746
                if (srs == null) {
747
                        srs = store.getDefaultFeatureType().getDefaultSRS();
748
                }
749

    
750
                this.dynObject.setDynValue("DefaultSRS", srs);
751

    
752
                String defGeomName = this.store.getDefaultFeatureType()
753
                                .getDefaultGeometryAttributeName();
754
                Envelope env = null;
755
                if (defGeomName != null && defGeomName.length() > 0) {
756
                        env = this.helper.getFullEnvelopeOfField(this.params, defGeomName,
757
                                        this.params.getWorkingArea());
758

    
759
                }
760
                this.dynObject.setDynValue("Envelope", env);
761

    
762
        }
763

    
764
        public void closeDone() throws DataException {
765
                clearMetadata();
766

    
767
        }
768

    
769
        public void opendDone() throws DataException {
770
                // Nothing to do
771
        }
772

    
773
        public Envelope getEnvelope() throws DataException {
774
                this.open();
775
                return (Envelope) this.dynObject.getDynValue("Envelope");
776
        }
777

    
778
        public void resourceChanged(ResourceProvider resource) {
779
                this.store.notifyChange(DataStoreNotification.RESOURCE_CHANGED,
780
                                resource);
781
        }
782

    
783
        protected void clearMetadata() {
784
                this.dynObject.setDynValue("DefaultSRS", null);
785
                this.dynObject.setDynValue("Envelope", null);
786
        }
787

    
788
        public boolean allowAutomaticValues() {
789
                return this.helper.allowAutomaticValues();
790
        }
791

    
792
        public DataServerExplorer getExplorer() throws ReadException {
793
                DataManager manager = DALLocator.getDataManager();
794
                JDBCServerExplorerParameters exParams;
795
                try {
796
                        exParams = (JDBCServerExplorerParameters) manager
797
                                        .createServerExplorerParameters(JDBCServerExplorer.NAME);
798
                        exParams.setHost(params.getHost());
799
                        exParams.setPort(params.getPort());
800
                        exParams.setDBName(params.getDBName());
801
                        exParams.setUser(params.getUser());
802
                        exParams.setPassword(params.getPassword());
803
                        exParams.setUrl(params.getUrl());
804
                        exParams.setCatalog(params.getCatalog());
805
                        exParams.setSchema(params.getSchema());
806
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
807

    
808
                        return manager.createServerExplorer(exParams);
809
                } catch (DataException e) {
810
                        throw new ReadException(this.getName(), e);
811
                } catch (ValidateDataParametersException e) {
812
                        // TODO Auto-generated catch block
813
                        throw new ReadException(this.getName(), e);
814
                }
815
        }
816

    
817
        public void dispose() throws CloseException {
818
                this.close();
819
                resulsetList = null;
820
                this.helper.dispose();
821
                super.dispose();
822
        }
823

    
824
        public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
825
                        throws InitializeException {
826
                super.initialize(store);
827
                this.initFeatureType();
828
                return this;
829
        }
830

    
831
        public Object createNewOID() {
832
                return null;
833
        }
834

    
835
        public String compoundSelect(FeatureType type, String filter, String order,
836
                        long limit, long offset) throws DataException {
837
                StringBuilder sql = new StringBuilder();
838
                if (directSQLMode) {
839
                        if (filter != null || order != null) {
840
                                // FIXME Exception
841
                                throw new UnsupportedOperationException();
842
                        }
843
                        sql.append(params.getSQL());
844
                        sql.append(' ');
845
                } else {
846
                        FeatureAttributeDescriptor[] fields = type
847
                                        .getAttributeDescriptors();
848

    
849
                        // Select
850
                        sql.append("Select ");
851
                        for (int i = 0; i < fields.length - 1; i++) {
852
                                sql.append(helper.getSqlFieldName(fields[i]));
853
                                sql.append(", ");
854
                        }
855
                        sql.append(helper.getSqlFieldName(fields[fields.length - 1]));
856
                        sql.append(' ');
857

    
858
                        FeatureAttributeDescriptor[] pkFields = store
859
                                        .getProviderFeatureType(type.getId()).getPrimaryKey();
860

    
861
                        if (pkFields != null && pkFields.length > 0) {
862
                                // checks for pk fields are in select
863
                                boolean toAdd;
864
                                for (int i = 0; i < pkFields.length; i++) {
865
                                        toAdd = true;
866
                                        for (int j = 0; j < fields.length; j++) {
867
                                                if (pkFields[i].getName().equals(fields[j].getName())) {
868
                                                        toAdd = false;
869
                                                        break;
870
                                                }
871
                                                if (toAdd) {
872
                                                        sql.append(", ");
873
                                                        sql.append(helper.getSqlFieldName(pkFields[i]));
874
                                                }
875
                                        }
876
                                }
877
                                sql.append(' ');
878
                        }
879

    
880
                        // table
881
                        sql.append("from ");
882
                        sql.append(params.tableID());
883
                        sql.append(' ');
884

    
885
                        // Where
886
                        appendWhere(sql, filter);
887

    
888
                        // Order
889
                        if ((params.getInitialOrder() != null && params.getInitialOrder()
890
                                        .length() != 0)
891
                                        || (order != null && order.length() != 0)) {
892
                                sql.append("order by ");
893

    
894
                                if (order != null && order.length() != 0) {
895
                                        // order
896
                                        sql.append(order);
897
                                } else {
898
                                        // initial order
899
                                        sql.append(params.getInitialOrder());
900
                                }
901
                                sql.append(' ');
902
                        }
903
                }
904
                // limit offset
905
                if (limit >= 1 || offset >= 1) {
906
                        sql.append(helper.compoundLimitAndOffset(limit,offset));
907
                }
908
                return sql.toString();
909
        }
910

    
911
        public long getFeatureCount() throws DataException {
912
                return getCount(null);
913
        }
914

    
915
        public PersistentState getState() throws PersistenceException {
916
                // TODO Auto-generated method stub
917
                return null;
918
        }
919

    
920
        public void loadState(PersistentState state) throws PersistenceException {
921
                // TODO Auto-generated method stub
922

    
923
        }
924

    
925
        public void loadFromState(PersistentState state)
926
                        throws PersistenceException {
927
                // TODO Auto-generated method stub
928

    
929
        }
930

    
931
        /*
932
         * (non-Javadoc)
933
         *
934
         * @seeorg.gvsig.tools.persistence.Persistent#saveToState(org.gvsig.tools.
935
         * persistence.PersistentState)
936
         */
937
        public void saveToState(PersistentState state) throws PersistenceException {
938
                // TODO Auto-generated method stub
939

    
940
        }
941

    
942

    
943
        public String getName() {
944
                return NAME;
945
        }
946

    
947
        public Iterator getChilds() {
948
                return null;
949
        }
950

    
951
        public boolean allowWrite() {
952
                return false;
953
        }
954

    
955
        public boolean canWriteGeometry(int geometryType) throws DataException {
956
                return false;
957
        }
958

    
959

    
960
        public void performEditing(Iterator deleteds, Iterator inserteds,
961
                        Iterator updateds, Iterator originalFeatureTypesUpdated)
962
                        throws PerformEditingException {
963
                // FIXME exception
964
                throw new UnsupportedOperationException();
965

    
966
        }
967

    
968
        public boolean supportsAppendMode() {
969
                return false;
970
        }
971

    
972
        public void endAppend() throws DataException {
973
                // FIXME exception
974
                throw new UnsupportedOperationException();
975

    
976
        }
977

    
978
        public void append(FeatureData featureData) throws DataException {
979
                // FIXME exception
980
                throw new UnsupportedOperationException();
981

    
982
        }
983

    
984
        public void beginAppend() throws DataException {
985
                // FIXME exception
986
                throw new UnsupportedOperationException();
987
        }
988

    
989
        public boolean hasGeometrySupport() {
990
                return true;
991
        }
992

    
993
        public FeatureSetProvider createSet(FeatureQuery query,
994
                        FeatureType featureType) throws DataException {
995

    
996
                return new JDBCSetProvider(this, query, featureType);
997
        }
998

    
999
        public Object getSourceId() {
1000
                return this.params.getSourceId();
1001
        }
1002

    
1003
}