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

History | View | Annotate | Download (41.4 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 42561 jjdelcerro
 * 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 40559 jjdelcerro
 *
11 42561 jjdelcerro
 * 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 40559 jjdelcerro
 *
16 42561 jjdelcerro
 * 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 40559 jjdelcerro
 *
20 42561 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40559 jjdelcerro
 */
23 40435 jjdelcerro
package org.gvsig.fmap.dal.feature.impl;
24
25 43739 jjdelcerro
import java.lang.ref.WeakReference;
26 40435 jjdelcerro
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 44128 jjdelcerro
import java.util.Objects;
33 42563 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
34 44190 jjdelcerro
import org.apache.commons.lang3.StringUtils;
35 40435 jjdelcerro
import org.cresques.cts.IProjection;
36 44022 jjdelcerro
import org.gvsig.fmap.dal.DataStore;
37 44083 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
38 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39 42563 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
40 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
41 43739 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43 44262 jjdelcerro
import org.gvsig.fmap.dal.feature.ForeingKey;
44 40435 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
45
import org.gvsig.fmap.geom.GeometryException;
46
import org.gvsig.fmap.geom.GeometryLocator;
47 44190 jjdelcerro
import org.gvsig.fmap.geom.GeometryUtils;
48 40435 jjdelcerro
import org.gvsig.fmap.geom.type.GeometryType;
49 44077 jjdelcerro
import org.gvsig.timesupport.Interval;
50 44190 jjdelcerro
import org.gvsig.timesupport.RelativeInterval;
51 44077 jjdelcerro
import org.gvsig.timesupport.TimeSupportLocator;
52 40435 jjdelcerro
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dataTypes.CoercionException;
54
import org.gvsig.tools.dataTypes.DataType;
55
import org.gvsig.tools.dynobject.DynField;
56 41323 jjdelcerro
import org.gvsig.tools.dynobject.DynField_LabelAttribute;
57 42563 jjdelcerro
import org.gvsig.tools.dynobject.DynField_v2;
58 42775 jjdelcerro
import org.gvsig.tools.dynobject.DynMethod;
59 42606 jjdelcerro
import org.gvsig.tools.dynobject.DynObject;
60 40435 jjdelcerro
import org.gvsig.tools.dynobject.DynObjectValueItem;
61
import org.gvsig.tools.dynobject.DynStruct;
62 42563 jjdelcerro
import org.gvsig.tools.dynobject.Tags;
63 40435 jjdelcerro
import org.gvsig.tools.dynobject.exception.DynFieldIsNotAContainerException;
64
import org.gvsig.tools.dynobject.exception.DynFieldValidateException;
65 42775 jjdelcerro
import org.gvsig.tools.dynobject.exception.DynMethodException;
66 42563 jjdelcerro
import org.gvsig.tools.dynobject.impl.DefaultTags;
67 41212 jjdelcerro
import org.gvsig.tools.evaluator.AbstractEvaluator;
68 40435 jjdelcerro
import org.gvsig.tools.evaluator.Evaluator;
69 41212 jjdelcerro
import org.gvsig.tools.evaluator.EvaluatorData;
70
import org.gvsig.tools.evaluator.EvaluatorException;
71 44338 jjdelcerro
import org.gvsig.tools.i18n.I18nManager;
72 44190 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
73 40435 jjdelcerro
import org.gvsig.tools.persistence.Persistent;
74
import org.gvsig.tools.persistence.PersistentState;
75
import org.gvsig.tools.persistence.exception.PersistenceException;
76 44190 jjdelcerro
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
78 40435 jjdelcerro
79 44259 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
80 40435 jjdelcerro
public class DefaultFeatureAttributeDescriptor implements
81 42563 jjdelcerro
        FeatureAttributeDescriptor, Persistent, DynField_v2, DynField_LabelAttribute {
82 40435 jjdelcerro
83 44190 jjdelcerro
    protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureAttributeDescriptor.class);
84
85 40435 jjdelcerro
    protected boolean allowNull;
86
    protected DataType dataType;
87 44128 jjdelcerro
    protected String dataProfile;
88 40435 jjdelcerro
    protected DateFormat dateFormat;
89
    protected Object defaultValue;
90
    protected int index;
91
    protected int maximumOccurrences;
92
    protected int minimumOccurrences;
93
    protected int size;
94
    protected String name;
95
    protected Class objectClass;
96
    protected int precision;
97
    protected Evaluator evaluator;
98
    protected boolean primaryKey;
99
    protected boolean readOnly;
100
    protected IProjection SRS;
101
    protected GeometryType geomType;
102
    protected int geometryType;
103
    protected int geometrySubType;
104
    protected Map additionalInfo;
105
    protected boolean isAutomatic;
106 41335 jjdelcerro
    protected boolean isTime = false;
107 44077 jjdelcerro
    protected Interval interval;
108 41335 jjdelcerro
    protected FeatureAttributeGetter featureAttributeGetter = null;
109
    protected FeatureAttributeEmulator featureAttributeEmulator = null;
110 41638 jjdelcerro
    protected boolean indexed = false;
111
    protected boolean isIndexAscending = true;
112
    protected boolean allowIndexDuplicateds = true;
113 40435 jjdelcerro
114 42563 jjdelcerro
    protected DynObjectValueItem[] availableValues;
115 44346 jjdelcerro
    private Map<Object,String> labelOfValueMap; // No persistente
116 42563 jjdelcerro
    protected String description;
117
    protected Object minValue;
118
    protected Object maxValue;
119
    protected String label;
120 44337 jjdelcerro
    protected String shortLabel;
121 42563 jjdelcerro
    protected int order;
122
    protected boolean hidden;
123
    protected String groupName;
124
    protected Tags tags = new DefaultTags();
125 42775 jjdelcerro
    private DynMethod availableValuesMethod;
126
    private DynMethod calculateMethod;
127 43739 jjdelcerro
    private WeakReference typeRef;
128 44262 jjdelcerro
    protected DefaultForeingKey foreingKey = null;
129 44253 jjdelcerro
130
    private int relationType = RELATION_TYPE_NONE;
131 42563 jjdelcerro
132 44190 jjdelcerro
    public DefaultFeatureAttributeDescriptor() {
133
        // Usada en la persistencia
134
    }
135
136 43739 jjdelcerro
    protected DefaultFeatureAttributeDescriptor(FeatureType type) {
137 44259 jjdelcerro
        this();
138
//        LOGGER.info(String.format("Created FeatureAttributeDescriptor [%08x].", this.hashCode()));
139 44190 jjdelcerro
        setFeatureType(type);
140 40435 jjdelcerro
        this.allowNull = true;
141
        this.dataType = null;
142
        this.dateFormat = null;
143
        this.defaultValue = null;
144
        this.index = -1;
145
        this.maximumOccurrences = 0;
146
        this.minimumOccurrences = 0;
147
        this.size = 0;
148
        this.name = null;
149
        this.objectClass = null;
150
        this.precision = 0;
151
        this.evaluator = null;
152
        this.primaryKey = false;
153
        this.readOnly = false;
154
        this.SRS = null;
155
        this.geometryType = Geometry.TYPES.NULL;
156
        this.geometrySubType = Geometry.SUBTYPES.UNKNOWN;
157
        this.additionalInfo = null;
158
        this.isAutomatic = false;
159 43362 jjdelcerro
        this.hidden = false;
160 44253 jjdelcerro
        this.relationType = RELATION_TYPE_NONE;
161 40435 jjdelcerro
    }
162
163
    protected DefaultFeatureAttributeDescriptor(
164 43739 jjdelcerro
            DefaultFeatureAttributeDescriptor other
165
        ) {
166 44259 jjdelcerro
        this();
167 42775 jjdelcerro
        copyFrom(other);
168 44259 jjdelcerro
//        LOGGER.info(String.format("Created FeatureAttributeDescriptor [%08x] [%s] (copy).", this.hashCode(), this.name));
169 42775 jjdelcerro
    }
170
171
    @Override
172
    public void copyFrom(DynField other1) {
173
        if( !(other1 instanceof DefaultFeatureAttributeDescriptor) ) {
174
            throw new IllegalArgumentException("Can't copy from a non DefaultFeatureAttributeDescriptor");
175
        }
176
        DefaultFeatureAttributeDescriptor other = (DefaultFeatureAttributeDescriptor) other1;
177 43739 jjdelcerro
        this.typeRef = other.typeRef;
178 40435 jjdelcerro
        this.allowNull = other.allowNull;
179
        this.dataType = other.dataType;
180
        this.dateFormat = other.dateFormat;
181
        this.defaultValue = other.defaultValue;
182
        this.index = other.index;
183
        this.maximumOccurrences = other.maximumOccurrences;
184
        this.minimumOccurrences = other.minimumOccurrences;
185
        this.size = other.size;
186
        this.name = other.name;
187
        this.objectClass = other.objectClass;
188
        this.precision = other.precision;
189
        this.evaluator = other.evaluator;
190
        this.primaryKey = other.primaryKey;
191
        this.readOnly = other.readOnly;
192
        this.SRS = other.SRS;
193
        this.geometryType = other.geometryType;
194
        this.geometrySubType = other.geometrySubType;
195
        this.geomType = other.geomType;
196
        if (other.additionalInfo != null) {
197
            Iterator iter = other.additionalInfo.entrySet().iterator();
198
            Map.Entry entry;
199
            this.additionalInfo = new HashMap();
200
            while (iter.hasNext()) {
201
                entry = (Entry) iter.next();
202
                this.additionalInfo.put(entry.getKey(), entry.getValue());
203
            }
204
        } else {
205
            this.additionalInfo = null;
206
        }
207
        this.isAutomatic = other.isAutomatic;
208 41335 jjdelcerro
        this.isTime = other.isTime;
209
        this.featureAttributeEmulator = other.featureAttributeEmulator;
210 41638 jjdelcerro
        this.indexed = other.indexed;
211
        this.isIndexAscending = other.isIndexAscending;
212
        this.allowIndexDuplicateds = other.allowIndexDuplicateds;
213 43362 jjdelcerro
        this.hidden = other.hidden;
214 44188 jjdelcerro
        this.dataProfile = other.dataProfile;
215 44202 jjdelcerro
216
        this.availableValues = other.availableValues;
217
        this.description = other.description;
218
        this.minValue = other.minValue;
219
        this.maxValue = other.maxValue;
220
        this.label = other.label;
221
        this.order = other.order;
222
        this.groupName = other.groupName;
223
        if( other.tags==null ) {
224
            this.tags = null;
225
        } else {
226
            try {
227
                this.tags = (Tags) other.tags.clone();
228
            } catch (Exception ex) {
229
            }
230
        }
231 44262 jjdelcerro
        this.foreingKey = null;
232
        if( other.foreingKey!=null ) {
233
            try {
234
                this.foreingKey = (DefaultForeingKey) other.foreingKey.clone();
235
            } catch (CloneNotSupportedException ex) {
236
            }
237
        }
238
        if( this.foreingKey!=null ) {
239
            this.foreingKey.setDescriptor(this);
240
        }
241
242 44202 jjdelcerro
        // TODO: ? Habria que clonarlos ?
243
        this.availableValuesMethod = other.availableValuesMethod;
244
        this.calculateMethod = other.calculateMethod;
245 44253 jjdelcerro
        this.relationType = other.relationType;
246 40435 jjdelcerro
    }
247 42775 jjdelcerro
248 44190 jjdelcerro
    public void setFeatureType(FeatureType type) {
249
        // Usada en la persistencia
250
        if( type == null ) {
251
            this.typeRef = null;
252
        } else {
253
            this.typeRef = new WeakReference(type);
254 44259 jjdelcerro
//            LOGGER.info(String.format("FeatureAttributeDescriptor[%08x] set FeatureType [%08x], ref [%08x].", this.hashCode(), type.hashCode(), typeRef.hashCode()));
255 44190 jjdelcerro
        }
256
    }
257
258 42561 jjdelcerro
    @Override
259 40435 jjdelcerro
    public String getDataTypeName() {
260 42561 jjdelcerro
        if (this.getDataType() == null) {
261 40435 jjdelcerro
            return "(unknow)";
262
        }
263 42561 jjdelcerro
        return this.getDataType().getName();
264 40435 jjdelcerro
    }
265
266 42561 jjdelcerro
    @Override
267 44318 jjdelcerro
    public DefaultFeatureAttributeDescriptor getCopy() {
268 40435 jjdelcerro
        return new DefaultFeatureAttributeDescriptor(this);
269
    }
270
271 42561 jjdelcerro
    @Override
272 42775 jjdelcerro
    public Object clone() throws CloneNotSupportedException {
273
        return new DefaultFeatureAttributeDescriptor(this);
274
    }
275
276
    @Override
277 40435 jjdelcerro
    public boolean allowNull() {
278
        return allowNull;
279
    }
280
281 42561 jjdelcerro
    @Override
282 40435 jjdelcerro
    public DataType getDataType() {
283 42561 jjdelcerro
        if (featureAttributeGetter != null) {
284
            return featureAttributeGetter.getDataType();
285
        }
286 40435 jjdelcerro
        return this.dataType;
287
    }
288
289 43954 jjdelcerro
    public FeatureAttributeDescriptor setDataType(int type) {
290
        this.dataType = ToolsLocator.getDataTypesManager().get(type);
291
        return this;
292
    }
293
294 42561 jjdelcerro
    @Override
295 40435 jjdelcerro
    public DateFormat getDateFormat() {
296
        return this.dateFormat;
297
    }
298
299 42561 jjdelcerro
    @Override
300 40435 jjdelcerro
    public Object getDefaultValue() {
301
        return this.defaultValue;
302
    }
303
304 42561 jjdelcerro
    @Override
305 40435 jjdelcerro
    public Evaluator getEvaluator() {
306
        return this.evaluator;
307
    }
308
309 42561 jjdelcerro
    @Override
310 40435 jjdelcerro
    public int getGeometryType() {
311 44083 jjdelcerro
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
312
            return Geometry.TYPES.UNKNOWN;
313
        }
314 40435 jjdelcerro
        return this.geometryType;
315
    }
