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 / DefaultFeatureAttributeDescriptor.java @ 44253

History | View | Annotate | Download (37.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.feature.impl;
24

    
25
import java.lang.ref.WeakReference;
26
import java.text.DateFormat;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.Map;
31
import java.util.Map.Entry;
32
import java.util.Objects;
33
import org.apache.commons.lang3.ArrayUtils;
34
import org.apache.commons.lang3.StringUtils;
35
import org.cresques.cts.IProjection;
36
import org.gvsig.fmap.dal.DataStore;
37
import org.gvsig.fmap.dal.DataTypes;
38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
40
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.GeometryException;
45
import org.gvsig.fmap.geom.GeometryLocator;
46
import org.gvsig.fmap.geom.GeometryUtils;
47
import org.gvsig.fmap.geom.type.GeometryType;
48
import org.gvsig.timesupport.Interval;
49
import org.gvsig.timesupport.RelativeInterval;
50
import org.gvsig.timesupport.TimeSupportLocator;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dataTypes.CoercionException;
53
import org.gvsig.tools.dataTypes.DataType;
54
import org.gvsig.tools.dynobject.DynField;
55
import org.gvsig.tools.dynobject.DynField_LabelAttribute;
56
import org.gvsig.tools.dynobject.DynField_v2;
57
import org.gvsig.tools.dynobject.DynMethod;
58
import org.gvsig.tools.dynobject.DynObject;
59
import org.gvsig.tools.dynobject.DynObjectValueItem;
60
import org.gvsig.tools.dynobject.DynStruct;
61
import org.gvsig.tools.dynobject.Tags;
62
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
63
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
64
import org.gvsig.tools.dynobject.exception.DynMethodException;
65
import org.gvsig.tools.dynobject.impl.DefaultTags;
66
import org.gvsig.tools.evaluator.AbstractEvaluator;
67
import org.gvsig.tools.evaluator.Evaluator;
68
import org.gvsig.tools.evaluator.EvaluatorData;
69
import org.gvsig.tools.evaluator.EvaluatorException;
70
import org.gvsig.tools.persistence.PersistenceManager;
71
import org.gvsig.tools.persistence.Persistent;
72
import org.gvsig.tools.persistence.PersistentState;
73
import org.gvsig.tools.persistence.exception.PersistenceException;
74
import org.slf4j.Logger;
75
import org.slf4j.LoggerFactory;
76

    
77
public class DefaultFeatureAttributeDescriptor implements
78
        FeatureAttributeDescriptor, Persistent, DynField_v2, DynField_LabelAttribute {
79

    
80
    protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributeDescriptor.class);
81
    
82
    protected boolean allowNull;
83
    protected DataType dataType;
84
    protected String dataProfile; 
85
    protected DateFormat dateFormat;
86
    protected Object defaultValue;
87
    protected int index;
88
    protected int maximumOccurrences;
89
    protected int minimumOccurrences;
90
    protected int size;
91
    protected String name;
92
    protected Class objectClass;
93
    protected int precision;
94
    protected Evaluator evaluator;
95
    protected boolean primaryKey;
96
    protected boolean readOnly;
97
    protected IProjection SRS;
98
    protected GeometryType geomType;
99
    protected int geometryType;
100
    protected int geometrySubType;
101
    protected Map additionalInfo;
102
    protected boolean isAutomatic;
103
    protected boolean isTime = false;
104
    protected Interval interval;
105
    protected FeatureAttributeGetter featureAttributeGetter = null;
106
    protected FeatureAttributeEmulator featureAttributeEmulator = null;
107
    protected boolean indexed = false;
108
    protected boolean isIndexAscending = true;
109
    protected boolean allowIndexDuplicateds = true;
110

    
111
    protected DynObjectValueItem[] availableValues;
112
    protected String description;
113
    protected Object minValue;
114
    protected Object maxValue;
115
    protected String label;
116
    protected int order;
117
    protected boolean hidden;
118
    protected String groupName;
119
    protected Tags tags = new DefaultTags();
120
    private DynMethod availableValuesMethod;
121
    private DynMethod calculateMethod;
122
    private WeakReference typeRef;
123
    
124
    private int relationType = RELATION_TYPE_NONE;
125

    
126
    public DefaultFeatureAttributeDescriptor() {
127
        // Usada en la persistencia
128
    }
129

    
130
    protected DefaultFeatureAttributeDescriptor(FeatureType type) {
131
        setFeatureType(type);
132
        this.allowNull = true;
133
        this.dataType = null;
134
        this.dateFormat = null;
135
        this.defaultValue = null;
136
        this.index = -1;
137
        this.maximumOccurrences = 0;
138
        this.minimumOccurrences = 0;
139
        this.size = 0;
140
        this.name = null;
141
        this.objectClass = null;
142
        this.precision = 0;
143
        this.evaluator = null;
144
        this.primaryKey = false;
145
        this.readOnly = false;
146
        this.SRS = null;
147
        this.geometryType = Geometry.TYPES.NULL;
148
        this.geometrySubType = Geometry.SUBTYPES.UNKNOWN;
149
        this.additionalInfo = null;
150
        this.isAutomatic = false;
151
        this.hidden = false;
152
        this.relationType = RELATION_TYPE_NONE;
153
    }
154

    
155
    protected DefaultFeatureAttributeDescriptor(
156
            DefaultFeatureAttributeDescriptor other
157
        ) {
158
        copyFrom(other);
159
    }
160
    
161
    @Override
162
    public void copyFrom(DynField other1) {
163
        if( !(other1 instanceof DefaultFeatureAttributeDescriptor) ) {
164
            throw new IllegalArgumentException("Can't copy from a non DefaultFeatureAttributeDescriptor");
165
        }
166
        DefaultFeatureAttributeDescriptor other = (DefaultFeatureAttributeDescriptor) other1;
167
        this.typeRef = other.typeRef;
168
        this.allowNull = other.allowNull;
169
        this.dataType = other.dataType;
170
        this.dateFormat = other.dateFormat;
171
        this.defaultValue = other.defaultValue;
172
        this.index = other.index;
173
        this.maximumOccurrences = other.maximumOccurrences;
174
        this.minimumOccurrences = other.minimumOccurrences;
175
        this.size = other.size;
176
        this.name = other.name;
177
        this.objectClass = other.objectClass;
178
        this.precision = other.precision;
179
        this.evaluator = other.evaluator;
180
        this.primaryKey = other.primaryKey;
181
        this.readOnly = other.readOnly;
182
        this.SRS = other.SRS;
183
        this.geometryType = other.geometryType;
184
        this.geometrySubType = other.geometrySubType;
185
        this.geomType = other.geomType;
186
        if (other.additionalInfo != null) {
187
            Iterator iter = other.additionalInfo.entrySet().iterator();
188
            Map.Entry entry;
189
            this.additionalInfo = new HashMap();
190
            while (iter.hasNext()) {
191
                entry = (Entry) iter.next();
192
                this.additionalInfo.put(entry.getKey(), entry.getValue());
193
            }
194
        } else {
195
            this.additionalInfo = null;
196
        }
197
        this.isAutomatic = other.isAutomatic;
198
        this.isTime = other.isTime;
199
        this.featureAttributeEmulator = other.featureAttributeEmulator;
200
        this.indexed = other.indexed;
201
        this.isIndexAscending = other.isIndexAscending;
202
        this.allowIndexDuplicateds = other.allowIndexDuplicateds;
203
        this.hidden = other.hidden;
204
        this.dataProfile = other.dataProfile;
205
        
206
        this.availableValues = other.availableValues;
207
        this.description = other.description;
208
        this.minValue = other.minValue;
209
        this.maxValue = other.maxValue;
210
        this.label = other.label;
211
        this.order = other.order;
212
        this.groupName = other.groupName;
213
        if( other.tags==null ) {
214
            this.tags = null;
215
        } else {
216
            try {
217
                this.tags = (Tags) other.tags.clone();
218
            } catch (Exception ex) {
219
            }
220
        }
221
        // TODO: ? Habria que clonarlos ?
222
        this.availableValuesMethod = other.availableValuesMethod;
223
        this.calculateMethod = other.calculateMethod;
224
        this.relationType = other.relationType;
225
    }
226
    
227
    public void setFeatureType(FeatureType type) {
228
        // Usada en la persistencia
229
        if( type == null ) {
230
            this.typeRef = null;
231
        } else {
232
            this.typeRef = new WeakReference(type);
233
        }
234
    }
235
    
236
    @Override
237
    public String getDataTypeName() {
238
        if (this.getDataType() == null) {
239
            return "(unknow)";
240
        }
241
        return this.getDataType().getName();
242
    }
243

    
244
    @Override
245
    public FeatureAttributeDescriptor getCopy() {
246
        return new DefaultFeatureAttributeDescriptor(this);
247
    }
248

    
249
    @Override
250
    public Object clone() throws CloneNotSupportedException {
251
        return new DefaultFeatureAttributeDescriptor(this);
252
    }
253
    
254
    @Override
255
    public boolean allowNull() {
256
        return allowNull;
257
    }
258

    
259
    @Override
260
    public DataType getDataType() {
261
        if (featureAttributeGetter != null) {
262
            return featureAttributeGetter.getDataType();
263
        }
264
        return this.dataType;
265
    }
266

    
267
    public FeatureAttributeDescriptor setDataType(int type) {
268
        this.dataType = ToolsLocator.getDataTypesManager().get(type);
269
        return this;
270
    }
271

    
272
    @Override
273
    public DateFormat getDateFormat() {
274
        return this.dateFormat;
275
    }
276

    
277
    @Override
278
    public Object getDefaultValue() {
279
        return this.defaultValue;
280
    }
281

    
282
    @Override
283
    public Evaluator getEvaluator() {
284
        return this.evaluator;
285
    }
286

    
287
    @Override
288
    public int getGeometryType() {
289
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
290
            return Geometry.TYPES.UNKNOWN;
291
        }
292
        return this.geometryType;
293
    }
