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

History | View | Annotate | Download (35.6 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
    public DefaultFeatureAttributeDescriptor() {
125
        // Usada en la persistencia
126
    }
127

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

    
152
    protected DefaultFeatureAttributeDescriptor(
153
            DefaultFeatureAttributeDescriptor other
154
        ) {
155
        copyFrom(other);
156
    }
157
    
158
    @Override
159
    public void copyFrom(DynField other1) {
160
        if( !(other1 instanceof DefaultFeatureAttributeDescriptor) ) {
161
            throw new IllegalArgumentException("Can't copy from a non DefaultFeatureAttributeDescriptor");
162
        }
163
        DefaultFeatureAttributeDescriptor other = (DefaultFeatureAttributeDescriptor) other1;
164
        this.typeRef = other.typeRef;
165
        this.allowNull = other.allowNull;
166
        this.dataType = other.dataType;
167
        this.dateFormat = other.dateFormat;
168
        this.defaultValue = other.defaultValue;
169
        this.index = other.index;
170
        this.maximumOccurrences = other.maximumOccurrences;
171
        this.minimumOccurrences = other.minimumOccurrences;
172
        this.size = other.size;
173
        this.name = other.name;
174
        this.objectClass = other.objectClass;
175
        this.precision = other.precision;
176
        this.evaluator = other.evaluator;
177
        this.primaryKey = other.primaryKey;
178
        this.readOnly = other.readOnly;
179
        this.SRS = other.SRS;
180
        this.geometryType = other.geometryType;
181
        this.geometrySubType = other.geometrySubType;
182
        this.geomType = other.geomType;
183
        if (other.additionalInfo != null) {
184
            Iterator iter = other.additionalInfo.entrySet().iterator();
185
            Map.Entry entry;
186
            this.additionalInfo = new HashMap();
187
            while (iter.hasNext()) {
188
                entry = (Entry) iter.next();
189
                this.additionalInfo.put(entry.getKey(), entry.getValue());
190
            }
191
        } else {
192
            this.additionalInfo = null;
193
        }
194
        this.isAutomatic = other.isAutomatic;
195
        this.isTime = other.isTime;
196
        this.featureAttributeEmulator = other.featureAttributeEmulator;
197
        this.indexed = other.indexed;
198
        this.isIndexAscending = other.isIndexAscending;
199
        this.allowIndexDuplicateds = other.allowIndexDuplicateds;
200
        this.hidden = other.hidden;
201
        this.dataProfile = other.dataProfile;
202
    }
203
    
204
    public void setFeatureType(FeatureType type) {
205
        // Usada en la persistencia
206
        if( type == null ) {
207
            this.typeRef = null;
208
        } else {
209
            this.typeRef = new WeakReference(type);
210
        }
211
    }
212
    
213
    @Override
214
    public String getDataTypeName() {
215
        if (this.getDataType() == null) {
216
            return "(unknow)";
217
        }
218
        return this.getDataType().getName();
219
    }
220

    
221
    @Override
222
    public FeatureAttributeDescriptor getCopy() {
223
        return new DefaultFeatureAttributeDescriptor(this);
224
    }
225

    
226
    @Override
227
    public Object clone() throws CloneNotSupportedException {
228
        return new DefaultFeatureAttributeDescriptor(this);
229
    }
230
    
231
    @Override
232
    public boolean allowNull() {
233
        return allowNull;
234
    }
235

    
236
    @Override
237
    public DataType getDataType() {
238
        if (featureAttributeGetter != null) {
239
            return featureAttributeGetter.getDataType();
240
        }
241
        return this.dataType;
242
    }
243

    
244
    public FeatureAttributeDescriptor setDataType(int type) {
245
        this.dataType = ToolsLocator.getDataTypesManager().get(type);
246
        return this;
247
    }
248

    
249
    @Override
250
    public DateFormat getDateFormat() {
251
        return this.dateFormat;
252
    }
253

    
254
    @Override
255
    public Object getDefaultValue() {
256
        return this.defaultValue;
257
    }
258

    
259
    @Override
260
    public Evaluator getEvaluator() {
261
        return this.evaluator;
262
    }
263

    
264
    @Override
265
    public int getGeometryType() {
266
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
267
            return Geometry.TYPES.UNKNOWN;
268
        }
269
        return this.geometryType;
270
    }
