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 / DefaultDataManager.java @ 44738

History | View | Annotate | Download (48.7 KB)

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

    
3
import java.io.ByteArrayInputStream;
4
import java.io.File;
5
import java.io.InputStream;
6
import java.net.URL;
7
import java.net.URLClassLoader;
8
import java.util.ArrayList;
9
import java.util.Collections;
10
import java.util.HashMap;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Objects;
14
import java.util.UUID;
15
import org.apache.commons.io.IOUtils;
16
import org.apache.commons.lang3.StringUtils;
17
import org.gvsig.expressionevaluator.Expression;
18
import org.gvsig.expressionevaluator.ExpressionBuilder;
19
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
20
import org.gvsig.expressionevaluator.MutableSymbolTable;
21
import org.gvsig.expressionevaluator.impl.symboltable.FeatureSymbolTableImpl;
22
import org.gvsig.fmap.dal.BaseStoresRepository;
23
import org.gvsig.fmap.dal.DALLocator;
24

    
25
import org.gvsig.fmap.dal.DataFactory;
26
import org.gvsig.fmap.dal.DataManager;
27
import org.gvsig.fmap.dal.DataServerExplorer;
28
import org.gvsig.fmap.dal.DataServerExplorerFactory;
29
import org.gvsig.fmap.dal.DataServerExplorerParameters;
30
import org.gvsig.fmap.dal.DataServerExplorerPool;
31
import org.gvsig.fmap.dal.DataStore;
32
import org.gvsig.fmap.dal.DataStoreFactory_v2_4;
33
import org.gvsig.fmap.dal.DataStoreParameters;
34
import org.gvsig.fmap.dal.DataStoreProviderFactory;
35
import org.gvsig.fmap.dal.DataTypes;
36
import org.gvsig.fmap.dal.DatabaseWorkspaceManager;
37
import org.gvsig.fmap.dal.DatabaseWorkspaceManager.AddDatabaseWorkspaceListener;
38

    
39
import org.gvsig.fmap.dal.NewDataStoreParameters;
40
import org.gvsig.fmap.dal.OpenErrorHandler;
41
import org.gvsig.fmap.dal.Register;
42
import org.gvsig.fmap.dal.StoresRepository;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.InitializeException;
45
import org.gvsig.fmap.dal.exception.OpenException;
46
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
47
import org.gvsig.fmap.dal.exception.CreateFileStoreException;
48
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
49
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
50
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
51
import org.gvsig.fmap.dal.feature.DataProfile;
52
import org.gvsig.fmap.dal.feature.EditableFeatureType;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
55
import org.gvsig.fmap.dal.feature.FeatureQuery;
56
import org.gvsig.fmap.dal.feature.FeatureStore;
57
import org.gvsig.fmap.dal.feature.FeatureType;
58
import org.gvsig.fmap.dal.feature.ForeingKey;
59
import static org.gvsig.fmap.dal.feature.ForeingKey.MAX_AVAILABLE_VALUES;
60
import org.gvsig.fmap.dal.feature.impl.DALFile;
61
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType;
62
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndex;
63
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
64
import org.gvsig.fmap.dal.feature.impl.FeatureStoreFactory;
65
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
66
import org.gvsig.fmap.dal.feature.paging.impl.FeaturePagingHelperImpl;
67
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
68
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
69
import org.gvsig.fmap.dal.feature.spi.cache.FeatureCacheProvider;
70
import org.gvsig.fmap.dal.feature.spi.cache.FeatureCacheProviderFactory;
71
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProvider;
72
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
73
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultExpressionEvaluator;
74
import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureAttributeEmulatorExpression;
75
import org.gvsig.fmap.dal.raster.impl.RasterStoreFactory;
76
import org.gvsig.fmap.dal.raster.impl.RasterStoreOldFactory;
77
import org.gvsig.fmap.dal.raster.spi.CoverageStoreProvider;
78
import org.gvsig.fmap.dal.spi.DALSPILocator;
79
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
80
import org.gvsig.fmap.dal.spi.DataStoreProvider;
81
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
82
import org.gvsig.fmap.dal.store.memory.MemoryStoreParameters;
83
import org.gvsig.fmap.dal.store.memory.MemoryStoreProvider;
84
import org.gvsig.tools.ToolsLocator;
85
import org.gvsig.tools.dataTypes.DataType;
86
import org.gvsig.tools.dataTypes.DataTypesManager;
87
import org.gvsig.tools.dynobject.DynObject;
88
import org.gvsig.tools.dynobject.DynObjectValueItem;
89
import org.gvsig.tools.dynobject.DynStruct;
90
import org.gvsig.tools.dynobject.DynStruct_v2;
91
import org.gvsig.tools.dynobject.Tags;
92
import org.gvsig.tools.evaluator.Evaluator;
93
import org.gvsig.tools.exception.BaseException;
94
import org.gvsig.tools.extensionpoint.ExtensionPoint;
95
import org.gvsig.tools.folders.FoldersManager;
96
import org.gvsig.tools.identitymanagement.SimpleIdentityManager;
97
import org.gvsig.tools.identitymanagement.UnauthorizedException;
98
import org.gvsig.tools.persistence.PersistenceManager;
99
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
100
import org.gvsig.tools.script.Script;
101
import org.gvsig.tools.script.ScriptManager;
102
import org.gvsig.tools.service.spi.Services;
103
import org.gvsig.tools.util.Callable;
104
import org.gvsig.tools.util.Invocable;
105
import org.slf4j.Logger;
106
import org.slf4j.LoggerFactory;
107

    
108
@SuppressWarnings("UseSpecificCatch")
109
public class DefaultDataManager
110
        implements DataManager, DataManagerProviderServices, Services {
111

    
112
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDataManager.class);
113
    
114
    final static private String DATA_MANAGER_CACHE = "Data.manager.caches";
115
    final static private String DATA_MANAGER_CACHE_DESCRIPTION =
116
        "DAL cache providers";
117

    
118
    public static final String FILESYSTEM_EXPLORER_NAME = "FilesystemExplorer";