294

    
295
    @Override
296
    public int getGeometrySubType() {
297
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
298
            return Geometry.SUBTYPES.UNKNOWN;
299
        }
300
        return this.geometrySubType;
301
    }
302

    
303
    @Override
304
    public GeometryType getGeomType() {
305
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
306
            return null;
307
        }
308
        if (this.geomType == null) {
309
            try {
310
                this.geomType
311
                        = GeometryLocator.getGeometryManager().getGeometryType(
312
                                this.geometryType, this.geometrySubType);
313
            } catch (GeometryException e) {
314
                throw new RuntimeException(
315
                        "Error getting geometry type with type = "
316
                        + this.geometryType + ", subtype = "
317
                        + this.geometrySubType, e);
318
            }
319
        }
320
        return this.geomType;
321
    }
322

    
323
    @Override
324
    public int getIndex() {
325
        return this.index;
326
    }
327

    
328
    protected FeatureAttributeDescriptor setIndex(int index) {
329
        this.index = index;
330
        return this;
331
    }
332

    
333
    @Override
334
    public int getMaximumOccurrences() {
335
        return this.maximumOccurrences;
336
    }
337

    
338
    @Override
339
    public int getMinimumOccurrences() {
340
        return this.minimumOccurrences;
341
    }
342

    
343
    @Override