271

    
272
    @Override
273
    public int getGeometrySubType() {
274
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
275
            return Geometry.SUBTYPES.UNKNOWN;
276
        }
277
        return this.geometrySubType;
278
    }
279

    
280
    @Override
281
    public GeometryType getGeomType() {
282
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
283
            return null;
284
        }
285
        if (this.geomType == null) {
286
            try {
287
                this.geomType
288
                        = GeometryLocator.getGeometryManager().getGeometryType(
289
                                this.geometryType, this.geometrySubType);
290
            } catch (GeometryException e) {
291
                throw new RuntimeException(
292
                        "Error getting geometry type with type = "
293
                        + this.geometryType + ", subtype = "
294
                        + this.geometrySubType, e);
295
            }
296
        }
297
        return this.geomType;
298
    }
299

    
300
    @Override
301
    public int getIndex() {
302
        return this.index;
303
    }
304

    
305
    protected FeatureAttributeDescriptor setIndex(int index) {
306
        this.index = index;
307
        return this;
308
    }
309

    
310
    @Override
311
    public int getMaximumOccurrences() {
312
        return this.maximumOccurrences;
313
    }
314

    
315
    @Override
316
    public int getMinimumOccurrences() {
317
        return this.minimumOccurrences;
318
    }
319

    
320
    @Override
321
    public String getName() {
322
        return this.name;
323
    }
324
    
325
    public FeatureAttributeDescriptor setName(String name) {
326
        this.name = name;
327
        return this;
328
    }
329
    
330
    @Override
331
    public Class getObjectClass() {
332
        if (getDataType().getType() == DataTypes.OBJECT) {
333
            return objectClass;
334
        }
335
        return getDataType().getDefaultClass();
336
    }
337

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

    
343
    @Override
344
    public IProjection getSRS() {
345
        return this.SRS;
346
    }
347

    
348
    @Override
349
    public Interval getInterval() {
350
        return this.interval;
351
    }
352

    
353
    public IProjection getSRS(WeakReference storeRef) {
354
        if( this.SRS==null ) {
355
            FeatureStore store = (FeatureStore) storeRef.get();
356
            this.SRS = (IProjection) store.getDynValue(DataStore.METADATA_CRS);
357
        }
358
        return this.SRS;
359
    }
360

    
361

    
362
    @Override
363
    public int getSize() {
364
        return this.size;
365
    }
366

    
367
    @Override
368
    public boolean isPrimaryKey() {
369
        return this.primaryKey;
370
    }
371

    
372
    @Override
373
    public boolean isReadOnly() {
374
        if (this.readOnly) {
375
            return true;
376
        }
377
        if (this.getEvaluator() != null) {
378
            return true;
379
        }
380
        if (this.featureAttributeEmulator != null) {
381
            return !this.featureAttributeEmulator.allowSetting();
382
        }
383
        return false;
384
    }
385

    
386
    @Override
387
    public Object getAdditionalInfo(String infoName) {
388
        if (this.additionalInfo == null) {
389
            return null;
390
        }
391
        return this.additionalInfo.get(infoName);
392
    }
393

    
394
    @Override
395
    public boolean isAutomatic() {
396
        return this.isAutomatic;
397
    }
398

    
399
    @Override
