Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / impl / DefaultDatabaseWorkspaceManager.java @ 47784

History | View | Annotate | Download (39.2 KB)

1
package org.gvsig.fmap.dal.impl;
2

    
3
import java.io.File;
4
import java.util.ArrayList;
5
import java.util.Collection;
6
import java.util.Collections;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Objects;
10
import org.apache.commons.collections4.map.LRUMap;
11
import org.apache.commons.lang3.StringUtils;
12
import org.gvsig.expressionevaluator.ExpressionBuilder;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
14
import org.gvsig.expressionevaluator.ExpressionUtils;
15
import org.gvsig.expressionevaluator.spi.AbstractSymbolTable;
16
import org.gvsig.fmap.dal.DALLocator;
17
import org.gvsig.fmap.dal.DataManager;
18
import org.gvsig.fmap.dal.DataServerExplorer;
19
import org.gvsig.fmap.dal.DataServerExplorerParameters;
20
import org.gvsig.fmap.dal.DataStoreParameters;
21
import org.gvsig.fmap.dal.DataTransaction;
22
import org.gvsig.fmap.dal.DataTypes;
23
import org.gvsig.fmap.dal.DatabaseWorkspaceManager;
24
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.CONFIG_NAME_STORESREPOSITORYID;
25
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.CONFIG_NAME_STORESREPOSITORYLABEL;
26
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_CONFIGURATION_NAME;
27
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_CONFIGURATION_VALUE;
28
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_REPOSITORY_FLAGS;
29
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_REPOSITORY_NAME;
30
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_REPOSITORY_PARAMETERS;
31
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_RESOURCES_NAME;
32
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.FIELD_RESOURCES_RESOURCE;
33
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_CONFIGURATION;
34
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_CONFIGURATION_NAME;
35
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_REPOSITORY;
36
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_REPOSITORY_NAME;
37
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_RESOURCES;
38
import static org.gvsig.fmap.dal.DatabaseWorkspaceManager.TABLE_RESOURCES_NAME;
39
import org.gvsig.fmap.dal.StoresRepository;
40
import org.gvsig.fmap.dal.SupportTransactionsHelper;
41
import org.gvsig.fmap.dal.feature.EditableFeature;
42
import org.gvsig.fmap.dal.feature.EditableFeatureType;
43
import org.gvsig.fmap.dal.feature.Feature;
44
import org.gvsig.fmap.dal.feature.FeatureStore;
45
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
46
import org.gvsig.fmap.dal.feature.spi.LocalTransaction;
47
import static org.gvsig.fmap.dal.impl.DatabaseWorkspaceStoresRepository.BIT_CHANGE_DBNAME_CATALOG_SCHEMA;
48
import static org.gvsig.fmap.dal.impl.DatabaseWorkspaceStoresRepository.BIT_CHANGE_PORT_HOST;
49
import static org.gvsig.fmap.dal.impl.DatabaseWorkspaceStoresRepository.BIT_CHANGE_USER;
50
import org.gvsig.tools.dispose.DisposeUtils;
51
import org.gvsig.tools.dynobject.DynClass;
52
import org.gvsig.tools.dynobject.DynField;
53
import org.gvsig.tools.resourcesstorage.FilesResourcesStorage;
54
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
55
import org.gvsig.tools.util.Bitmask;
56
import org.gvsig.tools.util.CachedValue;
57
import org.gvsig.tools.util.FileTools;
58
import org.gvsig.tools.util.HasAFile;
59
import org.slf4j.Logger;
60
import org.slf4j.LoggerFactory;
61

    
62
/**
63
 *
64
 * @author jjdelcerro
65
 */
66
@SuppressWarnings("UseSpecificCatch")
67
public class DefaultDatabaseWorkspaceManager 
68
        extends AbstractSymbolTable
69
        implements DatabaseWorkspaceManager
70
    {
71
    
72
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDatabaseWorkspaceManager.class);
73

    
74
    private static final String CONFIG_NAME_BASEFOLDER = "BASEFOLDER";
75
    private static final String CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH = "ALTERNATIVE_RESOURCES_PATH";
76
    
77
    private SupportTransactionsHelper transactionsHelper;
78

    
79
    private class CachedConfigValue extends CachedValue<String> {
80

    
81
        private final String name;
82
      
83
        public CachedConfigValue(String name, String value) {
84
          this.setValue(value);
85
          this.name = name;
86
        }
87
      
88
        public CachedConfigValue(String name, String value, long expireTime) {
89
          this.name = name;
90
          this.setValue(value);
91
          this.setExpireTime(expireTime);
92
        }
93
      
94
        @Override
95
        protected void reload() {
96
//            LOGGER.info("reload CachedConfigValue "+name);
97
            String s = DefaultDatabaseWorkspaceManager.this.getConfigValue(name);
98
            if( StringUtils.isBlank(s) ) {
99
                this.setValue(null);
100
            } else {
101
                this.setValue(s);
102
            }
103
        }
104

    
105
        @Override
106
        public String toString() {
107
            return this.name+" = "+this.getValue();
108
        }
109
        
110
        
111
    }