344
    public String getName() {
345
        return this.name;
346
    }
347
    
348
    public FeatureAttributeDescriptor setName(String name) {
349
        this.name = name;
350
        return this;
351
    }
352
    
353
    @Override
354
    public Class getObjectClass() {
355
        if (getDataType().getType() == DataTypes.OBJECT) {
356
            return objectClass;
357
        }
358
        return getDataType().getDefaultClass();
359
    }
360

    
361
    @Override
362
    public int getPrecision() {
363
        return this.precision;
364
    }
365

    
366
    @Override
367
    public IProjection getSRS() {
368
        return this.SRS;
369
    }
370

    
371
    @Override
372
    public Interval getInterval() {
373
        return this.interval;
374
    }
375

    
376
    public IProjection getSRS(WeakReference storeRef) {
377
        if( this.SRS==null ) {
378
            FeatureStore store = (FeatureStore) storeRef.get();
379
            this.SRS = (IProjection) store.getDynValue(DataStore.METADATA_CRS);
380
        }
381
        return this.SRS;
382
    }
383

    
384

    
385
    @Override
386
    public int getSize() {
387
        return this.size;
388
    }
389

    
390
    @Override
391
    public boolean isPrimaryKey() {
392
        return this.primaryKey;
393
    }
394

    
395
    @Override
396
    public boolean isReadOnly() {
397
        if (this.readOnly) {
398
            return true;
399
        }
400
        if (this.getEvaluator() != null) {
401
            return true;
402
        }
403
        if (this.featureAttributeEmulator != null) {
404
            return !this.featureAttributeEmulator.allowSetting();
405
        }
406
        return false;
407
    }
408

    
409
    @Override
410
    public Object getAdditionalInfo(String infoName) {
411
        if (this.additionalInfo == null) {
412
            return null;
413
        }
414
        return this.additionalInfo.get(infoName);
415
    }
416

    
417
    @Override
418
    public boolean isAutomatic() {
419
        return this.isAutomatic;
420
    }
421

    
422
    @Override
423
    public boolean equals(Object obj) {
424
        if (this == obj) {
425
            return true;
426
        }
427
        if (!(obj instanceof DefaultFeatureAttributeDescriptor)) {
428
            return false;
429
        }
430
        DefaultFeatureAttributeDescriptor other
431
                = (DefaultFeatureAttributeDescriptor) obj;
432

    
433
        if (this.allowNull != other.allowNull) {
434
            return false;
435
        }
436

    
437
        if (this.index != other.index) {
438
            return false;
439
        }
440

    
441
        if (!Objects.equals(this.name, other.name)) {
442
            return false;
443
        }
444

    
445
        if (this.getDataType() != other.getDataType()) {
446
            return false;
447
        }
448

    
449
        if (this.size != other.size) {
450
            return false;
451
        }
452

    
453
        if (!Objects.equals(this.defaultValue, other.defaultValue)) {
454
            return false;
455
        }
456

    
457
        if (this.primaryKey != other.primaryKey) {
458
            return false;
459
        }
460

    
461
        if (this.isAutomatic != other.isAutomatic) {
462
            return false;
463
        }
464

    
465
        if (this.readOnly != other.readOnly) {
466
            return false;
467
        }
468

    
469
        if (this.precision != other.precision) {
470
            return false;
471
        }
472

    
473
        if (this.maximumOccurrences != other.maximumOccurrences) {
474
            return false;
475
        }
476

    
477
        if (this.minimumOccurrences != other.minimumOccurrences) {
478
            return false;
479
        }
480

    
481
        if (this.geometryType != other.geometryType) {
482
            return false;
483
        }
484

    
485
        if (this.geometrySubType != other.geometrySubType) {
486
            return false;
487
        }
488

    
489
        if (!Objects.equals(this.evaluator, other.evaluator)) {
490
            return false;
491
        }
492

    
493
        if (!Objects.equals(this.featureAttributeEmulator, other.featureAttributeEmulator)) {
494
            return false;
495
        }
496

    
497
        if (!Objects.equals(this.SRS, other.SRS)) {
498
            return false;
499
        }
500

    
501
        if (!Objects.equals(this.dateFormat, other.dateFormat)) {
502
            return false;
503
        }
504

    
505
        if (!Objects.equals(this.objectClass, other.objectClass)) {
506
            return false;
507
        }
508

    
509
        if (!Objects.equals(this.dataProfile, other.dataProfile)) {
510
            return false;
511
        }
512

    
513
        return true;
514
    }