400
    public boolean equals(Object obj) {
401
        if (this == obj) {
402
            return true;
403
        }
404
        if (!(obj instanceof DefaultFeatureAttributeDescriptor)) {
405
            return false;
406
        }
407
        DefaultFeatureAttributeDescriptor other
408
                = (DefaultFeatureAttributeDescriptor) obj;
409

    
410
        if (this.allowNull != other.allowNull) {
411
            return false;
412
        }
413

    
414
        if (this.index != other.index) {
415
            return false;
416
        }
417

    
418
        if (!Objects.equals(this.name, other.name)) {
419
            return false;
420
        }
421

    
422
        if (this.getDataType() != other.getDataType()) {
423
            return false;
424
        }
425

    
426
        if (this.size != other.size) {
427
            return false;
428
        }
429

    
430
        if (!Objects.equals(this.defaultValue, other.defaultValue)) {
431
            return false;
432
        }
433

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

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

    
442
        if (this.readOnly != other.readOnly) {
443
            return false;
444
        }
445

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

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

    
454
        if (this.minimumOccurrences != other.minimumOccurrences) {
455
            return false;
456
        }
457

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

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

    
466
        if (!Objects.equals(this.evaluator, other.evaluator)) {
467
            return false;
468
        }
469

    
470
        if (!Objects.equals(this.featureAttributeEmulator, other.featureAttributeEmulator)) {
471
            return false;
472
        }
473

    
474
        if (!Objects.equals(this.SRS, other.SRS)) {
475
            return false;
476
        }
477

    
478
        if (!Objects.equals(this.dateFormat, other.dateFormat)) {
479
            return false;
480
        }
481

    
482
        if (!Objects.equals(this.objectClass, other.objectClass)) {
483
            return false;
484
        }
485

    
486
        if (!Objects.equals(this.dataProfile, other.dataProfile)) {
487
            return false;
488
        }
489

    
490
        return true;
491
    }
492

    
493
    @Override
494
    public void loadFromState(PersistentState state)
495
            throws PersistenceException {
496
        allowNull = state.getBoolean("allowNull");
497
        dataType = ToolsLocator.getDataTypesManager().get(state.getInt("dataType"));
498
        dataProfile = state.getString("dataProfile");
499
        
500
//        FIXME: dateFormat;
501
        try {
502
            defaultValue = dataType.coerce(state.get("defaultValue"));
503
        } catch (CoercionException ex) {
504
        }
505

    
506
        index = state.getInt("index");
507
        maximumOccurrences = state.getInt("maximumOccurrences");
508
        minimumOccurrences = state.getInt("minimumOccurrences");
509
        size = state.getInt("size");
510
        name = state.getString("name");
511
        try {
512
            String objectClassName = state.getString("objectClass"); 
513
            if( !StringUtils.isBlank(objectClassName) ) { 
514
                objectClass = Class.forName(objectClassName); 
515
            }
516
        } catch (Throwable e) {
517
            LOGGER.warn("Can't restore the objectClass of the FeatureAttributreDescriptor", e);
518
        }
519
        precision = state.getInt("precision");
520
        evaluator = (Evaluator) state.get("evaluator");
521
        primaryKey = state.getBoolean("primaryKey");
522
        readOnly = state.getBoolean("readOnly");
523
        SRS = (IProjection) state.get("SRS");
524
        geometryType = state.getInt("geometryType");
525
        geometrySubType = state.getInt("geometrySubType");
526
        if( geometryType!=Geometry.TYPES.UNKNOWN && 
527
                geometrySubType!=Geometry.SUBTYPES.UNKNOWN ) {
528
            geomType = GeometryUtils.getGeometryType(
529
                    geometryType, 
530
                    geometrySubType
531
            );
532
        }
533
//        additionalInfo = (Map) state.get("aditionalInfo");
534
        isAutomatic = state.getBoolean("isAutomatic");
535
        isTime = state.getBoolean("isTime");
536
        if( state.hasValue("intervalStart") ) {
537
            long intervalStart = state.getLong("interval_start");
538
            long intervalEnd = state.getLong("interval_end");
539
            interval = TimeSupportLocator.getManager().createRelativeInterval(intervalStart, intervalEnd);
540
        } else {
541
            interval = null;
542
        }
543
        featureAttributeEmulator = (FeatureAttributeEmulator) state.get("featureAttributeEmulator");
544
        indexed = state.getBoolean("indexed");
545
        isIndexAscending = state.getBoolean("isIndexAscending");
546
        allowIndexDuplicateds = state.getBoolean("allowIndexDuplicateds");
547

    
548
//        FIXME: availableValues 
549

    
550
        description = state.getString("description");
551
        minValue = state.get("minValue");
552
        maxValue = state.get("maxValue");
553
        label = state.getString("label");
554
        order = state.getInt("order");
555
        hidden = state.getBoolean("hidden");
556
        groupName = state.getString("groupName");
557
    }