119

    
120

    
121
    private class Registers {
122

    
123
        private final Register store;
124
        private final Register storeProvider;
125
        private final Register serverExplorer;
126
        private final Register featureIndexProvider;
127

    
128
        public Registers() {
129
            this.store = new RegisterImpl(
130
                    "Data.manager.stores.factory",
131
                    "DAL store factories"
132
            );
133
            this.storeProvider = new RegisterImpl(
134
                    "Data.manager.providers.factory",
135
                    "DAL store provider factories"
136
            );
137
            this.serverExplorer = new RegisterImpl(
138
                    "Data.manager.servereexplorer.factory",
139
                    "DAL server explorer factories"
140
            );
141
            this.featureIndexProvider = new RegisterImpl(
142
                    "Data.manager.feature.index.factory",
143
                    "DAL feature index factories"
144
            );
145

    
146
            this.store.register(new FeatureStoreFactory());
147
        }
148
    }
149
    private static final String TAG_DAL_OPENSTORE = "dal.openstore.";
150

    
151
    private final Registers registers;
152

    
153
    private final Map<Integer, String> defaultDataIndexProviders;
154

    
155
    private OpenErrorHandler openErrorHandler = null;
156

    
157
    private DataServerExplorerPool dataServerExplorerPool = null;
158

    
159
    private List<DataType> dataTypes = null;
160

    
161
    private ClassLoader resourcesLoader = null;
162

    
163
    private List<DataProfile> dataProfiles;
164
    
165
    private final Map<String, DatabaseWorkspaceManager> databaseWorkspaces = new HashMap<>();
166
 
167
    private final Map<String,AddDatabaseWorkspaceListener> addDatabaseWorkspaceListeners = new HashMap<>();
168
    
169
    public DefaultDataManager() {
170
        this.registers = new Registers();
171
        this.defaultDataIndexProviders = new HashMap<>();
172
    }
173

    
174
    @Override
175
    public Register getStoreRegister() {
176
        return this.registers.store;
177
    }
178

    
179
    @Override
180
    public Register getStoreProviderRegister() {
181
        return this.registers.storeProvider;
182
    }
183

    
184
    @Override
185
    public Register getServerExplorerRegister() {
186
        return this.registers.serverExplorer;
187
    }
188

    
189
    @Override
190
    public Register getFeatureIndexRegister() {
191
        return this.registers.featureIndexProvider;
192
    }
193

    
194
    private String getStoreName(DataStoreParameters parameters) {
195
        for (DataFactory factory : this.getStoreRegister()) {
196
            DataStoreFactory_v2_4 storeFactory = (DataStoreFactory_v2_4) factory;
197
            if (storeFactory.canUse(parameters)) {
198
                return storeFactory.getName();
199
            }
200
        }
201
        return null;
202
    }
203

    
204
    /**
205
     * @deprecated
206
     */
207
    @Override
208
    public void registerDefaultRasterStore(Class rasterStoreClass) {
209
        // Metodo usado por el raster nuevo para regstrar su factoria de store
210
        this.getStoreRegister().register(new RasterStoreFactory(rasterStoreClass));
211
    }
212

    
213
    /**
214
     * @deprecated
215
     */
216
    @Override
217
    public void registerStoreFactory(String name, Class storeFactoryClass) {
218
        // Metodo usado por el raster viejo para registrar las factorias de sus stores
219
        this.getStoreRegister().register(new RasterStoreOldFactory(name, storeFactoryClass));
220
    }
221

    
222
    /**
223
     * @param name
224
     * @param storeProviderClass
225
     * @param parametersClass
226
     * @deprecated use registerStoreProviderFactory
227
     */
228
    @Override
229
    public void registerStoreProvider(String name, Class storeProviderClass,
230
            Class parametersClass) {
231
        if (name == null || storeProviderClass == null || parametersClass == null) {
232
            throw new IllegalArgumentException("Any parameters can be null");
233
        }
234

    
235
        if (!DataStoreParameters.class.isAssignableFrom(parametersClass)) {
236
            throw new IllegalArgumentException(parametersClass.getName()
237
                    + " must implement org.gvsig.fmap.dal.DataStoreParameters");
238
        }
239

    
240
        if (CoverageStoreProvider.class.isAssignableFrom(storeProviderClass)) {
241
            // Envuelve al proveedor en una factoria por defecto.
242
            this.registerStoreProviderFactory(new DataStoreProviderToCoverageProviderFactoryWrapper(
243
                    name, "", storeProviderClass, parametersClass));
244
            return;
245
        }
246

    
247
        if (FeatureStoreProvider.class.isAssignableFrom(storeProviderClass)) {
248
            // Envuelve al proveedor en una factoria por defecto.
249
            this.registerStoreProviderFactory(new DataStoreProviderToFeatureStoreProviderFactoryWrapper(
250
                    name, "", storeProviderClass, parametersClass));
251
            return;
252
        }
253

    
254
        throw new IllegalArgumentException("Not supported implemtation: name="
255
                + name + " provider class=" + storeProviderClass.getName());
256

    
257
    }
258

    
259
    @Override
260
    public void registerExplorerProvider(String name, Class explorerClass, Class parametersClass) {
261
        if (name == null || explorerClass == null || parametersClass == null) {
262
            // FIXME Exception
263
            throw new IllegalArgumentException("Any parameters can be null");
264
        }
265

    
266
        if (!DataServerExplorerParameters.class
267
                .isAssignableFrom(parametersClass)) {
268
            // FIXME Exception
269
            throw new IllegalArgumentException(
270
                    parametersClass.getName()
271
                    + " must implement org.gvsig.fmap.dal.DataServerExplorerParameters");
272
        }
273

    
274
        if (!DataServerExplorer.class.isAssignableFrom(explorerClass)) {
275
            // FIXME Exception
276
            throw new IllegalArgumentException(explorerClass.getName()
277
                    + " must implement org.gvsig.fmap.dal.DataServerExplorer");
278
        }
279

    
280
        // Envuelve al proveedor en una factoria por defecto.
281
        this.registerServerExplorerFactory(
282
                new DataServerExplorerToDataExplorerFactoryWrapper(
283
                        name, "", explorerClass, parametersClass
284
                )
285
        );
286

    
287
    }
288

    
289
    @Override
290
    public void registerStoreFactory(DataStoreFactory_v2_4 factory) {
291
        this.getStoreRegister().register(factory);
292
    }
293

    
294
    @Override
295
    public void registerStoreProviderFactory(DataStoreProviderFactory factory) {
296
        this.getStoreProviderRegister().register(factory);
297
    }
298

    
299
    @Override
300
    public void registerServerExplorerFactory(DataServerExplorerFactory factory) {
301
        this.getServerExplorerRegister().register(factory);
302
    }
303

    
304
    @Override
