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 / jdbc2 / spi / JDBCServerExplorerBase.java @ 45614

History | View | Annotate | Download (33.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 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
package org.gvsig.fmap.dal.store.jdbc2.spi;
25

    
26
import java.io.File;
27
import java.util.ArrayList;
28
import java.util.Arrays;
29
import java.util.Collections;
30
import java.util.HashMap;
31
import java.util.List;
32
import java.util.Map;
33
import javax.json.JsonObject;
34
import javax.json.JsonString;
35
import javax.json.JsonValue;
36
import org.apache.commons.codec.binary.Hex;
37
import org.apache.commons.collections.map.LRUMap;
38
import org.apache.commons.lang3.BooleanUtils;
39
import org.apache.commons.lang3.ObjectUtils;
40
import org.apache.commons.lang3.StringUtils;
41
import org.apache.commons.lang3.tuple.ImmutablePair;
42
import org.apache.commons.lang3.tuple.Pair;
43
import org.gvsig.expressionevaluator.ExpressionBuilder;
44
import org.gvsig.expressionevaluator.ExpressionUtils;
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.DatabaseWorkspaceManager;
50
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_CONFIGURATION_NAME;
51
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_CONFIGURATION_VALUE;
52
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_CONFIGURATION_NAME;
53
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_RESOURCES_NAME;
54
import org.gvsig.fmap.dal.NewDataStoreParameters;
55
import org.gvsig.fmap.dal.SQLBuilder;
56
import org.gvsig.fmap.dal.SQLBuilder.Privilege;
57
import org.gvsig.fmap.dal.exception.CloseException;
58
import org.gvsig.fmap.dal.exception.DataException;
59
import org.gvsig.fmap.dal.exception.InitializeException;
60
import org.gvsig.fmap.dal.exception.OpenException;
61
import org.gvsig.fmap.dal.exception.RemoveException;
62
import org.gvsig.fmap.dal.feature.EditableFeature;
63
import org.gvsig.fmap.dal.feature.EditableFeatureType;
64
import org.gvsig.fmap.dal.feature.Feature;
65
import org.gvsig.fmap.dal.feature.FeatureStore;
66
import org.gvsig.fmap.dal.feature.FeatureType;
67
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
68
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
69
import org.gvsig.fmap.dal.serverexplorer.db.spi.AbstractDBServerExplorer;
70
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
71
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
72
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
73
import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters;
74
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
75
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
76
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
77
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
78
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
79
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer;
80
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
81
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CanCreateTablesOperation;
82
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CreateTableOperation;
83
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.DropTableOperation;
84
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.ExecuteOperation;
85
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
86
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.ListTablesOperation;
87
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.UpdateTableStatisticsOperation;
88
import org.gvsig.json.Json;
89
import org.gvsig.json.JsonObjectBuilder;
90
import org.gvsig.tools.dispose.DisposeUtils;
91
import org.gvsig.tools.exception.BaseException;
92
import org.gvsig.tools.resourcesstorage.EmptyResourcesStorage;
93
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
94
import org.gvsig.tools.util.CachedValue;
95
import org.slf4j.Logger;
96
import org.slf4j.LoggerFactory;
97

    
98
@SuppressWarnings("UseSpecificCatch")
99
public class JDBCServerExplorerBase extends AbstractDBServerExplorer implements JDBCServerExplorer {
100

    
101
    private static final Logger LOG = LoggerFactory.getLogger(JDBCServerExplorerBase.class);
102
    private static final String CONFIG_NAME_CUSTOM_RESOURCES = "CUSTOM_RESOURCES";
103

    
104
    protected JDBCHelper helper = null;
105

    
106
    private Boolean canAdd;
107

    
108
    private static final Map<String, CachedValue<List<JDBCStoreParameters>>> CACHED_TABLES = Collections.synchronizedMap(new LRUMap(10));
109
    private static final Map<String, CachedValue<CustomResourcesConfig>> CACHED_CUSTOM_RESOURCES_CONFIG = Collections.synchronizedMap(new LRUMap(10));
110

    
111
    private static class CustomResourcesConfig {
112

    
113
        private static final String CUSTOM_RESOURCES_CACHETIME = "CacheTime";
114
        private static final String CUSTOM_RESOURCES_MAPPING = "Mapping";
115

    
116

    
117
        private int cacheTime;
118
        private Map<String, String> mapping;
119

    
120
        public CustomResourcesConfig(String jsonConfig) {
121
            this.cacheTime = 30*60*1000; // 30min
122
            this.mapping = new HashMap<>();
123
            if (StringUtils.isNotBlank(jsonConfig)) {
124
                try {
125
                    JsonObject config = Json.createObject(jsonConfig);
126
                    this.cacheTime = config.getInt(CUSTOM_RESOURCES_CACHETIME, this.cacheTime);
127
                    if (!config.containsKey(CUSTOM_RESOURCES_MAPPING)) {
128
                        JsonObject m = config.getJsonObject(CUSTOM_RESOURCES_MAPPING);
129
                        for (Map.Entry<String, JsonValue> entry : m.entrySet()) {
130
                            String key = entry.getKey();
131
                            JsonValue value = entry.getValue();
132
                            if (value instanceof JsonString) {
133
                                this.mapping.put(key, ((JsonString) value).getString());
134
                            }
135
                        }
136
                    }
137
                } catch (Exception ex) {
138
                    LOG.debug("Can't parse json from "+CONFIG_NAME_CUSTOM_RESOURCES+" variable", ex);
139
                    // Do nothing.
140
                }
141
            }
142
        }
143

    
144
        public String toJsonString() {
145
            JsonObjectBuilder builder = Json.createObjectBuilder();
146
            builder.add(CUSTOM_RESOURCES_CACHETIME, cacheTime);
147
            JsonObjectBuilder m = Json.createObjectBuilder();
148
            for (Map.Entry<String, String> entry : mapping.entrySet()) {
149
                String key = entry.getKey();
150
                String value = entry.getValue();
151
                m.add(key, value);
152
            }
153
            builder.add(CUSTOM_RESOURCES_MAPPING, m);
154
            return builder.build().toString();
155
        }
156

    
157
        public int getCacheExpireTimeInMillis() {
158
            return cacheTime;
159
        }
160

    
161
        public String getResourcesTablename(String tablename) {
162
            String resourceTablename = mapping.get(tablename);
163
            return resourceTablename;
164
        }
165

    
166
        public void addResourceMapping(String tablename, String resourcesTablename) {
167
            this.mapping.put(tablename, resourcesTablename);
168
        }
169

    
170
        private boolean isInternalTable(String storeName) {
171
            if (DatabaseWorkspaceManager.isInternalTable(storeName)) {
172
                return true;
173
            }
174
            for (String resourcesTablename : this.mapping.values()) {
175
                if( StringUtils.equals(storeName, resourcesTablename) ) {
176
                    return true;
177
                }
178
            }
179
            return false;
180
        }
181
    }
182
    
183
    private static class CachedCustomResourcesConfig extends CachedValue<CustomResourcesConfig> {
184

    
185
        private final JDBCStoreParameters openParameters;
186

    
187
        private CachedCustomResourcesConfig(JDBCStoreParameters openParameters) {
188
            this.openParameters = openParameters;
189
            this.setExpireTime(30*60*1000); // 30min
190
        }
191

    
192
        @Override
193
        protected void reload() {
194
            String jsonConfig = getConfigValue(this.openParameters, CONFIG_NAME_CUSTOM_RESOURCES);
195
            CustomResourcesConfig config = new CustomResourcesConfig(jsonConfig);        
196
            this.setExpireTime(config.getCacheExpireTimeInMillis());
197
            this.setValue(config);
198
        }
199
        
200
    }
201

    
202
    private static class CachedTablesValue extends CachedValue<List<JDBCStoreParameters>> {
203

    
204
        private final int mode;
205
        private final JDBCServerExplorerParameters serverParameters;
206
        private final boolean informationTables;
207
        private JDBCHelper helper;
208

    
209
        public CachedTablesValue(JDBCHelper helper, int mode, JDBCServerExplorerParameters serverParameters, boolean informationTables) {
210
            this.mode = mode;
211
            this.serverParameters = serverParameters;
212
            this.informationTables = informationTables;
213
            this.helper = helper;
214
        }
215

    
216
        public CachedTablesValue(JDBCHelper helper, int mode, JDBCServerExplorerParameters serverParameters, boolean informationTables, long expireTime) {
217
            this.mode = mode;
218
            this.setExpireTime(expireTime);
219
            this.serverParameters = serverParameters;
220
            this.informationTables = informationTables;
221
            this.helper = helper;
222
        }
223

    
224
        @Override
225
        protected void reload() {
226
            List<JDBCStoreParameters> tables = null;
227
            if(helper == null){
228
                this.setValue(tables);
229
                return;
230
            }
231
            OperationsFactory operations = helper.getOperations();
232
            if (operations == null) {
233
                this.setValue(null);
234
                LOG.debug("Sets tables to null to force reload tables from new ServerExplorar.");
235
                return;
236
            }
237
            try {
238
                ListTablesOperation listTables = operations.createListTables(
239
                        this.mode, serverParameters, informationTables
240
                );
241
                tables = (List<JDBCStoreParameters>) listTables.perform();
242
            } catch (Exception ex) {
243
                LOG.debug("Can't reload cached list of tables.", ex);
244
            }
245
            this.setValue(tables);
246
        }
247
        
248
        public JDBCHelper getHelper(){
249
            return this.helper;
250
        }
251
        
252
        public void dispose() {
253
            this.helper = null;
254
        }
255
    }
256

    
257
    public JDBCServerExplorerBase(
258
            JDBCServerExplorerParameters parameters,
259
            DataServerExplorerProviderServices services,
260
            JDBCHelper helper
261
    ) throws InitializeException {
262
        super(parameters, services);
263
        this.helper = helper;
264
    }
265

    
266
    @Override
267
    public String getProviderName() {
268
        return this.getHelper().getProviderName();
269
    }
270

    
271
    @Override
272
    public String getStoreName() {
273
        return this.getHelper().getProviderName();
274
    }
275

    
276
    protected DataManagerProviderServices getManager() {
277
        return (DataManagerProviderServices) DALLocator.getDataManager();
278
    }
279

    
280
    @Override
281
    public JDBCServerExplorerParameters getParameters() {
282
        return (JDBCServerExplorerParameters) super.getParameters();
283
    }
284

    
285
    @Override
286
    public boolean closeResourceRequested(ResourceProvider resource) {
287
        this.getHelper().getResulSetControler().pack();
288
        return true;
289
    }
290

    
291
    @Override
292
    public void resourceChanged(ResourceProvider resource) {
293
        // Nothing to do
294
    }
295

    
296
    protected JDBCHelper getHelper() {
297
        return helper;
298
    }
299

    
300
    protected OperationsFactory getOperations() {
301
        return this.getHelper().getOperations();
302
    }
303

    
304
    @Override
305
    public DataStore open(DataStoreParameters params) throws DataException {
306
        checkIsMine(params);
307
        DataStore store = super.open(params);
308
        return store;
309
    }
310

    
311
    @Override
312
    public List list(int mode) throws DataException {
313
        boolean informationTables = BooleanUtils.isTrue(
314
                this.getParameters().getShowInformationDBTables()
315
        );
316

    
317
        JDBCServerExplorerParameters serverParams = this.getParameters();
318

    
319
        String key = buildKeyForCachedTables(mode, serverParams, informationTables);
320
        CachedValue<List<JDBCStoreParameters>> tablesValue = CACHED_TABLES.get(key);
321
        List<JDBCStoreParameters> tables = null;
322
        if (tablesValue != null) {
323
            tables = tablesValue.get();
324
        }
325
        if (tables != null) {
326
            return tables;
327
        }
328
        tablesValue = new CachedTablesValue(this.helper, mode, serverParams, informationTables, 60000); //60"
329
        CACHED_TABLES.put(key, tablesValue);
330
        tables = tablesValue.get();
331
        return tables;
332
    }
333

    
334
    public String buildKeyForCachedTables(int mode, JDBCServerExplorerParameters params, boolean informationTables) {
335
        JDBCServerExplorerParameters clonedParams = (JDBCServerExplorerParameters) params.getCopy();
336
        clonedParams.setSchema(null); //ListTableOperation no usa el schema
337

    
338
        StringBuilder builder = new StringBuilder();
339
        builder.append(String.valueOf(mode));
340
        builder.append(Hex.encodeHex(clonedParams.toByteArray()));
341
        builder.append(String.valueOf(informationTables));
342
        String key = builder.toString();
343
        return key;
344
    }
345

    
346
    @Override
347
    public void remove(DataStoreParameters theParams) throws RemoveException {
348
        JDBCStoreParameters params = (JDBCStoreParameters) theParams;
349
        DropTableOperation removeTable = this.getOperations().createDropTable(
350
                this.getOperations().createTableReference(params)
351
        );
352
        if ((Boolean) removeTable.perform()) {
353
            this.dropCachedTables();
354
        }
355
    }
356

    
357
    @Override
358
    public JDBCStoreParameters getOpenParameters() throws DataException {
359
        JDBCStoreParameters params = this.helper.createOpenStoreParameters(this.getParameters());
360
        return params;
361
    }
362

    
363
    @Override
364
    public NewDataStoreParameters getAddParameters(String storeName)
365
            throws DataException {
366
        JDBCNewStoreParameters params = this.getAddParameters();
367
        params.setTable(storeName);
368
        return params;
369
    }
370

    
371
    @Override
372
    public JDBCNewStoreParameters getAddParameters() throws DataException {
373
        JDBCServerExplorerParameters parameters = getParameters();
374
        JDBCNewStoreParameters params = this.helper.createNewStoreParameters();
375
        params.setHost(parameters.getHost());
376
        params.setPort(parameters.getPort());
377
        params.setDBName(parameters.getDBName());
378
        params.setUser(parameters.getUser());
379
        params.setPassword(parameters.getPassword());
380
        params.setCatalog(parameters.getCatalog());
381
        params.setSchema(parameters.getSchema());
382
        params.setJDBCDriverClassName(parameters.getJDBCDriverClassName());
383
        params.setUrl(parameters.getUrl());
384
        if (parameters instanceof FilesystemStoreParameters) {
385
            File f = ((FilesystemStoreParameters) parameters).getFile();
386
            ((FilesystemStoreParameters) params).setFile(f);
387
        }
388

    
389
        params.setDefaultFeatureType(this.getServerExplorerProviderServices()
390
                .createNewFeatureType());
391

    
392
        return params;
393
    }
394

    
395
    protected void checkIsMine(DataStoreParameters dsp) {
396
        if (!(dsp instanceof JDBCConnectionParameters)) {
397
            throw new IllegalArgumentException(
398
                    "not instance of FilesystemStoreParameters");
399
        }
400
        JDBCServerExplorerParameters parameters = getParameters();
401

    
402
        JDBCConnectionParameters pgp = (JDBCConnectionParameters) dsp;
403
        if (!StringUtils.equals(pgp.getHost(), parameters.getHost())) {
404
            throw new IllegalArgumentException("wrong explorer: Host (mine: "
405
                    + parameters.getHost() + " other:" + pgp.getHost() + ")");
406
        }
407
        if (!ObjectUtils.equals(pgp.getPort(), parameters.getPort())) {
408
            throw new IllegalArgumentException("wrong explorer: Port (mine: "
409
                    + parameters.getPort() + " other:" + pgp.getPort() + ")");
410
        }
411
        if (!StringUtils.equals(pgp.getDBName(), parameters.getDBName())) {
412
            throw new IllegalArgumentException("wrong explorer: DBName (mine: "
413
                    + parameters.getDBName() + " other:" + pgp.getDBName()
414
                    + ")");
415
        }
416
        if (!StringUtils.isEmpty(parameters.getCatalog())) {
417
            if (!StringUtils.equals(pgp.getCatalog(), parameters.getCatalog())) {
418
                throw new IllegalArgumentException(
419
                        "wrong explorer: Catalog (mine: "
420
                        + parameters.getCatalog() + " other:"
421
                        + pgp.getCatalog() + ")");
422
            }
423
        }
424
        if (!StringUtils.isEmpty(parameters.getSchema())) {
425
            if (!StringUtils.equals(pgp.getSchema(), parameters.getSchema())) {
426
                throw new IllegalArgumentException(
427
                        "wrong explorer: Schema (mine: "
428
                        + parameters.getSchema() + " other:"
429
                        + pgp.getSchema() + ")");
430
            }
431
        }
432
    }
433

    
434
    @Override
435
    public void open() throws OpenException {
436

    
437
    }
438

    
439
    @Override
440
    public void close() throws CloseException {
441

    
442
    }
443

    
444
    @Override
445
    protected void doDispose() throws BaseException {
446
        synchronized (CACHED_TABLES) {
447
            List<String> toRemove = new ArrayList<>();
448
            for (Map.Entry<String, CachedValue<List<JDBCStoreParameters>>> entry : CACHED_TABLES.entrySet()) {
449
                CachedTablesValue value = (CachedTablesValue) entry.getValue();
450
                if (value.getHelper() == this.helper) {
451
                    toRemove.add(entry.getKey());
452
                    value.dispose();
453
                }
454
            }
455
            for (String key : toRemove) {
456
                CACHED_TABLES.remove(key);
457
            }
458
            helper.dispose();
459
            helper = null;
460
        }
461
    }
462

    
463
    @Override
464
    public boolean canAdd() {
465
        if (this.canAdd == null) {
466
            CanCreateTablesOperation canAdd_ = this.getOperations().createCanCreateTables();
467
            this.canAdd = (Boolean) canAdd_.perform();
468
        }
469
        return this.canAdd;
470
    }
471

    
472
    @Override
473
    public FeatureType getFeatureType(DataStoreParameters theParams)
474
            throws DataException {
475

    
476
        JDBCStoreParameters params = (JDBCStoreParameters) theParams;
477

    
478
        checkIsMine(params);
479

    
480
        EditableFeatureType fetureType
481
                = this.getServerExplorerProviderServices().createNewFeatureType();
482

    
483
        List<String> primaryKeys = null;
484
        if (params.getPkFields() != null) {
485
            primaryKeys = Arrays.asList(params.getPkFields());
486
        }
487

    
488
        FetchFeatureTypeOperation fetch = this.getOperations().createFetchFeatureType(
489
                fetureType,
490
                this.getOperations().createTableReference(params),
491
                primaryKeys,
492
                params.getDefaultGeometryField(),
493
                params.getCRS()
494
        );
495
        fetch.perform();
496
        return fetureType;
497
    }
498

    
499
    @Override
500
    public boolean add(String providerName, NewDataStoreParameters theParams, boolean overwrite)
501
            throws DataException {
502

    
503
        List<Pair<String, Privilege>> userAndPrivileges = new ArrayList<>();
504
        JDBCNewStoreParameters params = (JDBCNewStoreParameters) theParams;
505
        if (!StringUtils.isEmpty(params.getAllRole())) {
506
            userAndPrivileges.add(
507
                    new ImmutablePair<>(params.getAllRole(), Privilege.ALL)
508
            );
509
        }
510
        if (!StringUtils.isEmpty(params.getDeleteRole())) {
511
            userAndPrivileges.add(
512
                    new ImmutablePair<>(params.getDeleteRole(), Privilege.DELETE)
513
            );
514
        }
515
        if (!StringUtils.isEmpty(params.getInsertRole())) {
516
            userAndPrivileges.add(
517
                    new ImmutablePair<>(params.getInsertRole(), Privilege.INSERT)
518
            );
519
        }
520
        if (!StringUtils.isEmpty(params.getReferenceRole())) {
521
            userAndPrivileges.add(
522
                    new ImmutablePair<>(params.getReferenceRole(), Privilege.REFERENCE)
523
            );
524
        }
525
        if (!StringUtils.isEmpty(params.getSelectRole())) {
526
            userAndPrivileges.add(
527
                    new ImmutablePair<>(params.getSelectRole(), Privilege.SELECT)
528
            );
529
        }
530
        if (!StringUtils.isEmpty(params.getTriggerRole())) {
531
            userAndPrivileges.add(
532
                    new ImmutablePair<>(params.getTriggerRole(), Privilege.TRIGGER)
533
            );
534
        }
535
        if (!StringUtils.isEmpty(params.getTruncateRole())) {
536
            userAndPrivileges.add(
537
                    new ImmutablePair<>(params.getTruncateRole(), Privilege.TRUNCATE)
538
            );
539
        }
540
        if (!StringUtils.isEmpty(params.getUpdateRole())) {
541
            userAndPrivileges.add(
542
                    new ImmutablePair<>(params.getUpdateRole(), Privilege.UPDATE)
543
            );
544
        }
545
        List<String> additionalSQLs = new ArrayList<>();
546
        if (!StringUtils.isEmpty(params.getPostCreatingStatement())) {
547
            additionalSQLs.add(params.getPostCreatingStatement());
548
        }
549
        CreateTableOperation createTable = this.getOperations().createTable(
550
                this.getOperations().createTableReference(params),
551
                params.getDefaultFeatureType(),
552
                userAndPrivileges,
553
                additionalSQLs
554
        );
555

    
556
        boolean isOk = (boolean) createTable.perform();
557
        if (!isOk) {
558
            return false;
559
        }
560

    
561
        // We collect the featureType of the operation because 
562
        // the provider has been able to make changes to it
563
        params.setDefaultFeatureType(createTable.getType());
564

    
565
        if (theParams instanceof NewFeatureStoreParameters) {
566
            DataManager dataManager = DALLocator.getDataManager();
567
            ResourcesStorage resources = this.getResourcesStorage(theParams);
568
            dataManager.writeDALResource(resources, ((NewFeatureStoreParameters) theParams).getDefaultFeatureType());
569
        }
570
        this.dropCachedTables();
571
        return true;
572
    }
573

    
574
    private void dropCachedTables() {
575
        boolean informationTables = BooleanUtils.isTrue(
576
                this.getParameters().getShowInformationDBTables()
577
        );
578
        synchronized(CACHED_TABLES){
579
            CACHED_TABLES.remove(buildKeyForCachedTables(MODE_ALL, this.getParameters(), informationTables));
580
            CACHED_TABLES.remove(buildKeyForCachedTables(MODE_FEATURE, this.getParameters(), informationTables));
581
            CACHED_TABLES.remove(buildKeyForCachedTables(MODE_GEOMETRY, this.getParameters(), informationTables));
582
        }
583
    }
584

    
585
    @Override
586
    public List getDataStoreProviderNames() {
587
        List x = new ArrayList(1);
588
        x.add(this.getProviderName());
589
        return x;
590
    }
591

    
592
    @Override
593
    public void updateTableStatistics(String database, String schema, String table) throws JDBCExecuteSQLException {
594
        UpdateTableStatisticsOperation updateStatistics = this.getOperations().createUpdateTableStatistics(
595
                this.getOperations().createTableReference(database, schema, table, null)
596
        );
597
        updateStatistics.perform();
598
    }
599

    
600
    @Override
601
    public Object execute(String sql) {
602
        ExecuteOperation execute = this.getOperations().createExecute(sql);
603
        return execute.perform();
604
    }
605

    
606
    @Override
607
    public JDBCStoreParameters get(String name) throws DataException {
608
        JDBCStoreParameters params = this.getOpenParameters();
609
        params.setTable(name);
610
        return params;
611
    }
612

    
613
    @Override
614
    public SQLBuilder createSQLBuilder() {
615
        JDBCSQLBuilderBase builder = this.getHelper().createSQLBuilder();
616
        return builder;
617
    }
618

    
619
    private CustomResourcesConfig getCustomResourcesConfig() {
620
        JDBCServerExplorerParameters serverParams = this.getParameters();
621
        String key = buildKeyForCachedTables(MODE_ALL, serverParams, false);
622
        CachedValue<CustomResourcesConfig> cachedConfig = CACHED_CUSTOM_RESOURCES_CONFIG.get(key);
623
        if (cachedConfig != null) {
624
            CustomResourcesConfig config = cachedConfig.get();
625
            return config;
626
        }
627
        JDBCStoreParameters params = this.helper.createOpenStoreParameters(this.getParameters());
628
        cachedConfig = new CachedCustomResourcesConfig(params);
629
        CACHED_CUSTOM_RESOURCES_CONFIG.put(key, cachedConfig);
630
        return cachedConfig.get();
631
    }
632

    
633
    private ResourcesStorage getResourcesStorage(DataStoreParameters parameters, String storeName) {
634
        if (DatabaseWorkspaceManager.isInternalTable(storeName)) {
635
            EmptyResourcesStorage resourcesStorage = new EmptyResourcesStorage();
636
            return resourcesStorage;
637
        }
638
        String resourcesTablename = null;
639
        try { 
640
            ResourcesStorage alternateResourcesStorage = null;
641
            DataManager dataManager = DALLocator.getDataManager();
642
            DatabaseWorkspaceManager workspace = dataManager.getDatabaseWorkspace(parameters);
643
            if (workspace != null) {
644
                alternateResourcesStorage = workspace.getAlternativeResourcesStorage(storeName);
645
            }
646
            
647
            CustomResourcesConfig config = getCustomResourcesConfig();
648
            if( config!=null ) {
649
                if( config.isInternalTable(storeName) ) {
650
                    EmptyResourcesStorage theResourcesStorage = new EmptyResourcesStorage();
651
                    return theResourcesStorage;
652
                }
653
                resourcesTablename = config.getResourcesTablename(storeName);
654
                if( StringUtils.isNotBlank(resourcesTablename) ) {
655
                    JDBCStoreParameters params = this.getOpenParameters();
656
                    params.setTable(resourcesTablename);
657
                    JDBCResourcesStorage resourcesStorage = new JDBCResourcesStorage(
658
                            alternateResourcesStorage,
659
                            params,
660
                            storeName
661
                    );
662
                    return resourcesStorage;
663
                }
664
            }
665
            // TODO: Habria que ver de localizar los parametros sin tener que hacer un list.
666
            resourcesTablename = TABLE_RESOURCES_NAME;
667
            List<JDBCStoreParameters> tables = this.list();
668
            for (JDBCStoreParameters params : tables) {
669
                String theTableName = params.getTable();
670
                if (StringUtils.equals(theTableName, resourcesTablename)) {
671
                    JDBCResourcesStorage theResourcesStorage = new JDBCResourcesStorage(
672
                            alternateResourcesStorage,
673
                            params,
674
                            storeName
675
                    );
676
                    return theResourcesStorage;
677
                }
678
            }
679
        } catch (Throwable ex) {
680
            LOG.warn("Can't retrieve reources storage for table '" + storeName + "' in '" + this.getParameters().getUrl() + " ("+resourcesTablename+").", ex);
681
        }
682
        EmptyResourcesStorage theResourcesStorage = new EmptyResourcesStorage();
683
        return theResourcesStorage;
684
    }
685

    
686
    @Override
687
    public ResourcesStorage getResourcesStorage() {
688
        JDBCStoreParameters params;
689
        try {
690
            params = this.getOpenParameters();
691
            params.setTable(DatabaseWorkspaceManager.TABLE_RESOURCES_NAME);
692
            JDBCResourcesStorage theResourcesStorage = new JDBCResourcesStorage(
693
                    null,
694
                    params,
695
                    "$ServerExplorer"
696
            );
697
            return theResourcesStorage;
698
        } catch (DataException ex) {
699
            return null;
700
        }
701
    }
702

    
703
    @Override
704
    public ResourcesStorage getResourcesStorage(DataStoreParameters parameters) {
705
        if (parameters == null) {
706
            throw new IllegalArgumentException("null is a valid value for parameters.");
707
        }
708
        String tableName;
709
        if (parameters instanceof JDBCNewStoreParameters) {
710
            tableName = ((JDBCNewStoreParameters) parameters).getTable();
711
        } else if (parameters instanceof JDBCStoreParameters) {
712
            tableName = ((JDBCStoreParameters) parameters).getTable();
713
        } else {
714
            throw new IllegalArgumentException("Required a JDBCStoreParameters or JDBCNewStoreParameters parameters, received " + parameters.getClass().getName() + ".");
715
        }
716
        return this.getResourcesStorage(parameters, tableName);
717
    }
718

    
719
    @Override
720
    public ResourcesStorage getResourcesStorage(DataStore dataStore) {
721
        return this.getResourcesStorage(
722
                (JDBCStoreParameters) dataStore.getParameters(),
723
                dataStore.getName()
724
        );
725
    }
726

    
727
    @Override
728
    public boolean exists(DataStoreParameters parameters) throws DataException {
729
        JDBCStoreParameters params = (JDBCStoreParameters) parameters;
730
        JDBCSQLBuilderBase builder = this.getHelper().createSQLBuilder();
731
        SQLBuilder.TableNameBuilder searchTable = builder.createTableNameBuilder()
732
                .database(params.getDBName())
733
                .schema(params.getSchema())
734
                .name(params.getTable());
735
        SQLBuilder.TableNameBuilder table = builder.createTableNameBuilder();
736

    
737
        List<JDBCStoreParameters> l = this.list();
738
        for (JDBCStoreParameters current : l) {
739
            table.database(current.getDBName())
740
                    .schema(current.getSchema())
741
                    .name(current.getTable());
742
            if (table.equals(searchTable)) {
743
                return true;
744
            }
745
        }
746
        return false;
747
    }
748

    
749
    @Override
750
    public void setCustomResources(String tableName, String resourcesTableName) {
751
        CustomResourcesConfig config = getCustomResourcesConfig();
752
        if( config==null ) {
753
            throw new RuntimeException("Can't retrieve alternative resources configuration");
754
        }
755
        config.addResourceMapping(tableName, resourcesTableName);
756
        JDBCStoreParameters params = this.helper.createOpenStoreParameters(this.getParameters());
757
        setConfigValue(params, CONFIG_NAME_CUSTOM_RESOURCES, config.toJsonString());
758
    }
759

    
760
    private static boolean setConfigValue(JDBCStoreParameters params, String name, String value) {
761
        FeatureStore store = null;
762
        try {
763
            DataManager dataManager = DALLocator.getDataManager();
764
            params.setTable(TABLE_CONFIGURATION_NAME);
765
            store = (FeatureStore) dataManager.openStore(
766
                    params.getProviderName(), 
767
                    params
768
            );
769
        } catch (Exception ex) {
770
            LOG.trace("Can't read configuration value '"+name+"'", ex);
771
            // Do noting
772
//        } finally {
773
//            DisposeUtils.disposeQuietly(store);
774
        }
775
        if( store == null ) {
776
            return false;
777
        }
778
        try {
779
            store.edit();
780
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
781
            String filter = builder.eq(
782
                    builder.column(FIELD_CONFIGURATION_NAME),
783
                    builder.constant(name)
784
            ).toString();
785
            Feature feature = store.findFirst(filter);
786
            EditableFeature efeature;
787
            if (feature == null) {
788
                efeature = store.createNewFeature();
789
                efeature.set(FIELD_CONFIGURATION_NAME, name);
790
                efeature.set(FIELD_CONFIGURATION_VALUE, value);
791
                store.insert(efeature);
792
            } else {
793
                efeature = feature.getEditable();
794
                efeature.set(FIELD_CONFIGURATION_VALUE, value);
795
                store.update(efeature);
796
            }
797
            store.finishEditing();
798
            return true;
799
        } catch (Exception ex) {
800
            LOG.debug("Can't write configuration value for '"+name+"'", ex);
801
            return false;
802
        } finally {
803
            DisposeUtils.disposeQuietly(store);
804
        }
805
    }
806
    
807
    private static String getConfigValue(JDBCStoreParameters params, String name) {
808
        FeatureStore store = null;
809
        try {
810
            DataManager dataManager = DALLocator.getDataManager();
811
            params.setTable(TABLE_CONFIGURATION_NAME);
812
            store = (FeatureStore) dataManager.openStore(
813
                    params.getProviderName(), 
814
                    params
815
            );
816
        } catch (Exception ex) {
817
            LOG.trace("Can't read configuration value '"+name+"'", ex);
818
            // Do noting
819
//        } finally {
820
//            DisposeUtils.disposeQuietly(store);
821
        }
822
        if( store == null ) {
823
            return null;
824
        }
825
        try {
826
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
827
            String filter = builder.eq(
828
                    builder.column(FIELD_CONFIGURATION_NAME),
829
                    builder.constant(name)
830
            ).toString();
831
            Feature feature = store.findFirst(filter);
832
            if( feature == null ) {
833
                return null;
834
            }
835
            String value = feature.getString(FIELD_CONFIGURATION_VALUE);
836
            return value;
837
            
838
        } catch (Exception ex) {
839
            LOG.debug("Can't read configuration value '"+name+"'", ex);
840
            return null;
841
        } finally {
842
            DisposeUtils.disposeQuietly(store);
843
        }
844
    }
845
    
846
}