558

    
559
    @Override
560
    public void saveToState(PersistentState state) throws PersistenceException {
561
        state.set("allowNull", allowNull);
562
        state.set("dataType", dataType.getType());
563
        state.set("dataProfile", dataProfile);
564
        
565
//        FIXME: dateFormat;
566

    
567
        state.set("defaultValue", Objects.toString(defaultValue));
568

    
569
        state.set("index", index);
570
        state.set("maximumOccurrences", maximumOccurrences);
571
        state.set("minimumOccurrences", minimumOccurrences);
572
        state.set("size", size);
573
        state.set("name", name);
574
        state.set("objectClass", objectClass==null? null:objectClass.getName());
575
        state.set("precision", precision);
576
        state.set("evaluator", evaluator);
577
        
578
        state.set("primaryKey", primaryKey);
579
        state.set("readOnly", readOnly);
580
        state.set("SRS", SRS);
581
        GeometryType theGeomType = this.getGeomType();
582
        if( theGeomType==null ) {
583
            state.set("geometryType", Geometry.TYPES.UNKNOWN);
584
            state.set("geometrySubType", Geometry.SUBTYPES.UNKNOWN);
585
        } else {
586
            state.set("geometryType", theGeomType.getType());
587
            state.set("geometrySubType", theGeomType.getSubType());
588
        }
589

    
590
//      FIXME: additionalInfo
591

    
592
        state.set("isAutomatic", isAutomatic);
593
        state.set("isTime", isTime);
594
        if( this.interval==null ) {
595
            state.setNull("interval_start");
596
            state.setNull("interval_end");
597
        } else {
598
            state.set("interval_start", ((RelativeInterval)interval).getStart().toMillis());
599
            state.set("interval_end", ((RelativeInterval)interval).getEnd().toMillis());
600
        }
601
        state.set("SRS", SRS);
602

    
603
//      FIXME: featureAttributeGetter
604

    
605
        if( featureAttributeEmulator instanceof Persistent ) {
606
            state.set("featureAttributeEmulator", featureAttributeEmulator);
607
        } else {
608
            state.setNull("featureAttributeEmulator");
609
        }
610

    
611
        state.set("indexed", indexed);
612
        state.set("isIndexAscending", isIndexAscending);
613
        state.set("allowIndexDuplicateds", allowIndexDuplicateds);
614
        
615
//        FIXME: availableValues 
616

    
617
        state.set("description", description);
618
        state.set("minValue", minValue);
619
        state.set("maxValue", maxValue);
620
        state.set("label", label);
621
        state.set("order", order);
622
        state.set("hidden", hidden);
623
        state.set("groupName", groupName);
624

    
625
    }
626
    
627
    private static final String FEATATTRDESC_PERSISTENCE_DEFINITION_NAME = "FeatureAttributeDescriptor";