316
317 42561 jjdelcerro
    @Override
318 40435 jjdelcerro
    public int getGeometrySubType() {
319 44083 jjdelcerro
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
320
            return Geometry.SUBTYPES.UNKNOWN;
321
        }
322 40435 jjdelcerro
        return this.geometrySubType;
323
    }
324
325 42561 jjdelcerro
    @Override
326 40435 jjdelcerro
    public GeometryType getGeomType() {
327 44083 jjdelcerro
        if( this.dataType.getType()!=DataTypes.GEOMETRY ) {
328
            return null;
329
        }
330 40435 jjdelcerro
        if (this.geomType == null) {
331
            try {
332 42561 jjdelcerro
                this.geomType
333
                        = GeometryLocator.getGeometryManager().getGeometryType(
334
                                this.geometryType, this.geometrySubType);
335 40435 jjdelcerro
            } catch (GeometryException e) {
336
                throw new RuntimeException(
337 42561 jjdelcerro
                        "Error getting geometry type with type = "
338 40435 jjdelcerro
                        + this.geometryType + ", subtype = "
339
                        + this.geometrySubType, e);
340
            }
341
        }
342
        return this.geomType;
343
    }
344
345 42561 jjdelcerro
    @Override
346 40435 jjdelcerro
    public int getIndex() {
347
        return this.index;
348
    }