305
    public DataStoreParameters createStoreParameters(byte[] data) {
306
        try {
307
            PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
308
            ByteArrayInputStream stream = new ByteArrayInputStream(data);
309
            DataStoreParameters parameters = (DataStoreParameters) persistenceManager.getObject(stream);
310
            return parameters;
311
        } catch (Exception ex) {
312
            LOGGER.warn("Can't get parameters from byte[].",ex);
313
            return null;
314
        }
315
    }
316

    
317
    @Override
318
    public DataStoreParameters createStoreParameters(String providerName, Object... arguments) throws InitializeException, ProviderNotRegisteredException {
319
        if( providerName == null ) {
320
            String msg = "Provider name can't be null.";
321
            LOGGER.warn(msg);
322
            throw new IllegalArgumentException(msg);
323
        }
324
        if( arguments.length == 1 ) { 
325
            // Desde jython entra por este metodo en lugar de los especificos
326
            // de DataStoreParameters o DynObject
327
            if( arguments[0] instanceof DataStoreParameters ) {
328
                return this.createStoreParameters(providerName, (DataStoreParameters)(arguments[0]));
329
            } else if( arguments[0] instanceof DynObject ) {
330
                return this.createStoreParameters(providerName, (DynObject)(arguments[0]));
331
            }
332
        }
333
        if( (arguments.length % 2)!= 0 ) {
334
            throw new IllegalArgumentException("The number of arguments must be even.");
335
        }
336
        if( providerName == null ) {
337
            String msg = "Provider name can't be null.";
338
            LOGGER.warn(msg);
339
            throw new IllegalArgumentException(msg);
340
        }
341
        DataFactory providerFactory = this.getStoreProviderRegister().getFactory(providerName);
342
        if( providerFactory == null ) {
343
            String msg = "Can't locate provider factory for '"+providerName+"'.";
344
            LOGGER.warn(msg);
345
            throw new IllegalArgumentException(msg);
346
        }
347
        DataStoreParameters parameters = (DataStoreParameters) providerFactory.createParameters();
348
        for( int i=0; i<arguments.length; i+=2 ) {
349
            String name = (String) arguments[i];
350
            if( name.endsWith("=") ) {
351
                name = name.substring(0, name.length()-1);
352
            }
353
            Object value = arguments[i+1];
354
            parameters.setDynValue(name, value);
355
        }
356
        return parameters;
357
    }
358

    
359
    @Override
360
    public NewDataStoreParameters createNewStoreParameters(String explorerName, String providerName) throws InitializeException, ProviderNotRegisteredException {
361
        try {
362
            DataServerExplorer explorer = this.openServerExplorer(explorerName, (DataServerExplorerParameters)null);
363
            return explorer.getAddParameters(providerName);
364
        } catch (Exception ex) {
365
            throw new InitializeException(ex);
366
        }
367
    }
368

    
369
    @Override
370
    public DataServerExplorerParameters createServerExplorerParameters(String explorerName) throws InitializeException, ProviderNotRegisteredException {
371
        if( explorerName == null ) {
372
            String msg = "Explorer name can't be null.";
373
            LOGGER.warn(msg);
374
            throw new IllegalArgumentException(msg);
375
        }
376
        DataFactory explorerFactory = this.getServerExplorerRegister().getFactory(explorerName);
377
        if( explorerFactory == null ) {
378
            String msg = "Can't locate server explorer factory for '"+explorerName+"'.";
379
            LOGGER.warn(msg);
380
            throw new IllegalArgumentException(msg);
381
        }
382
        DataServerExplorerParameters params = (DataServerExplorerParameters) explorerFactory.createParameters();
383
        return params;
384
    }
385

    
386
    @Override
387
    public DataStoreParameters createMemoryStoreParameters(String autoOrderAttributeName) throws InitializeException {
388
        try {
389
            DataStoreParameters parameters = createStoreParameters(MemoryStoreProvider.NAME);
390
            if (autoOrderAttributeName != null) {
391
                parameters.setDynValue(
392
                        MemoryStoreParameters.ORDER_PARAMETER_NAME,
393
                        autoOrderAttributeName);
394
            }
395
            return parameters;
396
        } catch (Exception ex) {
397
            throw new InitializeException(ex);
398
        }
399
    }
400

    
401
    @Override
402
    public DataServerExplorer openServerExplorer(String explorerName, DataServerExplorerParameters parameters) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
403
        if( explorerName == null ) {
404
            String msg = "Explorer name can't be null.";
405
            LOGGER.warn(msg);
406
            throw new IllegalArgumentException(msg);
407
        }
408
        DataFactory explorerFactory = this.getServerExplorerRegister().getFactory(explorerName);
409
        if( explorerFactory == null ) {
410
            String msg = "Can't locate server explorer factory for '"+explorerName+"'.";
411
            LOGGER.warn(msg);
412
            throw new IllegalArgumentException(msg);
413
        }
414
        if (parameters == null) {
415
            parameters = (DataServerExplorerParameters) explorerFactory.createParameters();
416
        }
417
        DataServerExplorer explorer = (DataServerExplorer) explorerFactory.create(
418
                parameters,
419
                new DefaultDataServerExplorerProviderServices()
420
        );
421
        return explorer;
422
    }
423

    
424
    @Override
425
    public DataServerExplorer openServerExplorer(String explorerName, Object... arguments) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
426
        if( arguments.length==1 && arguments[0] instanceof DataServerExplorerParameters ) {
427
            // Esto hace falta ya que desde scripting si se invoca a openServerExplorer con solo 
428
            // un parametro de tipo DataServerExplorerParameters llama ha este metodo en lugar de
429
            // llamar al que toca.
430
            return openServerExplorer(explorerName, (DataServerExplorerParameters)(arguments[0]));
431
        }
432
        if( explorerName == null ) {
433
            String msg = "Explorer name can't be null.";
434
            LOGGER.warn(msg);
435
            throw new IllegalArgumentException(msg);
436
        }
437
        if( (arguments.length % 2)!= 0 ) {
438
            throw new ValidateDataParametersException();
439
        }
440
        DataFactory explorerFactory = this.getServerExplorerRegister().getFactory(explorerName);
441
        DataServerExplorerParameters parameters = (DataServerExplorerParameters) explorerFactory.createParameters();
442
        for( int i=0; i<arguments.length; i+=2 ) {
443
            String name = (String) arguments[i];
444
            if( name.endsWith("=") ) {
445
                name = name.substring(0, name.length()-1);
446
            }
447
            Object value = arguments[i+1];
448
            parameters.setDynValue(name, value);
449
        }
450
        return this.openServerExplorer(explorerName, parameters);
