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

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