349
350
    protected FeatureAttributeDescriptor setIndex(int index) {
351
        this.index = index;
352
        return this;
353
    }
354
355 42561 jjdelcerro
    @Override
356 40435 jjdelcerro
    public int getMaximumOccurrences() {
357
        return this.maximumOccurrences;
358
    }
359
360 42561 jjdelcerro
    @Override
361 40435 jjdelcerro
    public int getMinimumOccurrences() {
362
        return this.minimumOccurrences;
363
    }
364
365 42561 jjdelcerro
    @Override
366 40435 jjdelcerro
    public String getName() {
367
        return this.name;
368
    }
369 43954 jjdelcerro
370
    public FeatureAttributeDescriptor setName(String name) {
371 44259 jjdelcerro
//        LOGGER.info(String.format("FeatureAttributeDescriptor[%08x] set name [%s].", this.hashCode(), name));
372 43954 jjdelcerro
        this.name = name;
373
        return this;
374
    }
375
376 42561 jjdelcerro
    @Override
377 40435 jjdelcerro
    public Class getObjectClass() {
378 42561 jjdelcerro
        if (getDataType().getType() == DataTypes.OBJECT) {
379 40435 jjdelcerro
            return objectClass;
380
        }
381 42561 jjdelcerro
        return getDataType().getDefaultClass();
382 40435 jjdelcerro
    }
383
384 42561 jjdelcerro
    @Override
385 40435 jjdelcerro
    public int getPrecision() {
386
        return this.precision;
387
    }
388
389 42561 jjdelcerro
    @Override
390 40435 jjdelcerro
    public IProjection getSRS() {
391
        return this.SRS;
392
    }
393
394 44077 jjdelcerro
    @Override
395
    public Interval getInterval() {
396
        return this.interval;
397
    }
398
399 44022 jjdelcerro
    public IProjection getSRS(WeakReference storeRef) {
400
        if( this.SRS==null ) {
401
            FeatureStore store = (FeatureStore) storeRef.get();
402
            this.SRS = (IProjection) store.getDynValue(DataStore.METADATA_CRS);
403
        }
404
        return this.SRS;
405
    }
406
407
408 42561 jjdelcerro
    @Override
409 40435 jjdelcerro
    public int getSize() {
410
        return this.size;
411
    }
412
413 42561 jjdelcerro
    @Override
414 40435 jjdelcerro
    public boolean isPrimaryKey() {
415
        return this.primaryKey;
416
    }
417
418 42561 jjdelcerro
    @Override
419 40435 jjdelcerro
    public boolean isReadOnly() {
420 42561 jjdelcerro
        if (this.readOnly) {
421 41335 jjdelcerro
            return true;
422
        }
423 42561 jjdelcerro
        if (this.getEvaluator() != null) {
424 41335 jjdelcerro
            return true;
425
        }
426 42561 jjdelcerro
        if (this.featureAttributeEmulator != null) {
427 41335 jjdelcerro
            return !this.featureAttributeEmulator.allowSetting();
428
        }
429
        return false;
430 40435 jjdelcerro
    }
431
432 42561 jjdelcerro
    @Override
433 40435 jjdelcerro
    public Object getAdditionalInfo(String infoName) {
434
        if (this.additionalInfo == null) {
435
            return null;
436
        }
437
        return this.additionalInfo.get(infoName);
438
    }
439
440 42561 jjdelcerro
    @Override
441 40435 jjdelcerro
    public boolean isAutomatic() {
442
        return this.isAutomatic;
443
    }
444
445 42561 jjdelcerro
    @Override
446 40435 jjdelcerro
    public boolean equals(Object obj) {
447
        if (this == obj) {
448
            return true;
449
        }
450
        if (!(obj instanceof DefaultFeatureAttributeDescriptor)) {
451
            return false;
452
        }
453 42561 jjdelcerro
        DefaultFeatureAttributeDescriptor other
454
                = (DefaultFeatureAttributeDescriptor) obj;
455 40435 jjdelcerro
456
        if (this.allowNull != other.allowNull) {
457
            return false;
458
        }
459
460
        if (this.index != other.index) {
461
            return false;
462
        }
463
464 44128 jjdelcerro
        if (!Objects.equals(this.name, other.name)) {
465 40435 jjdelcerro
            return false;
466
        }
467
468 42561 jjdelcerro
        if (this.getDataType() != other.getDataType()) {
469 40435 jjdelcerro
            return false;
470
        }
471
472
        if (this.size != other.size) {
473
            return false;
474
        }
475
476 44128 jjdelcerro
        if (!Objects.equals(this.defaultValue, other.defaultValue)) {
477 40435 jjdelcerro
            return false;
478
        }
479
480
        if (this.primaryKey != other.primaryKey) {
481
            return false;
482
        }
483
484
        if (this.isAutomatic != other.isAutomatic) {
485
            return false;
486
        }
487
488
        if (this.readOnly != other.readOnly) {
489
            return false;
490
        }
491
492
        if (this.precision != other.precision) {
493
            return false;
494
        }
495
496
        if (this.maximumOccurrences != other.maximumOccurrences) {
497
            return false;
498
        }
499
500
        if (this.minimumOccurrences != other.minimumOccurrences) {
501
            return false;
502
        }
503
504
        if (this.geometryType != other.geometryType) {
505
            return false;
506
        }
507
508
        if (this.geometrySubType != other.geometrySubType) {
509
            return false;
510
        }
511
512 44128 jjdelcerro
        if (!Objects.equals(this.evaluator, other.evaluator)) {
513 40435 jjdelcerro
            return false;
514
        }
515
516 44128 jjdelcerro
        if (!Objects.equals(this.featureAttributeEmulator, other.featureAttributeEmulator)) {
517 40435 jjdelcerro
            return false;
518
        }
519
520 44128 jjdelcerro
        if (!Objects.equals(this.SRS, other.SRS)) {
521 40435 jjdelcerro
            return false;
522
        }
523
524 44128 jjdelcerro
        if (!Objects.equals(this.dateFormat, other.dateFormat)) {
525 40435 jjdelcerro
            return false;
526
        }
527
528 44128 jjdelcerro
        if (!Objects.equals(this.objectClass, other.objectClass)) {
529
            return false;
530
        }
531
532
        if (!Objects.equals(this.dataProfile, other.dataProfile)) {
533
            return false;
534
        }
535
536 40435 jjdelcerro
        return true;
537
    }
