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 / feature / impl / DefaultForeingKey.java @ 45739

History | View | Annotate | Download (16.4 KB)

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

    
3
import org.gvsig.fmap.dal.feature.EditableForeingKey;
4
import org.gvsig.fmap.dal.feature.ForeingKey;
5
import java.util.List;
6
import java.util.Objects;
7
import org.apache.commons.lang3.StringUtils;
8
import org.gvsig.expressionevaluator.Expression;
9
import org.gvsig.expressionevaluator.ExpressionBuilder;
10
import org.gvsig.expressionevaluator.ExpressionUtils;
11
import org.gvsig.expressionevaluator.SymbolTable;
12
import org.gvsig.fmap.dal.DALLocator;
13
import org.gvsig.fmap.dal.DataManager;
14
import org.gvsig.fmap.dal.StoresRepository;
15
import org.gvsig.fmap.dal.exception.DataException;
16
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
17
import org.gvsig.fmap.dal.feature.Feature;
18
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
19
import org.gvsig.fmap.dal.feature.FeatureQuery;
20
import org.gvsig.fmap.dal.feature.FeatureStore;
21
import org.gvsig.fmap.dal.feature.FeatureType;
22
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
23
import org.gvsig.tools.ToolsLocator;
24
import org.gvsig.tools.dispose.DisposeUtils;
25
import org.gvsig.tools.dynobject.DynObject;
26
import org.gvsig.tools.dynobject.DynObjectValueItem;
27
import org.gvsig.tools.dynobject.DynStruct;
28
import org.gvsig.tools.persistence.PersistenceManager;
29
import org.gvsig.tools.persistence.Persistent;
30
import org.gvsig.tools.persistence.PersistentState;
31
import org.gvsig.tools.persistence.exception.PersistenceException;
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
/**
36
 *
37
 * @author jjdelcerro
38
 */
39
@SuppressWarnings("UseSpecificCatch")
40
public class DefaultForeingKey implements Persistent, ForeingKey, EditableForeingKey, org.gvsig.tools.lang.Cloneable {
41

    
42
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultForeingKey.class);
43

    
44
    private class DefaultContextForeingKey implements ContextForeingKey {
45

    
46
        private FeatureStore featureStore = null;
47
        private StoresRepository storesRepository = null;
48
        private Expression labelExpression;
49
        private SymbolTable symbolTable;
50
        private FeatureSymbolTable featureSymbolTable;
51
        private DynObject contextValues;
52
        private int refs;
53

    
54
        public DefaultContextForeingKey() {
55
            this.refs = 1;
56
        }
57
        
58
        public void addRef() {
59
            this.refs++;
60
        }
61

    
62
        public void relese() {
63
            this.refs--;
64
        }
65
        
66
        @Override
67
        public void dispose() {
68
            DisposeUtils.disposeQuietly(featureStore);
69
            DisposeUtils.disposeQuietly(contextValues);
70
            this.featureStore = null;
71
            this.storesRepository = null;
72
            this.labelExpression = null;
73
            this.symbolTable = null;
74
            this.featureSymbolTable = null;
75
        }
76

    
77
        @Override
78
        public StoresRepository getStoresRepository() {
79
            if (this.storesRepository == null) {
80
                FeatureStore store = descriptor.getStore();
81
                if (store == null) {
82
                    this.storesRepository = DALLocator.getDataManager().getStoresRepository();
83

    
84
                } else {
85
                    this.storesRepository = store.getStoresRepository();
86
                }
87
            }
88
            return this.storesRepository;
89
        }
90

    
91
        @Override
92
        public FeatureStore getFeatureStore() {
93
            if (this.featureStore == null) {
94
                StoresRepository repository = this.getStoresRepository();
95
                this.featureStore = (FeatureStore) repository.getStore(tableName);
96
                if (this.featureStore == null) {
97
                    LOGGER.warn("Can't locate store '" + tableName + "' to get available values of field '" + descriptor.getName() + "'.");
98
                    return null;
99
                }
100
            }
101
            return this.featureStore;
102
        }
103

    
104
        @Override
105
        public Expression getLabelExpression() {
106
            if (this.labelExpression == null) {
107
                if (StringUtils.isBlank(labelFormula)) {
108
                    return null;
109
                }
110
                this.labelExpression = ExpressionUtils.createExpression(labelFormula);
111
            }
112
            return this.labelExpression;
113
        }
114

    
115
        @Override
116
        public FeatureSymbolTable getFeatureSymbolTable() {
117
            if (this.featureSymbolTable == null) {
118
                DataManager dataManager = DALLocator.getDataManager();
119
                this.featureSymbolTable = dataManager.createFeatureSymbolTable();
120
                this.symbolTable = this.featureSymbolTable.createParent();
121
            }
122
            return this.featureSymbolTable;
123
        }
124

    
125
        @Override
126
        public SymbolTable getSymbolTable() {
127
            if (this.symbolTable == null) {
128
                DataManager dataManager = DALLocator.getDataManager();
129
                this.featureSymbolTable = dataManager.createFeatureSymbolTable();
130
                this.symbolTable = this.featureSymbolTable.createParent();
131
            }
132
            return this.symbolTable;
133
        }
134

    
135
        @Override
136
        public DynObject getContextValues() {
137
            return this.contextValues;
138
        }
139

    
140
        @Override
141
        public void setContextValues(DynObject values) {
142
            this.contextValues = values;
143
        }
144
    }