515

    
516
    @Override
517
    public void loadFromState(PersistentState state)
518
            throws PersistenceException {
519
        allowNull = state.getBoolean("allowNull");
520
        dataType = ToolsLocator.getDataTypesManager().get(state.getInt("dataType"));
521
        dataProfile = state.getString("dataProfile");
522
        
523
//        FIXME: dateFormat;
524
        try {
525
            defaultValue = dataType.coerce(state.get("defaultValue"));
526
        } catch (CoercionException ex) {
527
        }
528

    
529
        index = state.getInt("index");
530
        maximumOccurrences = state.getInt("maximumOccurrences");
531
        minimumOccurrences = state.getInt("minimumOccurrences");
532
        size = state.getInt("size");
533
        name = state.getString("name");
534
        try {
535
            String objectClassName = state.getString("objectClass"); 
536
            if( !StringUtils.isBlank(objectClassName) ) { 
537
                objectClass = Class.forName(objectClassName); 
538
            }
539
        } catch (Throwable e) {
540
            LOGGER.warn("Can't restore the objectClass of the FeatureAttributreDescriptor", e);
541
        }
542
        precision = state.getInt("precision");
543
        evaluator = (Evaluator) state.get("evaluator");
544
        primaryKey = state.getBoolean("primaryKey");
545
        readOnly = state.getBoolean("readOnly");
546
        SRS = (IProjection) state.get("SRS");
547
        geometryType = state.getInt("geometryType");
548
        geometrySubType = state.getInt("geometrySubType");
549
        if( geometryType!=Geometry.TYPES.UNKNOWN && 
550
                geometrySubType!=Geometry.SUBTYPES.UNKNOWN ) {
551
            geomType = GeometryUtils.getGeometryType(
552
                    geometryType, 
553
                    geometrySubType
554
            );
555
        }
556
//        additionalInfo = (Map) state.get("aditionalInfo");
557
        isAutomatic = state.getBoolean("isAutomatic");
558
        isTime = state.getBoolean("isTime");
559
        if( state.hasValue("intervalStart") ) {
560
            long intervalStart = state.getLong("interval_start");
561
            long intervalEnd = state.getLong("interval_end");
562
            interval = TimeSupportLocator.getManager().createRelativeInterval(intervalStart, intervalEnd);
563
        } else {
564
            interval = null;
565
        }
566
        featureAttributeEmulator = (FeatureAttributeEmulator) state.get("featureAttributeEmulator");
567
        indexed = state.getBoolean("indexed");
568
        isIndexAscending = state.getBoolean("isIndexAscending");
569
        allowIndexDuplicateds = state.getBoolean("allowIndexDuplicateds");
570

    
571
        Map<String,Object> values = state.getMap("availableValues");
572
        if( values == null || values.isEmpty()  ) {
573
            this.availableValues = null;
574
        } else {
575
            this.availableValues = new DynObjectValueItem[values.size()];
576
            int n = 0;
577
            for (Entry<String, Object> entry : values.entrySet()) {
578
                this.availableValues[n++] = new DynObjectValueItem(entry.getValue(), entry.getKey());
579
            }
580
        }
581
        
582
        description = state.getString("description");
583
        minValue = state.get("minValue");
584
        maxValue = state.get("maxValue");
585
        label = state.getString("label");
586
        order = state.getInt("order");
587
        hidden = state.getBoolean("hidden");
588
        groupName = state.getString("groupName");
589
        relationType = state.getInt("relationType");
590
    }
591

    
592
    @Override
