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 @ 40435

History | View | Annotate | Download (16.1 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.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44

    
45
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47
import org.gvsig.fmap.dal.DataStore;
48
import org.gvsig.fmap.dal.DataStoreParameters;
49
import org.gvsig.fmap.dal.NewDataStoreParameters;
50
import org.gvsig.fmap.dal.exception.CloseException;
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.exception.InitializeException;
53
import org.gvsig.fmap.dal.exception.OpenException;
54
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
55
import org.gvsig.fmap.dal.exception.ReadException;
56
import org.gvsig.fmap.dal.exception.RemoveException;
57
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
58
import org.gvsig.fmap.dal.feature.EditableFeatureType;
59
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
60
import org.gvsig.fmap.dal.feature.FeatureType;
61
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
62
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
63
import org.gvsig.fmap.dal.serverexplorer.db.spi.AbstractDBServerExplorer;
64
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
65
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
66
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
67
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
68
import org.gvsig.tools.exception.BaseException;
69

    
70

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

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

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

    
88
        private Boolean canAdd;
89

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

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

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

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

    
109

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

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

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

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

    
136

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

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

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

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

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

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

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

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

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

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

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

    
212
                return params;
213
        }
214

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

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

    
222
        }
223

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

    
234
                return store;
235
        }
236

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

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

    
250
                JDBCServerExplorerParameters parameters = getJDBCParameters();
251

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

    
286
        protected boolean compare(Object str1, Object str2) {
287
                if (str1 == str2){
288
                        return true;
289
                }
290
                if (str1 == null){
291
                        return false;
292
                }
293
                return  str1.equals(str2);
294
        }
295

    
296
        protected JDBCStoreParameters createStoreParams()
297
                        throws InitializeException, ProviderNotRegisteredException {
298
                DataManagerProviderServices manager = this.getManager();
299
                JDBCServerExplorerParameters parameters = getJDBCParameters();
300
                JDBCStoreParameters orgParams = (JDBCStoreParameters) manager
301
                                .createStoreParameters(getStoreName());
302
                orgParams.setHost(parameters.getHost());
303
                orgParams.setPort(parameters.getPort());
304
                orgParams.setDBName(parameters.getDBName());
305
                orgParams.setUser(parameters.getUser());
306
                orgParams.setPassword(parameters.getPassword());
307
        orgParams.setCatalog(parameters.getCatalog());
308
        orgParams.setJDBCDriverClassName(parameters.getJDBCDriverClassName());
309
        orgParams.setSchema(parameters.getSchema());
310
        orgParams.setUrl(parameters.getUrl());
311
                return orgParams;
312
        }
313

    
314
        public List list(final int mode, final boolean showInformationDBTables)
315
                        throws DataException {
316

    
317
                final JDBCStoreParameters orgParams = createStoreParams();
318

    
319
                ConnectionAction action = new ConnectionAction() {
320

    
321
                        public Object action(Connection conn) throws DataException {
322

    
323
                                String[] tableTypes = null;
324
                                if (!showInformationDBTables) {
325
                                        tableTypes = new String[] { "TABLE", "VIEW" };
326
                                }
327

    
328
                                ResultSet result = null;
329
                                try {
330
                                        DatabaseMetaData metadata = conn.getMetaData();
331
                                        result = metadata.getTables(null, null, null,
332
                                                        tableTypes);
333
                                        List<JDBCStoreParameters> paramList = new ArrayList<JDBCStoreParameters>();
334
                                        while (result.next()) {
335
                                                JDBCStoreParameters params = (JDBCStoreParameters) orgParams
336
                                                                .getCopy();
337
                                                params.setCatalog(result
338
                                                                .getString(METADATA_COLUMN_TABLE_CATALOG));
339
                                                params.setSchema(result
340
                                                                .getString(METADATA_COLUMN_TABLE_SCHEMA));
341
                                                params.setTable(result
342
                                                                .getString(METADATA_COLUMN_TABLE_NAME));
343
                                                paramList.add(params);
344
                                        }
345

    
346
                                        return paramList;
347
                                } catch (SQLException e) {
348
                                        throw new JDBCSQLException(e);
349
                                } finally {
350
                                        if (result != null) {
351
                                                try {
352
                                                        result.close();
353
                                                } catch (Exception e) {
354
                                                        LOG.error("Error closing DatabaseMetadata "
355
                                                                        + "getTables() Resultset", e);
356
                                                }
357
                                        }
358
                                }
359
                        }
360

    
361
                };
362

    
363
                try {
364
                        return (List) helper.doConnectionAction(action);
365
                } catch (Exception e) {
366
                        throw new ReadException(this.getProviderName(), e);
367
                }
368
        }
369

    
370

    
371
        public void open() throws OpenException {
372
                helper.open();
373
        }
374

    
375
        public void close() throws CloseException {
376
                helper.close();
377
        }
378

    
379
        @Override
380
        protected void doDispose() throws BaseException {
381
                helper.dispose();
382
                helper = null;
383
        }
384

    
385
        public String getProviderName() {
386
                return NAME;
387
        }
388

    
389
        protected String getStoreName() {
390
                return JDBCStoreProvider.NAME;
391
        }
