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 / JDBCServerExplorer.java @ 40559

History | View | Annotate | Download (17 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.sql.Connection;
57
import java.sql.DatabaseMetaData;
58
import java.sql.ResultSet;
59
import java.sql.SQLException;
60
import java.sql.Statement;
61
import java.util.ArrayList;
62
import java.util.Iterator;
63
import java.util.List;
64

    
65
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
67

    
68
import org.gvsig.fmap.dal.DALLocator;
69
import org.gvsig.fmap.dal.DataManager;
70
import org.gvsig.fmap.dal.DataStore;
71
import org.gvsig.fmap.dal.DataStoreParameters;
72
import org.gvsig.fmap.dal.NewDataStoreParameters;
73
import org.gvsig.fmap.dal.exception.CloseException;
74
import org.gvsig.fmap.dal.exception.DataException;
75
import org.gvsig.fmap.dal.exception.InitializeException;
76
import org.gvsig.fmap.dal.exception.OpenException;
77
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
78
import org.gvsig.fmap.dal.exception.ReadException;
79
import org.gvsig.fmap.dal.exception.RemoveException;
80
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
81
import org.gvsig.fmap.dal.feature.EditableFeatureType;
82
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
83
import org.gvsig.fmap.dal.feature.FeatureType;
84
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
85
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
86
import org.gvsig.fmap.dal.serverexplorer.db.spi.AbstractDBServerExplorer;
87
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
88
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
89
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
90
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
91
import org.gvsig.tools.exception.BaseException;
92

    
93

    
94
/**
95
 * @author jmvivo
96
 *
97
 */
98
public class JDBCServerExplorer extends AbstractDBServerExplorer
99
                implements JDBCHelperUser {
100

    
101
        private static final Logger LOG = LoggerFactory
102
                        .getLogger(JDBCServerExplorer.class);
103
        
104
        private static final String METADATA_COLUMN_TABLE_CATALOG = "TABLE_CAT";
105
        private static final String METADATA_COLUMN_TABLE_SCHEMA = "TABLE_SCHEM";
106
        private static final String METADATA_COLUMN_TABLE_NAME = "TABLE_NAME";
107

    
108
        public static final String NAME = "JDBCServerExplorer";
109
        protected JDBCHelper helper;
110

    
111
        private Boolean canAdd;
112

    
113
        public JDBCServerExplorer(JDBCServerExplorerParameters parameters,
114
                        DataServerExplorerProviderServices services)
115
                        throws InitializeException {
116
                super(parameters, services);
117
                this.helper = createHelper();
118
        }
119

    
120
        protected JDBCServerExplorerParameters getJDBCParameters() {
121
                return (JDBCServerExplorerParameters) getParameters();
122
        }
123

    
124
        protected JDBCHelper createHelper() throws InitializeException {
125
                return new JDBCHelper(this, getJDBCParameters());
126
        }
127

    
128
        protected JDBCHelper getHelper() {
129
                return helper;
130
        }
131

    
132

    
133
        public List list() throws DataException {
134
                return this.list(MODE_ALL);
135
        }
136

    
137
        public List list(boolean showInformationDBTables) throws DataException {
138
                return this.list(MODE_ALL, showInformationDBTables);
139
        }
140

    
141
        public List list(int mode) throws DataException {
142
                JDBCServerExplorerParameters parameters = getJDBCParameters();
143
                if (parameters.getShowInformationDBTables() != null) {
144
                        return this.list(mode, parameters.getShowInformationDBTables()
145
                                        .booleanValue());
146
                }
147
                Boolean show = (Boolean) parameters
148
                                .getDynClass()
149
                                .getDynField(
150
                                                JDBCServerExplorerParameters.SHOWINFORMATIONDBTABLES_PARAMTER_NAME)
151
                                .getDefaultValue();
152
                if (show == null){
153
                        show = Boolean.FALSE;
154
                }
155

    
156
                return this.list(mode, show.booleanValue());
157
        }
158

    
159

    
160
        protected DataManagerProviderServices getManager() {
161
                return (DataManagerProviderServices) DALLocator.getDataManager();
162
        }
163

    
164
        public boolean hasGeometrySupport() {
165
                return false;
166
        }
167

    
168
        public boolean closeResourceRequested(ResourceProvider resource) {
169
                try {
170
                        this.helper.close();
171
                } catch (CloseException e) {
172
                        LOG.error("Exception in close Request", e);
173
                }
174
                return !this.helper.isOpen();
175
        }
176

    
177
        public void resourceChanged(ResourceProvider resource) {
178
                // Nothing to do
179
        }
180

    
181
        public void remove(DataStoreParameters dsp) throws RemoveException {
182
                final JDBCStoreParameters dsParams =(JDBCStoreParameters) dsp;
183

    
184
                TransactionalAction action = new TransactionalAction() {
185
                        public boolean continueTransactionAllowed() {
186
                                return false;
187
                        }
188
                        public Object action(Connection conn) throws DataException {
189
                                Statement st;
190
                                try{
191
                                        st = conn.createStatement();
192
                                } catch (SQLException e) {
193
                                        throw new JDBCSQLException(e);
194
                                }
195

    
196
                                String sqlDrop = "Drop table "
197
                                        + dsParams.tableID();
198

    
199
                                try{
200
                                        try{
201
                                                st.execute(sqlDrop);
202
                                        } catch (SQLException e) {
203
                                                throw new JDBCExecuteSQLException(sqlDrop, e);
204
                                        }
205

    
206
                                } finally{
207
                                        try{ st.close(); } catch (SQLException e) {};
208
                                }
209
                                return null;
210
                        }
211
                };
212
                try {
213
                        this.helper.doConnectionAction(action);
214
                } catch (Exception e) {
215
                        throw new RemoveException(this.getProviderName(), e);
216
                }
217
        }
218

    
219
        public NewDataStoreParameters getAddParameters() throws DataException {
220
                JDBCServerExplorerParameters parameters = getJDBCParameters();
221
                JDBCNewStoreParameters params = new JDBCNewStoreParameters();
222
                params.setHost(parameters.getHost());
223
                params.setPort(parameters.getPort());
224
                params.setDBName(parameters.getDBName());
225
                params.setUser(parameters.getUser());
226
                params.setPassword(parameters.getPassword());
227
                params.setCatalog(parameters.getCatalog());
228
                params.setSchema(parameters.getSchema());
229
                params.setJDBCDriverClassName(parameters.getJDBCDriverClassName());
230
                params.setUrl(parameters.getUrl());
231

    
232
                params.setDefaultFeatureType(this.getServerExplorerProviderServices()
233
                                .createNewFeatureType());
234

    
235
                return params;
236
        }
237

    
238
        public void closeDone() throws DataException {
239
                // Nothing to do
240
        }
241

    
242
        public void opendDone() throws DataException {
243
                // Nothin to do
244

    
245
        }
246

    
247
        public DataStore open(DataStoreParameters dsp) throws DataException {
248
                checkIsMine(dsp);
249
                DataManager dataMan = DALLocator.getDataManager();
250
                DataStore store;
251
                try {
252
                        store = dataMan.openStore(dsp.getDataStoreName(), dsp);
253
                } catch (ValidateDataParametersException e) {
254
                        throw new InitializeException(e);
255
                }
256

    
257
                return store;
258
        }
259

    
260
        protected void checkIsMine(DataStoreParameters dsp) {
261
                if (!(dsp instanceof JDBCStoreParameters)) {
262
                        // FIXME Exception ???
263
                        throw new IllegalArgumentException(
264
                                        "not instance of FilesystemStoreParameters");
265
                }
266

    
267
                // try {
268
                // dsp.validate();
269
                // } catch (ValidateDataParametersException e) {
270
                // throw new IllegalArgumentException("check parameters", e);
271
                // }
272

    
273
                JDBCServerExplorerParameters parameters = getJDBCParameters();
274

    
275
                JDBCStoreParameters pgp = (JDBCStoreParameters) dsp;
276
                if (!compare(pgp.getHost(), parameters.getHost())) {
277
                        throw new IllegalArgumentException("wrong explorer: Host (mine: "
278
                                        + parameters.getHost() + " other:" + pgp.getHost() + ")");
279
                }
280
                if (!compare(pgp.getPort(), parameters.getPort())) {
281
                        throw new IllegalArgumentException("wrong explorer: Port (mine: "
282
                                        + parameters.getPort() + " other:" + pgp.getPort() + ")");
283
                }
284
                if (!compare(pgp.getDBName(), parameters.getDBName())) {
285
                        throw new IllegalArgumentException("wrong explorer: DBName (mine: "
286
                                        + parameters.getDBName() + " other:" + pgp.getDBName()
287
                                        + ")");
288
                }
289
                if (parameters.getCatalog() != null && !parameters.getCatalog().trim().equals("")) {
290
                        // implicit catalog
291
                        if (!compare(pgp.getCatalog(), parameters.getCatalog())) {
292
                                throw new IllegalArgumentException(
293
                                                "wrong explorer: Catalog (mine: "
294
                                                                + parameters.getCatalog() + " other:"
295
                                                                + pgp.getCatalog() + ")");
296
                        }
297
                }
298
                if (parameters.getSchema() != null && !parameters.getSchema().trim().equals("")) {
299
                        // implicit schema
300
                        if (!compare(pgp.getSchema(), parameters.getSchema())) {
301
                                throw new IllegalArgumentException(
302
                                                "wrong explorer: Schema (mine: "
303
                                                                + parameters.getSchema() + " other:"
304
                                                                + pgp.getSchema() + ")");
305
                        }
306
                }
307
        }
308

    
309
        protected boolean compare(Object str1, Object str2) {
310
                if (str1 == str2){
311
                        return true;
312
                }
313
                if (str1 == null){
314
                        return false;
315
                }
316
                return  str1.equals(str2);
317
        }
318

    
319
        protected JDBCStoreParameters createStoreParams()
320
                        throws InitializeException, ProviderNotRegisteredException {
321
                DataManagerProviderServices manager = this.getManager();
322
                JDBCServerExplorerParameters parameters = getJDBCParameters();
323
                JDBCStoreParameters orgParams = (JDBCStoreParameters) manager
324
                                .createStoreParameters(getStoreName());
325
                orgParams.setHost(parameters.getHost());
326
                orgParams.setPort(parameters.getPort());
327
                orgParams.setDBName(parameters.getDBName());
328
                orgParams.setUser(parameters.getUser());
329
                orgParams.setPassword(parameters.getPassword());
330
        orgParams.setCatalog(parameters.getCatalog());
331
        orgParams.setJDBCDriverClassName(parameters.getJDBCDriverClassName());
332
        orgParams.setSchema(parameters.getSchema());
333
        orgParams.setUrl(parameters.getUrl());
334
                return orgParams;
335
        }
336

    
337
        public List list(final int mode, final boolean showInformationDBTables)
338
                        throws DataException {
339

    
340
                final JDBCStoreParameters orgParams = createStoreParams();
341

    
342
                ConnectionAction action = new ConnectionAction() {
343

    
344
                        public Object action(Connection conn) throws DataException {
345

    
346
                                String[] tableTypes = null;
347
                                if (!showInformationDBTables) {
348
                                        tableTypes = new String[] { "TABLE", "VIEW" };
349
                                }
350

    
351
                                ResultSet result = null;
352
                                try {
353
                                        DatabaseMetaData metadata = conn.getMetaData();
354
                                        result = metadata.getTables(null, null, null,
355
                                                        tableTypes);
356
                                        List<JDBCStoreParameters> paramList = new ArrayList<JDBCStoreParameters>();
357
                                        while (result.next()) {
358
                                                JDBCStoreParameters params = (JDBCStoreParameters) orgParams
359
                                                                .getCopy();
360
                                                params.setCatalog(result
361
                                                                .getString(METADATA_COLUMN_TABLE_CATALOG));
362
                                                params.setSchema(result
363
                                                                .getString(METADATA_COLUMN_TABLE_SCHEMA));
364
                                                params.setTable(result
365
                                                                .getString(METADATA_COLUMN_TABLE_NAME));
366
                                                paramList.add(params);
367
                                        }
368

    
369
                                        return paramList;
370
                                } catch (SQLException e) {
371
                                        throw new JDBCSQLException(e);
372
                                } finally {
373
                                        if (result != null) {
374
                                                try {
375
                                                        result.close();
376
                                                } catch (Exception e) {
377
                                                        LOG.error("Error closing DatabaseMetadata "
378
                                                                        + "getTables() Resultset", e);
379
                                                }
380
                                        }
381
                                }
382
                        }
383

    
384
                };
385

    
386
                try {
387
                        return (List) helper.doConnectionAction(action);
388
                } catch (Exception e) {
389
                        throw new ReadException(this.getProviderName(), e);
390
                }
391
        }
392

    
393

    
394
        public void open() throws OpenException {
395
                helper.open();
396
        }
397

    
398
        public void close() throws CloseException {
399
                helper.close();
400
        }
401

    
402
        @Override
403
        protected void doDispose() throws BaseException {
404
                helper.dispose();
405
                helper = null;
406
        }
407

    
408
        public String getProviderName() {
409
                return NAME;
410
        }
411

    
412
        protected String getStoreName() {
413
                return JDBCStoreProvider.NAME;
414
        }
415

    
416
        public boolean canAdd() {
417
                if (this.canAdd == null){
418
                        ConnectionAction action = new ConnectionAction(){
419

    
420
                                public Object action(Connection conn) throws DataException {
421
                                        try {
422
                                        DatabaseMetaData metadata = conn.getMetaData();
423
                                                if (metadata.isReadOnly()) {
424
                                                        return Boolean.FALSE;
425
                                                }
426
                                                return Boolean.TRUE;
427
                                        } catch (SQLException e) {
428
                                                throw new JDBCSQLException(e);
429
                                        }
430
                                }
431

    
432
                        };
433

    
434
                        try {
435
                                this.canAdd = (Boolean) helper.doConnectionAction(action);
436
                        } catch (Exception e) {
437
                                // FIXME Exception
438
                                throw new RuntimeException(e);
439
                        }
440
                }
441
                return this.canAdd.booleanValue();
442
        }
443

    
444
        public FeatureType getFeatureType(DataStoreParameters dsp)
445
                        throws DataException {
446
                checkIsMine(dsp);
447

    
448
                // TODO: checks geometry columns and driver geometry supports
449
                EditableFeatureType edType = this.getServerExplorerProviderServices()
450
                                .createNewFeatureType();
451
                helper.loadFeatureType(edType, (JDBCStoreParameters) dsp);
452

    
453
                return edType;
454

    
455
        }
456

    
457

    
458
        public boolean add(String providerName, NewDataStoreParameters ndsp, boolean overwrite)
459
                        throws DataException {
460

    
461
                /**
462
                 * CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
463
                 * { column_name data_type [ DEFAULT default_expr ] [ column_constraint
464
                 * [ ... ] ] | table_constraint | LIKE parent_table [ { INCLUDING |
465
                 * EXCLUDING } DEFAULTS ] } [, ... ] ) [ INHERITS ( parent_table [, ...
466
                 * ] ) ] [ WITH OIDS | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS |
467
                 * DELETE ROWS | DROP } ]
468
                 *
469
                 * where column_constraint is:
470
                 *
471
                 * [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE | PRIMARY
472
                 * KEY | CHECK (expression) | REFERENCES reftable [ ( refcolumn ) ] [
473
                 * MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON
474
                 * UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY
475
                 * DEFERRED | INITIALLY IMMEDIATE ]
476
                 *
477
                 * and table_constraint is:
478
                 *
479
                 * [ CONSTRAINT constraint_name ] { UNIQUE ( column_name [, ... ] ) |
480
                 * PRIMARY KEY ( column_name [, ... ] ) | CHECK ( expression ) | FOREIGN
481
                 * KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ...
482
                 * ] ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE
483
                 * action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [
484
                 * INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
485
                 */
486

    
487
                if (!(ndsp instanceof NewFeatureStoreParameters)) {
488
                        // FIXME exception
489
                        throw new IllegalArgumentException();
490
                }
491
                checkIsMine(ndsp);
492

    
493
                NewFeatureStoreParameters nfdsp = (NewFeatureStoreParameters) ndsp;
494

    
495
                StringBuilder sql = new StringBuilder();
496

    
497
                if (!nfdsp.isValid()) {
498
                        // TODO Exception
499
                        throw new InitializeException(this.getProviderName(), new Exception(
500
                                        "Parameters not valid"));
501
                }
502
                try {
503
                        nfdsp.validate();
504
                } catch (ValidateDataParametersException e1) {
505
                        throw new InitializeException(this.getProviderName(), e1);
506
                }
507

    
508
                FeatureType fType = nfdsp.getDefaultFeatureType();
509

    
510
                sql.append("Create table " + ((JDBCStoreParameters) ndsp).tableID()
511
                                + "(");
512
                Iterator attrs = fType.iterator();
513
                String sqlAttr;
514
                List sqlAttrs = new ArrayList();
515

    
516
                while (attrs.hasNext()) {
517
                        sqlAttr = helper
518
                                        .getSqlFieldDescription((FeatureAttributeDescriptor) attrs
519
                                                        .next());
520
                        if (sqlAttr != null) {
521
                                sqlAttrs.add(sqlAttr);
522
                        }
523
                }
524

    
525
                helper.stringJoin(sqlAttrs, ", ", sql);
526

    
527
                sql.append(")");
528

    
529
                final String sqlCreate = sql.toString();
530
                final List sqlAdditional = helper
531
                                .getAdditionalSqlToCreate(ndsp, fType);
532

    
533
                TransactionalAction action = new TransactionalAction() {
534

    
535
                        public boolean continueTransactionAllowed() {
536
                                // TODO Auto-generated method stub
537
                                return false;
538
                        }
539

    
540
                        public Object action(Connection conn) throws DataException {
541
                                Statement st = null;
542

    
543
                                try {
544
                                        st = conn.createStatement();
545
                                } catch (SQLException e1) {
546
                                        throw new JDBCSQLException(e1);
547
                                }
548
                                String sql = null;
549

    
550
                                try {
551
                                        sql = sqlCreate;
552
                                        st.execute(sql);
553
                                        if (sqlAdditional != null) {
554
                                                Iterator iter = sqlAdditional.iterator();
555
                                                while (iter.hasNext()) {
556
                                                        sql = (String) iter.next();
557
                                                        st.execute(sql);
558
                                                }
559
                                        }
560

    
561
                                } catch (SQLException e) {
562
                                        throw new JDBCExecuteSQLException(sql, e);
563
                                } finally {
564
                                        try {
565
                                                st.close();
566
                                        } catch (SQLException e) {
567
                                                LOG.error("Exception clossing statement", e);
568
                                        }
569
                                        ;
570
                                }
571

    
572
                                return Boolean.TRUE;
573
                        }
574

    
575
                };
576

    
577
                Boolean result = Boolean.FALSE;
578

    
579
                try {
580
                        result = (Boolean) helper.doConnectionAction(action);
581
                } catch (Exception e) {
582
                        // FIXME Exception
583
                        throw new RuntimeException(e);
584
                }
585

    
586
                return result.booleanValue();
587
        }
588

    
589
        public List getDataStoreProviderNames() {
590
                List x = new ArrayList(1);
591
                x.add(JDBCStoreProvider.NAME);
592
                return x;
593
        }
594

    
595
}