145

    
146
    private boolean foreingKey;
147
    private boolean closedList;
148
    private String labelFormula;
149
    private String tableName;
150
    private String codeName;
151
    private DynObjectValueItem[] availableValues;
152
    private boolean ensureReferentialIntegrity;
153
    private FeatureAttributeDescriptor descriptor;
154

    
155
    public DefaultForeingKey() {
156
        this.foreingKey = false;
157
        this.closedList = false;
158
        this.tableName = null;
159
        this.codeName = null;
160
        this.labelFormula = null;
161
        this.ensureReferentialIntegrity = false;
162
    }
163

    
164
    public void setDescriptor(FeatureAttributeDescriptor descriptor) {
165
        this.descriptor = descriptor;
166
    }
167

    
168
    @Override
169
    public boolean isClosedList() {
170
        return this.closedList;
171
    }
172

    
173
    @Override
174
    public void setClosedList(boolean selectable) {
175
        this.closedList = selectable;
176
    }
177

    
178
    @Override
179
    public boolean isForeingKey() {
180
        return this.foreingKey;
181
    }
182

    
183
    @Override
184
    public void setForeingKey(boolean foreingKey) {
185
        this.foreingKey = foreingKey;
186
    }
187

    
188
    @Override
189
    public String getLabelFormula() {
190
        return this.labelFormula;
191
    }
192

    
193
    @Override
194
    public void setLabelFormula(String labelFormula) {
195
        this.labelFormula = labelFormula;
196
    }
197

    
198
    @Override
199
    public String getCodeName() {
200
        return this.codeName;
201
    }
202

    
203
    @Override
204
    public void setCodeName(String codeName) {
205
        this.codeName = codeName;
206
    }
207

    
208
    @Override
209
    public String getTableName() {
210
        return this.tableName;
211
    }
212

    
213
    @Override
214
    public void setTableName(String tableName) {
215
        this.tableName = tableName;
216
    }
217

    
218
    @Override
219
    public boolean isEmpty() {
220
        if (!this.foreingKey
221
                && !this.closedList
222
                && StringUtils.isBlank(this.tableName)
223
                && StringUtils.isBlank(this.codeName)
224
                && StringUtils.isBlank(this.labelFormula)) {
225
            return true;
226
        }
227
        return false;
228
    }
229

    
230
    @Override
231
    public void clean() {
232
        this.foreingKey = false;
233
        this.closedList = false;
234
        this.tableName = null;
235
        this.codeName = null;
236
        this.labelFormula = null;
237
        this.ensureReferentialIntegrity = false;
238
    }
239

    
240
    private void disposeIfLocalContext(ContextForeingKey context) {
241
        DefaultContextForeingKey c = (DefaultContextForeingKey) context;
242
        c.relese();
243
        if( c.refs == 0 ) {
244
            context.dispose();
245
        }
246
    }
247

    
248
    private ContextForeingKey createLocalContextIfNull(ContextForeingKey context) {
249
        if (context == null) {
250
            return new DefaultContextForeingKey();
251
        }
252
        DefaultContextForeingKey c = (DefaultContextForeingKey) context;
253
        c.addRef();
254
        return c;
255
    }
256

    
257
    @Override