112
    
113
    private final DataServerExplorerParameters serverParameters;
114
    private Boolean existsConfiguration = null;
115
    private StoresRepository storesRepository;
116
    private CachedConfigValue alternativeResourcesFolder = null;
117
    private CachedValue<File> baseFolder;
118
    private Map<String,CachedConfigValue> cachedConfigValues;
119
    
120
    public DefaultDatabaseWorkspaceManager(DataServerExplorerParameters serverParameters) {
121
        this.serverParameters = serverParameters;
122
        this.transactionsHelper = new SupportTransactionsHelper();
123
        this.baseFolder = new CachedValue() {
124
          @Override
125
          protected void reload() {
126
            String s = DefaultDatabaseWorkspaceManager.this.getConfigValue(CONFIG_NAME_BASEFOLDER);
127
            if( StringUtils.isBlank(s) ) {
128
                this.setValue(null);
129
            } else {
130
                s = ExpressionUtils.evaluateDynamicText(DefaultDatabaseWorkspaceManager.this, s);
131
                this.setValue(new File(s));
132
            }
133
          }
134
          
135
        };
136
        this.baseFolder.setExpireTime(20000); // 20seg
137
        this.alternativeResourcesFolder = new CachedConfigValue(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH, null, 30000);
138
//        this.alternativeResourcesFolder = new CachedValue() {
139
//          @Override
140
//          protected void reload() {
141
//            String s = DefaultDatabaseWorkspaceManager.this.getConfigValue(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH);
142
//            if( StringUtils.isBlank(s) ) {
143
//                this.setValue(null);
144
//            } else {
145
//                this.setValue(new File(s));
146
//            }
147
//          }
148
//          
149
//        };
150
//        this.alternativeResourcesFolder.setExpireTime(30000); // 20seg
151
        
152
        this.cachedConfigValues = new LRUMap<>(20, 20);
153
        ExpressionEvaluatorLocator.getExpressionEvaluatorManager().populateSymbolTable(this);
154
        
155
    }
156

    
157
    @Override
158
    public String toString() {
159
        return this.getLabel();
160
    }
161
    
162
    @Override
163
    public String getId() {
164
        String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
165
        return id;
166
    }
167
    
168
    @Override
169
    public String getLabel() {
170
        String label = this.get(CONFIG_NAME_STORESREPOSITORYLABEL);
171
        if (StringUtils.isBlank(label)) {
172
            return this.getId();
173
        }
174
        return label;
175
    }
176

    
177
    @Override
178
    public DatabaseWorkspaceManager getValue() {
179
        return this;
180
    }
181
    
182
    @Override
183
    public boolean existsTable(int tableid) {
184
        switch(tableid) {
185
            case TABLE_RESOURCES:
186
                return this.existsTable(TABLE_RESOURCES_NAME);
187
            case TABLE_REPOSITORY:
188
                return this.existsTable(TABLE_REPOSITORY_NAME);
189
            case TABLE_CONFIGURATION:
190
                return this.existsTable(TABLE_CONFIGURATION_NAME);
191
            default:
192
                throw new IllegalArgumentException("Invalid table identitier "+tableid);
193
        }
194
    }
195
    
196
    @Override
197
    public void createTable(int tableid) {
198
        switch(tableid) {
199
            case TABLE_RESOURCES:
200
                createTableResources();
201
                break;
202
            case TABLE_REPOSITORY:
203
                createTableRepository();
204
                break;
205
            case TABLE_CONFIGURATION:
206
                createTableConfiguration();
207
                break;
208
            default:
209
                throw new IllegalArgumentException("Invalid table identitier "+tableid);
210
        }
211
    }
212
    
213
    @Override
214
    public void dropTable(int tableid) {
215
        switch(tableid) {
216
            case TABLE_RESOURCES:
217
                this.dropTable(TABLE_RESOURCES_NAME);
218
                break;
219
            case TABLE_REPOSITORY:
220
                this.dropTable(TABLE_REPOSITORY_NAME);
221
                break;
222
            case TABLE_CONFIGURATION:
223
                this.dropTable(TABLE_CONFIGURATION_NAME);
224
                break;
225
            default:
226
                throw new IllegalArgumentException("Invalid table identitier "+tableid);
227
        }
228
    }
229
    
230
    @Override
231
    public FeatureStore getTable(int tableid) {
232
        switch(tableid) {
233
            case TABLE_RESOURCES:
234
                return this.getTable(TABLE_RESOURCES_NAME);
235
            case TABLE_REPOSITORY:
236
                return this.getTable(TABLE_REPOSITORY_NAME);
237
            case TABLE_CONFIGURATION:
238
                return this.getTable(TABLE_CONFIGURATION_NAME);
239
            default:
240
                throw new IllegalArgumentException("Invalid table identitier "+tableid);
241
        }
242
    }