538
539 42561 jjdelcerro
    @Override
540 40435 jjdelcerro
    public void loadFromState(PersistentState state)
541 42561 jjdelcerro
            throws PersistenceException {
542 40435 jjdelcerro
        allowNull = state.getBoolean("allowNull");
543 44077 jjdelcerro
        dataType = ToolsLocator.getDataTypesManager().get(state.getInt("dataType"));
544 44190 jjdelcerro
        dataProfile = state.getString("dataProfile");
545
546
//        FIXME: dateFormat;
547
        try {
548
            defaultValue = dataType.coerce(state.get("defaultValue"));
549
        } catch (CoercionException ex) {
550
        }
551 40435 jjdelcerro
552
        index = state.getInt("index");
553
        maximumOccurrences = state.getInt("maximumOccurrences");
554
        minimumOccurrences = state.getInt("minimumOccurrences");
555
        size = state.getInt("size");
556
        name = state.getString("name");
557
        try {
558 44190 jjdelcerro
            String objectClassName = state.getString("objectClass");
559
            if( !StringUtils.isBlank(objectClassName) ) {
560
                objectClass = Class.forName(objectClassName);
561
            }
562
        } catch (Throwable e) {
563
            LOGGER.warn("Can't restore the objectClass of the FeatureAttributreDescriptor", e);
564 40435 jjdelcerro
        }
565
        precision = state.getInt("precision");
566
        evaluator = (Evaluator) state.get("evaluator");
567
        primaryKey = state.getBoolean("primaryKey");
568
        readOnly = state.getBoolean("readOnly");
569 44190 jjdelcerro
        SRS = (IProjection) state.get("SRS");
570 40435 jjdelcerro
        geometryType = state.getInt("geometryType");
571
        geometrySubType = state.getInt("geometrySubType");
572 44190 jjdelcerro
        if( geometryType!=Geometry.TYPES.UNKNOWN &&
573
                geometrySubType!=Geometry.SUBTYPES.UNKNOWN ) {
574
            geomType = GeometryUtils.getGeometryType(
575
                    geometryType,
576
                    geometrySubType
577
            );
578
        }
579
//        additionalInfo = (Map) state.get("aditionalInfo");
580 40435 jjdelcerro
        isAutomatic = state.getBoolean("isAutomatic");
581 44077 jjdelcerro
        isTime = state.getBoolean("isTime");
582
        if( state.hasValue("intervalStart") ) {
583 44190 jjdelcerro
            long intervalStart = state.getLong("interval_start");
584
            long intervalEnd = state.getLong("interval_end");
585 44077 jjdelcerro
            interval = TimeSupportLocator.getManager().createRelativeInterval(intervalStart, intervalEnd);
586
        } else {
587
            interval = null;
588
        }
589 44190 jjdelcerro
        featureAttributeEmulator = (FeatureAttributeEmulator) state.get("featureAttributeEmulator");
590
        indexed = state.getBoolean("indexed");
591
        isIndexAscending = state.getBoolean("isIndexAscending");
592
        allowIndexDuplicateds = state.getBoolean("allowIndexDuplicateds");
593
594 44202 jjdelcerro
        Map<String,Object> values = state.getMap("availableValues");
595
        if( values == null || values.isEmpty()  ) {
596
            this.availableValues = null;
597
        } else {
598
            this.availableValues = new DynObjectValueItem[values.size()];
599
            int n = 0;
600
            for (Entry<String, Object> entry : values.entrySet()) {
601
                this.availableValues[n++] = new DynObjectValueItem(entry.getValue(), entry.getKey());
602
            }
603
        }
604
605 44190 jjdelcerro
        description = state.getString("description");
606
        minValue = state.get("minValue");
607
        maxValue = state.get("maxValue");
608
        label = state.getString("label");
609
        order = state.getInt("order");
610
        hidden = state.getBoolean("hidden");
611
        groupName = state.getString("groupName");
612 44253 jjdelcerro
        relationType = state.getInt("relationType");
613 44262 jjdelcerro
614
        foreingKey = (DefaultForeingKey) state.get("foreingKey");
615
        if( foreingKey!=null ) {
616
            this.foreingKey.setDescriptor(this);
617
        }
618
        tags = (Tags) state.get("tags");
619
        if( tags == null ) {
620
            this.tags = new DefaultTags();
621
        }
622 40435 jjdelcerro
    }
623
624 42561 jjdelcerro
    @Override
625 40435 jjdelcerro
    public void saveToState(PersistentState state) throws PersistenceException {
626
        state.set("allowNull", allowNull);
627 44190 jjdelcerro
        state.set("dataType", dataType.getType());
628
        state.set("dataProfile", dataProfile);
629
630
//        FIXME: dateFormat;
631 40435 jjdelcerro
632 44190 jjdelcerro
        state.set("defaultValue", Objects.toString(defaultValue));
633 40435 jjdelcerro
634 44190 jjdelcerro
        state.set("index", index);
635
        state.set("maximumOccurrences", maximumOccurrences);
636
        state.set("minimumOccurrences", minimumOccurrences);
637
        state.set("size", size);
638
        state.set("name", name);
639
        state.set("objectClass", objectClass==null? null:objectClass.getName());
640
        state.set("precision", precision);
641
        state.set("evaluator", evaluator);
642
643
        state.set("primaryKey", primaryKey);
644
        state.set("readOnly", readOnly);
645
        state.set("SRS", SRS);
646
        GeometryType theGeomType = this.getGeomType();
647
        if( theGeomType==null ) {
648
            state.set("geometryType", Geometry.TYPES.UNKNOWN);
649
            state.set("geometrySubType", Geometry.SUBTYPES.UNKNOWN);
650
        } else {
651
            state.set("geometryType", theGeomType.getType());
652
            state.set("geometrySubType", theGeomType.getSubType());
653 40435 jjdelcerro
        }
654 44190 jjdelcerro
655
//      FIXME: additionalInfo
656
657
        state.set("isAutomatic", isAutomatic);
658
        state.set("isTime", isTime);
659
        if( this.interval==null ) {
660
            state.setNull("interval_start");
661
            state.setNull("interval_end");
662
        } else {
663
            state.set("interval_start", ((RelativeInterval)interval).getStart().toMillis());
664
            state.set("interval_end", ((RelativeInterval)interval).getEnd().toMillis());
665 40435 jjdelcerro
        }
666 44190 jjdelcerro
        state.set("SRS", SRS);
667
668
//      FIXME: featureAttributeGetter
669
670
        if( featureAttributeEmulator instanceof Persistent ) {
671
            state.set("featureAttributeEmulator", featureAttributeEmulator);
672
        } else {
673
            state.setNull("featureAttributeEmulator");
674
        }
675
676
        state.set("indexed", indexed);
677
        state.set("isIndexAscending", isIndexAscending);
678
        state.set("allowIndexDuplicateds", allowIndexDuplicateds);
679
680 44202 jjdelcerro
        if( this.availableValues==null ) {
681
            state.setNull("availableValues");
682
        } else {
683
            Map<String,Object> values = new HashMap<>();
684
            for (DynObjectValueItem value : availableValues) {
685
                values.put(value.getLabel(),value.getValue());
686
            }
687
            state.set("availableValues", values);
688
        }
689 44190 jjdelcerro
        state.set("description", description);
690
        state.set("minValue", minValue);
691
        state.set("maxValue", maxValue);
692
        state.set("label", label);
693
        state.set("order", order);
694
        state.set("hidden", hidden);
695
        state.set("groupName", groupName);
696 44253 jjdelcerro
        state.set("relationType",relationType);
697 44262 jjdelcerro
698
        state.set("foreingKey" ,this.foreingKey);
699
        state.set("tags" ,this.tags);
700 44190 jjdelcerro
701 40435 jjdelcerro
    }