392

    
393
        public boolean canAdd() {
394
                if (this.canAdd == null){
395
                        ConnectionAction action = new ConnectionAction(){
396

    
397
                                public Object action(Connection conn) throws DataException {
398
                                        try {
399
                                        DatabaseMetaData metadata = conn.getMetaData();
400
                                                if (metadata.isReadOnly()) {
401
                                                        return Boolean.FALSE;
402
                                                }
403
                                                return Boolean.TRUE;
404
                                        } catch (SQLException e) {
405
                                                throw new JDBCSQLException(e);
406
                                        }
407
                                }
408

    
409
                        };
410

    
411
                        try {
412
                                this.canAdd = (Boolean) helper.doConnectionAction(action);
413
                        } catch (Exception e) {
414
                                // FIXME Exception
415
                                throw new RuntimeException(e);
416
                        }
417
                }
418
                return this.canAdd.booleanValue();
419
        }
420

    
421
        public FeatureType getFeatureType(DataStoreParameters dsp)
422
                        throws DataException {
423
                checkIsMine(dsp);
424

    
425
                // TODO: checks geometry columns and driver geometry supports
426
                EditableFeatureType edType = this.getServerExplorerProviderServices()
427
                                .createNewFeatureType();
428
                helper.loadFeatureType(edType, (JDBCStoreParameters) dsp);
429

    
430
                return edType;
431

    
432
        }
433

    
434

    
435
        public boolean add(String providerName, NewDataStoreParameters ndsp, boolean overwrite)
436
                        throws DataException {
437

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

    
464
                if (!(ndsp instanceof NewFeatureStoreParameters)) {
465
                        // FIXME exception
466
                        throw new IllegalArgumentException();
467
                }
468
                checkIsMine(ndsp);
469

    
470
                NewFeatureStoreParameters nfdsp = (NewFeatureStoreParameters) ndsp;
471

    
472
                StringBuilder sql = new StringBuilder();
473

    
474
                if (!nfdsp.isValid()) {
475
                        // TODO Exception
476
                        throw new InitializeException(this.getProviderName(), new Exception(
477
                                        "Parameters not valid"));
478
                }
479
                try {
480
                        nfdsp.validate();
481
                } catch (ValidateDataParametersException e1) {
482
                        throw new InitializeException(this.getProviderName(), e1);
483
                }
484

    
485
                FeatureType fType = nfdsp.getDefaultFeatureType();
486

    
487
                sql.append("Create table " + ((JDBCStoreParameters) ndsp).tableID()
488
                                + "(");
489
                Iterator attrs = fType.iterator();
490
                String sqlAttr;
491
                List sqlAttrs = new ArrayList();
492

    
493
                while (attrs.hasNext()) {
494
                        sqlAttr = helper
495
                                        .getSqlFieldDescription((FeatureAttributeDescriptor) attrs
496
                                                        .next());
497
                        if (sqlAttr != null) {
498
                                sqlAttrs.add(sqlAttr);
499
                        }
500
                }
501

    
502
                helper.stringJoin(sqlAttrs, ", ", sql);
503

    
504
                sql.append(")");
505

    
506
                final String sqlCreate = sql.toString();
507
                final List sqlAdditional = helper
508
                                .getAdditionalSqlToCreate(ndsp, fType);
509

    
510
                TransactionalAction action = new TransactionalAction() {
511

    
512
                        public boolean continueTransactionAllowed() {
513
                                // TODO Auto-generated method stub
514
                                return false;
515
                        }
516

    
517
                        public Object action(Connection conn) throws DataException {
518
                                Statement st = null;
519

    
520
                                try {
521
                                        st = conn.createStatement();
522
                                } catch (SQLException e1) {
523
                                        throw new JDBCSQLException(e1);
524
                                }
525
                                String sql = null;
526

    
527
                                try {
528
                                        sql = sqlCreate;
529
                                        st.execute(sql);
530
                                        if (sqlAdditional != null) {
531
                                                Iterator iter = sqlAdditional.iterator();
532
                                                while (iter.hasNext()) {
533
                                                        sql = (String) iter.next();
534
                                                        st.execute(sql);
535
                                                }
536
                                        }
537

    
538
                                } catch (SQLException e) {
539
                                        throw new JDBCExecuteSQLException(sql, e);
540
                                } finally {
541
                                        try {
542
                                                st.close();
543
                                        } catch (SQLException e) {
544
                                                LOG.error("Exception clossing statement", e);
545
                                        }
546
                                        ;
547
                                }
548

    
549
                                return Boolean.TRUE;
550
                        }
551

    
552
                };
553

    
554
                Boolean result = Boolean.FALSE;
555

    
556
                try {
557
                        result = (Boolean) helper.doConnectionAction(action);
558
                } catch (Exception e) {
559
                        // FIXME Exception
560
                        throw new RuntimeException(e);
561
                }
562

    
563
                return result.booleanValue();
564
        }
565

    
566
        public List getDataStoreProviderNames() {
567
                List x = new ArrayList(1);
568
                x.add(JDBCStoreProvider.NAME);
569
                return x;
570
        }
571

    
572
}