593
    public void saveToState(PersistentState state) throws PersistenceException {
594
        state.set("allowNull", allowNull);
595
        state.set("dataType", dataType.getType());
596
        state.set("dataProfile", dataProfile);
597
        
598
//        FIXME: dateFormat;
599

    
600
        state.set("defaultValue", Objects.toString(defaultValue));
601

    
602
        state.set("index", index);
603
        state.set("maximumOccurrences", maximumOccurrences);
604
        state.set("minimumOccurrences", minimumOccurrences);
605
        state.set("size", size);
606
        state.set("name", name);
607
        state.set("objectClass", objectClass==null? null:objectClass.getName());
608
        state.set("precision", precision);
609
        state.set("evaluator", evaluator);
610
        
611
        state.set("primaryKey", primaryKey);
612
        state.set("readOnly", readOnly);
613
        state.set("SRS", SRS);
614
        GeometryType theGeomType = this.getGeomType();
615
        if( theGeomType==null ) {
616
            state.set("geometryType", Geometry.TYPES.UNKNOWN);
617
            state.set("geometrySubType", Geometry.SUBTYPES.UNKNOWN);
618
        } else {
619
            state.set("geometryType", theGeomType.getType());
620
            state.set("geometrySubType", theGeomType.getSubType());
621
        }
622

    
623
//      FIXME: additionalInfo
624

    
625
        state.set("isAutomatic", isAutomatic);
626
        state.set("isTime", isTime);
627
        if( this.interval==null ) {
628
            state.setNull("interval_start");
629
            state.setNull("interval_end");
630
        } else {
631
            state.set("interval_start", ((RelativeInterval)interval).getStart().toMillis());
632
            state.set("interval_end", ((RelativeInterval)interval).getEnd().toMillis());
633
        }
634
        state.set("SRS", SRS);
635

    
636
//      FIXME: featureAttributeGetter
637

    
638
        if( featureAttributeEmulator instanceof Persistent ) {
639
            state.set("featureAttributeEmulator", featureAttributeEmulator);
640
        } else {
641
            state.setNull("featureAttributeEmulator");
642
        }
643

    
644
        state.set("indexed", indexed);
645
        state.set("isIndexAscending", isIndexAscending);
646
        state.set("allowIndexDuplicateds", allowIndexDuplicateds);
647
        
648
        if( this.availableValues==null ) {
649
            state.setNull("availableValues");
650
        } else {
651
            Map<String,Object> values = new HashMap<>();
652
            for (DynObjectValueItem value : availableValues) {
653
                values.put(value.getLabel(),value.getValue());
654
            }
655
            state.set("availableValues", values);
656
        }
657
        state.set("description", description);
658
        state.set("minValue", minValue);
659
        state.set("maxValue", maxValue);
660
        state.set("label", label);
661
        state.set("order", order);
662
        state.set("hidden", hidden);
663
        state.set("groupName", groupName);
664
        state.set("relationType",relationType);
665

    
666
    }
667
    
668
    private static final String FEATATTRDESC_PERSISTENCE_DEFINITION_NAME = "FeatureAttributeDescriptor";
669

    
670
    public static void registerPersistenceDefinition() {
671
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
672
        
673

    
674
        if (manager.getDefinition(FEATATTRDESC_PERSISTENCE_DEFINITION_NAME)
675
                == null) {
676
            DynStruct definition = manager.addDefinition(DefaultFeatureAttributeDescriptor.class,
677
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME,
678
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME
679
                        + " persistent definition",
680
                    null,
681
                    null
682
            );
683
            definition.addDynFieldBoolean("allowNull");
684
            definition.addDynFieldInt("dataType");
685
            definition.addDynFieldString("dataProfile");
686
//            definition.addDynFieldString("dateFormat");
687
            definition.addDynFieldString("defaultValue");
688
            definition.addDynFieldInt("index");
689
            definition.addDynFieldInt("maximumOccurrences");
690
            definition.addDynFieldInt("minimumOccurrences");
691
            definition.addDynFieldInt("size");
692
            definition.addDynFieldString("name");
693
            definition.addDynFieldString("objectClass");
694
            definition.addDynFieldInt("precision");
695
            definition.addDynFieldObject("evaluator")
696
                    .setClassOfValue(Evaluator.class);
697
            definition.addDynFieldBoolean("primaryKey");
698
            definition.addDynFieldBoolean("readOnly");
699
            definition.addDynFieldObject("SRS")
700
                    .setClassOfValue(IProjection.class);
701
            definition.addDynFieldInt("geometryType");
702
            definition.addDynFieldInt("geometrySubType");
703
//            definition.addDynFieldMap("additionalInfo");
704
            definition.addDynFieldBoolean("isAutomatic");
705
            definition.addDynFieldBoolean("isTime");
706
            definition.addDynFieldLong("interval_start");
707
            definition.addDynFieldLong("interval_end");
708
            definition.addDynFieldObject("featureAttributeEmulator")
709
                    .setClassOfValue(FeatureAttributeEmulator.class);
710
            definition.addDynFieldBoolean("indexed");
711
            definition.addDynFieldBoolean("isIndexAscending");
712
            definition.addDynFieldBoolean("allowIndexDuplicateds");
713
            definition.addDynFieldMap("availableValues");
714
            definition.addDynFieldString("description");
715
            definition.addDynFieldObject("minValue");
716
            definition.addDynFieldObject("maxValue");
717
            definition.addDynFieldString("label");
718
            definition.addDynFieldInt("order");
719
            definition.addDynFieldBoolean("hidden");
720
            definition.addDynFieldString("groupName");
721
            definition.addDynFieldInt("relationType");
722
        }
723
    }