702 44190 jjdelcerro
703
    private static final String FEATATTRDESC_PERSISTENCE_DEFINITION_NAME = "FeatureAttributeDescriptor";
704 40435 jjdelcerro
705 44190 jjdelcerro
    public static void registerPersistenceDefinition() {
706
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
707
708
709
        if (manager.getDefinition(FEATATTRDESC_PERSISTENCE_DEFINITION_NAME)
710
                == null) {
711
            DynStruct definition = manager.addDefinition(DefaultFeatureAttributeDescriptor.class,
712
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME,
713
                    FEATATTRDESC_PERSISTENCE_DEFINITION_NAME
714
                        + " persistent definition",
715
                    null,
716
                    null
717
            );
718
            definition.addDynFieldBoolean("allowNull");
719
            definition.addDynFieldInt("dataType");
720
            definition.addDynFieldString("dataProfile");
721
//            definition.addDynFieldString("dateFormat");
722
            definition.addDynFieldString("defaultValue");
723
            definition.addDynFieldInt("index");
724
            definition.addDynFieldInt("maximumOccurrences");
725
            definition.addDynFieldInt("minimumOccurrences");
726
            definition.addDynFieldInt("size");
727
            definition.addDynFieldString("name");
728
            definition.addDynFieldString("objectClass");
729
            definition.addDynFieldInt("precision");
730
            definition.addDynFieldObject("evaluator")
731
                    .setClassOfValue(Evaluator.class);
732
            definition.addDynFieldBoolean("primaryKey");
733
            definition.addDynFieldBoolean("readOnly");
734
            definition.addDynFieldObject("SRS")
735
                    .setClassOfValue(IProjection.class);
736
            definition.addDynFieldInt("geometryType");
737
            definition.addDynFieldInt("geometrySubType");
738
//            definition.addDynFieldMap("additionalInfo");
739
            definition.addDynFieldBoolean("isAutomatic");
740
            definition.addDynFieldBoolean("isTime");
741
            definition.addDynFieldLong("interval_start");
742
            definition.addDynFieldLong("interval_end");
743
            definition.addDynFieldObject("featureAttributeEmulator")
744
                    .setClassOfValue(FeatureAttributeEmulator.class);
745
            definition.addDynFieldBoolean("indexed");
746
            definition.addDynFieldBoolean("isIndexAscending");
747
            definition.addDynFieldBoolean("allowIndexDuplicateds");
748 44202 jjdelcerro
            definition.addDynFieldMap("availableValues");
749
            definition.addDynFieldString("description");
750
            definition.addDynFieldObject("minValue");
751
            definition.addDynFieldObject("maxValue");
752
            definition.addDynFieldString("label");
753 44190 jjdelcerro
            definition.addDynFieldInt("order");
754
            definition.addDynFieldBoolean("hidden");
755 44202 jjdelcerro
            definition.addDynFieldString("groupName");
756 44253 jjdelcerro
            definition.addDynFieldInt("relationType");
757 44262 jjdelcerro
758
            definition.addDynFieldObject("foreingKey")
759
                    .setClassOfValue(DefaultForeingKey.class);
760
761
            definition.addDynFieldObject("tags")
762
                    .setClassOfValue(Tags.class);
763
764 44190 jjdelcerro
        }
765
    }
766
767
768 42563 jjdelcerro
    /*
769 40435 jjdelcerro
     * Start of DynField interface Implementation
770 42561 jjdelcerro
     *
771 40435 jjdelcerro
     */
772 42634 fdiaz
773 43739 jjdelcerro
    @Override
774 42563 jjdelcerro
    public Tags getTags() {
775
        return tags;
776
    }
777 42634 fdiaz
778 42561 jjdelcerro
    @Override
779 40435 jjdelcerro
    public DynObjectValueItem[] getAvailableValues() {
780 44259 jjdelcerro
        if( this.availableValues == null ) {
781 44338 jjdelcerro
            if( this.isForeingKey() && this.foreingKey.isClosedList() ) {
782
                return this.foreingKey.getAvailableValues(null);
783 44259 jjdelcerro
            }
784
        }
785 42563 jjdelcerro
        return this.availableValues;
786 40435 jjdelcerro
    }
787
788 42561 jjdelcerro
    @Override
789 44346 jjdelcerro
    public String getLabelOfValue(Object value) {
790
        if( this.labelOfValueMap != null ) {
791
            String theLabel = this.labelOfValueMap.get(value);
792
            if( theLabel == null ) {
793
                theLabel = Objects.toString(value, "");
794
            }
795
            return theLabel;
796
        }
797
        DynObjectValueItem[] values = this.getAvailableValues();
798
        if( values == null ) {
799
            return Objects.toString(value, "");
800
        }
801
        Map<Object, String> map = new HashMap<>();
802
        for (DynObjectValueItem theValue : values) {
803
            map.put(theValue.getValue(), theValue.getLabel());
804
        }
805
        this.labelOfValueMap = map;
806
        String theLabel = this.labelOfValueMap.get(value);
807
        if( theLabel == null ) {
808
            theLabel = Objects.toString(value, "");
809
        }
810
        return theLabel;
811
    }
812
813
    @Override
814 40435 jjdelcerro
    public String getDescription() {
815 42563 jjdelcerro
        if( this.description == null ) {
816
            return getName();
817
        }
818
        return this.description;
819 40435 jjdelcerro
    }
820
821 42561 jjdelcerro
    @Override