628

    
629
    public static void registerPersistenceDefinition() {
630
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
631
        
632

    
633
        if (manager.getDefinition(FEATATTRDESC_PERSISTENCE_DEFINITION_NAME)
634
                == null) {
635
            DynStruct definition = manager.addDefinition(DefaultFeatureAttributeDescriptor.class,
636
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME,
637
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME
638
                        + " persistent definition",
639
                    null,
640
                    null
641
            );
642
            definition.addDynFieldBoolean("allowNull");
643
            definition.addDynFieldInt("dataType");
644
            definition.addDynFieldString("dataProfile");
645
//            definition.addDynFieldString("dateFormat");
646
            definition.addDynFieldString("defaultValue");
647
            definition.addDynFieldInt("index");
648
            definition.addDynFieldInt("maximumOccurrences");
649
            definition.addDynFieldInt("minimumOccurrences");
650
            definition.addDynFieldInt("size");
651
            definition.addDynFieldString("name");
652
            definition.addDynFieldString("objectClass");
653
            definition.addDynFieldInt("precision");
654
            definition.addDynFieldObject("evaluator")
655
                    .setClassOfValue(Evaluator.class);
656
            definition.addDynFieldBoolean("primaryKey");
657
            definition.addDynFieldBoolean("readOnly");
658
            definition.addDynFieldObject("SRS")
659
                    .setClassOfValue(IProjection.class);
660
            definition.addDynFieldInt("geometryType");
661
            definition.addDynFieldInt("geometrySubType");
662
//            definition.addDynFieldMap("additionalInfo");
663
            definition.addDynFieldBoolean("isAutomatic");
664
            definition.addDynFieldBoolean("isTime");
665
            definition.addDynFieldLong("interval_start");
666
            definition.addDynFieldLong("interval_end");
667
            definition.addDynFieldObject("featureAttributeEmulator")
668
                    .setClassOfValue(FeatureAttributeEmulator.class);
669
            definition.addDynFieldBoolean("indexed");
670
            definition.addDynFieldBoolean("isIndexAscending");
671
            definition.addDynFieldBoolean("allowIndexDuplicateds");
672
//            definition.addDynFieldInt("availableValues");
673
            definition.addDynFieldInt("description");
674
            definition.addDynFieldInt("minValue");
675
            definition.addDynFieldInt("maxValue");
676
            definition.addDynFieldInt("label");
677
            definition.addDynFieldInt("order");
678
            definition.addDynFieldBoolean("hidden");
679
            definition.addDynFieldInt("groupName");
680
        }
681
    }
682

    
683
    
684
    /*
685
     * Start of DynField interface Implementation
686
     *
687
     */
688

    
689
    @Override
690
    public Tags getTags() {
691
        return tags;
692
    }
693

    
694
    @Override
695
    public DynObjectValueItem[] getAvailableValues() {
696
        return this.availableValues;
697
    }
698

    
699
    @Override
700
    public String getDescription() {
701
        if( this.description == null ) {
702
            return getName();
703
        }
704
        return this.description;
705
    }
706

    
707
    @Override
708
    public Object getMaxValue() {
709
        return this.maxValue;
710
    }
711

    
712
    @Override
713
    public Object getMinValue() {
714
        return this.minValue;
715
    }
716

    
717
    @Override
718
    public int getTheTypeOfAvailableValues() {
719
        return 1;
720
    }
721

    
722
    @Override
723
    public int getType() {
724
        if (featureAttributeGetter != null) {
725
            return featureAttributeGetter.getDataType().getType();
726
        }
727
        return getDataType().getType();
728
    }
729

    
730
    @Override
731
    public boolean isMandatory() {
732
        return !allowNull() || isPrimaryKey();
733
    }
734

    
735
    @Override
736
    public boolean isPersistent() {
737
        return false;
738
    }
739

    
740
    @Override
741
    public DynField setAvailableValues(DynObjectValueItem[] values) {
742
        if ( ArrayUtils.isEmpty(values) ) {
743
            this.availableValues = null;
744
        } else {
745
            this.availableValues = values;
746
        }
747
        return this;
748
    }
749

    
750
    @Override
751
    public DynField setDescription(String description) {
752
        this.description = description;
753
        return this;
754
    }
755

    
756
    @Override
757
    public DynField setMandatory(boolean mandatory) {
758
        throw new UnsupportedOperationException();
759
    }
760

    
761
    @Override
762
    public DynField setMaxValue(Object maxValue) {
763
        try {
764
            this.maxValue = this.coerce(maxValue);
765
        } catch (CoercionException e) {
766
            throw new IllegalArgumentException(e);
767
        }
768
        return this;
769
    }
770

    
771
    @Override
772
    public DynField setMinValue(Object minValue) {
773
        try {
774
            this.maxValue = this.coerce(minValue);
775
        } catch (CoercionException e) {
776
            throw new IllegalArgumentException(e);
777
        }
778
        return this;
779
    }
780

    
781
    @Override
782
    public DynField setPersistent(boolean persistent) {
783
        throw new UnsupportedOperationException();
784
    }
