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

History | View | Annotate | Download (38.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.feature.EditableFeature;
41
import org.gvsig.fmap.dal.feature.EditableFeatureType;
42
import org.gvsig.fmap.dal.feature.Feature;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
45
import org.gvsig.fmap.dal.feature.spi.LocalTransaction;
46
import org.gvsig.tools.dispose.DisposeUtils;
47
import org.gvsig.tools.dynobject.DynClass;
48
import org.gvsig.tools.dynobject.DynField;
49
import org.gvsig.tools.resourcesstorage.FilesResourcesStorage;
50
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
51
import org.gvsig.tools.util.CachedValue;
52
import org.gvsig.tools.util.FileTools;
53
import org.gvsig.tools.util.HasAFile;
54
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
56

    
57
/**
58
 *
59
 * @author jjdelcerro
60
 */
61
@SuppressWarnings("UseSpecificCatch")
62
public class DefaultDatabaseWorkspaceManager 
63
        extends AbstractSymbolTable
64
        implements DatabaseWorkspaceManager
65
    {
66
    
67
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDatabaseWorkspaceManager.class);
68

    
69
    private static final String CONFIG_NAME_BASEFOLDER = "BASEFOLDER";
70
    private static final String CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH = "ALTERNATIVE_RESOURCES_PATH";
71
    
72
    private DataTransaction transaction;
73

    
74
    private class CachedConfigValue extends CachedValue<String> {
75

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

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

    
151
    @Override
152
    public String toString() {
153
        return this.getLabel();
154
    }
155
    
156
    @Override
157
    public String getId() {
158
        String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
159
        return id;
160
    }
161
    
162
    @Override
163
    public String getLabel() {
164
        String label = this.get(CONFIG_NAME_STORESREPOSITORYLABEL);
165
        if (StringUtils.isBlank(label)) {
166
            return this.getId();
167
        }
168
        return label;
169
    }
170

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

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

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

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

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

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

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

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

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

    
611
    @Override
612
    public StoresRepository getStoresRepository() {
613
        if( this.storesRepository==null ) {
614
            String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
615
            String label = this.get(CONFIG_NAME_STORESREPOSITORYLABEL);
616
            this.storesRepository = new DatabaseWorkspaceStoresRepository(
617
                    id,
618
                    label,
619
                    this
620
            );
621
        }
622
        return this.storesRepository;
623
    }
624
    
625
    public boolean contains(DataStoreParameters parameters) {
626
        boolean c = this.getStoresRepository().contains(parameters);
627
        return c;
628
    }
629

    
630
    @Override
631
    public boolean canAnonymousUserWriteInTheTables() {
632
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
633
    }
634

    
635
    @Override
636
    public File getBaseFolder() {
637
        return this.baseFolder.get();
638
    }
639
    
640
    @Override
641
    public void setBaseFolder(File baseFolder) {
642
        this.baseFolder.set(baseFolder);
643
        this.set(CONFIG_NAME_BASEFOLDER, baseFolder.toString());
644
    }
645

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

    
758
    @Override
759
    public boolean isValid() {
760
      try {
761
        String id = this.get(CONFIG_NAME_STORESREPOSITORYID);
762
        if( StringUtils.isBlank(id) ) {
763
            return false;
764
        }
765
        return true;
766
      } catch(Exception ex) {
767
        return false;
768
      }
769
    }
770

    
771
    @Override
772
    public boolean isValidStoresRepository() {
773
        if( !this.isValid() ) {
774
            return false;
775
        }
776
        if( !this.existsTable(TABLE_REPOSITORY_NAME) ) {
777
            return false;
778
        }
779
        return true;
780
        
781
    }
782
    
783
    @Override
784
    public ResourcesStorage getAlternativeResourcesStorage(String tableName) {
785
//        LOGGER.info("getAlternativeResourcesStorage from cache: "+!this.alternativeResourcesFolder.isExpired());
786
        String s = this.alternativeResourcesFolder.get();
787
//        LOGGER.info("alternativeResourcesStorage: "+s);
788
        if( StringUtils.isBlank(s) ) {
789
            return null;
790
        }
791
        
792
        s = ExpressionUtils.evaluateDynamicText(this, s);
793

    
794
        File folder = new File(s);
795
        
796
        if( folder==null ) {
797
            return null;
798
        }
799
        String resourcesRoot = folder.getAbsolutePath().replace("\\","/") + "/" + tableName;
800
        ResourcesStorage resources = new FilesResourcesStorage(resourcesRoot);
801
        return resources;
802
    }
803
    
804
    @Override
805
    public boolean hasAlternativeResourcesStorage() {
806
        String path = this.get(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH);
807
        return StringUtils.isNotBlank(path);
808
    }
809

    
810
    @Override
811
    public void setAlternativeResourcesStorage(String resourcesPath) {
812
//        this.fix();
813
      this.set(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH, resourcesPath);
814
//      this.alternativeResourcesFolder.expired();
815
    }
816

    
817
    @Override
818
    public void drop() {
819
        if( !this.existsTable(TABLE_RESOURCES) ) {
820
            this.dropTable(TABLE_RESOURCES);
821
        }
822
        if( !this.existsTable(TABLE_CONFIGURATION) ) {
823
            this.dropTable(TABLE_CONFIGURATION);
824
        }
825
        if( !this.existsTable(TABLE_REPOSITORY) ) {
826
            this.dropTable(TABLE_REPOSITORY);
827
        }
828
    }
829
    
830
   
831
    @Override
832
    public void create(String id, String description) {
833
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
834
        try {
835
            trans.begin();
836
            trans.add(this);
837

    
838
            if (!this.existsTable(TABLE_RESOURCES)) {
839
                this.createTable(TABLE_RESOURCES);
840
            }
841
            if (!this.existsTable(TABLE_CONFIGURATION)) {
842
                this.createTable(TABLE_CONFIGURATION);
843
            }
844
            if (!this.existsTable(TABLE_REPOSITORY)) {
845
                this.createTable(TABLE_REPOSITORY);
846
            }
847
            this.set(CONFIG_NAME_STORESREPOSITORYID, id);
848
            this.set(CONFIG_NAME_STORESREPOSITORYLABEL, description);
849
            this.set(CONFIG_CAN_ANONYMOUS_USER_WRITE_IN_THE_TABLES, "true");
850
            this.set(CONFIG_NAME_ALTERNATIVE_RESOURCES_PATH, "");
851
            File theBaseFolder = this.getBaseFolder();
852
            if (this.serverParameters instanceof HasAFile && theBaseFolder == null) {
853
                File f = ((HasAFile) this.serverParameters).getFile();
854
                if (f != null) {
855
                    theBaseFolder = f.getParentFile();
856
                    this.setBaseFolder(theBaseFolder);
857
                } else {
858
                    this.set(CONFIG_NAME_BASEFOLDER, "");
859
                }
860
            } else {
861
                this.set(CONFIG_NAME_BASEFOLDER, "");
862
            }
863
            trans.commit();
864
        } catch (RuntimeException ex) {
865
            trans.abortQuietly();
866
            throw ex;
867
        } catch (Exception ex) {
868
            trans.abortQuietly();
869
            throw new RuntimeException("Can't create table " + id, ex);
870
        } finally {
871
            trans.closeQuietly();
872
        }
873
    }
874

    
875
    @Override
876
    public boolean exists(String name) {
877
        FeatureStore store = null;
878
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
879
        try {
880
            trans.begin();
881
            trans.add(this);
882
            if( StringUtils.equalsIgnoreCase(name, "WORKSPACEFILE") ) {
883
                File wsfile = getWorkspaceFile();
884
                if( wsfile!=null ) {
885
                    trans.commit();
886
                    return true;
887
                }
888
            }
889
            if (this.existsConfiguration()) {
890
              if( StringUtils.equalsIgnoreCase(name, CONFIG_NAME_BASEFOLDER) ) {
891
                trans.commit();
892
                return true;
893
              }
894
              if( this.cachedConfigValues.containsKey(name) ) {
895
                trans.commit();
896
                return true;
897
              }
898
              store = this.getTable(TABLE_CONFIGURATION);
899
              trans.add(store);
900
              if (store != null) {
901
                  ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
902
                  String filter = builder.eq(
903
                          builder.column(FIELD_CONFIGURATION_NAME),
904
                          builder.constant(name)
905
                  ).toString();
906
                  Feature feature = store.findFirst(filter);
907
                  if (feature != null) {
908
                      String value = feature.getString(FIELD_CONFIGURATION_VALUE);
909
                      value = ExpressionUtils.evaluateDynamicText(this, value);
910
                      this.cachedConfigValues.put(name, new CachedConfigValue(name, value, 15000));
911
                      trans.commit();
912
                      return true;
913
                  }
914
                }
915
            }
916
            boolean b = super.exists(name);
917
            trans.commit();
918
            return b;
919
        } catch (Exception ex) {
920
            LOGGER.warn("Can't read configuration value '" + name + "'", ex);
921
            trans.abortQuietly();
922
            return false;
923
        } finally {
924
            trans.closeQuietly();
925
            DisposeUtils.disposeQuietly(store);
926
        }
927
    }
928

    
929
    @Override
930
    public Object value(String name) {
931
        if( StringUtils.equalsIgnoreCase(name, "WORKSPACEFILE") ) {
932
            File wsfile = getWorkspaceFile();
933
            if( wsfile!=null ) {
934
                return wsfile.toString();
935
            }
936
        }
937
        String v = this.get(name);
938
        if( v!=null ) {
939
            return v;
940
        }
941
        return super.value(name);
942
    }
943

    
944
    @Override
945
    public Collection<String> localvariables() {
946
        FeatureStore store = null;
947
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
948
        try {
949
            trans.begin();
950
            trans.add(this);
951
            final List<String> theVars = new ArrayList<>();
952
            if (this.existsConfiguration()) {
953
                store = this.getTable(TABLE_CONFIGURATION);
954
                if (store != null) {
955
                    store.accept((Object obj) -> {
956
                      Feature feature = (Feature) obj;
957
                      theVars.add(feature.getString(FIELD_CONFIGURATION_NAME));
958
                    });
959
                }
960
            }
961
            trans.commit();
962
            return theVars;
963
        } catch (Exception ex) {
964
            LOGGER.warn("Can't read configuration variables", ex);
965
            trans.abortQuietly();
966
            return Collections.EMPTY_LIST;
967
        } finally {
968
            trans.closeQuietly();
969
            DisposeUtils.disposeQuietly(store);
970
        }
971
    }
972

    
973
    @Override
974
    public ResourcesStorage getResourcesStorage() {
975
        DataServerExplorer server = null;
976
        LocalTransaction trans = new LocalTransaction(null, this.getTransaction());
977
        try {
978
            trans.begin();
979
            trans.add(this);
980
            server = this.getServerExplorer();
981
            trans.add(server);
982
            ResourcesStorage resourcesStorage = server.getResourcesStorage();
983
            trans.commit();
984
            return resourcesStorage;
985
        } catch (Exception ex) {
986
            trans.abortQuietly();
987
            LOGGER.warn("Can't get resorces storage.",ex);
988
            return null;
989
        } finally {
990
            trans.closeQuietly();
991
            DisposeUtils.disposeQuietly(server);
992
        }
993
    }
994
    
995
    public void fix() {
996
      if( !(this.serverParameters instanceof HasAFile) ) {
997
        return;
998
      }
999
      HasAFile f = (HasAFile) this.serverParameters;
1000
      if( f.getFile()==null ) {
1001
        return;
1002
      }
1003
      if( !this.isValid() ) {
1004
        return;
1005
      }
1006
      this.set(CONFIG_NAME_BASEFOLDER, f.getFile().getParent());
1007
    }
1008

    
1009
    @Override
1010
    public void connect() {
1011
      DataManager manager = DALLocator.getDataManager();
1012
      this.fix();
1013
      manager.addDatabaseWorkspace(this);
1014
    }
1015
    
1016
    @Override
1017
    public void disconnect() {
1018
      DataManager manager = DALLocator.getDataManager();
1019
      manager.removeDatabaseWorkspace(this);
1020
    }
1021

    
1022
    @Override
1023
    public boolean isConnected() {
1024
      DataManager manager = DALLocator.getDataManager();
1025
      DatabaseWorkspaceManager ws = manager.getDatabaseWorkspace(this.getId());
1026
      if(ws == null){
1027
          return false;
1028
      }
1029
      if(ws.getServerExplorerParameters().isTheSameServerExplorer(this.getServerExplorerParameters())){
1030
          return true;
1031
      }
1032
      return false;
1033
    }
1034
    
1035
    @Override
1036
    public String getLabelOrId() {
1037
        String label = this.getLabel();
1038
        if(StringUtils.isBlank(label)){
1039
            label = this.getId();
1040
        }
1041
        return label;
1042
    }
1043
    
1044
    @Override
1045
    public void setTransaction(DataTransaction transaction) {
1046
        this.transaction = transaction;
1047
    }
1048

    
1049
    @Override
1050
    public DataTransaction getTransaction() {
1051
        return this.transaction;
1052
    }
1053
    
1054
    
1055
    
1056
}