243
    
244
    @Override
245
    public DataServerExplorer getServerExplorer() {
246
        DataManager dataManager = DALLocator.getDataManager();
247
        DataServerExplorer server = null;
248
        LocalTransaction trans = new LocalTransaction(dataManager, this.getTransaction());
249
        try {
250
            trans.begin();
251
            trans.add(this);
252
            server = dataManager.openServerExplorer(
253
                    this.serverParameters.getProviderName(),
254
                    this.serverParameters
255
            );
256
            trans.add(server);
257
            trans.commit();
258
            return server;
259
        } catch (Exception ex) {
260
            trans.abortQuietly();
261
            throw new RuntimeException("Can't get server explorer for workspace '"+Objects.toString(this.serverParameters)+"'", ex);
262
        } finally {
263
            trans.closeQuietly();
264
        }
265
    }
266

    
267
    @Override
268
    public DataServerExplorerParameters getServerExplorerParameters() {
269
        return this.serverParameters;
270
    }
271
    
272
    
273
    
274
    private boolean existsTable(String tableName) {
275
        DataServerExplorer server = null;
276
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
277
        try {
278
            trans.begin();
279
            trans.add(this);
280
            server = this.getServerExplorer();
281
            trans.add(server);
282
            List<DataStoreParameters> list = server.list();
283
            if(list == null){
284
                trans.commit();
285
                return false;
286
            }
287
            for (DataStoreParameters params : server.list()) {
288
                String theTableName = (String) params.getDynValue("Table");
289
                if( StringUtils.equals(theTableName, tableName) ) {
290
                    trans.commit();
291
                    return true;
292
                }
293
            }
294
            trans.commit();
295
        } catch (Exception ex) {
296
            LOGGER.warn("Can't check if the table '"+tableName+"' exists.",ex);
297
            trans.abortQuietly();
298
        } finally {
299
            trans.closeQuietly();
300
            DisposeUtils.disposeQuietly(server);
301
        }
302
        return false;
303
    }
304

    
305
    private FeatureStore getTable(String tableName) {
306
        DataServerExplorer server = null;
307
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
308
        try {
309
            trans.begin();
310
            trans.add(this);
311
            DataManager dataManager = DALLocator.getDataManager();
312
            server = this.getServerExplorer();
313
            trans.add(server);
314
            DataStoreParameters params = server.get(tableName);
315
            if( params!=null ) {
316
                FeatureStore store = (FeatureStore) dataManager.openStore(
317
                        this.getTransaction(),
318
                        params.getProviderName(), 
319
                        params,
320
                        true
321
                );
322
                trans.commit();
323
                return store;
324
            }
325
            trans.commit();
326
        } catch (Exception ex) {
327
            LOGGER.warn("Can't open table '"+tableName+"'.",ex);
328
            trans.abortQuietly();
329
        } finally {
330
            trans.closeQuietly();
331
            DisposeUtils.disposeQuietly(server);
332
        }
333
        return null;
334
    }
335

    
336
    private void dropTable(String tableName) {
337
        DataServerExplorer server = null;
338
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
339
        try {
340
            trans.begin();
341
            trans.add(this);
342
            server = this.getServerExplorer();
343
            trans.add(server);
344
            DataStoreParameters params = server.get(tableName);
345
            if( params!=null ) {
346
                server.remove(params);
347
            }
348
            trans.commit();
349
        } catch (Exception ex) {
350
            LOGGER.warn("Can't drop table '"+tableName+"'.",ex);
351
            trans.abortQuietly();
352
        } finally {
353
            trans.closeQuietly();
354
            DisposeUtils.disposeQuietly(server);
355
        }
356
    }
357
    
358
    @Override
359
    public void createTableResources(String tableName) throws RuntimeException {
360
        // H2Spatial crea esta table a mano. 
361
        // Si tocamos algo aqu? hay que modificar 
362
        // la creacion de esta tabla en el helper de H2
363

    
364
        DataServerExplorer server = null;
365
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
366
        try {
367
            trans.begin();
368
            trans.add(this);
369
            server = this.getServerExplorer();
370
            trans.add(server);
371
            NewFeatureStoreParameters params = (NewFeatureStoreParameters) server.getAddParameters(tableName);
372
            EditableFeatureType ft = params.getDefaultFeatureType();
373
            ft.add(FIELD_RESOURCES_NAME, DataTypes.STRING, 150)
374
                    .setAllowNull(false)
375
                    .setIsPrimaryKey(true);
376
            ft.add(FIELD_RESOURCES_RESOURCE, DataTypes.BYTEARRAY)
377
                    .setAllowNull(true);
378
            server.add(tableName, params, false);
379
            trans.commit();
380
        } catch (Exception ex) {
381
            LOGGER.debug("Can't create resources table '"+tableName+"'.",ex);
382
            trans.abortQuietly();
383
            throw new RuntimeException("Can't create resources table '"+tableName+"'.", ex);
384
        } finally {
385
            trans.closeQuietly();
386
            DisposeUtils.disposeQuietly(server);
387
        }
388
    }