724

    
725
    
726
    /*
727
     * Start of DynField interface Implementation
728
     *
729
     */
730

    
731
    @Override
732
    public Tags getTags() {
733
        return tags;
734
    }
735

    
736
    @Override
737
    public DynObjectValueItem[] getAvailableValues() {
738
        return this.availableValues;
739
    }
740

    
741
    @Override
742
    public String getDescription() {
743
        if( this.description == null ) {
744
            return getName();
745
        }
746
        return this.description;
747
    }
748

    
749
    @Override
750
    public Object getMaxValue() {
751
        return this.maxValue;
752
    }
753

    
754
    @Override
755
    public Object getMinValue() {
756
        return this.minValue;
757
    }
758

    
759
    @Override
760
    public int getTheTypeOfAvailableValues() {
761
        return 1;
762
    }
763

    
764
    @Override
765
    public int getType() {
766
        if (featureAttributeGetter != null) {
767
            return featureAttributeGetter.getDataType().getType();
768
        }
769
        return getDataType().getType();
770
    }
771

    
772
    @Override
773
    public boolean isMandatory() {
774
        return !allowNull() || isPrimaryKey();
775
    }
776

    
777
    @Override
778
    public boolean isPersistent() {
779
        return false;
780
    }
781

    
782
    @Override
783
    public DynField setAvailableValues(DynObjectValueItem[] values) {
784
        if ( ArrayUtils.isEmpty(values) ) {
785
            this.availableValues = null;
786
        } else {
787
            this.availableValues = values;
788
        }
789
        return this;
790
    }
791

    
792
    @Override
793
    public DynField setDescription(String description) {
794
        this.description = description;
795
        return this;
796
    }
797

    
798
    @Override
799
    public DynField setMandatory(boolean mandatory) {
800
        throw new UnsupportedOperationException();
801
    }
802

    
803
    @Override
804
    public DynField setMaxValue(Object maxValue) {
805
        try {
806
            this.maxValue = this.coerce(maxValue);
807
        } catch (CoercionException e) {
808
            throw new IllegalArgumentException(e);
809
        }
810
        return this;
811
    }
812

    
813
    @Override
814
    public DynField setMinValue(Object minValue) {
815
        try {
816
            this.maxValue = this.coerce(minValue);
817
        } catch (CoercionException e) {
818
            throw new IllegalArgumentException(e);
819
        }
820
        return this;
821
    }
822

    
823
    @Override
824
    public DynField setPersistent(boolean persistent) {
825
        throw new UnsupportedOperationException();
826
    }
827

    
828
    @Override
829
    public DynField setTheTypeOfAvailableValues(int type) {
830
        throw new UnsupportedOperationException();
831
    }
832

    
833
    @Override
834
    public DynField setType(int type) {
835
        throw new UnsupportedOperationException();
836
    }
837

    
838
    @Override
839
    public DynField setDefaultDynValue(Object defaultValue) {
840
        throw new UnsupportedOperationException();
841
    }
842

    
843
    @Override
844
    public Class getClassOfValue() {
845
        return null;
846
    }
847

    
848
    @Override
849
    public DynField getElementsType() {
850
        return null;
851
    }
852

    
853
    @Override
854
    public DynField setClassOfValue(Class theClass)
855
            throws DynFieldIsNotAContainerException {
856
        throw new UnsupportedOperationException();
857
    }
858

    
859
    @Override
860
    public DynField setElementsType(DynStruct type)
861
            throws DynFieldIsNotAContainerException {
862
        throw new UnsupportedOperationException();
863
    }
864

    
865
    @Override
866
    public DynField setElementsType(int type)
867
            throws DynFieldIsNotAContainerException {
868
        throw new UnsupportedOperationException();
869
    }
870

    
871
    public FeatureAttributeDescriptor setDataProfileName(String dataProfile) {
872
        this.dataProfile = dataProfile;
873
        return this;
874
    }
875

    
876
    @Override
877
    public String getDataProfileName() {
878
        return dataProfile;
879
    }
880

    
881
    @Override
882
    public void validate(Object value) throws DynFieldValidateException {
883

    
884
        if (value == null && !this.allowNull()) {
885
            throw new DynFieldValidateException(value, this, null);
886
        }
887

    
888
        try {
889
            this.dataType.coerce(value);
890
        } catch (CoercionException e) {
891
            throw new DynFieldValidateException(value, this, e);
892
        }
893

    
894
        /*
895
         * Other checks will be needed
896
         */
897
    }
898

    
899
    @Override
900
    public String getSubtype() {
901
        if (featureAttributeGetter != null) {
902
            return featureAttributeGetter.getDataType().getSubtype();
903
        }
904
        return this.dataType.getSubtype();
905
    }
906

    
907
    @Override