258
    public ContextForeingKey createContext() {
259
        return new DefaultContextForeingKey();
260
    }
261

    
262
    @Override
263
    public StoresRepository getStoresRepository(ContextForeingKey context) {
264
        context = createLocalContextIfNull(context);
265
        try {
266
            return context.getStoresRepository();
267
        } finally {
268
            disposeIfLocalContext(context);
269
        }
270
    }
271

    
272
    @Override
273
    public FeatureStore getFeatureStore(ContextForeingKey context) {
274
        context = createLocalContextIfNull(context);
275
        try {
276
            return context.getFeatureStore();
277
        } finally {
278
            disposeIfLocalContext(context);
279
        }
280
    }
281

    
282
    @Override
283
    public FeatureType getFeatureType(ContextForeingKey context) {
284
        context = createLocalContextIfNull(context);
285
        FeatureStore store = context.getFeatureStore();
286
        if (store == null) {
287
            return null;
288
        }
289
        try {
290
            return store.getDefaultFeatureType();
291
        } catch (DataException ex) {
292
            return null;
293
        } finally {
294
            disposeIfLocalContext(context);
295
        }
296
    }
297

    
298
    @Override
299
    public List<Feature> getFeatures(ContextForeingKey context) {
300
        context = createLocalContextIfNull(context);
301
        FeatureStore store = context.getFeatureStore();
302
        if (store == null) {
303
            return null;
304
        }
305
        try {
306
            return store.getFeatures();
307
        } finally {
308
            disposeIfLocalContext(context);
309
        }
310
    }
311

    
312
    @Override
313
    public Object getCode(ContextForeingKey context, Feature feature) {
314
//        context = createLocalContextIfNull(context);
315
        try {
316
            return feature.get(codeName);
317
        } finally {
318
//            disposeIfLocalContext(context);
319
        }
320
    }
321

    
322
    @Override
323
    public FeatureQuery getQuery(ContextForeingKey context, Object codeValue) {
324
        context = createLocalContextIfNull(context);
325
        try {
326
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
327
            FeatureStore store = context.getFeatureStore();
328
            FeatureQuery query = store.createFeatureQuery();
329
            query.setFilter(builder.eq(
330
                    builder.variable(codeName),
331
                    builder.constant(codeValue)
332
            ).toString()
333
            );
334
            query.retrievesAllAttributes();
335
            return query;
336
        } finally {
337
            disposeIfLocalContext(context);
338
        }
339
    }
340

    
341
    @Override
342
    public Feature getFeature(ContextForeingKey context, Object codeValue) {
343
        context = createLocalContextIfNull(context);
344
        try {
345
            FeatureStore store = context.getFeatureStore();
346
            if (store == null) {
347
                return null;
348
            }
349
            FeatureQuery query = this.getQuery(context, codeValue);
350
            Feature feature = store.findFirst(query);
351
            return feature;
352
        } catch (DataException ex) {
353
            return null;
354
        } finally {
355
            disposeIfLocalContext(context);
356
        }
357
    }
358

    
359
    @Override
360
    public String getLabel(ContextForeingKey context, Object codeValue) {
361
        context = createLocalContextIfNull(context);
362
        try {
363
            Feature feature = this.getFeature(context, codeValue);
364
            if (feature == null) {
365
                return null;
366
            }
367
            return getLabel(context, feature);
368
        } finally {
369
            disposeIfLocalContext(context);
370
        }
371
    }
372

    
373
    @Override
374
    public Expression getLabelExpression(ContextForeingKey context) {
375
        context = createLocalContextIfNull(context);
376
        try {
377
            return context.getLabelExpression();
378
        } finally {
379
            disposeIfLocalContext(context);
380
        }
381
    }
382

    
383
    @Override
384
    public String getLabel(ContextForeingKey context, Feature feature) {
385
        if (feature == null) {
386
            return null;
387
        }
388
        context = createLocalContextIfNull(context);
389
        try {
390
            Expression labelExpression = context.getLabelExpression();
391
            if (labelExpression == null) {
392
                return feature.toString();
393
            }
394
            context.getFeatureSymbolTable().setFeature(feature);
395
            Object x = labelExpression.execute(context.getSymbolTable());
396
            if (x == null) {
397
                return null;
398
            }
399
            return x.toString();
400
        } finally {
401
            disposeIfLocalContext(context);
402
        }
403
    }