389

    
390
    private void createTableResources() {    
391
        createTableResources(TABLE_RESOURCES_NAME);
392
    }
393
    
394
    @Override
395
    public void createTableRepository(String tableName) throws RuntimeException {
396
        DataServerExplorer server = null;
397
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
398
        try {
399
            trans.begin();
400
            trans.add(this);
401
            server = this.getServerExplorer();
402
            trans.add(server);
403
            NewFeatureStoreParameters params = (NewFeatureStoreParameters) server.getAddParameters(tableName);
404
            EditableFeatureType ft = params.getDefaultFeatureType();
405
            ft.add(FIELD_REPOSITORY_NAME, DataTypes.STRING, 150)
406
                    .setAllowNull(false)
407
                    .setIsPrimaryKey(true);
408
            ft.add(FIELD_REPOSITORY_PARAMETERS, DataTypes.BYTEARRAY)
409
                    .setAllowNull(true);
410
            ft.add(FIELD_REPOSITORY_FLAGS, DataTypes.INT)
411
                    .setAllowNull(false)
412
                    .setDefaultValue(0);
413
            server.add(tableName, params, false);
414
            trans.commit();
415
        } catch (Exception ex) {
416
            LOGGER.debug("Can't create repository table '"+tableName+"'.",ex);
417
            trans.abortQuietly();
418
            throw new RuntimeException("Can't create repository table '"+tableName+"'.", ex);
419
        } finally {
420
            trans.closeQuietly();
421
            DisposeUtils.disposeQuietly(server);
422
        }
423
    }
424

    
425
    private void createTableRepository() {
426
        createTableRepository(TABLE_REPOSITORY_NAME);
427
    }
428
    
429
    private void createTableConfiguration() {
430
        // H2Spatial crea esta table a mano. 
431
        // Si tocamos algo aqu? hay que modificar 
432
        // la creacion de esta tabla en el helper de H2
433
        String tableName = TABLE_CONFIGURATION_NAME;
434
        DataServerExplorer server = null;
435
        FeatureStore store = null;
436
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
437
        try {
438
            trans.begin();
439
            trans.add(this);
440
            server = this.getServerExplorer();
441
            trans.add(server);
442
            NewFeatureStoreParameters params = (NewFeatureStoreParameters) server.getAddParameters(tableName);
443
            EditableFeatureType ft = params.getDefaultFeatureType();
444
            ft.add(FIELD_CONFIGURATION_NAME, DataTypes.STRING, 200)
445
                    .setAllowNull(false)
446
                    .setIsPrimaryKey(true);
447
            ft.add(FIELD_CONFIGURATION_VALUE, DataTypes.STRING, 10240)
448
                    .setAllowNull(true);
449
            server.add(tableName, params, false);
450
            
451
            DataStoreParameters openParams = server.get(TABLE_CONFIGURATION_NAME);
452
            store = (FeatureStore) DALLocator.getDataManager().openStore(
453
                    this.getTransaction(), openParams.getProviderName(), openParams
454
            );
455
            store.edit();
456
            EditableFeature efeature = store.createNewFeature();
457
            efeature.set(FIELD_CONFIGURATION_NAME, CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH);
458
            efeature.set(FIELD_CONFIGURATION_VALUE, null);
459
            store.insert(efeature);
460
            store.finishEditing();                    
461
                    
462
            this.existsConfiguration = null;
463
            trans.commit();
464
        } catch (Exception ex) {
465
            LOGGER.warn("Can't create table '"+tableName+"'.",ex);
466
//            FeatureStore.cancelEditingQuietly(store);
467
            trans.abortQuietly();
468
        } finally {
469
            trans.closeQuietly();
470
            DisposeUtils.disposeQuietly(server);
471
            DisposeUtils.disposeQuietly(store);
472
        }
473
    }
474
    
475
    private boolean existsConfiguration() {
476
        if( this.existsConfiguration==null ) {
477
            this.existsConfiguration = this.existsTable(TABLE_CONFIGURATION_NAME);
478
        }
479
        return this.existsConfiguration;
480
    }
481

    
482
    @Override
483
    public String get(String name) {
484
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
485
        try {
486
            trans.begin();
487
            trans.add(this);
488
            if (!this.existsConfiguration()) {
489
                trans.commit();
490
                return null;
491
            }
492
            if (StringUtils.equalsIgnoreCase(name, CONFIG_NAME_BASEFOLDER)) {
493
                String s = Objects.toString(this.baseFolder.get(), null);
494
                trans.commit();
495
                return s;
496
            }
497
            if (StringUtils.equalsIgnoreCase(name, CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH)) {
498
                String s = Objects.toString(this.alternativeResourcesFolder.get(), null);
499
                trans.commit();
500
                return s;
501
            }
502
            CachedConfigValue cachedValue = this.cachedConfigValues.get(name);
503
            if (cachedValue != null) {
504
                String s = cachedValue.get();
505
                trans.commit();
506
                return s;
507
            }
508
            String value = this.getConfigValue(name);
509
            this.cachedConfigValues.put(name, new CachedConfigValue(name, value, 15000));
510
            value = ExpressionUtils.evaluateDynamicText(this, value);
511
            trans.commit();
512
            return value;
513
        } catch (Exception ex) {
514
            LOGGER.warn("Can't read configuration value '"+name+"'", ex);
515
            trans.abortQuietly();
516
            return null;
517
        } finally {
518
            trans.closeQuietly();
519
        }
520
    }
