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

History | View | Annotate | Download (15.2 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.DynObjectValueItem;
26
import org.gvsig.tools.dynobject.DynStruct;
27
import org.gvsig.tools.persistence.PersistenceManager;
28
import org.gvsig.tools.persistence.Persistent;
29
import org.gvsig.tools.persistence.PersistentState;
30
import org.gvsig.tools.persistence.exception.PersistenceException;
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

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

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

    
43
    private class DefaultContextForeingKey implements ContextForeingKey {
44

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

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

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

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

    
81
                } else {
82
                    this.storesRepository = store.getStoresRepository();
83
                }
84
            }
85
            return this.storesRepository;
86
        }
87

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

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

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

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

    
133
    private boolean foreingKey;
134
    private boolean closedList;
135
    private String labelFormula;
136
    private String tableName;
137
    private String codeName;
138
    private DynObjectValueItem[] availableValues;
139
    private boolean ensureReferentialIntegrity;
140
    private FeatureAttributeDescriptor descriptor;
141

    
142
    public DefaultForeingKey() {
143
        this.foreingKey = false;
144
        this.closedList = false;
145
        this.tableName = null;
146
        this.codeName = null;
147
        this.labelFormula = null;
148
        this.ensureReferentialIntegrity = false;
149
    }
150

    
151
    public void setDescriptor(FeatureAttributeDescriptor descriptor) {
152
        this.descriptor = descriptor;
153
    }
154

    
155
    @Override
156
    public boolean isClosedList() {
157
        return this.closedList;
158
    }
159

    
160
    @Override
161
    public void setClosedList(boolean selectable) {
162
        this.closedList = selectable;
163
    }
164

    
165
    @Override
166
    public boolean isForeingKey() {
167
        return this.foreingKey;
168
    }
169

    
170
    @Override
171
    public void setForeingKey(boolean foreingKey) {
172
        this.foreingKey = foreingKey;
173
    }
174

    
175
    @Override
176
    public String getLabelFormula() {
177
        return this.labelFormula;
178
    }
179

    
180
    @Override
181
    public void setLabelFormula(String labelFormula) {
182
        this.labelFormula = labelFormula;
183
    }
184

    
185
    @Override
186
    public String getCodeName() {
187
        return this.codeName;
188
    }
189

    
190
    @Override
191
    public void setCodeName(String codeName) {
192
        this.codeName = codeName;
193
    }
194

    
195
    @Override
196
    public String getTableName() {
197
        return this.tableName;
198
    }
199

    
200
    @Override
201
    public void setTableName(String tableName) {
202
        this.tableName = tableName;
203
    }
204

    
205
    @Override
206
    public boolean isEmpty() {
207
        if (!this.foreingKey
208
                && !this.closedList
209
                && StringUtils.isBlank(this.tableName)
210
                && StringUtils.isBlank(this.codeName)
211
                && StringUtils.isBlank(this.labelFormula)) {
212
            return true;
213
        }
214
        return false;
215
    }
216

    
217
    @Override
218
    public void clean() {
219
        this.foreingKey = false;
220
        this.closedList = false;
221
        this.tableName = null;
222
        this.codeName = null;
223
        this.labelFormula = null;
224
        this.ensureReferentialIntegrity = false;
225
    }
226

    
227
    private void disposeIfLocalContext(ContextForeingKey context) {
228
        DefaultContextForeingKey c = (DefaultContextForeingKey) context;
229
        c.relese();
230
        if( c.refs == 0 ) {
231
            context.dispose();
232
        }
233
    }
234

    
235
    private ContextForeingKey createLocalContextIfNull(ContextForeingKey context) {
236
        if (context == null) {
237
            return new DefaultContextForeingKey();
238
        }
239
        DefaultContextForeingKey c = (DefaultContextForeingKey) context;
240
        c.addRef();
241
        return c;
242
    }
243

    
244
    @Override
245
    public ContextForeingKey createContext() {
246
        return new DefaultContextForeingKey();
247
    }