451

    
452
    }
453

    
454
    /**
455
     * @param parameters
456
     * @return
457
     * @throws org.gvsig.fmap.dal.exception.InitializeException
458
     * @throws org.gvsig.fmap.dal.exception.ProviderNotRegisteredException
459
     * @throws org.gvsig.fmap.dal.exception.ValidateDataParametersException
460
     * @deprecated see openServerExplorer
461
     */
462
    @Override
463
    public DataServerExplorer createServerExplorer(
464
            DataServerExplorerParameters parameters) throws InitializeException,
465
            ProviderNotRegisteredException, ValidateDataParametersException {
466
        return openServerExplorer(parameters.getExplorerName(), parameters);
467
    }
468

    
469
    /**
470
     * @deprecated use openStore
471
     * @param parameters
472
     * @return
473
     * @throws InitializeException
474
     * @throws ProviderNotRegisteredException
475
     * @throws ValidateDataParametersException
476
     */
477
    @Override
478
    public DataStore createStore(DataStoreParameters parameters)
479
        throws InitializeException, ProviderNotRegisteredException,
480
        ValidateDataParametersException {
481
        return openStore(parameters.getDataStoreName(), parameters);
482
    }
483

    
484
    @Override
485
    public DataStore openStore(String providerName, DataStoreParameters parameters) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
486
        if( providerName == null ) {
487
            String msg = "Provider name can't be null.";
488
            LOGGER.warn(msg);
489
            throw new IllegalArgumentException(msg);
490
        }
491
        SimpleIdentityManager identityManager = ToolsLocator.getIdentityManager();
492
        if (!identityManager.getCurrentIdentity().isAuthorized(READ_STORE_AUTHORIZATION, parameters, providerName)) {
493
            throw new UnauthorizedException(READ_STORE_AUTHORIZATION, parameters, providerName);
494
        }
495

    
496
        parameters.validate();
497

    
498
        String storeName = this.getStoreName(parameters);
499
        if( StringUtils.isEmpty(storeName) ) {
500
            String msg = "Can't locate the store name from the parameters. parameters=" + parameters.toString();
501
            LOGGER.warn(msg);
502
            throw new IllegalArgumentException(msg);
503
        }
504

    
505
        DataStoreFactory_v2_4 storeFactory = (DataStoreFactory_v2_4) this.getStoreRegister().getFactory(storeName);
506
        if( storeFactory == null ) {
507
            String msg = "Can't locate store factory for '"+storeName+"'.";
508
            LOGGER.warn(msg);
509
            throw new IllegalArgumentException(msg);
510
        }
511
        DataFactory providerFactory = this.getStoreProviderRegister().getFactory(providerName);
512
        if( providerFactory == null ) {
513
            String msg = "Can't locate provider factory for '"+providerName+"'.";
514
            LOGGER.warn(msg);
515
            throw new IllegalArgumentException(msg);
516
        }
517

    
518
        DataStore store = (DataStore) storeFactory.create(parameters, this);
519
        DataStoreProvider provider = (DataStoreProvider) providerFactory.create(parameters, store);
520

    
521
        storeFactory.setProvider(store, provider);
522
        return store;
523
    }
524

    
525
    public DataStore openStore(DataStoreParameters parameters, DataStoreProvider provider) {
526
        String storeName = this.getStoreName(parameters);
527
        if( StringUtils.isEmpty(storeName) ) {
528
            String msg = "Can't locate the store name from the parameters. parameters=" + parameters.toString();
529
            LOGGER.warn(msg);
530
            throw new IllegalArgumentException(msg);
531
        }
532

    
533
        DataStoreFactory_v2_4 storeFactory = (DataStoreFactory_v2_4) this.getStoreRegister().getFactory(storeName);
534
        if( storeFactory == null ) {
535
            String msg = "Can't locate store factory for '"+storeName+"'.";
536
            LOGGER.warn(msg);
537
            throw new IllegalArgumentException(msg);
538
        }
539
        DataStore store = (DataStore) storeFactory.create(parameters, this);
540
        storeFactory.setProvider(store, provider);
541
        return store;
542
    }
543
    
544
    @Override
545
    public DataStore openStore(String provider, DynObject parameters) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
546
        DataStoreParameters params = toDataStoreParameters(provider, parameters);
547
        DataStore store = openStore(params.getDataStoreName(), params);
548
        return store;
549
    }
550

    
551
    @Override
552
    public DataStore openStore(String providerName, Object... arguments) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
553
        if( arguments.length == 1 ) { 
554
            // Desde jython entra por este metodo en lugar de los especificos
555
            // de DataStoreParameters o DynObject
556
            if( arguments[0] instanceof DataStoreParameters ) {
557
                return this.openStore(providerName, (DataStoreParameters)(arguments[0]));
558
            } else if( arguments[0] instanceof DynObject ) {
559
                return this.openStore(providerName, (DynObject)(arguments[0]));
560
            }
561
        }
562
        if( (arguments.length % 2)!= 0 ) {
563
            throw new ValidateDataParametersException();
564
        }
565
        if( providerName == null ) {
566
            String msg = "Provider name can't be null.";
567
            LOGGER.warn(msg);
568
            throw new IllegalArgumentException(msg);
569
        }
570
        DataFactory providerFactory = this.getStoreProviderRegister().getFactory(providerName);
571
        DataStoreParameters parameters = (DataStoreParameters) providerFactory.createParameters();
572
        for( int i=0; i<arguments.length; i+=2 ) {
573
            String name = (String) arguments[i];
574
            if( name.endsWith("=") ) {
575
                name = name.substring(0, name.length()-1);
576
            }
577
            Object value = arguments[i+1];
578
            parameters.setDynValue(name, value);
579
        }
580
        return this.openStore(providerName, parameters);
581
    }
582

    
583
    @Override
584
    public FeatureStore createMemoryStore(String autoOrderAttributeName) throws InitializeException {
585
        try {
586
            DataStoreParameters parameters = createMemoryStoreParameters(autoOrderAttributeName);
587
            DataStore store = openStore(MemoryStoreProvider.NAME, parameters);
588
            return (FeatureStore) store;
589
        } catch (Exception ex) {
590
            throw new InitializeException(ex);
591
        }
592
    }
593

    
594
    @Override
595
    public DataStoreProviderFactory getStoreProviderFactory(String providerName) {
596
        if( providerName == null ) {
597
            String msg = "Provider name can't be null.";
598
            LOGGER.warn(msg);
599
            throw new IllegalArgumentException(msg);
600
        }
601
        DataFactory providerFactory = this.getStoreProviderRegister().getFactory(providerName);
602
        return (DataStoreProviderFactory) providerFactory;
603
    }