822 40435 jjdelcerro
    public Object getMaxValue() {
823 42563 jjdelcerro
        return this.maxValue;
824 40435 jjdelcerro
    }
825
826 42561 jjdelcerro
    @Override
827 40435 jjdelcerro
    public Object getMinValue() {
828 42563 jjdelcerro
        return this.minValue;
829 40435 jjdelcerro
    }
830
831 42561 jjdelcerro
    @Override
832 40435 jjdelcerro
    public int getTheTypeOfAvailableValues() {
833 42563 jjdelcerro
        return 1;
834 40435 jjdelcerro
    }
835
836 42561 jjdelcerro
    @Override
837 40435 jjdelcerro
    public int getType() {
838 42561 jjdelcerro
        if (featureAttributeGetter != null) {
839 40435 jjdelcerro
            return featureAttributeGetter.getDataType().getType();
840
        }
841
        return getDataType().getType();
842
    }
843
844 42561 jjdelcerro
    @Override
845 40435 jjdelcerro
    public boolean isMandatory() {
846
        return !allowNull() || isPrimaryKey();
847
    }
848
849 42561 jjdelcerro
    @Override
850 40435 jjdelcerro
    public boolean isPersistent() {
851
        return false;
852
    }
853
854 42561 jjdelcerro
    @Override
855 40435 jjdelcerro
    public DynField setAvailableValues(DynObjectValueItem[] values) {
856 42563 jjdelcerro
        if ( ArrayUtils.isEmpty(values) ) {
857
            this.availableValues = null;
858
        } else {
859
            this.availableValues = values;
860
        }
861
        return this;
862 40435 jjdelcerro
    }
863
864 42561 jjdelcerro
    @Override
865 40435 jjdelcerro
    public DynField setDescription(String description) {
866 42563 jjdelcerro
        this.description = description;
867
        return this;
868 40435 jjdelcerro
    }
869
870 42561 jjdelcerro
    @Override
871 40435 jjdelcerro
    public DynField setMandatory(boolean mandatory) {
872
        throw new UnsupportedOperationException();
873
    }
874
875 42561 jjdelcerro
    @Override
876 40435 jjdelcerro
    public DynField setMaxValue(Object maxValue) {
877 42563 jjdelcerro
        try {
878
            this.maxValue = this.coerce(maxValue);
879
        } catch (CoercionException e) {
880
            throw new IllegalArgumentException(e);
881
        }
882
        return this;
883 40435 jjdelcerro
    }
884
885 42561 jjdelcerro
    @Override
886 40435 jjdelcerro
    public DynField setMinValue(Object minValue) {
887 42563 jjdelcerro
        try {
888
            this.maxValue = this.coerce(minValue);
889
        } catch (CoercionException e) {
890
            throw new IllegalArgumentException(e);
891
        }
892
        return this;
893 40435 jjdelcerro
    }
894
895 42561 jjdelcerro
    @Override
896 40435 jjdelcerro
    public DynField setPersistent(boolean persistent) {
897
        throw new UnsupportedOperationException();
898
    }
899
900 42561 jjdelcerro
    @Override
901 40435 jjdelcerro
    public DynField setTheTypeOfAvailableValues(int type) {
902
        throw new UnsupportedOperationException();
903
    }
904
905 42561 jjdelcerro
    @Override
906 40435 jjdelcerro
    public DynField setType(int type) {
907
        throw new UnsupportedOperationException();
908
    }
909
910 42561 jjdelcerro
    @Override
911 40435 jjdelcerro
    public DynField setDefaultDynValue(Object defaultValue) {
912
        throw new UnsupportedOperationException();
913
    }
914
915 42561 jjdelcerro
    @Override
916 40435 jjdelcerro
    public Class getClassOfValue() {
917
        return null;
918
    }
919
920 42561 jjdelcerro
    @Override
921 40435 jjdelcerro
    public DynField getElementsType() {
922
        return null;
923
    }
924
925 42561 jjdelcerro
    @Override
926 40435 jjdelcerro
    public DynField setClassOfValue(Class theClass)
927 42561 jjdelcerro
            throws DynFieldIsNotAContainerException {
928 40435 jjdelcerro
        throw new UnsupportedOperationException();
929
    }
930
931 42561 jjdelcerro
    @Override
932 40435 jjdelcerro
    public DynField setElementsType(DynStruct type)
933 42561 jjdelcerro
            throws DynFieldIsNotAContainerException {
934 40435 jjdelcerro
        throw new UnsupportedOperationException();
935
    }
936
937 42561 jjdelcerro
    @Override
938 40435 jjdelcerro
    public DynField setElementsType(int type)
939 42561 jjdelcerro
            throws DynFieldIsNotAContainerException {
940 40435 jjdelcerro
        throw new UnsupportedOperationException();
941
    }
942
943 44128 jjdelcerro
    public FeatureAttributeDescriptor setDataProfileName(String dataProfile) {
944
        this.dataProfile = dataProfile;
945
        return this;
946
    }
947
948 42561 jjdelcerro
    @Override
949 44128 jjdelcerro
    public String getDataProfileName() {
950
        return dataProfile;
951 40435 jjdelcerro
    }
952
953 42561 jjdelcerro
    @Override
954 40435 jjdelcerro
    public void validate(Object value) throws DynFieldValidateException {
955 42561 jjdelcerro
956 40435 jjdelcerro
        if (value == null && !this.allowNull()) {
957
            throw new DynFieldValidateException(value, this, null);
958
        }
959 42561 jjdelcerro
960 40435 jjdelcerro
        try {
961
            this.dataType.coerce(value);
962
        } catch (CoercionException e) {
963
            throw new DynFieldValidateException(value, this, e);
964
        }
965 42561 jjdelcerro
966 40435 jjdelcerro
        /*
967
         * Other checks will be needed
968
         */
969
    }
970
971 42561 jjdelcerro
    @Override
972 40435 jjdelcerro
    public String getSubtype() {
973 42561 jjdelcerro
        if (featureAttributeGetter != null) {
974 40435 jjdelcerro
            return featureAttributeGetter.getDataType().getSubtype();
975 42561 jjdelcerro
        }
976 40435 jjdelcerro
        return this.dataType.getSubtype();
977
    }
978
979 42561 jjdelcerro
    @Override
980 42563 jjdelcerro
    public Object coerce(Object value) throws CoercionException {
981
        if ( value == null ) {
982
            return value; // O debe devolver this.defaultValue
983
        }
984
        try {
985
            return this.getDataType().coerce(value);
986
        } catch(Exception ex){
987
            throw new RuntimeException(ex);
988
        }
989 40435 jjdelcerro
    }
990
991 42561 jjdelcerro
    @Override
992 40435 jjdelcerro
    public DynField setAvailableValues(List values) {
993 42563 jjdelcerro
        if (  values == null || values.isEmpty() ) {
994
            this.availableValues = null;
995
        } else {
996
            this.availableValues = (DynObjectValueItem[]) values.toArray(
997
                new DynObjectValueItem[values.size()]
998
            );
999
        }
1000
        return this;
1001 40435 jjdelcerro
    }