248

    
249
    @Override
250
    public StoresRepository getStoresRepository(ContextForeingKey context) {
251
        context = createLocalContextIfNull(context);
252
        try {
253
            return context.getStoresRepository();
254
        } finally {
255
            disposeIfLocalContext(context);
256
        }
257
    }
258

    
259
    @Override
260
    public FeatureStore getFeatureStore(ContextForeingKey context) {
261
        context = createLocalContextIfNull(context);
262
        try {
263
            return context.getFeatureStore();
264
        } finally {
265
            disposeIfLocalContext(context);
266
        }
267
    }
268

    
269
    @Override
270
    public FeatureType getFeatureType(ContextForeingKey context) {
271
        context = createLocalContextIfNull(context);
272
        FeatureStore store = context.getFeatureStore();
273
        if (store == null) {
274
            return null;
275
        }
276
        try {
277
            return store.getDefaultFeatureType();
278
        } catch (DataException ex) {
279
            return null;
280
        } finally {
281
            disposeIfLocalContext(context);
282
        }
283
    }
284

    
285
    @Override
286
    public List<Feature> getFeatures(ContextForeingKey context) {
287
        context = createLocalContextIfNull(context);
288
        FeatureStore store = context.getFeatureStore();
289
        if (store == null) {
290
            return null;
291
        }
292
        try {
293
            return store.getFeatures();
294
        } finally {
295
            disposeIfLocalContext(context);
296
        }
297
    }
298

    
299
    @Override
300
    public Object getCode(ContextForeingKey context, Feature feature) {
301
//        context = createLocalContextIfNull(context);
302
        try {
303
            return feature.get(codeName);
304
        } finally {
305
//            disposeIfLocalContext(context);
306
        }
307
    }
308

    
309
    @Override
310
    public FeatureQuery getQuery(ContextForeingKey context, Object codeValue) {
311
        context = createLocalContextIfNull(context);
312
        try {
313
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
314
            FeatureStore store = context.getFeatureStore();
315
            FeatureQuery query = store.createFeatureQuery();
316
            query.setFilter(builder.eq(
317
                    builder.variable(codeName),
318
                    builder.constant(codeValue)
319
            ).toString()
320
            );
321
            query.retrievesAllAttributes();
322
            return query;
323
        } finally {
324
            disposeIfLocalContext(context);
325
        }
326
    }
327

    
328
    @Override
329
    public Feature getFeature(ContextForeingKey context, Object codeValue) {
330
        context = createLocalContextIfNull(context);
331
        try {
332
            FeatureStore store = context.getFeatureStore();
333
            if (store == null) {
334
                return null;
335
            }
336
            FeatureQuery query = this.getQuery(context, codeValue);
337
            Feature feature = store.findFirst(query);
338
            return feature;
339
        } catch (DataException ex) {
340
            return null;
341
        } finally {
342
            disposeIfLocalContext(context);
343
        }
344
    }
345

    
346
    @Override
347
    public String getLabel(ContextForeingKey context, Object codeValue) {
348
        context = createLocalContextIfNull(context);
349
        try {
350
            Feature feature = this.getFeature(context, codeValue);
351
            if (feature == null) {
352
                return null;
353
            }
354
            return getLabel(context, feature);
355
        } finally {
356
            disposeIfLocalContext(context);
357
        }
358
    }
359

    
360
    @Override
361
    public Expression getLabelExpression(ContextForeingKey context) {
362
        context = createLocalContextIfNull(context);
363
        try {
364
            return context.getLabelExpression();
365
        } finally {
366
            disposeIfLocalContext(context);
367
        }
368
    }
369

    
370
    @Override