785

    
786
    @Override
787
    public DynField setTheTypeOfAvailableValues(int type) {
788
        throw new UnsupportedOperationException();
789
    }
790

    
791
    @Override
792
    public DynField setType(int type) {
793
        throw new UnsupportedOperationException();
794
    }
795

    
796
    @Override
797
    public DynField setDefaultDynValue(Object defaultValue) {
798
        throw new UnsupportedOperationException();
799
    }
800

    
801
    @Override
802
    public Class getClassOfValue() {
803
        return null;
804
    }
805

    
806
    @Override
807
    public DynField getElementsType() {
808
        return null;
809
    }
810

    
811
    @Override
812
    public DynField setClassOfValue(Class theClass)
813
            throws DynFieldIsNotAContainerException {
814
        throw new UnsupportedOperationException();
815
    }
816

    
817
    @Override
818
    public DynField setElementsType(DynStruct type)
819
            throws DynFieldIsNotAContainerException {
820
        throw new UnsupportedOperationException();
821
    }
822

    
823
    @Override
824
    public DynField setElementsType(int type)
825
            throws DynFieldIsNotAContainerException {
826
        throw new UnsupportedOperationException();
827
    }
828

    
829
    public FeatureAttributeDescriptor setDataProfileName(String dataProfile) {
830
        this.dataProfile = dataProfile;
831
        return this;
832
    }
833

    
834
    @Override
835
    public String getDataProfileName() {
836
        return dataProfile;
837
    }
838

    
839
    @Override
840
    public void validate(Object value) throws DynFieldValidateException {
841

    
842
        if (value == null && !this.allowNull()) {
843
            throw new DynFieldValidateException(value, this, null);
844
        }
845

    
846
        try {
847
            this.dataType.coerce(value);
848
        } catch (CoercionException e) {
849
            throw new DynFieldValidateException(value, this, e);
850
        }
851

    
852
        /*
853
         * Other checks will be needed
854
         */
855
    }
856

    
857
    @Override
858
    public String getSubtype() {
859
        if (featureAttributeGetter != null) {
860
            return featureAttributeGetter.getDataType().getSubtype();
861
        }
862
        return this.dataType.getSubtype();
863
    }
864

    
865
    @Override
866
    public Object coerce(Object value) throws CoercionException {
867
        if ( value == null ) {
868
            return value; // O debe devolver this.defaultValue
869
        }
870
        try {
871
            return this.getDataType().coerce(value);
872
        } catch(Exception ex){
873
            throw new RuntimeException(ex);
874
        }
875
    }
876

    
877
    @Override
878
    public DynField setAvailableValues(List values) {
879
        if (  values == null || values.isEmpty() ) {
880
            this.availableValues = null;
881
        } else {
882
            this.availableValues = (DynObjectValueItem[]) values.toArray(
883
                new DynObjectValueItem[values.size()]
884
            );
885
        }
886
        return this;
887
    }
888

    
889
    @Override
890
    public String getGroup() {
891
        return this.groupName;
892
    }
893

    
894
    @Override
895
    public int getOder() {
896
        return this.order;
897
    }
898

    
899
    @Override
900
    public String getLabel() {
901
        if( this.label == null ) {
902
            return this.getName();
903
        }
904
        return this.label;
905
    }
906

    
907
    @Override
908
    public DynField setLabel(String label) {
909
        this.label = label;
910
        return this;
911
    }
912

    
913
    @Override
914
    public DynField setGroup(String groupName) {
915
        this.groupName = groupName;
916
        return this;
917
    }
918

    
919
    @Override
920
    public DynField setOrder(int order) {
921
        this.order = order;
922
        return this;
923
    }
924

    
925
    @Override
926
    public DynField setHidden(boolean hidden) {
927
        this.hidden = hidden;
928
        return this;
929
    }
930

    
931
    @Override
932
    public boolean isHidden() {
933
        return this.hidden;
934
    }
935

    
936
    @Override
937
    public DynField setReadOnly(boolean arg0) {
938
        throw new UnsupportedOperationException();
939
    }