604

    
605
    @Override
606
    public List<String> getStoreProviders() {
607
        return this.getStoreProviderRegister().getFactoryNames();
608
    }
609

    
610
    @Override
611
    public List<String> getStoreProviders(String explorerName) {
612
        if( explorerName == null ) {
613
            String msg = "Explorer name can't be null.";
614
            LOGGER.warn(msg);
615
            throw new IllegalArgumentException(msg);
616
        }
617
        try {
618
            DataServerExplorer explorer = openServerExplorer(explorerName, (DataServerExplorerParameters)null);
619
            List names = explorer.getDataStoreProviderNames();
620
            return names;
621
        } catch (Exception ex) {
622
            throw new RuntimeException("Can't get stores availables for explorer '" + explorerName + "'.", ex);
623
        }
624
    }
625

    
626
    @Override
627
    public List<String> getExplorerProviders() {
628
        List<String> names = this.getServerExplorerRegister().getFactoryNames();
629
        return names;
630
    }
631

    
632
    @Override
633
    public DataStoreProvider createProvider(DataStoreProviderServices providerServices, DataStoreParameters parameters) throws InitializeException, ProviderNotRegisteredException {
634

    
635
        String providerName = parameters.getDataStoreName();
636
        DataFactory providerFactory = this.getStoreProviderRegister().getFactory(providerName);
637
        if (providerFactory == null) {
638
            throw new ProviderNotRegisteredException(providerName);
639
        }
640
        while (true) {
641
            try {
642
                DataStoreProvider provider = (DataStoreProvider) providerFactory.create(
643
                        parameters, providerServices
644
                );
645
                return provider;
646
            } catch (Exception e) {
647
                if (openErrorHandler == null) {
648
                    throw new InitializeException(providerName, e);
649
                }
650
                boolean retry = openErrorHandler.canRetryOpen(e, parameters);
651
                if (!retry) {
652
                    throw new InitializeException(providerName, e);
653
                }
654
            }
655
        }
656
    }
657

    
658
    @Override
659
    public List<String> getFeatureIndexProviders() {
660
        List<String> names = this.getFeatureIndexRegister().getFactoryNames();
661
        return names;
662
    }
663

    
664
    @Override
665
    public void setDefaultFeatureIndexProviderName(int dataType, String name) {
666
        this.defaultDataIndexProviders.put(dataType, name);
667
    }
668

    
669
    @Override
670
    public String getDefaultFeatureIndexProviderName(int dataType) {
671
        return this.defaultDataIndexProviders.get(dataType);
672
    }
673

    
674
    @Override
675
    public FeatureIndexProviderServices createFeatureIndexProvider(
676
            String name,
677
            FeatureStore store,
678
            FeatureType type,
679
            String indexName,
680
            FeatureAttributeDescriptor attr
681
    ) throws InitializeException, ProviderNotRegisteredException {
682

    
683
        if (name == null) {
684
            name = getDefaultFeatureIndexProviderName(attr.getType());
685
        }
686

    
687
        if (name == null) {
688
            throw new InitializeException(
689
                    "There not any index provider registered.", null);
690
        }
691
        DataFactory indexfactory = this.getFeatureIndexRegister().getFactory(name);
692
        if (indexfactory == null) {
693
            throw new InitializeException(
694
                    "There not any index provider registered with name '" + name + "'.", null);
695

    
696
        }
697
        FeatureIndexProvider provider = (FeatureIndexProvider) indexfactory.create(null, null);
698

    
699
        FeatureIndexProviderServices services = new DefaultFeatureIndex(
700
                (FeatureStoreProviderServices) store,
701
                type,
702
                provider,
703
                attr.getName(),
704
                indexName
705
        );
706
        services.initialize();
707
        return services;
708

    
709
    }
710

    
711
    @Override
712
    public String getTemporaryDirectory() {
713
        FoldersManager manager = ToolsLocator.getFoldersManager();
714
        File folder = manager.getUniqueTemporaryFile("_daltmp_");
715
        return folder.getAbsolutePath();
716
    }
717

    
718
    @Override
719
    public DataStoreParameters createStoreParameters(DynStruct struct) throws InitializeException, ProviderNotRegisteredException {
720
        if (!(struct instanceof DynStruct_v2)) {
721
            throw new IllegalArgumentException("A DynStruct_v2 is required.");
722
        }
723
        Tags tags = ((DynStruct_v2) struct).getTags();
724
        return this.createStoreParameters(tags);
725
    }
726

    
727
    @Override
728
    public DataStoreParameters createStoreParameters(Tags tags) throws InitializeException, ProviderNotRegisteredException {
729
        String providerName = (String) tags.get(TAG_DAL_OPENSTORE + "provider");
730
        if (providerName == null) {
731
            throw new IllegalArgumentException("Tag DAL.OpenStore.provider is missing in struct.");
732
        }
733
        int prefixlen = TAG_DAL_OPENSTORE.length();
734
        DataStoreParameters parameters = this.createStoreParameters(providerName);
735
        for (String key : tags) {
736
            if (key.startsWith(TAG_DAL_OPENSTORE)) {
737
                parameters.setDynValue(key.substring(prefixlen), tags.get(key));
738
            }
739
        }
740
        return parameters;
741
    }
742

    
743
    @Override
744
    public DataStore openStore(DynStruct struct) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
745
        DataStoreParameters paramters = this.createStoreParameters(struct);
746
        DataStore store = this.openStore(paramters.getDataStoreName(), paramters);
747
        return store;
748
    }
749

    
750
    @Override
751
    public void newStore(String explorerName, String providerName, NewDataStoreParameters parameters, boolean overwrite) throws InitializeException, ProviderNotRegisteredException, ValidateDataParametersException {
752
        if( explorerName == null ) {
753
            String msg = "Explorer name can't be null.";
754
            LOGGER.warn(msg);
755
            throw new IllegalArgumentException(msg);
756
        }
757
        if( providerName == null ) {
758
            String msg = "Provider name can't be null.";
759
            LOGGER.warn(msg);
760
            throw new IllegalArgumentException(msg);
761
        }
762

    
763
        SimpleIdentityManager identityManager = ToolsLocator.getIdentityManager();
764
        if (!identityManager.getCurrentIdentity().isAuthorized(CREATE_STORE_AUTHORIZATION, parameters, providerName)) {
765
            throw new UnauthorizedException(CREATE_STORE_AUTHORIZATION, parameters, providerName);
766
        }
767
        parameters.validate();
768
        try {
769
            DataServerExplorerParameters explorerParameters = this.createServerExplorerParameters(explorerName);
770
            DataServerExplorer server = this.openServerExplorer(explorerName, explorerParameters);
771
            server.add(providerName, parameters, overwrite);
772
        } catch (Exception e) {
773
            throw new InitializeException(e);
774
        }
775
    }