908
    public Object coerce(Object value) throws CoercionException {
909
        if ( value == null ) {
910
            return value; // O debe devolver this.defaultValue
911
        }
912
        try {
913
            return this.getDataType().coerce(value);
914
        } catch(Exception ex){
915
            throw new RuntimeException(ex);
916
        }
917
    }
918

    
919
    @Override
920
    public DynField setAvailableValues(List values) {
921
        if (  values == null || values.isEmpty() ) {
922
            this.availableValues = null;
923
        } else {
924
            this.availableValues = (DynObjectValueItem[]) values.toArray(
925
                new DynObjectValueItem[values.size()]
926
            );
927
        }
928
        return this;
929
    }
930

    
931
    @Override
932
    public String getGroup() {
933
        return this.groupName;
934
    }
935

    
936
    @Override
937
    public int getOder() {
938
        return this.order;
939
    }
940

    
941
    @Override
942
    public String getLabel() {
943
        if( this.label == null ) {
944
            return this.getName();
945
        }
946
        return this.label;
947
    }
948

    
949
    @Override
950
    public DynField setLabel(String label) {
951
        this.label = label;
952
        return this;
953
    }
954

    
955
    @Override
956
    public DynField setGroup(String groupName) {
957
        this.groupName = groupName;
958
        return this;
959
    }
960

    
961
    @Override
962
    public DynField setOrder(int order) {
963
        this.order = order;
964
        return this;
965
    }
966

    
967
    @Override
968
    public DynField setHidden(boolean hidden) {
969
        this.hidden = hidden;
970
        return this;
971
    }
972

    
973
    @Override
974
    public boolean isHidden() {
975
        return this.hidden;
976
    }
977

    
978
    @Override
979
    public DynField setReadOnly(boolean arg0) {
980
        throw new UnsupportedOperationException();
981
    }
982

    
983
    @Override
984
    public boolean isContainer() {
985
        return false;
986
    }
987

    
988
    @Override
989
    public Class getClassOfItems() {
990
        return null;
991
    }
992

    
993
    @Override
994
    public DynField setDefaultFieldValue(Object defaultValue) {
995
        throw new UnsupportedOperationException();
996
    }
997

    
998
    @Override
999
    public DynField setClassOfItems(Class theClass) {
1000
        throw new UnsupportedOperationException();
1001
    }
1002

    
1003
    @Override
1004
    public DynField setType(DataType type) {
1005
        throw new UnsupportedOperationException();
1006
    }
1007

    
1008
    @Override
1009
    public DynField setSubtype(String subtype) {
1010
        throw new UnsupportedOperationException();
1011
    }
1012

    
1013
    @Override
1014
    public boolean isTime() {
1015
        return isTime;
1016
    }
1017

    
1018
    @Override
1019
    public FeatureAttributeGetter getFeatureAttributeGetter() {
1020
        return featureAttributeGetter;
1021
    }
1022

    
1023
    @Override
1024
    public void setFeatureAttributeGetter(
1025
            FeatureAttributeGetter featureAttributeTransform) {
1026
        this.featureAttributeGetter = featureAttributeTransform;
1027
    }
1028

    
1029
    @Override
1030
    public FeatureAttributeEmulator getFeatureAttributeEmulator() {
1031
        return this.featureAttributeEmulator;
1032
    }
1033

    
1034
    public FeatureAttributeDescriptor setFeatureAttributeEmulator(FeatureAttributeEmulator featureAttributeEmulator) {
1035
        this.featureAttributeEmulator = featureAttributeEmulator;
1036
        return this;
1037
    }
1038
        
1039
    @Override
1040
    public boolean isIndexed() {
1041
        return this.indexed;
1042
    }
1043

    
1044
    @Override
1045
    public boolean allowIndexDuplicateds() {
1046
        return this.allowIndexDuplicateds;
1047
    }
1048

    
1049
    @Override
1050
    public boolean isIndexAscending() {
1051
        return this.isIndexAscending;
1052
    }
1053

    
1054
    @Override
1055
    public DynField setClassOfValue(DynStruct dynStrct) {
1056
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1057
    }
1058

    
1059
    @Override
1060
    public DynField setClassOfValue(String theClassNameOfValue) {
1061
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1062
    }
1063

    
1064
    @Override
1065
    public String getClassNameOfValue() {
1066
        return null;
1067
    }
1068

    
1069
    @Override
1070
    public DynStruct getDynClassOfValue() {
1071
        return null;
1072
    }
1073

    
1074
    @Override
1075
    public DynField setTypeOfItems(int type) {
1076
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1077
    }
1078

    
1079
    @Override
1080
    public int getTypeOfItems() {
1081
        return DataTypes.INVALID;
1082
    }
1083

    
1084
    @Override
1085
    public DynField setClassOfItems(DynStruct dynStrct) {
1086
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1087
    }
1088

    
1089
    @Override
1090
    public DynField setClassOfItems(String theClassNameOfValue) {
1091
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1092
    }
1093

    
1094
    @Override
1095
    public String getClassNameOfItems() {
1096
        return null;
1097
    }