521
    
522
    private String getConfigValue(String name) {
523
        FeatureStore store = null;
524
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
525
        try {
526
            trans.begin();
527
            trans.add(this);
528
            if( !this.existsConfiguration() ) {
529
                trans.commit();
530
                return null;
531
            }
532
            store = this.getTable(TABLE_CONFIGURATION);
533
            if( store == null ) {
534
                trans.commit();
535
                return null;
536
            }
537
            trans.add(store);
538
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
539
            String filter = builder.eq(
540
                    builder.column(FIELD_CONFIGURATION_NAME),
541
                    builder.constant(name)
542
            ).toString();
543
            Feature feature = store.findFirst(filter);
544
            if( feature == null ) {
545
                trans.commit();
546
                return null;
547
            }
548
            String value = feature.getString(FIELD_CONFIGURATION_VALUE);
549
//            value = ExpressionUtils.evaluateDynamicText(this, value);
550
            trans.commit();
551
            return value;
552
            
553
        } catch (Exception ex) {
554
            LOGGER.warn("Can't read configuration value '"+name+"'", ex);
555
            trans.abortQuietly();
556
            return null;
557
        } finally {
558
            trans.closeQuietly();
559
            DisposeUtils.disposeQuietly(store);
560
        }
561
    }
562

    
563
    @Override
564
    public boolean set(String name, String value) {
565
        FeatureStore store = null;
566
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
567
        try {
568
            trans.begin();
569
            trans.add(this);
570
            if( !this.existsConfiguration() ) {
571
                trans.commit();
572
                return false;
573
            }
574
            store = this.getTable(TABLE_CONFIGURATION);
575
            if( store == null ) {
576
                trans.commit();
577
                return false;
578
            }
579
            trans.add(store);
580
            store.edit();
581
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
582
            String filter = builder.eq(
583
                    builder.column(FIELD_CONFIGURATION_NAME),
584
                    builder.constant(name)
585
            ).toString();
586
            Feature feature = store.findFirst(filter);
587
            EditableFeature efeature;
588
            if (feature == null) {
589
                efeature = store.createNewFeature();
590
                efeature.set(FIELD_CONFIGURATION_NAME, name);
591
                efeature.set(FIELD_CONFIGURATION_VALUE, value);
592
                store.insert(efeature);
593
            } else {
594
                efeature = feature.getEditable();
595
                efeature.set(FIELD_CONFIGURATION_VALUE, value);
596
                store.update(efeature);
597
            }
598
            store.finishEditing();
599
            if( StringUtils.equalsIgnoreCase(name, CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH)) {
600
                this.alternativeResourcesFolder.expired();
601
            } else if( this.cachedConfigValues.containsKey(name) ) {
602
                value = ExpressionUtils.evaluateDynamicText(this, value);
603
                this.cachedConfigValues.get(name).set(value);
604
            }
605
            trans.commit();
606
            return true;
607
        } catch (Exception ex) {
608
            LOGGER.warn("Can't write configuration value '"+name+"'", ex);
609
            trans.abortQuietly();
610
            return false;
611
        } finally {
612
            trans.closeQuietly();
613
            DisposeUtils.disposeQuietly(store);
614
        }
615
    }
616

    
617
    @Override
618
    public StoresRepository getStoresRepository() {
619
        if( this.storesRepository==null ) {
620
            String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
621
            String label = this.get(CONFIG_NAME_STORESREPOSITORYLABEL);
622
            this.storesRepository = new DatabaseWorkspaceStoresRepository(
623
                    id,
624
                    label,
625
                    this
626
            );
627
        }
628
        return this.storesRepository;
629
    }
630
    
631
    public boolean contains(DataStoreParameters parameters) {
632
        boolean c = this.getStoresRepository().contains(parameters);
633
        return c;
634
    }
635

    
636
    @Override
637
    public boolean canAnonymousUserWriteInTheTables() {
638
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
639
    }
640

    
641
    @Override
642
    public File getBaseFolder() {
643
        return this.baseFolder.get();
644
    }
645
    
646
    @Override
647
    public void setBaseFolder(File baseFolder) {
648
        this.baseFolder.set(baseFolder);
649
        this.set(CONFIG_NAME_BASEFOLDER, baseFolder.toString());
650
    }