371
    public String getLabel(ContextForeingKey context, Feature feature) {
372
        if (feature == null) {
373
            return null;
374
        }
375
        context = createLocalContextIfNull(context);
376
        try {
377
            Expression labelExpression = context.getLabelExpression();
378
            if (labelExpression == null) {
379
                return feature.toString();
380
            }
381
            context.getFeatureSymbolTable().setFeature(feature);
382
            Object x = labelExpression.execute(context.getSymbolTable());
383
            if (x == null) {
384
                return null;
385
            }
386
            return x.toString();
387
        } finally {
388
            disposeIfLocalContext(context);
389
        }
390
    }
391

    
392
    @Override
393
    public DynObjectValueItem[] getAvailableValues(ContextForeingKey context) {
394
        if (!this.isClosedList()) {
395
            return null;
396
        }
397
        if( this.availableValues == null ) {
398
            DataManagerProviderServices dataManager = (DataManagerProviderServices) DALLocator.getDataManager();
399
            FeatureStore myStore = this.descriptor.getStore();
400
            if( myStore!=null ) {
401
                this.availableValues = dataManager.getAvailableValues(myStore, this.descriptor);
402
            }
403
        }
404
        return this.availableValues;
405
    }
406
    
407
    @Override
408
    public String getLabelForValue(Object value) {
409
        DynObjectValueItem[] values = this.getAvailableValues(null);
410
        if( values != null ) {
411
            for (DynObjectValueItem value1 : values) {
412
                if( Objects.equals(value, value1.getValue()) ) {
413
                    return value1.getLabel();
414
                }
415
            }
416
        }
417
        return Objects.toString(value, "##ERROR##");
418
    }
419

    
420
    @Override
421
    public void loadFromState(PersistentState state)
422
            throws PersistenceException {
423
        foreingKey = state.getBoolean("foreingKey");
424
        closedList = state.getBoolean("selectable");
425
        labelFormula = state.getString("labelFormula");
426
        codeName = state.getString("codeName");
427
        tableName = state.getString("tableName");
428
        ensureReferentialIntegrity = state.getBoolean("ensureReferentialIntegrity");
429
    }
430

    
431
    @Override
432
    public void saveToState(PersistentState state) throws PersistenceException {
433
        state.set("foreingKey", foreingKey);
434
        state.set("selectable", closedList);
435
        state.set("labelFormula", labelFormula);
436
        state.set("codeName", codeName);
437
        state.set("tableName", tableName);
438
        state.set("ensureReferentialIntegrity", ensureReferentialIntegrity);
439
    }
440

    
441
    private static final String FOREINGKEY_PERSISTENCE_DEFINITION_NAME = "ForeingKey";
442

    
443
    public static void registerPersistenceDefinition() {
444
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
445

    
446
        if (manager.getDefinition(FOREINGKEY_PERSISTENCE_DEFINITION_NAME)
447
                == null) {
448
            DynStruct definition = manager.addDefinition(DefaultForeingKey.class,
449
                    FOREINGKEY_PERSISTENCE_DEFINITION_NAME,
450
                    FOREINGKEY_PERSISTENCE_DEFINITION_NAME
451
                    + " persistent definition",
452
                    null,
453
                    null
454
            );
455
            definition.addDynFieldBoolean("foreingKey");
456
            definition.addDynFieldBoolean("selectable");
457
            definition.addDynFieldString("LabelFormula");
458
            definition.addDynFieldString("codeName");
459
            definition.addDynFieldString("tableName");
460
            definition.addDynFieldBoolean("ensureReferentialIntegrity");
461
        }
462
    }
463

    
464
    @Override
465
    public ForeingKey clone() throws CloneNotSupportedException {
466
        DefaultForeingKey other = (DefaultForeingKey) super.clone();
467
        return other;
468
    }
469

    
470
    @Override
471
    public boolean getEnsureReferentialIntegrity() {
472
        return this.ensureReferentialIntegrity;
473
    }
474

    
475
    @Override
476
    public void setEnsureReferentialIntegrity(boolean ensureReferentialIntegrity) {
477
        this.ensureReferentialIntegrity = ensureReferentialIntegrity;
478
    }
479
    
480
    
481

    
482
}