776

    
777
    @Override
778
    @Deprecated
779
    public Evaluator createExpresion(String expression) throws InitializeException {
780
        Expression exp = ExpressionEvaluatorLocator.getManager().createExpression();
781
        exp.setPhrase(expression);
782
        return this.createExpresion(exp);
783
    }
784

    
785
    @Override
786
    @Deprecated
787
    public Evaluator createExpresion(Expression expression) throws InitializeException {
788
        DefaultExpressionEvaluator exp = new DefaultExpressionEvaluator(expression);
789
        return exp;        
790
    }
791

    
792

    
793
    @Override
794
    public Evaluator createFilter(String expression) throws InitializeException {
795
        Expression exp = ExpressionEvaluatorLocator.getManager().createExpression();
796
        exp.setPhrase(expression);
797
        return this.createFilter(exp);
798
    }
799

    
800
    @Override
801
    public Evaluator createFilter(Expression expression) throws InitializeException {
802
        DefaultExpressionEvaluator exp = new DefaultExpressionEvaluator(expression);
803
        return exp;        
804
    }
805

    
806
    @Override
807
    public FeaturePagingHelper createFeaturePagingHelper(
808
            FeatureStore featureStore, int pageSize) throws BaseException {
809
        return new FeaturePagingHelperImpl(featureStore, pageSize);
810
    }
811

    
812
    @Override
813
    public FeaturePagingHelper createFeaturePagingHelper(
814
            FeatureStore featureStore, FeatureQuery featureQuery, int pageSize)
815
            throws BaseException {
816
        return new FeaturePagingHelperImpl(featureStore, featureQuery, pageSize);
817
    }
818

    
819
    @Override
820
    public void setOpenErrorHandler(OpenErrorHandler handler) {
821
        openErrorHandler = handler;
822
    }
823

    
824
    @Override
825
    public OpenErrorHandler getOpenErrorHandler() {
826
        return this.openErrorHandler;
827
    }
828

    
829
    @Override
830
    public EditableFeatureType createFeatureType() {
831
        return new DefaultEditableFeatureType(null);
832
    }
833

    
834
    @Override
835
    public DataServerExplorerPool getDataServerExplorerPool() {
836
        if (this.dataServerExplorerPool == null) {
837
            this.dataServerExplorerPool = new DefaultDataServerExplorerPool();
838
        }
839
        return this.dataServerExplorerPool;
840
    }
841

    
842
    @Override
843
    public void setDataServerExplorerPool(DataServerExplorerPool pool) {
844
        this.dataServerExplorerPool = pool;
845
    }
846

    
847
    public DataStoreParameters toDataStoreParameters(String provider, DynObject params) throws InitializeException, ProviderNotRegisteredException {
848
        if (params instanceof DataStoreParameters) {
849
            return (DataStoreParameters) params;
850
        }
851
        String providerName;
852
        try {
853
            providerName = (String) params.getDynValue(DataStoreProviderServices.PROVIDER_PARAMTER_NAME);
854
        } catch (Exception ex) {
855
            providerName = provider;
856
        }
857
        DataStoreParameters parameters = this.createStoreParameters(providerName);
858
        ToolsLocator.getDynObjectManager().copy(params, parameters);
859
        return parameters;
860
    }
861

    
862
    @Override
863
    public List<DataType> getDataTypes() {
864
        if (dataTypes == null) {
865
            DataTypesManager manager = ToolsLocator.getDataTypesManager();
866
            dataTypes = new ArrayList<>();
867
            dataTypes.add(manager.get(DataTypes.STRING));
868
            dataTypes.add(manager.get(DataTypes.BOOLEAN));
869
            dataTypes.add(manager.get(DataTypes.INT));
870
            dataTypes.add(manager.get(DataTypes.DOUBLE));
871
            dataTypes.add(manager.get(DataTypes.DATE));
872
            dataTypes.add(manager.get(DataTypes.GEOMETRY));
873
        }
874
        return dataTypes;
875
    }
876

    
877
    @Override
878
    public void setResourcesLoader(ClassLoader loader) {
879
        this.resourcesLoader = loader;
880
    }
881

    
882
    @Override
883
    public void setResourcesLoader(File folder) {
884
        if (folder == null) {
885
            this.resourcesLoader = null;
886
            return;
887
        }
888
        try {
889
            URL[] urls = new URL[]{folder.toURI().toURL()};
890
            this.resourcesLoader = new URLClassLoader(urls);
891
        } catch (Exception ex) {
892
            throw new IllegalArgumentException("Can't create a ClassLoader from '" + folder.toString() + "'.", ex);
893
        }
894
    }
895

    
896
    @Override
897
    public URL getResource(Object reourceLoader, String name) {
898
        URL x;
899
        if (this.resourcesLoader != null) {
900
            x = this.resourcesLoader.getResource(name);
901
            if (x != null) {
902
                return x;
903
            }
904
        }
905
        x = reourceLoader.getClass().getResource(name);
906
        return x;
907
    }
908

    
909
    @Override
910
    public InputStream getResourceAsStream(Object reourceLoader, String name) {
911
        InputStream x;
912
        if (this.resourcesLoader != null) {
913
            x = this.resourcesLoader.getResourceAsStream(name);
914
            if (x != null) {
915
                return x;
916
            }
917
        }
918
        x = reourceLoader.getClass().getResourceAsStream(name);
919
        return x;
920
    }
921

    
922
    @Override
923
    public ExpressionBuilder createExpressionBuilder() {
924
        return ExpressionEvaluatorLocator.getManager().createExpressionBuilder();
925
    }
926

    
927
    public void registerFeatureCacheProvider(
928
        FeatureCacheProviderFactory providerFactory) {
929
        ToolsLocator.getExtensionPointManager()
930
            .add(DATA_MANAGER_CACHE, DATA_MANAGER_CACHE_DESCRIPTION)
931
            .append(providerFactory.getName(), "", providerFactory);
932
    }
