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

History | View | Annotate | Download (16.4 KB)

1 44262 jjdelcerro
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 44376 jjdelcerro
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
23 44262 jjdelcerro
import org.gvsig.tools.ToolsLocator;
24
import org.gvsig.tools.dispose.DisposeUtils;
25 45739 jjdelcerro
import org.gvsig.tools.dynobject.DynObject;
26 44262 jjdelcerro
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 45739 jjdelcerro
        private DynObject contextValues;
52 44262 jjdelcerro
        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 45739 jjdelcerro
            DisposeUtils.disposeQuietly(contextValues);
70 44262 jjdelcerro
            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 44304 jjdelcerro
                this.featureStore = (FeatureStore) repository.getStore(tableName);
96 44262 jjdelcerro
                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 45739 jjdelcerro
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 44262 jjdelcerro
    }
145
146
    private boolean foreingKey;
147 44338 jjdelcerro
    private boolean closedList;
148 44262 jjdelcerro
    private String labelFormula;
149
    private String tableName;
150
    private String codeName;
151 44338 jjdelcerro
    private DynObjectValueItem[] availableValues;
152 44363 jjdelcerro
    private boolean ensureReferentialIntegrity;
153 44262 jjdelcerro
    private FeatureAttributeDescriptor descriptor;
154
155
    public DefaultForeingKey() {
156 44363 jjdelcerro
        this.foreingKey = false;
157
        this.closedList = false;
158
        this.tableName = null;
159
        this.codeName = null;
160
        this.labelFormula = null;
161
        this.ensureReferentialIntegrity = false;
162 44262 jjdelcerro
    }
163
164
    public void setDescriptor(FeatureAttributeDescriptor descriptor) {
165
        this.descriptor = descriptor;
166
    }
167
168
    @Override
169 44338 jjdelcerro
    public boolean isClosedList() {
170
        return this.closedList;
171 44262 jjdelcerro
    }
172
173
    @Override
174 44338 jjdelcerro
    public void setClosedList(boolean selectable) {
175
        this.closedList = selectable;
176 44262 jjdelcerro
    }
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 44338 jjdelcerro
                && !this.closedList
222 44262 jjdelcerro
                && 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 44338 jjdelcerro
        this.closedList = false;
234 44262 jjdelcerro
        this.tableName = null;
235
        this.codeName = null;
236
        this.labelFormula = null;
237 44363 jjdelcerro
        this.ensureReferentialIntegrity = false;
238 44262 jjdelcerro
    }
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 44338 jjdelcerro
        if (!this.isClosedList()) {
408 44262 jjdelcerro
            return null;
409
        }
410 44338 jjdelcerro
        if( this.availableValues == null ) {
411 45739 jjdelcerro
            DynObject contextValues = null;
412
            if( context != null ) {
413
                contextValues = context.getContextValues();
414
            }
415 44376 jjdelcerro
            DataManagerProviderServices dataManager = (DataManagerProviderServices) DALLocator.getDataManager();
416
            FeatureStore myStore = this.descriptor.getStore();
417
            if( myStore!=null ) {
418 45739 jjdelcerro
                this.availableValues = dataManager.getAvailableValues(contextValues, myStore, this.descriptor);
419 44262 jjdelcerro
            }
420
        }
421 44338 jjdelcerro
        return this.availableValues;
422 44262 jjdelcerro
    }
423 44338 jjdelcerro
424 44363 jjdelcerro
    @Override
425 44338 jjdelcerro
    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 44262 jjdelcerro
437
    @Override
438
    public void loadFromState(PersistentState state)
439
            throws PersistenceException {
440
        foreingKey = state.getBoolean("foreingKey");
441 44338 jjdelcerro
        closedList = state.getBoolean("selectable");
442 44262 jjdelcerro
        labelFormula = state.getString("labelFormula");
443
        codeName = state.getString("codeName");
444
        tableName = state.getString("tableName");
445 44363 jjdelcerro
        ensureReferentialIntegrity = state.getBoolean("ensureReferentialIntegrity");
446 44262 jjdelcerro
    }
447
448
    @Override
449
    public void saveToState(PersistentState state) throws PersistenceException {
450
        state.set("foreingKey", foreingKey);
451 44338 jjdelcerro
        state.set("selectable", closedList);
452 44262 jjdelcerro
        state.set("labelFormula", labelFormula);
453
        state.set("codeName", codeName);
454
        state.set("tableName", tableName);
455 44363 jjdelcerro
        state.set("ensureReferentialIntegrity", ensureReferentialIntegrity);
456 44262 jjdelcerro
    }
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 44363 jjdelcerro
            definition.addDynFieldBoolean("ensureReferentialIntegrity");
478 44262 jjdelcerro
        }
479
    }
480
481
    @Override
482
    public ForeingKey clone() throws CloneNotSupportedException {
483
        DefaultForeingKey other = (DefaultForeingKey) super.clone();
484
        return other;
485
    }
486
487 44363 jjdelcerro
    @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 45258 omartinez
    @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 44363 jjdelcerro
517 44262 jjdelcerro
}