940

    
941
    @Override
942
    public boolean isContainer() {
943
        return false;
944
    }
945

    
946
    @Override
947
    public Class getClassOfItems() {
948
        return null;
949
    }
950

    
951
    @Override
952
    public DynField setDefaultFieldValue(Object defaultValue) {
953
        throw new UnsupportedOperationException();
954
    }
955

    
956
    @Override
957
    public DynField setClassOfItems(Class theClass) {
958
        throw new UnsupportedOperationException();
959
    }
960

    
961
    @Override
962
    public DynField setType(DataType type) {
963
        throw new UnsupportedOperationException();
964
    }
965

    
966
    @Override
967
    public DynField setSubtype(String subtype) {
968
        throw new UnsupportedOperationException();
969
    }
970

    
971
    @Override
972
    public boolean isTime() {
973
        return isTime;
974
    }
975

    
976
    @Override
977
    public FeatureAttributeGetter getFeatureAttributeGetter() {
978
        return featureAttributeGetter;
979
    }
980

    
981
    @Override
982
    public void setFeatureAttributeGetter(
983
            FeatureAttributeGetter featureAttributeTransform) {
984
        this.featureAttributeGetter = featureAttributeTransform;
985
    }
986

    
987
    @Override
988
    public FeatureAttributeEmulator getFeatureAttributeEmulator() {
989
        return this.featureAttributeEmulator;
990
    }
991

    
992
    public FeatureAttributeDescriptor setFeatureAttributeEmulator(FeatureAttributeEmulator featureAttributeEmulator) {
993
        this.featureAttributeEmulator = featureAttributeEmulator;
994
        return this;
995
    }
996
        
997
    @Override
998
    public boolean isIndexed() {
999
        return this.indexed;
1000
    }
1001

    
1002
    @Override
1003
    public boolean allowIndexDuplicateds() {
1004
        return this.allowIndexDuplicateds;
1005
    }
1006

    
1007
    @Override
1008
    public boolean isIndexAscending() {
1009
        return this.isIndexAscending;
1010
    }
1011

    
1012
    @Override
1013
    public DynField setClassOfValue(DynStruct dynStrct) {
1014
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1015
    }
1016

    
1017
    @Override
1018
    public DynField setClassOfValue(String theClassNameOfValue) {
1019
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1020
    }
1021

    
1022
    @Override
1023
    public String getClassNameOfValue() {
1024
        return null;
1025
    }
1026

    
1027
    @Override
1028
    public DynStruct getDynClassOfValue() {
1029
        return null;
1030
    }
1031

    
1032
    @Override
1033
    public DynField setTypeOfItems(int type) {
1034
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1035
    }
1036

    
1037
    @Override
1038
    public int getTypeOfItems() {
1039
        return DataTypes.INVALID;
1040
    }
1041

    
1042
    @Override
1043
    public DynField setClassOfItems(DynStruct dynStrct) {
1044
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1045
    }
1046

    
1047
    @Override
1048
    public DynField setClassOfItems(String theClassNameOfValue) {
1049
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1050
    }
1051

    
1052
    @Override
1053
    public String getClassNameOfItems() {
1054
        return null;
1055
    }
1056

    
1057
    @Override
1058
    public DynStruct getDynClassOfItems() {
1059
        return null;
1060
    }
1061

    
1062
    @Override
1063
    public DynField setRelationType(int relationType) {
1064
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1065
    }
1066

    
1067
    @Override
1068
    public int getRelationType() {
1069
        return RELATION_TYPE_NONE;
1070
    }
1071

    
1072
    @Override
1073
    public DynField setAvailableValues(DynMethod availableValuesMethod) {
1074
        this.availableValuesMethod = availableValuesMethod;
1075
        return this;
1076
    }
1077

    
1078
    @Override
1079
    public DynObjectValueItem[] getAvailableValues(DynObject self) {
1080
        if( this.availableValuesMethod != null ) {
1081
            DynObjectValueItem[] values;
1082
            try {
1083
                values = (DynObjectValueItem[]) this.availableValuesMethod.invoke(self,new Object[] {this});
1084
            } catch (DynMethodException ex) {
1085
                return this.availableValues;
1086
            }
1087
            if( values != null ) {
1088
                return values;
1089
            }
1090
        }
1091
        return this.availableValues;
1092
    }