404

    
405
    @Override
406
    public DynObjectValueItem[] getAvailableValues(ContextForeingKey context) {
407
        if (!this.isClosedList()) {
408
            return null;
409
        }
410
        if( this.availableValues == null ) {
411
            DynObject contextValues = null;
412
            if( context != null ) {
413
                contextValues = context.getContextValues();
414
            }
415
            DataManagerProviderServices dataManager = (DataManagerProviderServices) DALLocator.getDataManager();
416
            FeatureStore myStore = this.descriptor.getStore();
417
            if( myStore!=null ) {
418
                this.availableValues = dataManager.getAvailableValues(contextValues, myStore, this.descriptor);
419
            }
420
        }
421
        return this.availableValues;
422
    }
423
    
424
    @Override
425
    public String getLabelForValue(Object value) {
426
        DynObjectValueItem[] values = this.getAvailableValues(null);
427
        if( values != null ) {
428
            for (DynObjectValueItem value1 : values) {
429
                if( Objects.equals(value, value1.getValue()) ) {
430
                    return value1.getLabel();
431
                }
432
            }
433
        }
434
        return Objects.toString(value, "##ERROR##");
435
    }
436

    
437
    @Override
438
    public void loadFromState(PersistentState state)
439
            throws PersistenceException {
440
        foreingKey = state.getBoolean("foreingKey");
441
        closedList = state.getBoolean("selectable");
442
        labelFormula = state.getString("labelFormula");
443
        codeName = state.getString("codeName");
444
        tableName = state.getString("tableName");
445
        ensureReferentialIntegrity = state.getBoolean("ensureReferentialIntegrity");
446
    }
447

    
448
    @Override
449
    public void saveToState(PersistentState state) throws PersistenceException {
450
        state.set("foreingKey", foreingKey);
451
        state.set("selectable", closedList);
452
        state.set("labelFormula", labelFormula);
453
        state.set("codeName", codeName);
454
        state.set("tableName", tableName);
455
        state.set("ensureReferentialIntegrity", ensureReferentialIntegrity);
456
    }
457

    
458
    private static final String FOREINGKEY_PERSISTENCE_DEFINITION_NAME = "ForeingKey";
459

    
460
    public static void registerPersistenceDefinition() {
461
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
462

    
463
        if (manager.getDefinition(FOREINGKEY_PERSISTENCE_DEFINITION_NAME)
464
                == null) {
465
            DynStruct definition = manager.addDefinition(DefaultForeingKey.class,
466
                    FOREINGKEY_PERSISTENCE_DEFINITION_NAME,
467
                    FOREINGKEY_PERSISTENCE_DEFINITION_NAME
468
                    + " persistent definition",
469
                    null,
470
                    null
471
            );
472
            definition.addDynFieldBoolean("foreingKey");
473
            definition.addDynFieldBoolean("selectable");
474
            definition.addDynFieldString("LabelFormula");
475
            definition.addDynFieldString("codeName");
476
            definition.addDynFieldString("tableName");
477
            definition.addDynFieldBoolean("ensureReferentialIntegrity");
478
        }
479
    }
480

    
481
    @Override
482
    public ForeingKey clone() throws CloneNotSupportedException {
483
        DefaultForeingKey other = (DefaultForeingKey) super.clone();
484
        return other;
485
    }
486

    
487
    @Override
488
    public boolean getEnsureReferentialIntegrity() {
489
        return this.ensureReferentialIntegrity;
490
    }
491

    
492
    @Override
493
    public void setEnsureReferentialIntegrity(boolean ensureReferentialIntegrity) {
494
        this.ensureReferentialIntegrity = ensureReferentialIntegrity;
495
    }
496
    
497
    @Override
498
    public boolean isInAvailableValues(Object valueToCheck) {
499
        if (this.hasAvailableValues() && availableValues.length > 0) {
500
            for (DynObjectValueItem availableValue : availableValues) {
501
                if (Objects.equals(valueToCheck, availableValue.getValue())) {
502
                    return true;
503
                }
504
            }
505
        }
506
        return false;
507
    }
508

    
509
    @Override
510
    public boolean hasAvailableValues() {
511
        if (this.availableValues==null) {
512
            this.getAvailableValues(null);
513
        }
514
        return this.availableValues != null;
515
    }
516
    
517
}