1098

    
1099
    @Override
1100
    public DynStruct getDynClassOfItems() {
1101
        return null;
1102
    }
1103

    
1104
    @Override
1105
    public DynField setRelationType(int relationType) {
1106
        this.relationType = relationType;
1107
        return this;
1108
    }
1109

    
1110
    @Override
1111
    public int getRelationType() {
1112
        return this.relationType;
1113
    }
1114

    
1115
    @Override
1116
    public DynField setAvailableValues(DynMethod availableValuesMethod) {
1117
        this.availableValuesMethod = availableValuesMethod;
1118
        return this;
1119
    }
1120

    
1121
    @Override
1122
    public DynObjectValueItem[] getAvailableValues(DynObject self) {
1123
        if( this.availableValuesMethod != null ) {
1124
            DynObjectValueItem[] values;
1125
            try {
1126
                values = (DynObjectValueItem[]) this.availableValuesMethod.invoke(self,new Object[] {this});
1127
            } catch (DynMethodException ex) {
1128
                return this.availableValues;
1129
            }
1130
            if( values != null ) {
1131
                return values;
1132
            }
1133
        }
1134
        return this.availableValues;
1135
    }
1136

    
1137
    @Override
1138
    public DynMethod getAvailableValuesMethod() {
1139
        return this.availableValuesMethod;
1140
    }
1141

    
1142
    @Override
1143
    public boolean isAvailableValuesCalculated() {
1144
        return this.availableValuesMethod!=null;
1145
    }
1146

    
1147
    @Override
1148
    public DynMethod getCalculateMethod() {
1149
        return this.calculateMethod;
1150
    }
1151

    
1152
    @Override
1153
    public DynField setCalculateMethod(DynMethod method) {
1154
        this.calculateMethod = method;
1155
        return this;
1156
    }
1157
    
1158
    @Override
1159
    public boolean isCalculated() {
1160
        return this.calculateMethod != null;
1161
    }
1162
    
1163
    @Override
1164
    public Object getCalculatedValue(DynObject self) {
1165
        try {
1166
            return this.calculateMethod.invoke(self, new Object[] { this });
1167
        } catch (DynMethodException ex) {
1168
            throw new RuntimeException(ex);
1169
        }
1170
    }
1171

    
1172
    @Override
1173
    public DynField setValidateElements(boolean validate) {
1174
        return this;
1175
    }
1176

    
1177
    @Override
1178
    public boolean getValidateElements() {
1179
        return false;
1180
    }
1181

    
1182
    private class ConstantValueEvaluator extends AbstractEvaluator {
1183

    
1184
        @Override
1185
        public Object evaluate(EvaluatorData data) throws EvaluatorException {
1186
            return defaultValue;
1187
        }
1188

    
1189
        @Override
1190
        public String getName() {
1191
            return "Constant attribute " + name;
1192
        }
1193
    }
1194

    
1195
    public void setConstantValue(boolean isConstantValue) {
1196
        if (isConstantValue) {
1197
            /* Cuando un attributo tiene asociado un evaluador, este se interpreta
1198
             * como que no debe cargarse de la fuente de datos subyacente, siendo
1199
             * el evaluador el que se encarga de proporcionar su valor.
1200
             * Nos limitamos a asignar un evaluador que retorna simpre el valor
1201
             * por defecto para ese attributo.
1202
             */
1203
            this.evaluator = new ConstantValueEvaluator();
1204
        } else {
1205
            this.evaluator = null;
1206
        }
1207
    }
1208

    
1209
    @Override
1210
    public boolean isComputed() {
1211
        return featureAttributeEmulator!=null || evaluator!=null || isCalculated();
1212
    }
1213

    
1214
    @Override
1215
    public FeatureStore getStore() {
1216
        FeatureType ftype = this.getFeatureType();
1217
        if( ftype == null ) {
1218
            return null;
1219
        }
1220
        return ftype.getStore();
1221
    }
1222
    
1223
    @Override
1224
    public FeatureType getFeatureType() {
1225
        if( this.typeRef==null ) {
1226
            return null;
1227
        }
1228
        return (FeatureType) this.typeRef.get();
1229
    }
1230

    
1231
    public FeatureAttributeDescriptor setInterval(Interval interval) {
1232
        this.interval = interval;
1233
        return this;
1234
    }
1235

    
1236
    public void fixAll() {
1237
        switch(this.getType()) {
1238
            case DataTypes.INSTANT:
1239
            case DataTypes.INTERVAL:
1240
            case DataTypes.DATE:
1241
                if( this.getInterval()!=null ) {
1242
                    this.isTime = true;
1243
                }
1244
                break;
1245
        }
1246
    }
1247

    
1248
    @Override
1249
    public String[] getRequiredFieldNames() {
1250
        FeatureAttributeEmulator emulator = this.getFeatureAttributeEmulator();
1251
        if( emulator==null ) {
1252
            return null;
1253
        }
1254
        return emulator.getRequiredFieldNames();
1255
    }
1256

    
1257
}