1093

    
1094
    @Override
1095
    public DynMethod getAvailableValuesMethod() {
1096
        return this.availableValuesMethod;
1097
    }
1098

    
1099
    @Override
1100
    public boolean isAvailableValuesCalculated() {
1101
        return this.availableValuesMethod!=null;
1102
    }
1103

    
1104
    @Override
1105
    public DynMethod getCalculateMethod() {
1106
        return this.calculateMethod;
1107
    }
1108

    
1109
    @Override
1110
    public DynField setCalculateMethod(DynMethod method) {
1111
        this.calculateMethod = method;
1112
        return this;
1113
    }
1114
    
1115
    @Override
1116
    public boolean isCalculated() {
1117
        return this.calculateMethod != null;
1118
    }
1119
    
1120
    @Override
1121
    public Object getCalculatedValue(DynObject self) {
1122
        try {
1123
            return this.calculateMethod.invoke(self, new Object[] { this });
1124
        } catch (DynMethodException ex) {
1125
            throw new RuntimeException(ex);
1126
        }
1127
    }
1128

    
1129
    @Override
1130
    public DynField setValidateElements(boolean validate) {
1131
        return this;
1132
    }
1133

    
1134
    @Override
1135
    public boolean getValidateElements() {
1136
        return false;
1137
    }
1138

    
1139
    private class ConstantValueEvaluator extends AbstractEvaluator {
1140

    
1141
        @Override
1142
        public Object evaluate(EvaluatorData data) throws EvaluatorException {
1143
            return defaultValue;
1144
        }
1145

    
1146
        @Override
1147
        public String getName() {
1148
            return "Constant attribute " + name;
1149
        }
1150
    }
1151

    
1152
    public void setConstantValue(boolean isConstantValue) {
1153
        if (isConstantValue) {
1154
            /* Cuando un attributo tiene asociado un evaluador, este se interpreta
1155
             * como que no debe cargarse de la fuente de datos subyacente, siendo
1156
             * el evaluador el que se encarga de proporcionar su valor.
1157
             * Nos limitamos a asignar un evaluador que retorna simpre el valor
1158
             * por defecto para ese attributo.
1159
             */
1160
            this.evaluator = new ConstantValueEvaluator();
1161
        } else {
1162
            this.evaluator = null;
1163
        }
1164
    }
1165

    
1166
    @Override
1167
    public boolean isComputed() {
1168
        return featureAttributeEmulator!=null || evaluator!=null || isCalculated();
1169
    }
1170

    
1171
    @Override
1172
    public FeatureStore getStore() {
1173
        FeatureType ftype = this.getFeatureType();
1174
        if( ftype == null ) {
1175
            return null;
1176
        }
1177
        return ftype.getStore();
1178
    }
1179
    
1180
    @Override
1181
    public FeatureType getFeatureType() {
1182
        if( this.typeRef==null ) {
1183
            return null;
1184
        }
1185
        return (FeatureType) this.typeRef.get();
1186
    }
1187

    
1188
    public FeatureAttributeDescriptor setInterval(Interval interval) {
1189
        this.interval = interval;
1190
        return this;
1191
    }
1192

    
1193
    public void fixAll() {
1194
        switch(this.getType()) {
1195
            case DataTypes.INSTANT:
1196
            case DataTypes.INTERVAL:
1197
            case DataTypes.DATE:
1198
                if( this.getInterval()!=null ) {
1199
                    this.isTime = true;
1200
                }
1201
                break;
1202
        }
1203
    }
1204

    
1205
    @Override
1206
    public String[] getRequiredFieldNames() {
1207
        FeatureAttributeEmulator emulator = this.getFeatureAttributeEmulator();
1208
        if( emulator==null ) {
1209
            return null;
1210
        }
1211
        return emulator.getRequiredFieldNames();
1212
    }
1213

    
1214
}