933

    
934
    public FeatureCacheProvider createFeatureCacheProvider(String name,
935
        DynObject parameters) throws DataException {
936
        if (name == null) {
937
            throw new InitializeException(
938
                "It is necessary to provide a cache name", null);
939
        }
940
        if (parameters == null) {
941
            throw new InitializeException(
942
                "It is necessary to provide parameters to create the explorer",
943
                null);
944
        }
945
        FeatureCacheProviderFactory featureCacheProviderFactory;
946
        try {
947
            featureCacheProviderFactory =
948
                (FeatureCacheProviderFactory) ToolsLocator
949
                    .getExtensionPointManager().get(DATA_MANAGER_CACHE)
950
                    .create(name);
951
            if (featureCacheProviderFactory == null) {
952
                throw new ProviderNotRegisteredException(name);
953
            }
954
            return featureCacheProviderFactory.createCacheProvider(parameters);
955
        } catch (InstantiationException e) {
956
            throw new InitializeException(e);
957
        } catch (IllegalAccessException e) {
958
            throw new InitializeException(e);
959
        }
960
    }
961

    
962
    @Override
963
    public List getFeatureCacheProviders() {
964
        ExtensionPoint extensionPoint =
965
            ToolsLocator.getExtensionPointManager().get(DATA_MANAGER_CACHE);
966
        if (extensionPoint != null) {
967
            return ToolsLocator.getExtensionPointManager()
968
                .get(DATA_MANAGER_CACHE).getNames();
969
        } else {
970
            return new ArrayList();
971
        }
972
    }
973

    
974
    @Override
975
    public DynObject createCacheParameters(String name)
976
        throws InitializeException, ProviderNotRegisteredException {
977
        if (name == null) {
978
            throw new InitializeException(
979
                "It is necessary to provide a cache name", null);
980
        }
981
        FeatureCacheProviderFactory featureCacheProviderFactory;
982
        try {
983
            featureCacheProviderFactory =
984
                (FeatureCacheProviderFactory) ToolsLocator
985
                    .getExtensionPointManager().get(DATA_MANAGER_CACHE)
986
                    .create(name);
987
            if (featureCacheProviderFactory == null) {
988
                throw new ProviderNotRegisteredException(name);
989
            }
990
            return featureCacheProviderFactory.createParameters();
991
        } catch (InstantiationException e) {
992
            throw new InitializeException(e);
993
        } catch (IllegalAccessException e) {
994
            throw new InitializeException(e);
995
        }
996
    }
997

    
998
    @Override
999
    public void createFileStore(String providerName, NewDataStoreParameters params, boolean overwrite) throws DataException {
1000
        DataManagerProviderServices dataManager = DALSPILocator.getDataManagerProviderServices();
1001
        DataServerExplorerParameters eparams = null;
1002
        DataServerExplorer serverExplorer;
1003
        try {
1004
            serverExplorer = dataManager.openServerExplorer(FILESYSTEM_EXPLORER_NAME, eparams);
1005
        } catch (ValidateDataParametersException | InitializeException | ProviderNotRegisteredException e) {
1006
            throw new OpenException(FILESYSTEM_EXPLORER_NAME, e);
1007
        }
1008

    
1009
        try {
1010
            serverExplorer.add(providerName, params, overwrite);
1011
        } catch (DataException e) {
1012
            throw new CreateFileStoreException(e, providerName);
1013
        }
1014
    }
1015

    
1016
    @Override
1017
    public FeatureSymbolTable createFeatureSymbolTable() {
1018
        FeatureSymbolTable symbolTable = new FeatureSymbolTableImpl();
1019
        return symbolTable;
1020
    }
1021

    
1022
    @Override
1023
    public FeatureAttributeEmulatorExpression createFeatureAttributeEmulatorExpression(FeatureType type, Expression expression) {
1024
        FeatureAttributeEmulatorExpression emulator = new DefaultFeatureAttributeEmulatorExpression(type, expression);
1025
        return emulator;
1026
    }
1027

    
1028
    @Override
1029
    public void registerDataProfile(DataProfile profile) {
1030
        if( profile==null ) {
1031
            return;
1032
        }
1033
        if( this.dataProfiles==null ) {
1034
            this.dataProfiles = new ArrayList<>();
1035
            this.dataProfiles.add(profile);
1036
            return;
1037
        }
1038
        for (DataProfile theProfile : this.dataProfiles) {
1039
            if( theProfile.getID().equalsIgnoreCase(profile.getID()) ) {
1040
                return;
1041
            }
1042
        }
1043
        this.dataProfiles.add(profile);
1044
    }
1045

    
1046
    @Override
1047
    public List<DataProfile> getDataProfiles() {
1048
        if( this.dataProfiles==null ) {
1049
            return null;
1050
        }
1051
        return Collections.unmodifiableList(this.dataProfiles);
1052
    }
1053

    
1054
    @Override
1055
    public DataProfile getDataProfile(String name) {
1056
        if( StringUtils.isBlank(name) ) {
1057
            return null;
1058
        }
1059
        for (DataProfile theProfile : this.dataProfiles) {
1060
            if( name.equalsIgnoreCase(theProfile.getName()) ) {
1061
                return theProfile;
1062
            }
1063
        }
1064
        return null;
1065
    }
1066

    
1067
    private StoresRepository storesRepository;
1068
    
1069
    @Override
1070
    public StoresRepository getStoresRepository() {
1071
        if( this.storesRepository==null ) {
1072
            this.storesRepository = new BaseStoresRepository("DAL");
1073
        }
1074
        return this.storesRepository;
1075
    }
1076
    
1077
    @Override
1078
    public DatabaseWorkspaceManager createDatabaseWorkspaceManager(DataServerExplorerParameters connection) {
1079
        DatabaseWorkspaceManager workspace = new DefaultDatabaseWorkspaceManager(connection);
1080
        return workspace;
1081
    }
1082

    
1083
    @Override