1002
1003 42561 jjdelcerro
    @Override
1004 40435 jjdelcerro
    public String getGroup() {
1005 42563 jjdelcerro
        return this.groupName;
1006 40435 jjdelcerro
    }
1007
1008 42561 jjdelcerro
    @Override
1009 40435 jjdelcerro
    public int getOder() {
1010 42563 jjdelcerro
        return this.order;
1011 40435 jjdelcerro
    }
1012
1013 42561 jjdelcerro
    @Override
1014 41323 jjdelcerro
    public String getLabel() {
1015 42563 jjdelcerro
        if( this.label == null ) {
1016
            return this.getName();
1017
        }
1018
        return this.label;
1019 41323 jjdelcerro
    }
1020 44338 jjdelcerro
1021
    @Override
1022
    public String getLocalizedLabel() {
1023
        if( StringUtils.isBlank(this.label) ) {
1024
            return this.getName();
1025
        }
1026
        I18nManager i18n = ToolsLocator.getI18nManager();
1027
        return i18n.getTranslation(this.label);
1028
    }
1029 41323 jjdelcerro
1030 42561 jjdelcerro
    @Override
1031 41323 jjdelcerro
    public DynField setLabel(String label) {
1032 42563 jjdelcerro
        this.label = label;
1033
        return this;
1034 41323 jjdelcerro
    }
1035
1036 42561 jjdelcerro
    @Override
1037 44337 jjdelcerro
    public DynField setShortLabel(String shortLabel) {
1038
        this.shortLabel = shortLabel;
1039
        return this;
1040
    }
1041
1042
    @Override
1043
    public String getShortLabel() {
1044
        return StringUtils.isBlank(shortLabel) ? getLabel() : shortLabel;
1045
    }
1046
1047
    @Override
1048 44338 jjdelcerro
    public String getLocalizedShortLabel() {
1049
        if( StringUtils.isBlank(shortLabel) ) {
1050
            return this.getLocalizedLabel();
1051
        }
1052
        I18nManager i18n = ToolsLocator.getI18nManager();
1053
        return i18n.getTranslation(shortLabel);
1054
    }
1055
1056
    @Override
1057 40435 jjdelcerro
    public DynField setGroup(String groupName) {
1058 42563 jjdelcerro
        this.groupName = groupName;
1059
        return this;
1060 40435 jjdelcerro
    }
1061
1062 42561 jjdelcerro
    @Override
1063 40435 jjdelcerro
    public DynField setOrder(int order) {
1064 42563 jjdelcerro
        this.order = order;
1065
        return this;
1066 40435 jjdelcerro
    }
1067
1068 42561 jjdelcerro
    @Override
1069 40435 jjdelcerro
    public DynField setHidden(boolean hidden) {
1070 42563 jjdelcerro
        this.hidden = hidden;
1071
        return this;
1072 40435 jjdelcerro
    }
1073
1074 42561 jjdelcerro
    @Override
1075 40435 jjdelcerro
    public boolean isHidden() {
1076 42563 jjdelcerro
        return this.hidden;
1077 40435 jjdelcerro
    }
1078
1079 42561 jjdelcerro
    @Override
1080 44325 jjdelcerro
    public DynField setReadOnly(boolean readOnly) {
1081
        this.readOnly = readOnly;
1082
        return this;
1083 40435 jjdelcerro
    }
1084
1085 42561 jjdelcerro
    @Override
1086 40435 jjdelcerro
    public boolean isContainer() {
1087
        return false;
1088
    }
1089
1090 42561 jjdelcerro
    @Override
1091 40435 jjdelcerro
    public Class getClassOfItems() {
1092
        return null;
1093
    }
1094
1095 42561 jjdelcerro
    @Override
1096 40435 jjdelcerro
    public DynField setDefaultFieldValue(Object defaultValue) {
1097
        throw new UnsupportedOperationException();
1098
    }
1099
1100 42561 jjdelcerro
    @Override
1101 40435 jjdelcerro
    public DynField setClassOfItems(Class theClass) {
1102
        throw new UnsupportedOperationException();
1103
    }
1104
1105 42561 jjdelcerro
    @Override
1106 40435 jjdelcerro
    public DynField setType(DataType type) {
1107
        throw new UnsupportedOperationException();
1108
    }
1109
1110 42561 jjdelcerro
    @Override
1111 44128 jjdelcerro
    public DynField setSubtype(String subtype) {
1112
        throw new UnsupportedOperationException();
1113
    }
1114
1115
    @Override
1116 42561 jjdelcerro
    public boolean isTime() {
1117
        return isTime;
1118
    }
1119 40435 jjdelcerro
1120 42561 jjdelcerro
    @Override
1121 40435 jjdelcerro
    public FeatureAttributeGetter getFeatureAttributeGetter() {
1122 42561 jjdelcerro
        return featureAttributeGetter;
1123 40435 jjdelcerro
    }
1124
1125 42561 jjdelcerro
    @Override
1126 40435 jjdelcerro
    public void setFeatureAttributeGetter(
1127 42561 jjdelcerro
            FeatureAttributeGetter featureAttributeTransform) {
1128
        this.featureAttributeGetter = featureAttributeTransform;
1129
    }
1130 41335 jjdelcerro
1131 42561 jjdelcerro
    @Override
1132 41335 jjdelcerro
    public FeatureAttributeEmulator getFeatureAttributeEmulator() {
1133
        return this.featureAttributeEmulator;
1134
    }
1135
1136 43954 jjdelcerro
    public FeatureAttributeDescriptor setFeatureAttributeEmulator(FeatureAttributeEmulator featureAttributeEmulator) {
1137
        this.featureAttributeEmulator = featureAttributeEmulator;
1138
        return this;
1139
    }
1140
1141 42561 jjdelcerro
    @Override
1142 41638 jjdelcerro
    public boolean isIndexed() {
1143
        return this.indexed;
1144
    }
1145 44262 jjdelcerro
1146
    public boolean isForeingKey() {
1147
        return this.foreingKey!=null && this.foreingKey.isForeingKey();
1148
    }
1149
1150
    public ForeingKey getForeingKey() {
1151
        return this.foreingKey;
1152
    }
1153 41638 jjdelcerro
1154 42561 jjdelcerro
    @Override
1155 41638 jjdelcerro
    public boolean allowIndexDuplicateds() {
1156
        return this.allowIndexDuplicateds;
1157
    }
1158
1159 42561 jjdelcerro
    @Override
1160 41638 jjdelcerro
    public boolean isIndexAscending() {
1161
        return this.isIndexAscending;
1162
    }
1163
1164 42563 jjdelcerro
    @Override
1165
    public DynField setClassOfValue(DynStruct dynStrct) {
1166
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1167
    }
1168
1169
    @Override
1170
    public DynField setClassOfValue(String theClassNameOfValue) {
1171
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1172
    }
1173
1174
    @Override
1175
    public String getClassNameOfValue() {
1176 42634 fdiaz
        return null;
1177 42563 jjdelcerro
    }
1178
1179
    @Override