651

    
652
    public File getWorkspaceFile() {
653
        if( this.serverParameters instanceof HasAFile ) {
654
            return ((HasAFile)this.serverParameters).getFile();
655
        }
656
        return null;
657
    }
658
    
659
    private DataStoreParameters replaceInFilesToUseBaseFolder(DataStoreParameters parameters) {
660
        DynClass dynClass = parameters.getDynClass();
661
        if( dynClass == null ) {
662
            return parameters;
663
        }
664
        File theBaseFolder = this.getBaseFolder();
665
        File wsfile = getWorkspaceFile();
666
        if( theBaseFolder==null && wsfile==null ) {
667
            return parameters;
668
        }
669
        DataStoreParameters replaced = parameters;
670
        for (DynField dynField : dynClass.getDynFields()) {
671
            switch(dynField.getType()) {
672
                case DataTypes.FILE:
673
                case DataTypes.FOLDER:
674
                    File f = (File) parameters.getDynValue(dynField.getName());
675
                    File newf = null;
676
                    if( f!=null ) {
677
                        if( wsfile!=null ) {
678
                            if( wsfile.equals(f) ) {
679
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
680
                                newf = ExpressionUtils.createDynamicFile(
681
                                    builder.ifnull(
682
                                        builder.variable("WORKSPACEFILE"), 
683
                                        builder.constant(f.toString()), 
684
                                        builder.variable("WORKSPACEFILE")
685
                                    )
686
                                );
687
                            }
688
                        }
689
                        if( newf==null ) {
690
                            File frel = FileTools.relativizeFile(theBaseFolder, f);
691
                            if( frel!=f ) {
692
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
693
                                newf = ExpressionUtils.createDynamicFile(
694
                                    builder.concat(
695
                                            builder.variable(CONFIG_NAME_BASEFOLDER), 
696
                                            builder.constant("/"), 
697
                                            builder.variable(frel.getPath())
698
                                    )
699
                                );
700
                            }
701
                        }
702
                        if( newf!=null ) {
703
                            if( replaced == parameters ) {
704
                                replaced = (DataStoreParameters) replaced.getCopy();
705
                            }
706
                            replaced.setDynValue(dynField.getName(), newf);
707
                        }
708
                    }
709
                    break;
710
            }
711
        }
712
        return replaced;
713
    }
714
    
715
    @Override
716
    public boolean writeStoresRepositoryEntry(String name, DataStoreParameters parameters) {
717
        return writeStoresRepositoryEntry(
718
                name, 
719
                parameters,
720
                Bitmask.createBitmask(0)
721
                        .setBit(BIT_CHANGE_PORT_HOST)
722
                        .setBit(BIT_CHANGE_USER)
723
                        .setBit(BIT_CHANGE_DBNAME_CATALOG_SCHEMA)
724
        );
725
    }
726
    
727
    @Override
728
    public boolean writeStoresRepositoryEntry(String name, DataStoreParameters parameters, Bitmask flags) {
729
        FeatureStore store = null;
730
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
731
        try {
732
            trans.begin();
733
            trans.add(this);
734
            parameters = this.replaceInFilesToUseBaseFolder(parameters);
735
            byte[] data = parameters.toByteArray();
736
            if( data == null ) {
737
                throw new RuntimeException("Can't convert parameters to byte array.");
738
            }
739
            store = this.getTable(TABLE_REPOSITORY);
740
            trans.add(store);
741
            store.edit();
742
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
743
            String filter = builder.eq(
744
                    builder.column(FIELD_REPOSITORY_NAME),
745
                    builder.constant(name)
746
            ).toString();
747
            Feature feature = store.findFirst(filter);
748
            EditableFeature efeature;
749
            if (feature == null) {
750
                efeature = store.createNewFeature();
751
                efeature.set(FIELD_REPOSITORY_NAME, name);
752
                efeature.set(FIELD_REPOSITORY_PARAMETERS, data);
753
                efeature.set(FIELD_REPOSITORY_FLAGS, flags.get());
754
                store.insert(efeature);
755
            } else {
756
                efeature = feature.getEditable();
757
                efeature.set(FIELD_REPOSITORY_PARAMETERS, data);
758
                efeature.set(FIELD_REPOSITORY_FLAGS, flags.get());
759
                store.update(efeature);
760
            }
761
            store.finishEditing();
762
            this.storesRepository = null;
763
            trans.commit();
764
            return true;
765
            
766
        } catch (Exception ex) {
767
            LOGGER.warn("Can't save entry '"+name+"' in repository information", ex);
768
            trans.abortQuietly();
769
            return false;
770
        } finally {
771
            trans.closeQuietly();
772
            DisposeUtils.disposeQuietly(store);
773
        }
774
    }
775

    
776
    @Override
777
    public boolean isValid() {
778
      try {
779
        String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
780
        if( StringUtils.isBlank(id) ) {
781
            return false;
782
        }
783
        return true;
784
      } catch(Exception ex) {
785
        return false;
786
      }
787
    }
788

    
789
    @Override