1084
    public void addDatabaseWorkspace(DatabaseWorkspaceManager databaseWorkspace) {
1085
        this.databaseWorkspaces.put(databaseWorkspace.getId(),databaseWorkspace);
1086
        StoresRepository repo = databaseWorkspace.getStoresRepository();
1087
        this.getStoresRepository().addRepository(repo);
1088

    
1089
        for (AddDatabaseWorkspaceListener listener : this.addDatabaseWorkspaceListeners.values()) {
1090
            if( listener!=null ) {
1091
                try {
1092
                    listener.onAddDatabaseWorkspace(databaseWorkspace);
1093
                } catch(Throwable th) {
1094
                    LOGGER.warn("Problems calling databaseworkspace listener '"+listener.getName()+"'.",th);
1095
                }
1096
            }
1097
        }
1098
        try {
1099
            ResourcesStorage resources = databaseWorkspace.getResourcesStorage();
1100
            ScriptManager scriptManager = ToolsLocator.getScriptManager();
1101
            Script script = scriptManager.loadScript(resources, "OnConnectToWorkspace.script");
1102
            if( script != null ) {
1103
                script.invokeFunction("main", new Object[] {databaseWorkspace});
1104
            }
1105
        } catch(Throwable th) {
1106
            LOGGER.warn("Problems executing 'OnConnectToWorkspace.script' from workspace '"+databaseWorkspace.getId()+"'.",th);
1107
        }
1108
    }
1109
    
1110
    @Override
1111
    public void addDatabaseWorkspaceListener(AddDatabaseWorkspaceListener listener) {
1112
        this.addDatabaseWorkspaceListeners.put(listener.getName(), listener);
1113
    }
1114

    
1115
    @Override
1116
    public DatabaseWorkspaceManager getDatabaseWorkspace(String name) {
1117
        return this.databaseWorkspaces.get(name);
1118
    }
1119
    
1120
    @Override
1121
    public DatabaseWorkspaceManager getDatabaseWorkspace(DataStoreParameters params) {
1122
        for (DatabaseWorkspaceManager databaseWorkspace : this.databaseWorkspaces.values()) {
1123
            if( databaseWorkspace.getStoresRepository().contains(params) ) {
1124
                return databaseWorkspace;
1125
            }
1126
        }
1127
        return null;
1128
    }
1129
    
1130
    @Override
1131
    public void writeDALResource(ResourcesStorage resources, DataStore store) {
1132
        ResourcesStorage.Resource resource = null;
1133
        try {
1134
            if( resources == null || resources.isReadOnly() ) {
1135
                return;
1136
            }
1137
            resource = resources.getResource("dal");
1138
            if( resource == null || resource.isReadOnly() ) {
1139
                return;
1140
            }
1141
            DALFile dalFile = DALFile.getDALFile();
1142
            dalFile.setStore((DefaultFeatureStore) store);
1143
            if( !dalFile.isEmpty() ) {
1144
                dalFile.write(resource);
1145
            }
1146
        } catch (Throwable ex) {
1147
            LOGGER.warn("Can't save DAL resource", ex);
1148
        } finally {
1149
            IOUtils.closeQuietly(resource);
1150
        }
1151
    
1152
        
1153
    }
1154

    
1155
    @Override
1156
    public void writeDALResource(ResourcesStorage resources, FeatureType featureType) {
1157
        ResourcesStorage.Resource resource = null;
1158
        try {
1159
            if( resources == null || resources.isReadOnly() ) {
1160
                return;
1161
            }
1162
            resource = resources.getResource("dal");
1163
            if( resource == null || resource.isReadOnly() ) {
1164
                return;
1165
            }
1166
            DALFile dalFile = DALFile.getDALFile();
1167
            dalFile.setFeatureType(featureType);
1168
            if( !dalFile.isEmpty() ) {
1169
                dalFile.write(resource);
1170
            }
1171
        } catch (Throwable ex) {
1172
            LOGGER.warn("Can't save DAL resource", ex);
1173
        } finally {
1174
            IOUtils.closeQuietly(resource);
1175
        }
1176
    }
1177

    
1178
    private Map<String,DynObjectValueItem[]> availableValues = null;
1179
    
1180
    @Override
1181
    public void clearAvailableValuesCache() {
1182
      this.availableValues = null;
1183
    }
1184
    
1185
    @Override
1186
    public DynObjectValueItem[] getAvailableValues(FeatureStore myStore, FeatureAttributeDescriptor descriptor) {
1187
        String keyName = myStore.getFullName() + ":columnName=" + descriptor.getName();
1188
        if( this.availableValues==null ) {
1189
            this.availableValues = new HashMap<>();
1190
        }
1191
        DynObjectValueItem[] values = this.availableValues.get(keyName);
1192
        if( values != null ) {
1193
            return values;
1194
        }
1195
        if( !descriptor.isForeingKey() ) {
1196
            return null;
1197
        }
1198
        ForeingKey foreingKey = descriptor.getForeingKey();
1199
        try {
1200
            StoresRepository theStoresRepository;
1201
            FeatureStore store = descriptor.getStore();
1202
            if (store == null) {
1203
                theStoresRepository = DALLocator.getDataManager().getStoresRepository();
1204

    
1205
            } else {
1206
                theStoresRepository = store.getStoresRepository();
1207
            }
1208
            FeatureStore foreingStore = (FeatureStore) theStoresRepository.getStore(
1209
                foreingKey.getTableName()
1210
            );
1211
            Expression labelExpression = foreingKey.getLabelExpression(null);
1212
            String codeName = foreingKey.getCodeName();
1213
            FeatureSymbolTable featureSymbolTable = this.createFeatureSymbolTable();
1214
            MutableSymbolTable symbolTable = featureSymbolTable.createParent();
1215
        
1216
            int count = (int) foreingStore.getFeatureCount();
1217
            values = new DynObjectValueItem[Math.min(count, MAX_AVAILABLE_VALUES)];
1218
            int n = 0;
1219
            for (Feature feature : foreingStore.getFeatureSet()) {
1220
                Object code = feature.get(codeName);
1221
                Object value;
1222
                if (labelExpression == null) {
1223
                    value = code;
1224
                } else {
1225
                    featureSymbolTable.setFeature(feature);
1226
                    value = labelExpression.execute(symbolTable);
1227
                }
1228
                values[n++] = new DynObjectValueItem(code, Objects.toString(value, Objects.toString(code, "##ERROR##")));
1229
                if( n>=MAX_AVAILABLE_VALUES ) {
1230
                    break;
1231
                }
1232
            }
1233
            this.availableValues.put(keyName, values);
1234
            return values;
1235
        } catch (Exception ex) {
1236
            LOGGER.warn("Can't get available values for field '"+myStore.getName()+"."+descriptor.getName()+"' from table '" + foreingKey.getTableName() + "'.", ex);
1237
        }
1238
        return null;
1239
    }
1240

    
1241
    @Override
1242
    public String createUniqueID() {
1243
        UUID x = UUID.randomUUID();
1244
        String s = x.toString();
1245
        return s;
1246
    }
1247
}