1180
    public DynStruct getDynClassOfValue() {
1181 42634 fdiaz
        return null;
1182 42563 jjdelcerro
    }
1183
1184
    @Override
1185
    public DynField setTypeOfItems(int type) {
1186
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1187
    }
1188
1189
    @Override
1190
    public int getTypeOfItems() {
1191 42634 fdiaz
        return DataTypes.INVALID;
1192 42563 jjdelcerro
    }
1193
1194
    @Override
1195
    public DynField setClassOfItems(DynStruct dynStrct) {
1196
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1197
    }
1198
1199
    @Override
1200
    public DynField setClassOfItems(String theClassNameOfValue) {
1201
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
1202
    }
1203
1204
    @Override
1205
    public String getClassNameOfItems() {
1206 42634 fdiaz
        return null;
1207 42563 jjdelcerro
    }
1208
1209
    @Override
1210
    public DynStruct getDynClassOfItems() {
1211 42634 fdiaz
        return null;
1212 42563 jjdelcerro
    }
1213
1214
    @Override
1215
    public DynField setRelationType(int relationType) {
1216 44253 jjdelcerro
        this.relationType = relationType;
1217
        return this;
1218 42563 jjdelcerro
    }
1219
1220
    @Override
1221
    public int getRelationType() {
1222 44253 jjdelcerro
        return this.relationType;
1223 42563 jjdelcerro
    }
1224
1225 42606 jjdelcerro
    @Override
1226 42775 jjdelcerro
    public DynField setAvailableValues(DynMethod availableValuesMethod) {
1227
        this.availableValuesMethod = availableValuesMethod;
1228
        return this;
1229 42606 jjdelcerro
    }
1230
1231
    @Override
1232 42775 jjdelcerro
    public DynObjectValueItem[] getAvailableValues(DynObject self) {
1233
        if( this.availableValuesMethod != null ) {
1234
            DynObjectValueItem[] values;
1235
            try {
1236
                values = (DynObjectValueItem[]) this.availableValuesMethod.invoke(self,new Object[] {this});
1237
            } catch (DynMethodException ex) {
1238
                return this.availableValues;
1239
            }
1240 42606 jjdelcerro
            if( values != null ) {
1241
                return values;
1242
            }
1243
        }
1244
        return this.availableValues;
1245
    }
1246
1247 42775 jjdelcerro
    @Override
1248
    public DynMethod getAvailableValuesMethod() {
1249
        return this.availableValuesMethod;
1250
    }
1251
1252
    @Override
1253
    public boolean isAvailableValuesCalculated() {
1254
        return this.availableValuesMethod!=null;
1255
    }
1256
1257
    @Override
1258
    public DynMethod getCalculateMethod() {
1259
        return this.calculateMethod;
1260
    }
1261
1262
    @Override
1263
    public DynField setCalculateMethod(DynMethod method) {
1264
        this.calculateMethod = method;
1265
        return this;
1266
    }
1267
1268
    @Override
1269
    public boolean isCalculated() {
1270
        return this.calculateMethod != null;
1271
    }
1272
1273
    @Override
1274
    public Object getCalculatedValue(DynObject self) {
1275
        try {
1276
            return this.calculateMethod.invoke(self, new Object[] { this });
1277
        } catch (DynMethodException ex) {
1278
            throw new RuntimeException(ex);
1279
        }
1280
    }
1281
1282
    @Override
1283
    public DynField setValidateElements(boolean validate) {
1284
        return this;
1285
    }
1286
1287
    @Override
1288
    public boolean getValidateElements() {
1289
        return false;
1290
    }
1291
1292 41212 jjdelcerro
    private class ConstantValueEvaluator extends AbstractEvaluator {
1293 42561 jjdelcerro
1294
        @Override
1295 41212 jjdelcerro
        public Object evaluate(EvaluatorData data) throws EvaluatorException {
1296
            return defaultValue;
1297
        }
1298 42561 jjdelcerro
1299
        @Override
1300 41212 jjdelcerro
        public String getName() {
1301 42561 jjdelcerro
            return "Constant attribute " + name;
1302 41212 jjdelcerro
        }
1303
    }
1304 41335 jjdelcerro
1305 41212 jjdelcerro
    public void setConstantValue(boolean isConstantValue) {
1306 42561 jjdelcerro
        if (isConstantValue) {
1307 41212 jjdelcerro
            /* Cuando un attributo tiene asociado un evaluador, este se interpreta
1308 42634 fdiaz
             * como que no debe cargarse de la fuente de datos subyacente, siendo
1309 41212 jjdelcerro
             * el evaluador el que se encarga de proporcionar su valor.
1310
             * Nos limitamos a asignar un evaluador que retorna simpre el valor
1311
             * por defecto para ese attributo.
1312
             */
1313
            this.evaluator = new ConstantValueEvaluator();
1314
        } else {
1315
            this.evaluator = null;
1316
        }
1317
    }
1318 42561 jjdelcerro
1319 43739 jjdelcerro
    @Override
1320 43135 jjdelcerro
    public boolean isComputed() {
1321 44190 jjdelcerro
        return featureAttributeEmulator!=null || evaluator!=null || isCalculated();
1322 43135 jjdelcerro
    }
1323 43739 jjdelcerro
1324
    @Override
1325
    public FeatureStore getStore() {
1326
        FeatureType ftype = this.getFeatureType();
1327
        if( ftype == null ) {
1328
            return null;
1329
        }
1330
        return ftype.getStore();
1331
    }
1332
1333
    @Override
1334
    public FeatureType getFeatureType() {
1335
        if( this.typeRef==null ) {
1336
            return null;
1337
        }
1338 44259 jjdelcerro
        FeatureType ftype = (FeatureType) this.typeRef.get();
1339
//        LOGGER.info(String.format("FeatureAttributeDescriptor[%08x] get FeatureType [%08x], ref [%08x].", this.hashCode(), ftype.hashCode(), typeRef.hashCode()));
1340
        return ftype;
1341 43739 jjdelcerro
    }
1342 44094 jjdelcerro
1343
    public FeatureAttributeDescriptor setInterval(Interval interval) {
1344
        this.interval = interval;
1345
        return this;
1346
    }
1347
1348
    public void fixAll() {
1349
        switch(this.getType()) {
1350
            case DataTypes.INSTANT:
1351
            case DataTypes.INTERVAL:
1352
            case DataTypes.DATE:
1353
                if( this.getInterval()!=null ) {
1354
                    this.isTime = true;
1355
                }
1356
                break;
1357
        }
1358
    }
1359
1360 44158 jjdelcerro
    @Override
1361
    public String[] getRequiredFieldNames() {
1362
        FeatureAttributeEmulator emulator = this.getFeatureAttributeEmulator();
1363
        if( emulator==null ) {
1364
            return null;
1365
        }
1366
        return emulator.getRequiredFieldNames();
1367
    }
1368
1369 44262 jjdelcerro
    @Override
1370
    public void recentUsed() {
1371
        DefaultFeatureType.RECENTS_USEDS.add(this);
1372
    }
1373
1374 40435 jjdelcerro
}