790
    public boolean isValidStoresRepository() {
791
        if( !this.isValid() ) {
792
            return false;
793
        }
794
        if( !this.existsTable(TABLE_REPOSITORY_NAME) ) {
795
            return false;
796
        }
797
        return true;
798
        
799
    }
800
    
801
    @Override
802
    public ResourcesStorage getAlternativeResourcesStorage(String tableName) {
803
//        LOGGER.info("getAlternativeResourcesStorage from cache: "+!this.alternativeResourcesFolder.isExpired());
804
        String s = this.alternativeResourcesFolder.get();
805
//        LOGGER.info("alternativeResourcesStorage: "+s);
806
        if( StringUtils.isBlank(s) ) {
807
            return null;
808
        }
809
        
810
        s = ExpressionUtils.evaluateDynamicText(this, s);
811

    
812
        File folder = new File(s);
813
        
814
        if( folder==null ) {
815
            return null;
816
        }
817
        String resourcesRoot = folder.getAbsolutePath().replace("\\","/") + "/" + tableName;
818
        ResourcesStorage resources = new FilesResourcesStorage(resourcesRoot);
819
        return resources;
820
    }
821
    
822
    @Override
823
    public boolean hasAlternativeResourcesStorage() {
824
        String path = this.get(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH);
825
        return StringUtils.isNotBlank(path);
826
    }
827

    
828
    @Override
829
    public void setAlternativeResourcesStorage(String resourcesPath) {
830
//        this.fix();
831
      this.set(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH, resourcesPath);
832
//      this.alternativeResourcesFolder.expired();
833
    }
834

    
835
    @Override
836
    public void drop() {
837
        if( !this.existsTable(TABLE_RESOURCES) ) {
838
            this.dropTable(TABLE_RESOURCES);
839
        }
840
        if( !this.existsTable(TABLE_CONFIGURATION) ) {
841
            this.dropTable(TABLE_CONFIGURATION);
842
        }
843
        if( !this.existsTable(TABLE_REPOSITORY) ) {
844
            this.dropTable(TABLE_REPOSITORY);
845
        }
846
    }
847
    
848
   
849
    @Override
850
    public void create(String id, String description) {
851
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
852
        try {
853
            trans.begin();
854
            trans.add(this);
855

    
856
            if (!this.existsTable(TABLE_RESOURCES)) {
857
                this.createTable(TABLE_RESOURCES);
858
            }
859
            if (!this.existsTable(TABLE_CONFIGURATION)) {
860
                this.createTable(TABLE_CONFIGURATION);
861
            }
862
            if (!this.existsTable(TABLE_REPOSITORY)) {
863
                this.createTable(TABLE_REPOSITORY);
864
            }
865
            this.set(CONFIG_NAME_STORESREPOSITORYID, id);
866
            this.set(CONFIG_NAME_STORESREPOSITORYLABEL, description);
867
            this.set(CONFIG_CAN_ANONYMOUS_USER_WRITE_IN_THE_TABLES, "true");
868
            this.set(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH, "");
869
            File theBaseFolder = this.getBaseFolder();
870
            if (this.serverParameters instanceof HasAFile && theBaseFolder == null) {
871
                File f = ((HasAFile) this.serverParameters).getFile();
872
                if (f != null) {
873
                    theBaseFolder = f.getParentFile();
874
                    this.setBaseFolder(theBaseFolder);
875
                } else {
876
                    this.set(CONFIG_NAME_BASEFOLDER, "");
877
                }
878
            } else {
879
                this.set(CONFIG_NAME_BASEFOLDER, "");
880
            }
881
            trans.commit();
882
        } catch (RuntimeException ex) {
883
            trans.abortQuietly();
884
            throw ex;
885
        } catch (Exception ex) {
886
            trans.abortQuietly();
887
            throw new RuntimeException("Can't create table " + id, ex);
888
        } finally {
889
            trans.closeQuietly();
890
        }
891
    }
892

    
893
    @Override
894
    public boolean exists(String name) {
895
        FeatureStore store = null;
896
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
897
        try {
898
            trans.begin();
899
            trans.add(this);
900
            if( StringUtils.equalsIgnoreCase(name, "WORKSPACEFILE") ) {
901
                File wsfile = getWorkspaceFile();
902
                if( wsfile!=null ) {
903
                    trans.commit();
904
                    return true;
905
                }
906
            }
907
            if (this.existsConfiguration()) {
908
              if( StringUtils.equalsIgnoreCase(name, CONFIG_NAME_BASEFOLDER) ) {
909
                trans.commit();
910
                return true;
911
              }
912
              if( this.cachedConfigValues.containsKey(name) ) {
913
                trans.commit();
914
                return true;
915
              }
916
              store = this.getTable(TABLE_CONFIGURATION);
917
              trans.add(store);
918
              if (store != null) {
919
                  ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
920
                  String filter = builder.eq(
921
                          builder.column(FIELD_CONFIGURATION_NAME),
922
                          builder.constant(name)
923
                  ).toString();
924
                  Feature feature = store.findFirst(filter);
925
                  if (feature != null) {
926
                      String value = feature.getString(FIELD_CONFIGURATION_VALUE);
927
                      value = ExpressionUtils.evaluateDynamicText(this, value);
928
                      this.cachedConfigValues.put(name, new CachedConfigValue(name, value, 15000));
929
                      trans.commit();
930
                      return true;
931
                  }
932
                }
933
            }
934
            boolean b = super.exists(name);
935
            trans.commit();
936
            return b;
937
        } catch (Exception ex) {
938
            LOGGER.warn("Can't read configuration value '" + name + "'", ex);
939
            trans.abortQuietly();
940
            return false;
941
        } finally {
942
            trans.closeQuietly();
943
            DisposeUtils.disposeQuietly(store);
944
        }
945
    }
