Statistics
| Revision:

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

History | View | Annotate | Download (16.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
* MA  02110-1301, USA.
20
*
21
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.jdbc;
32

    
33
import java.sql.Connection;
34
import java.sql.DatabaseMetaData;
35
import java.sql.ResultSet;
36
import java.sql.SQLException;
37
import java.sql.Statement;
38
import java.util.ArrayList;
39
import java.util.Iterator;
40
import java.util.List;
41

    
42
import org.gvsig.fmap.dal.DALLocator;
43
import org.gvsig.fmap.dal.DataManager;
44
import org.gvsig.fmap.dal.DataStore;
45
import org.gvsig.fmap.dal.DataStoreParameters;
46
import org.gvsig.fmap.dal.NewDataStoreParameters;
47
import org.gvsig.fmap.dal.exception.CloseException;
48
import org.gvsig.fmap.dal.exception.DataException;
49
import org.gvsig.fmap.dal.exception.InitializeException;
50
import org.gvsig.fmap.dal.exception.OpenException;
51
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
52
import org.gvsig.fmap.dal.exception.ReadException;
53
import org.gvsig.fmap.dal.exception.RemoveException;
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.FeatureType;
58
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
59
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
60
import org.gvsig.fmap.dal.serverexplorer.db.spi.AbstractDBServerExplorer;
61
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
62
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
63
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
64
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
65
import org.gvsig.tools.exception.BaseException;
66
import org.slf4j.Logger;
67
import org.slf4j.LoggerFactory;
68

    
69

    
70
/**
71
 * @author jmvivo
72
 *
73
 */
74
public class JDBCServerExplorer extends AbstractDBServerExplorer
75
                implements JDBCHelperUser {
76

    
77
        private static final Logger LOG = LoggerFactory
78
                        .getLogger(JDBCServerExplorer.class);
79
        
80
        private static final String METADATA_COLUMN_TABLE_CATALOG = "TABLE_CAT";
81
        private static final String METADATA_COLUMN_TABLE_SCHEMA = "TABLE_SCHEM";
82
        private static final String METADATA_COLUMN_TABLE_NAME = "TABLE_NAME";
83

    
84
        public static final String NAME = "JDBCServerExplorer";
85
        protected JDBCHelper helper;
86

    
87
        private Boolean canAdd;
88

    
89
        public JDBCServerExplorer(JDBCServerExplorerParameters parameters,
90
                        DataServerExplorerProviderServices services)
91
                        throws InitializeException {
92
                super(parameters, services);
93
                this.helper = createHelper();
94
        }
95

    
96
        protected JDBCServerExplorerParameters getJDBCParameters() {
97
                return (JDBCServerExplorerParameters) getParameters();
98
        }
99

    
100
        protected JDBCHelper createHelper() throws InitializeException {
101
                return new JDBCHelper(this, getJDBCParameters());
102
        }
103

    
104
        protected JDBCHelper getHelper() {
105
                return helper;
106
        }
107

    
108

    
109
        public List list() throws DataException {
110
                return this.list(MODE_ALL);
111
        }
112

    
113
        public List list(boolean showInformationDBTables) throws DataException {
114
                return this.list(MODE_ALL, showInformationDBTables);
115
        }
116

    
117
        public List list(int mode) throws DataException {
118
                JDBCServerExplorerParameters parameters = getJDBCParameters();
119
                if (parameters.getShowInformationDBTables() != null) {
120
                        return this.list(mode, parameters.getShowInformationDBTables()
121
                                        .booleanValue());
122
                }
123
                Boolean show = (Boolean) parameters
124
                                .getDynClass()
125
                                .getDynField(
126
                                                JDBCServerExplorerParameters.SHOWINFORMATIONDBTABLES_PARAMTER_NAME)
127
                                .getDefaultValue();
128
                if (show == null){
129
                        show = Boolean.FALSE;
130
                }
131

    
132
                return this.list(mode, show.booleanValue());
133
        }
134

    
135

    
136
        protected DataManagerProviderServices getManager() {
137
                return (DataManagerProviderServices) DALLocator.getDataManager();
138
        }
139

    
140
        public boolean hasGeometrySupport() {
141
                return false;
142
        }
143

    
144
        public boolean closeResourceRequested(ResourceProvider resource) {
145
                try {
146
                        this.helper.close();
147
                } catch (CloseException e) {
148
                        LOG.error("Exception in close Request", e);
149
                }
150
                return !this.helper.isOpen();
151
        }
152

    
153
        public void resourceChanged(ResourceProvider resource) {
154
                // Nothing to do
155
        }
156

    
157
        public void remove(DataStoreParameters dsp) throws RemoveException {
158
                final JDBCStoreParameters dsParams =(JDBCStoreParameters) dsp;
159

    
160
                TransactionalAction action = new TransactionalAction() {
161
                        public boolean continueTransactionAllowed() {
162
                                return false;
163
                        }
164
                        public Object action(Connection conn) throws DataException {
165
                                Statement st;
166
                                try{
167
                                        st = conn.createStatement();
168
                                } catch (SQLException e) {
169
                                        throw new JDBCSQLException(e);
170
                                }
171

    
172
                                String sqlDrop = "Drop table "
173
                                        + dsParams.tableID();
174

    
175
                                try{
176
                                        try{
177
                                                st.execute(sqlDrop);
178
                                        } catch (SQLException e) {
179
                                                throw new JDBCExecuteSQLException(sqlDrop, e);
180
                                        }
181

    
182
                                } finally{
183
                                        try{ st.close(); } catch (SQLException e) {};
184
                                }
185
                                return null;
186
                        }
187
                };
188
                try {
189
                        this.helper.doConnectionAction(action);
190
                } catch (Exception e) {
191
                        throw new RemoveException(this.getProviderName(), e);
192
                }
193
        }
194

    
195
        public NewDataStoreParameters getAddParameters() throws DataException {
196
                JDBCServerExplorerParameters parameters = getJDBCParameters();
197
                JDBCNewStoreParameters params = new JDBCNewStoreParameters();
198
                params.setHost(parameters.getHost());
199
                params.setPort(parameters.getPort());
200
                params.setDBName(parameters.getDBName());
201
                params.setUser(parameters.getUser());
202
                params.setPassword(parameters.getPassword());
203
                params.setCatalog(parameters.getCatalog());
204
                params.setSchema(parameters.getSchema());
205
                params.setJDBCDriverClassName(parameters.getJDBCDriverClassName());
206
                params.setUrl(parameters.getUrl());
207

    
208
                params.setDefaultFeatureType(this.getServerExplorerProviderServices()
209
                                .createNewFeatureType());
210

    
211
                return params;
212
        }
213

    
214
        public void closeDone() throws DataException {
215
                // Nothing to do
216
        }
217

    
218
        public void opendDone() throws DataException {
219
                // Nothin to do
220

    
221
        }
222

    
223
        public DataStore open(DataStoreParameters dsp) throws DataException {
224
                checkIsMine(dsp);
225
                DataManager dataMan = DALLocator.getDataManager();
226
                DataStore store;
227
                try {
228
                        store = dataMan.openStore(dsp.getDataStoreName(), dsp);
229
                } catch (ValidateDataParametersException e) {
230
                        throw new InitializeException(e);
231
                }
232

    
233
                return store;
234
        }
235

    
236
        protected void checkIsMine(DataStoreParameters dsp) {
237
                if (!(dsp instanceof JDBCStoreParameters)) {
238
                        // FIXME Exception ???
239
                        throw new IllegalArgumentException(
240
                                        "not instance of FilesystemStoreParameters");
241
                }
242

    
243
                // try {
244
                // dsp.validate();
245
                // } catch (ValidateDataParametersException e) {
246
                // throw new IllegalArgumentException("check parameters", e);
247
                // }
248

    
249
                JDBCServerExplorerParameters parameters = getJDBCParameters();
250

    
251
                JDBCStoreParameters pgp = (JDBCStoreParameters) dsp;
252
                if (!compare(pgp.getHost(), parameters.getHost())) {
253
                        // FIXME Exception ???
254
                        throw new IllegalArgumentException("wrong explorer: Host (mine: "
255
                                        + parameters.getHost() + " other:" + pgp.getHost() + ")");
256
                }
257
                if (!compare(pgp.getPort(), parameters.getPort())) {
258
                        // FIXME Exception ???
259
                        throw new IllegalArgumentException("wrong explorer: Port (mine: "
260
                                        + parameters.getPort() + " other:" + pgp.getPort() + ")");
261
                }
262
                if (!compare(pgp.getDBName(), parameters.getDBName())) {
263
                        // FIXME Exception ???
264
                        throw new IllegalArgumentException("wrong explorer: DBName (mine: "
265
                                        + parameters.getDBName() + " other:" + pgp.getDBName()
266
                                        + ")");
267
                }
268
                if (parameters.getCatalog() != null && !parameters.getCatalog().trim().equals("")) {
269
                        // implicit catalog
270
                        if (!compare(pgp.getCatalog(), parameters.getCatalog())) {
271
                                // FIXME Exception ???
272
                                throw new IllegalArgumentException(
273
                                                "wrong explorer: Catalog (mine: "
274
                                                                + parameters.getCatalog() + " other:"
275
                                                                + pgp.getCatalog() + ")");
276
                        }
277
                }
278
                if (parameters.getSchema() != null && !parameters.getSchema().trim().equals("")) {
279
                        // implicit schema
280
                        if (!compare(pgp.getSchema(), parameters.getSchema())) {
281
                                // FIXME Exception ???
282
                                throw new IllegalArgumentException(
283
                                                "wrong explorer: Schema (mine: "
284
                                                                + parameters.getSchema() + " other:"
285
                                                                + pgp.getSchema() + ")");
286
                        }
287
                }
288
                if (!compare(pgp.getJDBCDriverClassName(), parameters
289
                                .getJDBCDriverClassName())) {
290
                        // FIXME Exception ???
291
                        throw new IllegalArgumentException(
292
                                        "wrong explorer: JDBCDriverClassName");
293
                }
294
        }
295

    
296
        protected boolean compare(Object str1, Object str2) {
297
                if (str1 == str2){
298
                        return true;
299
                }
300
                if (str1 == null){
301
                        return false;
302
                }
303
                return  str1.equals(str2);
304
        }
305

    
306
        protected JDBCStoreParameters createStoreParams()
307
                        throws InitializeException, ProviderNotRegisteredException {
308
                DataManagerProviderServices manager = this.getManager();
309
                JDBCServerExplorerParameters parameters = getJDBCParameters();
310
                JDBCStoreParameters orgParams = (JDBCStoreParameters) manager
311
                                .createStoreParameters(getStoreName());
312
                orgParams.setHost(parameters.getHost());
313
                orgParams.setPort(parameters.getPort());
314
                orgParams.setDBName(parameters.getDBName());
315
                orgParams.setUser(parameters.getUser());
316
                orgParams.setPassword(parameters.getPassword());
317
        orgParams.setCatalog(parameters.getCatalog());
318
                return orgParams;
319
        }
320

    
321
        public List list(final int mode, final boolean showInformationDBTables)
322
                        throws DataException {
323

    
324
                final JDBCStoreParameters orgParams = createStoreParams();
325

    
326
                ConnectionAction action = new ConnectionAction() {
327

    
328
                        public Object action(Connection conn) throws DataException {
329

    
330
                                String[] tableTypes = null;
331
                                if (!showInformationDBTables) {
332
                                        tableTypes = new String[] { "TABLE", "VIEW" };
333
                                }
334

    
335
                                ResultSet result = null;
336
                                try {
337
                                        DatabaseMetaData metadata = conn.getMetaData();
338
                                        result = metadata.getTables(null, null, null,
339
                                                        tableTypes);
340
                                        List<JDBCStoreParameters> paramList = new ArrayList<JDBCStoreParameters>();
341
                                        while (result.next()) {
342
                                                JDBCStoreParameters params = (JDBCStoreParameters) orgParams
343
                                                                .getCopy();
344
                                                params.setCatalog(result
345
                                                                .getString(METADATA_COLUMN_TABLE_CATALOG));
346
                                                params.setSchema(result
347
                                                                .getString(METADATA_COLUMN_TABLE_SCHEMA));
348
                                                params.setTable(result
349
                                                                .getString(METADATA_COLUMN_TABLE_NAME));
350
                                                paramList.add(params);
351
                                        }
352

    
353
                                        return paramList;
354
                                } catch (SQLException e) {
355
                                        throw new JDBCSQLException(e);
356
                                } finally {
357
                                        if (result != null) {
358
                                                try {
359
                                                        result.close();
360
                                                } catch (Exception e) {
361
                                                        LOG.error("Error closing DatabaseMetadata "
362
                                                                        + "getTables() Resultset", e);
363
                                                }
364
                                        }
365
                                }
366
                        }
367

    
368
                };
369

    
370
                try {
371
                        return (List) helper.doConnectionAction(action);
372
                } catch (Exception e) {
373
                        throw new ReadException(this.getProviderName(), e);
374
                }
375
        }
376

    
377

    
378
        public void open() throws OpenException {
379
                helper.open();
380
        }
381

    
382
        public void close() throws CloseException {
383
                helper.close();
384
        }
385

    
386
        @Override
387
        protected void doDispose() throws BaseException {
388
                helper.dispose();
389
                helper = null;
390
        }
391

    
392
        public String getProviderName() {
393
                return NAME;
394
        }
395

    
396
        protected String getStoreName() {
397
                return JDBCStoreProvider.NAME;
398
        }
399

    
400
        public boolean canAdd() {
401
                if (this.canAdd == null){
402
                        ConnectionAction action = new ConnectionAction(){
403

    
404
                                public Object action(Connection conn) throws DataException {
405
                                        try {
406
                                        DatabaseMetaData metadata = conn.getMetaData();
407
                                                if (metadata.isReadOnly()) {
408
                                                        return Boolean.FALSE;
409
                                                }
410
                                                return Boolean.TRUE;
411
                                        } catch (SQLException e) {
412
                                                throw new JDBCSQLException(e);
413
                                        }
414
                                }
415

    
416
                        };
417

    
418
                        try {
419
                                this.canAdd = (Boolean) helper.doConnectionAction(action);
420
                        } catch (Exception e) {
421
                                // FIXME Exception
422
                                throw new RuntimeException(e);
423
                        }
424
                }
425
                return this.canAdd.booleanValue();
426
        }
427

    
428
        public FeatureType getFeatureType(DataStoreParameters dsp)
429
                        throws DataException {
430
                checkIsMine(dsp);
431

    
432
                // TODO: checks geometry columns and driver geometry supports
433
                EditableFeatureType edType = this.getServerExplorerProviderServices()
434
                                .createNewFeatureType();
435
                helper.loadFeatureType(edType, (JDBCStoreParameters) dsp);
436

    
437
                return edType;
438

    
439
        }
440

    
441

    
442
        public boolean add(String providerName, NewDataStoreParameters ndsp, boolean overwrite)
443
                        throws DataException {
444

    
445
                /**
446
                 * CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
447
                 * { column_name data_type [ DEFAULT default_expr ] [ column_constraint
448
                 * [ ... ] ] | table_constraint | LIKE parent_table [ { INCLUDING |
449
                 * EXCLUDING } DEFAULTS ] } [, ... ] ) [ INHERITS ( parent_table [, ...
450
                 * ] ) ] [ WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS |
451
                 * DELETE ROWS | DROP } ]
452
                 *
453
                 * where column_constraint is:
454
                 *
455
                 * [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE | PRIMARY
456
                 * KEY | CHECK (expression) | REFERENCES reftable [ ( refcolumn ) ] [
457
                 * MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON
458
                 * UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY
459
                 * DEFERRED | INITIALLY IMMEDIATE ]
460
                 *
461
                 * and table_constraint is:
462
                 *
463
                 * [ CONSTRAINT constraint_name ] { UNIQUE ( column_name [, ... ] ) |
464
                 * PRIMARY KEY ( column_name [, ... ] ) | CHECK ( expression ) | FOREIGN
465
                 * KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ...
466
                 * ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE
467
                 * action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [
468
                 * INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
469
                 */
470

    
471
                if (!(ndsp instanceof NewFeatureStoreParameters)) {
472
                        // FIXME exception
473
                        throw new IllegalArgumentException();
474
                }
475
                checkIsMine(ndsp);
476

    
477
                NewFeatureStoreParameters nfdsp = (NewFeatureStoreParameters) ndsp;
478

    
479
                StringBuilder sql = new StringBuilder();
480

    
481
                if (!nfdsp.isValid()) {
482
                        // TODO Exception
483
                        throw new InitializeException(this.getProviderName(), new Exception(
484
                                        "Parameters not valid"));
485
                }
486
                try {
487
                        nfdsp.validate();
488
                } catch (ValidateDataParametersException e1) {
489
                        throw new InitializeException(this.getProviderName(), e1);
490
                }
491

    
492
                FeatureType fType = nfdsp.getDefaultFeatureType();
493

    
494
                sql.append("Create table " + ((JDBCStoreParameters) ndsp).tableID()
495
                                + "(");
496
                Iterator attrs = fType.iterator();
497
                String sqlAttr;
498
                List sqlAttrs = new ArrayList();
499

    
500
                while (attrs.hasNext()) {
501
                        sqlAttr = helper
502
                                        .getSqlFieldDescription((FeatureAttributeDescriptor) attrs
503
                                                        .next());
504
                        if (sqlAttr != null) {
505
                                sqlAttrs.add(sqlAttr);
506
                        }
507
                }
508

    
509
                helper.stringJoin(sqlAttrs, ", ", sql);
510

    
511
                sql.append(")");
512

    
513
                final String sqlCreate = sql.toString();
514
                final List sqlAdditional = helper
515
                                .getAdditionalSqlToCreate(ndsp, fType);
516

    
517
                TransactionalAction action = new TransactionalAction() {
518

    
519
                        public boolean continueTransactionAllowed() {
520
                                // TODO Auto-generated method stub
521
                                return false;
522
                        }
523

    
524
                        public Object action(Connection conn) throws DataException {
525
                                Statement st = null;
526

    
527
                                try {
528
                                        st = conn.createStatement();
529
                                } catch (SQLException e1) {
530
                                        throw new JDBCSQLException(e1);
531
                                }
532
                                String sql = null;
533

    
534
                                try {
535
                                        sql = sqlCreate;
536
                                        st.execute(sql);
537
                                        if (sqlAdditional != null) {
538
                                                Iterator iter = sqlAdditional.iterator();
539
                                                while (iter.hasNext()) {
540
                                                        sql = (String) iter.next();
541
                                                        st.execute(sql);
542
                                                }
543
                                        }
544

    
545
                                } catch (SQLException e) {
546
                                        throw new JDBCExecuteSQLException(sql, e);
547
                                } finally {
548
                                        try {
549
                                                st.close();
550
                                        } catch (SQLException e) {
551
                                                LOG.error("Exception clossing statement", e);
552
                                        }
553
                                        ;
554
                                }
555

    
556
                                return Boolean.TRUE;
557
                        }
558

    
559
                };
560

    
561
                Boolean result = Boolean.FALSE;
562

    
563
                try {
564
                        result = (Boolean) helper.doConnectionAction(action);
565
                } catch (Exception e) {
566
                        // FIXME Exception
567
                        throw new RuntimeException(e);
568
                }
569

    
570
                return result.booleanValue();
571
        }
572

    
573
        public List getDataStoreProviderNames() {
574
                List x = new ArrayList(1);
575
                x.add(JDBCStoreProvider.NAME);
576
                return x;
577
        }
578

    
579
}