946

    
947
    @Override
948
    public Object value(String name) {
949
        if( StringUtils.equalsIgnoreCase(name, "WORKSPACEFILE") ) {
950
            File wsfile = getWorkspaceFile();
951
            if( wsfile!=null ) {
952
                return wsfile.toString();
953
            }
954
        }
955
        String v = this.get(name);
956
        if( v!=null ) {
957
            return v;
958
        }
959
        return super.value(name);
960
    }
961

    
962
    @Override
963
    public Collection<String> localvariables() {
964
        FeatureStore store = null;
965
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
966
        try {
967
            trans.begin();
968
            trans.add(this);
969
            final List<String> theVars = new ArrayList<>();
970
            if (this.existsConfiguration()) {
971
                store = this.getTable(TABLE_CONFIGURATION);
972
                if (store != null) {
973
                    store.accept((Object obj) -> {
974
                      Feature feature = (Feature) obj;
975
                      theVars.add(feature.getString(FIELD_CONFIGURATION_NAME));
976
                    });
977
                }
978
            }
979
            trans.commit();
980
            return theVars;
981
        } catch (Exception ex) {
982
            LOGGER.warn("Can't read configuration variables", ex);
983
            trans.abortQuietly();
984
            return Collections.EMPTY_LIST;
985
        } finally {
986
            trans.closeQuietly();
987
            DisposeUtils.disposeQuietly(store);
988
        }
989
    }
990

    
991
    @Override
992
    public ResourcesStorage getResourcesStorage() {
993
        DataServerExplorer server = null;
994
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
995
        try {
996
            trans.begin();
997
            trans.add(this);
998
            server = this.getServerExplorer();
999
            trans.add(server);
1000
            ResourcesStorage resourcesStorage = server.getResourcesStorage();
1001
            trans.commit();
1002
            return resourcesStorage;
1003
        } catch (Exception ex) {
1004
            trans.abortQuietly();
1005
            LOGGER.warn("Can't get resorces storage.",ex);
1006
            return null;
1007
        } finally {
1008
            trans.closeQuietly();
1009
            DisposeUtils.disposeQuietly(server);
1010
        }
1011
    }
1012
    
1013
    public void fix() {
1014
      if( !(this.serverParameters instanceof HasAFile) ) {
1015
        return;
1016
      }
1017
      HasAFile f = (HasAFile) this.serverParameters;
1018
      if( f.getFile()==null ) {
1019
        return;
1020
      }
1021
      if( !this.isValid() ) {
1022
        return;
1023
      }
1024
      this.set(CONFIG_NAME_BASEFOLDER, f.getFile().getParent());
1025
    }
1026

    
1027
    @Override
1028
    public void connect() {
1029
      DataManager manager = DALLocator.getDataManager();
1030
      this.fix();
1031
      manager.addDatabaseWorkspace(this);
1032
    }
1033
    
1034
    @Override
1035
    public void disconnect() {
1036
      DataManager manager = DALLocator.getDataManager();
1037
      manager.removeDatabaseWorkspace(this);
1038
    }
1039

    
1040
    @Override
1041
    public boolean isConnected() {
1042
      DataManager manager = DALLocator.getDataManager();
1043
      DatabaseWorkspaceManager ws = manager.getDatabaseWorkspace(this.getId());
1044
      if(ws == null){
1045
          return false;
1046
      }
1047
      if(ws.getServerExplorerParameters().isTheSameServerExplorer(this.getServerExplorerParameters())){
1048
          return true;
1049
      }
1050
      return false;
1051
    }
1052
    
1053
    @Override
1054
    public String getLabelOrId() {
1055
        String label = this.getLabel();
1056
        if(StringUtils.isBlank(label)){
1057
            label = this.getId();
1058
        }
1059
        return label;
1060
    }
1061
    
1062
    @Override
1063
    public void setTransaction(DataTransaction transaction) {
1064
        this.transactionsHelper.setTransaction(transaction);
1065
    }
1066

    
1067
    @Override
1068
    public DataTransaction getTransaction() {
1069
        return this.transactionsHelper.getTransaction();
1070
    }
1071
    
1072
    
1073
    
1074
}