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 / DefaultFeature.java @ 46505

History | View | Annotate | Download (51.5 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24 40435 jjdelcerro
package org.gvsig.fmap.dal.feature.impl;
25
26
import java.lang.ref.WeakReference;
27 44669 jjdelcerro
import java.math.BigDecimal;
28 45023 fdiaz
import java.time.LocalDateTime;
29
import java.time.ZoneId;
30 44655 jjdelcerro
import java.time.format.DateTimeFormatter;
31 43550 jjdelcerro
import java.util.ArrayList;
32 40435 jjdelcerro
import java.util.Date;
33 44858 jjdelcerro
import java.util.HashMap;
34 40435 jjdelcerro
import java.util.Iterator;
35
import java.util.List;
36 43550 jjdelcerro
import java.util.Map;
37 44655 jjdelcerro
import java.util.Objects;
38 46024 jjdelcerro
import java.util.function.Predicate;
39 44655 jjdelcerro
import javax.json.JsonObject;
40 44779 omartinez
import org.apache.commons.lang3.ArrayUtils;
41 44128 jjdelcerro
import org.apache.commons.lang3.StringUtils;
42 40435 jjdelcerro
import org.cresques.cts.IProjection;
43 44818 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionUtils;
44 44128 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
45 40435 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
46
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
47
import org.gvsig.fmap.dal.exception.DataException;
48 44128 jjdelcerro
import org.gvsig.fmap.dal.feature.DataProfile;
49 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
50 44773 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
51 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
55 45581 fdiaz
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
56 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureReference;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureType;
59
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
60
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
61 42775 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
62 45647 fdiaz
import org.gvsig.fmap.dal.feature.impl.featurereference.FeatureReferenceFactory;
63 43729 fdiaz
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
64 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
65
import org.gvsig.fmap.geom.Geometry;
66
import org.gvsig.fmap.geom.primitive.Envelope;
67 45581 fdiaz
import org.gvsig.json.Json;
68
import org.gvsig.json.JsonObjectBuilder;
69 40435 jjdelcerro
import org.gvsig.tools.ToolsLocator;
70 44799 jjdelcerro
import org.gvsig.tools.dataTypes.Coercion;
71 40435 jjdelcerro
import org.gvsig.tools.dataTypes.CoercionException;
72 45581 fdiaz
import org.gvsig.tools.dataTypes.DataType;
73 40435 jjdelcerro
import org.gvsig.tools.dataTypes.DataTypesManager;
74
import org.gvsig.tools.dynobject.DynObject;
75
import org.gvsig.tools.evaluator.Evaluator;
76
import org.gvsig.tools.evaluator.EvaluatorData;
77
import org.gvsig.tools.evaluator.EvaluatorException;
78
import org.gvsig.tools.exception.BaseException;
79
import org.gvsig.tools.exception.BaseRuntimeException;
80 40876 jjdelcerro
import org.gvsig.tools.lang.Cloneable;
81 45581 fdiaz
import org.slf4j.Logger;
82
import org.slf4j.LoggerFactory;
83 40435 jjdelcerro
84 44799 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
85 40876 jjdelcerro
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
86 40435 jjdelcerro
87 45581 fdiaz
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeature.class);
88 43729 fdiaz
89 45581 fdiaz
    private static DataTypesManager dataTypesManager = null;
90
    protected FeatureProvider data;
91
    protected FeatureReference reference;
92
    private WeakReference storeRef;
93 40435 jjdelcerro
94 45581 fdiaz
    private boolean inserted = false;
95
    private Object[] extraValuesData;
96
    private Map<String, Object> extraValues; // not persistent
97
98 40435 jjdelcerro
    /*
99
         * Usar con mucha precaucion o mejor no usar. Lo precisa el
100
         * DefaultFeatureSet en la ordenacion.
101 45581 fdiaz
     */
102
    public DefaultFeature(FeatureStore store) {
103
        this.storeRef = new WeakReference(store);
104
        this.reference = null;
105
    }
106 40435 jjdelcerro
107 45581 fdiaz
    public DefaultFeature(FeatureStore store, FeatureProvider data) {
108
        this.data = data;
109
        this.extraValuesData = null;
110
        this.storeRef = new WeakReference(store);
111
        this.reference = null;
112
        this.inserted = !data.isNew();
113
    }
114 40435 jjdelcerro
115 45581 fdiaz
    DefaultFeature(DefaultFeature feature) {
116
        this.data = feature.data.getCopy();
117
        this.extraValuesData = ArrayUtils.clone(feature.extraValuesData);
118
        this.storeRef = feature.storeRef;
119
        this.reference = feature.reference;
120
        this.inserted = feature.isInserted();
121
    }
122 40435 jjdelcerro
123 43729 fdiaz
    public DefaultFeature(FeatureType targetType, Feature sourceFeature) {
124 45581 fdiaz
        DefaultFeature defaultFeature = (DefaultFeature) sourceFeature;
125
        this.data = new DefaultFeatureProvider(targetType, (DefaultFeatureProvider) defaultFeature.getData());
126 44779 omartinez
        this.extraValuesData = null;
127 43729 fdiaz
        this.storeRef = defaultFeature.storeRef;
128
        this.reference = defaultFeature.reference;
129
        this.inserted = defaultFeature.isInserted();
130
131
        FeatureType sourceType = sourceFeature.getType();
132
133
        for (FeatureAttributeDescriptor targetAttrDescriptor : targetType) {
134 45581 fdiaz
            if (targetAttrDescriptor.isComputed()) {
135
                continue;
136 43729 fdiaz
            }
137
            int sourceIndex = sourceType.getIndex(targetAttrDescriptor.getName());
138 45581 fdiaz
            if (sourceIndex < 0) {
139 43729 fdiaz
                continue;
140
            }
141
            Object value = sourceFeature.get(sourceIndex);
142
            if (value == null && !targetAttrDescriptor.allowNull()) {
143
                continue;
144
            }
145 45581 fdiaz
            this.setforced(targetAttrDescriptor.getIndex(), targetAttrDescriptor, value);
146 43729 fdiaz
        }
147
    }
148
149 45581 fdiaz
    public void setData(FeatureProvider data) {
150
        this.data = data;
151
        this.extraValuesData = null;
152
        this.reference = null;
153
        this.inserted = true;
154
    }
155 40435 jjdelcerro
156 45581 fdiaz
    public FeatureProvider getData() {
157
        return this.data;
158
    }
159 40435 jjdelcerro
160 45581 fdiaz
    protected DataTypesManager getDataTypesManager() {
161
        if (dataTypesManager == null) {
162
            dataTypesManager = ToolsLocator.getDataTypesManager();
163
        }
164
        return dataTypesManager;
165
    }
166 40435 jjdelcerro
167 46024 jjdelcerro
    public boolean canSetValue(String name) {
168
        return this.canSetValue(this.getType().getAttributeDescriptor(name), null);
169
    }
170
171
    public boolean canSetValue(FeatureAttributeDescriptor attr,Predicate<FeatureAttributeDescriptor> filter) {
172
        // helper function to use in copyFrom
173
        if (attr==null  ) {
174
            return false;
175
        }
176
        if (attr.isAutomatic()  || attr.isComputed() ) {
177
            return false;
178
        }
179
        if( this.isInserted() &&  attr.isReadOnly()) {
180
            return false;
181
        }
182
        if( filter!=null && !filter.test(attr) ) {
183
            return false;
184
        }
185
        return true;
186
    }
187
188 44641 jjdelcerro
    protected void set(FeatureAttributeDescriptor attribute, Object value) {
189 41335 jjdelcerro
        int i = attribute.getIndex();
190 40435 jjdelcerro
191 45769 jjdelcerro
        if( this.isInserted() ) {
192
            if (attribute.isReadOnly()) {
193
                throw new SetReadOnlyAttributeException(attribute.getName(), this.getType());
194
            }
195
        } else {
196
            if (attribute.isComputed()) {
197
                throw new SetReadOnlyAttributeException(attribute.getName(), this.getType());
198
            }
199 41335 jjdelcerro
        }
200
        FeatureAttributeEmulator emulator = attribute.getFeatureAttributeEmulator();
201 45581 fdiaz
        if (emulator != null) {
202
            emulator.set((EditableFeature) this, value);
203 41335 jjdelcerro
            return;
204
        }
205 43729 fdiaz
206 45581 fdiaz
        if (value == null) {
207
            if (!attribute.allowNull()) {
208
                if (!attribute.isAutomatic()) {
209 41335 jjdelcerro
                    throw new IllegalValueException(attribute, value);
210
                }
211
            }
212
            this.data.set(i, null);
213
            return;
214 40435 jjdelcerro
215 41335 jjdelcerro
        }
216 40435 jjdelcerro
217 45581 fdiaz
        if (attribute.getFeatureAttributeGetter() != null) {
218 41335 jjdelcerro
            value = attribute.getFeatureAttributeGetter().setter(value);
219 40435 jjdelcerro
        }
220 44641 jjdelcerro
        this.setforced(i, attribute, value);
221
    }
222 41335 jjdelcerro
223 44641 jjdelcerro
    private void setforced(int i, FeatureAttributeDescriptor attribute, Object value) {
224
225 42218 jjdelcerro
        Class objectClass = attribute.getObjectClass();
226 45581 fdiaz
        if (objectClass != null) {
227
            if (objectClass.isInstance(value)) {
228
                if (attribute.getType() == DataTypes.DECIMAL) {
229
                    BigDecimal d = (BigDecimal) value;
230
                    if (d.scale() == attribute.getScale() && d.precision() <= attribute.getPrecision()) {
231
                        this.data.set(i, value);
232
                        return;
233
                    }
234 45693 fdiaz
                } else if (attribute.getType() == DataTypes.GEOMETRY) {
235
                    if (!attribute.getGeomType().equals(((Geometry) value).getGeometryType())) {
236
                        try {
237
                            Coercion coercer = attribute.getDataType().getCoercion();
238
                            value = coercer.coerce(value, attribute.getCoercionContext());
239
                        } catch (CoercionException e) {
240
                            throw new IllegalArgumentException("Can't convert to "
241
                                    + attribute.getDataType().getName()
242
                                    + " from '"
243
                                    + value == null ? "NULL" : value.getClass().getName()
244
                                            + "' with value '"
245
                                            + Objects.toString(value)
246
                                            + "' and context '"
247
                                            + attribute.getCoercionContext()
248
                                            + "'.");
249
                        }
250
                    }
251
                    this.data.set(i, value);
252
                    return;
253 45581 fdiaz
                } else {
254 44799 jjdelcerro
                    this.data.set(i, value);
255
                    return;
256
                }
257
            }
258
            DataProfile dataProfile = attribute.getDataProfile();
259 45581 fdiaz
            if (dataProfile != null) {
260 42218 jjdelcerro
                try {
261 44799 jjdelcerro
                    value = dataProfile.coerce(
262
                            attribute.getDataType(),
263 45581 fdiaz
                            value,
264 44799 jjdelcerro
                            attribute.getTags()
265
                    );
266 42218 jjdelcerro
                } catch (CoercionException e) {
267 44799 jjdelcerro
268 42218 jjdelcerro
                }
269 45581 fdiaz
            }
270 44799 jjdelcerro
            try {
271
                Coercion coercer = attribute.getDataType().getCoercion();
272 45581 fdiaz
                if (attribute.getType() == DataTypes.STRING && value instanceof Boolean) {
273 45131 fdiaz
                    value = coercer.coerce(value, attribute.getCoercionContext());
274
                    value = StringUtils.left((String) value, attribute.getSize());
275
                } else {
276 45581 fdiaz
                    value = coercer.coerce(value, attribute.getCoercionContext());
277 45131 fdiaz
                }
278 44799 jjdelcerro
            } catch (CoercionException e) {
279
                throw new IllegalArgumentException("Can't convert to "
280
                        + attribute.getDataType().getName()
281
                        + " from '"
282 45581 fdiaz
                        + value == null ? "NULL" : value.getClass().getName()
283
                                + "' with value '"
284
                                + Objects.toString(value)
285
                                + "' and context '"
286
                                + attribute.getCoercionContext()
287
                                + "'.");
288 40435 jjdelcerro
            }
289 41335 jjdelcerro
        }
290 40435 jjdelcerro
        this.data.set(i, value);
291
    }
292 43729 fdiaz
293 45581 fdiaz
    private Object get(int index, Class theClass, int type) {
294 40435 jjdelcerro
        Object value = this.get(index);
295 45581 fdiaz
        if (theClass.isInstance(value)) {
296 40435 jjdelcerro
            return value;
297
        }
298
        try {
299
            return this.getDataTypesManager().coerce(type, value);
300
        } catch (CoercionException e) {
301 43729 fdiaz
302 40435 jjdelcerro
            if (value == null) {
303
                return null;
304
            }
305
            throw new IllegalArgumentException(
306 45581 fdiaz
                    "Can't convert to " + theClass.getName()
307
                    + " from '" + value.getClass().getName()
308
                    + "' with value '" + value.toString() + "'.");
309 40435 jjdelcerro
        }
310
    }
311 43729 fdiaz
312 40435 jjdelcerro
    public void initializeValues() {
313
        FeatureType type = this.getType();
314 44297 jjdelcerro
        for (FeatureAttributeDescriptor attribute : type) {
315 40435 jjdelcerro
            if (attribute.isAutomatic() || attribute.isReadOnly()
316 45581 fdiaz
                    || attribute.isComputed()) {
317 40435 jjdelcerro
                continue;
318
            }
319
            if (attribute.getDefaultValue() == null && !attribute.allowNull()) {
320
                continue;
321
            }
322 45581 fdiaz
            Object value = attribute.getDefaultValue();
323
            if (value instanceof CharSequence) {
324
                String s = ((CharSequence) value).toString();
325
                if (ExpressionUtils.isDynamicText(s)) {
326
                    try {
327
                        value = ExpressionUtils.evaluateDynamicText(s);
328
                    } catch (Throwable th) {
329
                        value = null;
330
                    }
331 44818 jjdelcerro
                }
332
            }
333
            this.set(attribute, value);
334 40435 jjdelcerro
        }
335
    }
336
337
    public void clear() {
338
        initializeValues();
339
    }
340
341
    public void initializeValues(Feature feature) {
342 45581 fdiaz
        FeatureType myType = this.getType();
343
        FeatureType type = feature.getType();
344 44779 omartinez
        extraValuesData = null;
345 44297 jjdelcerro
        for (FeatureAttributeDescriptor attribute : type) {
346 45581 fdiaz
            FeatureAttributeDescriptor myAttribute = myType.getAttributeDescriptor(attribute.getName());
347 40435 jjdelcerro
            if (myAttribute != null) {
348
                this.set(myAttribute, feature.get(attribute.getIndex()));
349
            }
350
        }
351
    }
352
353 44297 jjdelcerro
    @Override
354 40435 jjdelcerro
    public FeatureStore getStore() {
355
        return (FeatureStore) this.storeRef.get();
356
    }
357
358 44297 jjdelcerro
    @Override
359 40435 jjdelcerro
    public FeatureType getType() {
360
        return this.data.getType();
361
    }
362
363 44297 jjdelcerro
    @Override
364 40435 jjdelcerro
    public EditableFeature getEditable() {
365
        return new DefaultEditableFeature(this);
366
    }
367
368 44297 jjdelcerro
    @Override
369 40435 jjdelcerro
    public Feature getCopy() {
370
        return new DefaultFeature(this);
371
    }
372 43729 fdiaz
373 44297 jjdelcerro
    @Override
374
    @SuppressWarnings("CloneDoesntCallSuperClone")
375 40876 jjdelcerro
    public Object clone() throws CloneNotSupportedException {
376
        return new DefaultFeature(this);
377
    }
378 40435 jjdelcerro
379 44297 jjdelcerro
    @Override
380 40435 jjdelcerro
    public FeatureReference getReference() {
381
        if (this.reference == null) {
382
            if (!isInserted()) {
383
                return null;
384
            }
385 45647 fdiaz
            reference = FeatureReferenceFactory.createFromFeature(this);
386 40435 jjdelcerro
        }
387
        return this.reference;
388
    }
389
390 44331 jjdelcerro
    @Override
391
    public Object getOrDefault(String name, Object defaultValue) {
392
        int index = this.data.getType().getIndex(name);
393 45581 fdiaz
        if (index < 0) {
394 44331 jjdelcerro
            return defaultValue;
395
        }
396
        return this.get(index);
397
    }
398 45738 fdiaz
399
    @Override
400
    public Object getOrDefault(String name, int type, Object defaultValue) {
401
        DataType dataType = ToolsLocator.getDataTypesManager().get(type);
402
        return getOrDefault(name, dataType, defaultValue);
403
    }
404
405
    @Override
406
    public Object getOrDefault(String name, DataType type, Object defaultValue) {
407
        int index = this.data.getType().getIndex(name);
408
        if (index < 0) {
409
            return defaultValue;
410
        }
411
        try {
412
            Object value = this.get(index);
413
            if(value == null){
414
                return defaultValue;
415
            }
416
            return type.coerce(value);
417
        } catch (Throwable th) {
418
            return defaultValue;
419
        }
420
    }
421 44331 jjdelcerro
422
    @Override
423
    public String getStringOrDefault(String name, String defaultValue) {
424
        int index = this.data.getType().getIndex(name);
425 45581 fdiaz
        if (index < 0) {
426 44331 jjdelcerro
            return defaultValue;
427
        }
428
        try {
429
            return (String) this.get(index);
430 45581 fdiaz
        } catch (Throwable th) {
431 44331 jjdelcerro
            return defaultValue;
432
        }
433
    }
434
435
    @Override
436 45540 jjdelcerro
    public boolean getBooleanOrDefault(String name, boolean defaultValue) {
437
        int index = this.data.getType().getIndex(name);
438 45581 fdiaz
        if (index < 0) {
439 45540 jjdelcerro
            return defaultValue;
440
        }
441
        try {
442
            return this.getBoolean(index);
443 45581 fdiaz
        } catch (Throwable th) {
444 45540 jjdelcerro
            return defaultValue;
445
        }
446
    }
447
448
    @Override
449 44331 jjdelcerro
    public int getIntOrDefault(String name, int defaultValue) {
450
        int index = this.data.getType().getIndex(name);
451 45581 fdiaz
        if (index < 0) {
452 44331 jjdelcerro
            return defaultValue;
453
        }
454
        try {
455 45540 jjdelcerro
            return this.getInt(index);
456 45581 fdiaz
        } catch (Throwable th) {
457 44331 jjdelcerro
            return defaultValue;
458
        }
459
    }
460
461
    @Override
462
    public long getLongOrDefault(String name, long defaultValue) {
463
        int index = this.data.getType().getIndex(name);
464 45581 fdiaz
        if (index < 0) {
465 44331 jjdelcerro
            return defaultValue;
466
        }
467
        try {
468 45540 jjdelcerro
            return this.getLong(index);
469 45581 fdiaz
        } catch (Throwable th) {
470 44331 jjdelcerro
            return defaultValue;
471
        }
472
    }
473
474
    @Override
475
    public float getFloatOrDefault(String name, float defaultValue) {
476
        int index = this.data.getType().getIndex(name);
477 45581 fdiaz
        if (index < 0) {
478 44331 jjdelcerro
            return defaultValue;
479
        }
480
        try {
481 45540 jjdelcerro
            return this.getFloat(index);
482 45581 fdiaz
        } catch (Throwable th) {
483 44331 jjdelcerro
            return defaultValue;
484
        }
485
    }
486
487
    @Override
488
    public double getDoubleOrDefault(String name, double defaultValue) {
489
        int index = this.data.getType().getIndex(name);
490 45581 fdiaz
        if (index < 0) {
491 44331 jjdelcerro
            return defaultValue;
492
        }
493
        try {
494 45540 jjdelcerro
            return this.getDouble(index);
495 45581 fdiaz
        } catch (Throwable th) {
496 44331 jjdelcerro
            return defaultValue;
497
        }
498
    }
499
500
    @Override
501 44669 jjdelcerro
    public BigDecimal getDecimalOrDefault(String name, BigDecimal defaultValue) {
502
        int index = this.data.getType().getIndex(name);
503 45581 fdiaz
        if (index < 0) {
504 44669 jjdelcerro
            return defaultValue;
505
        }
506
        try {
507 45540 jjdelcerro
            return this.getDecimal(index);
508 45581 fdiaz
        } catch (Throwable th) {
509 44669 jjdelcerro
            return defaultValue;
510
        }
511
    }
512
513
    @Override
514 44331 jjdelcerro
    public Date getDateOrDefault(String name, Date defaultValue) {
515
        int index = this.data.getType().getIndex(name);
516 45581 fdiaz
        if (index < 0) {
517 44331 jjdelcerro
            return defaultValue;
518
        }
519
        try {
520 45540 jjdelcerro
            return this.getDate(index);
521 45581 fdiaz
        } catch (Throwable th) {
522 44331 jjdelcerro
            return defaultValue;
523
        }
524
    }
525
526
    @Override
527
    public Object getOrDefault(int index, Object defaultValue) {
528 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
529 44331 jjdelcerro
            return defaultValue;
530
        }
531
        try {
532
            return this.get(index);
533 45581 fdiaz
        } catch (Throwable th) {
534 44331 jjdelcerro
            return defaultValue;
535
        }
536
    }
537
538
    @Override
539
    public String getStringOrDefault(int index, String defaultValue) {
540 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
541 44331 jjdelcerro
            return defaultValue;
542
        }
543
        try {
544 45540 jjdelcerro
            return this.getString(index);
545 45581 fdiaz
        } catch (Throwable th) {
546 44331 jjdelcerro
            return defaultValue;
547
        }
548
    }
549
550
    @Override
551 45540 jjdelcerro
    public boolean getBooleanOrDefault(int index, boolean defaultValue) {
552 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
553 45540 jjdelcerro
            return defaultValue;
554
        }
555
        try {
556
            return this.getBoolean(index);
557 45581 fdiaz
        } catch (Throwable th) {
558 45540 jjdelcerro
            return defaultValue;
559
        }
560
    }
561
562
    @Override
563 44331 jjdelcerro
    public int getIntOrDefault(int index, int defaultValue) {
564 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
565 44331 jjdelcerro
            return defaultValue;
566
        }
567
        try {
568 45540 jjdelcerro
            return this.getInt(index);
569 45581 fdiaz
        } catch (Throwable th) {
570 44331 jjdelcerro
            return defaultValue;
571
        }
572
    }
573
574
    @Override
575
    public long getLongOrDefault(int index, long defaultValue) {
576 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
577 44331 jjdelcerro
            return defaultValue;
578
        }
579
        try {
580 45540 jjdelcerro
            return this.getLong(index);
581 45581 fdiaz
        } catch (Throwable th) {
582 44331 jjdelcerro
            return defaultValue;
583
        }
584
    }
585
586
    @Override
587
    public float getFloatOrDefault(int index, float defaultValue) {
588 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
589 44331 jjdelcerro
            return defaultValue;
590
        }
591
        try {
592 45540 jjdelcerro
            return this.getFloat(index);
593 45581 fdiaz
        } catch (Throwable th) {
594 44331 jjdelcerro
            return defaultValue;
595
        }
596
    }
597
598
    @Override
599
    public double getDoubleOrDefault(int index, double defaultValue) {
600 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
601 44331 jjdelcerro
            return defaultValue;
602
        }
603
        try {
604 45540 jjdelcerro
            return this.getDouble(index);
605 45581 fdiaz
        } catch (Throwable th) {
606 44331 jjdelcerro
            return defaultValue;
607
        }
608
    }
609
610
    @Override
611 44669 jjdelcerro
    public BigDecimal getDecimalOrDefault(int index, BigDecimal defaultValue) {
612 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
613 44669 jjdelcerro
            return defaultValue;
614
        }
615
        try {
616 45540 jjdelcerro
            return this.getDecimal(index);
617 45581 fdiaz
        } catch (Throwable th) {
618 44669 jjdelcerro
            return defaultValue;
619
        }
620
    }
621
622
    @Override
623 44331 jjdelcerro
    public Date getDateOrDefault(int index, Date defaultValue) {
624 45581 fdiaz
        if (index < 0 || index >= this.data.getType().size()) {
625 44331 jjdelcerro
            return defaultValue;
626
        }
627
        try {
628 45540 jjdelcerro
            return this.getDate(index);
629 45581 fdiaz
        } catch (Throwable th) {
630 44331 jjdelcerro
            return defaultValue;
631
        }
632
    }
633
634 45739 jjdelcerro
    @Override
635
    public void validate(int check) throws DataException {
636
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, check);
637
    }
638
639 40435 jjdelcerro
    class UnableToGetReferenceException extends BaseRuntimeException {
640
641
        /**
642 43729 fdiaz
         *
643 40435 jjdelcerro
         */
644
        private static final long serialVersionUID = 1812805035204824163L;
645
646
        /**
647
         * @param exception
648
         */
649 44799 jjdelcerro
        @SuppressWarnings("OverridableMethodCallInConstructor")
650 40435 jjdelcerro
        public UnableToGetReferenceException(BaseException exception) {
651
            super("Unable to get reference", "_UnableToGetReferenceException",
652 45581 fdiaz
                    serialVersionUID);
653 40435 jjdelcerro
            this.initCause(exception);
654 43729 fdiaz
655 40435 jjdelcerro
        }
656 43729 fdiaz
657 40435 jjdelcerro
    }
658 43729 fdiaz
659 44297 jjdelcerro
    @Override
660 40435 jjdelcerro
    public List getSRSs() {
661
        // TODO Auto-generated method stub
662
        return null;
663
    }
664
665 44297 jjdelcerro
    @Override
666 40435 jjdelcerro
    public Envelope getDefaultEnvelope() {
667 41342 jjdelcerro
        Envelope envelope = this.data.getDefaultEnvelope();
668 45581 fdiaz
        if (envelope == null) {
669 44618 jjdelcerro
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
670 45581 fdiaz
            if (i < 0) {
671 44618 jjdelcerro
                return null;
672
            }
673 41342 jjdelcerro
            Geometry geom = this.getDefaultGeometry();
674 45581 fdiaz
            if (geom != null) {
675 41348 jjdelcerro
                envelope = geom.getEnvelope();
676
            }
677 41342 jjdelcerro
        }
678
        return envelope;
679 40435 jjdelcerro
    }
680
681 44022 jjdelcerro
    @Override
682 40435 jjdelcerro
    public Geometry getDefaultGeometry() {
683 45581 fdiaz
        Geometry geom = this.data.getDefaultGeometry();
684
        if (geom == null) {
685 44022 jjdelcerro
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
686 45581 fdiaz
            if (i < 0) {
687 44618 jjdelcerro
                return null;
688
            }
689 44022 jjdelcerro
            Object x = this.get(i);
690 45581 fdiaz
            if (x instanceof Geometry) {
691 44022 jjdelcerro
                geom = (Geometry) x;
692
            } else {
693
                geom = this.getGeometry(i);
694
            }
695 43420 jjdelcerro
        }
696 45581 fdiaz
        if (geom != null) {
697
            if (geom.getProjection() == null) {
698 44022 jjdelcerro
                FeatureType type = this.getType();
699
                DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
700
                IProjection proj = attrdesc.getSRS(this.storeRef);
701
                geom.setProjection(proj);
702
            }
703
        }
704
        return geom;
705 40435 jjdelcerro
    }
706
707 44767 jjdelcerro
//    @Override
708
//    public Time getDefaultTime() {
709
//            Time time = this.data.getDefaultTime();
710
//        if( time == null ) {
711
//            int i = this.data.getType().getDefaultTimeAttributeIndex();
712
//            Object x = this.get(i);
713
//            if( x instanceof Time ) {
714
//                time = (Time) x;
715
//            } else {
716
//                time = this.getTime(i);
717
//            }
718
//        }
719
//        return time;
720
//    }
721
//
722 44086 jjdelcerro
    @Override
723 40435 jjdelcerro
    public IProjection getDefaultSRS() {
724 44022 jjdelcerro
        IProjection srs = this.data.getType().getDefaultSRS();
725 45581 fdiaz
        if (srs == null) {
726 44022 jjdelcerro
            FeatureType type = this.getType();
727
            DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
728
            srs = attrdesc.getSRS(this.storeRef);
729
        }
730
        return srs;
731 40435 jjdelcerro
    }
732
733 44297 jjdelcerro
    @Override
734 40435 jjdelcerro
    public List getGeometries() {
735
        // TODO Auto-generated method stub
736
        return null;
737
    }
738
739 44128 jjdelcerro
    @Override
740
    public Object getFromProfile(int index) {
741
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(index);
742
        Object value = this.get(index);
743
        String profileName = descriptor.getDataProfileName();
744 45581 fdiaz
        if (StringUtils.isBlank(profileName)) {
745 44128 jjdelcerro
            return value;
746
        }
747
        DataProfile profile = DALLocator.getDataManager().getDataProfile(profileName);
748 45581 fdiaz
        if (profile == null) {
749 44128 jjdelcerro
            return value;
750
        }
751 44253 jjdelcerro
        return profile.createData(value, descriptor.getTags());
752 44128 jjdelcerro
    }
753
754
    @Override
755
    public Object getFromProfile(String name) {
756
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(name);
757
        return this.getFromProfile(descriptor.getIndex());
758
    }
759
760 46162 jjdelcerro
    private Object get(String name, Class theClass, int type) {
761
        Object value = this.get(name);
762
        if (theClass.isInstance(value)) {
763
            return value;
764
        }
765
        try {
766
            return this.getDataTypesManager().coerce(type, value);
767
        } catch (CoercionException e) {
768
769
            if (value == null) {
770
                return null;
771
            }
772
            throw new IllegalArgumentException(
773
                    "Can't convert to " + theClass.getName()
774
                    + " from '" + value.getClass().getName()
775
                    + "' with value '" + value.toString() + "'.");
776
        }
777
    }
778
779 44297 jjdelcerro
    @Override
780 40435 jjdelcerro
    public Object get(String name) {
781
        int index = this.data.getType().getIndex(name);
782 45581 fdiaz
        if (index < 0) {
783 45155 omartinez
            // buscamos en los extra cols
784 45581 fdiaz
            if (hasExtraColumnValue(name)) {
785 45155 omartinez
                return getExtraColumnValue(name);
786
            }
787
            if (hasExtraValue(name)) {
788
                return getExtraValue(name);
789
            }
790
            // y si esta ahi return
791 45581 fdiaz
            throw new IllegalArgumentException("Attribute name '" + name + "' not found in the feature.");
792 40435 jjdelcerro
        }
793
        return this.get(index);
794
    }
795 45581 fdiaz
796 44669 jjdelcerro
    @Override
797
    public boolean isNull(int index) {
798
        FeatureType type = this.data.getType();
799 45581 fdiaz
        if (index < 0 || index >= type.size()) {
800
            throw new IllegalArgumentException("Attribute index '" + index + "' out of range (0 to " + this.data.getType().size() + ".");
801 44669 jjdelcerro
        }
802
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
803
        if (!this.data.getType().hasEvaluators()) {
804 45581 fdiaz
            return this.data.get(index) == null;
805 44669 jjdelcerro
        }
806
        Evaluator eval = attribute.getEvaluator();
807
        if (eval == null) {
808 45581 fdiaz
            return this.data.get(index) == null;
809 44669 jjdelcerro
        }
810
        Object value = this.data.get(index);
811
        if (value != null) {
812
            return true;
813
        }
814
        try {
815
            value = eval.evaluate(this);
816
        } catch (EvaluatorException e) {
817
            throw new DataEvaluatorRuntimeException(e);
818
        }
819
        this.data.set(index, value);
820 45581 fdiaz
        return value == null;
821 44669 jjdelcerro
    }
822 45581 fdiaz
823 44669 jjdelcerro
    @Override
824
    public boolean isNull(String name) {
825
        int index = this.data.getType().getIndex(name);
826 45581 fdiaz
        if (index < 0) {
827
            throw new IllegalArgumentException("Attribute name '" + name + "' not found in the feature.");
828 44669 jjdelcerro
        }
829
        return this.isNull(index);
830
    }
831 43729 fdiaz
832 43550 jjdelcerro
    public boolean has_key(String key) {
833
        Object x = this.getType().get(key);
834
        return x != null;
835
    }
836 43729 fdiaz
837 43550 jjdelcerro
    public List<String> keys() {
838
        List<String> ks = new ArrayList<>();
839 45581 fdiaz
        for (FeatureAttributeDescriptor attr : this.getType()) {
840 43550 jjdelcerro
            ks.add(attr.getName());
841
        }
842
        return ks;
843
    }
844 43729 fdiaz
845 43550 jjdelcerro
    public Iterator<String> iterkeys() {
846
        final Iterator it = this.getType().iterator();
847
        return new Iterator<String>() {
848
            @Override
849
            public boolean hasNext() {
850
                return it.hasNext();
851
            }
852 40435 jjdelcerro
853 43550 jjdelcerro
            @Override
854
            public String next() {
855 45581 fdiaz
                return ((FeatureAttributeDescriptor) it.next()).getName();
856 43550 jjdelcerro
            }
857 43561 jjdelcerro
858
            @Override
859
            public void remove() {
860
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
861
            }
862 43550 jjdelcerro
        };
863
    }
864 40435 jjdelcerro
865 43550 jjdelcerro
    public Iterator iteritems() {
866
        final Iterator it = this.getType().iterator();
867
        return new Iterator<Map.Entry>() {
868
            @Override
869
            public boolean hasNext() {
870
                return it.hasNext();
871
            }
872
873
            @Override
874
            public Map.Entry next() {
875 45581 fdiaz
                final String name = ((FeatureAttributeDescriptor) it.next()).getName();
876 43550 jjdelcerro
                return new Map.Entry<String, Object>() {
877
                    @Override
878
                    public String getKey() {
879
                        return name;
880
                    }
881
882
                    @Override
883
                    public Object getValue() {
884
                        return get(name);
885
                    }
886
887
                    @Override
888
                    public Object setValue(Object value) {
889
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
890
                    }
891 43729 fdiaz
892 43550 jjdelcerro
                };
893
            }
894 43561 jjdelcerro
895
            @Override
896
            public void remove() {
897
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
898
            }
899 43729 fdiaz
        };
900 43550 jjdelcerro
    }
901
902
    @Override
903 40435 jjdelcerro
    public Object get(int index) {
904
        FeatureType type = this.data.getType();
905 45581 fdiaz
        if (index < 0 || index >= type.size()) {
906
            throw new IllegalArgumentException("Attribute index '" + index + "' out of range (0 to " + this.data.getType().size() + ".");
907 40435 jjdelcerro
        }
908 44840 jjdelcerro
        Object value = this.data.get(index);
909 40435 jjdelcerro
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
910 44840 jjdelcerro
        if (type.hasEvaluators()) {
911 45581 fdiaz
            Evaluator eval = attribute.getEvaluator();
912
            if (eval != null) {
913
                if (value == null) { // Ya hemos calculado el campo ?
914
                    // FIXME: para comprobar si esta calculado usar un array especifico.
915
                    try {
916
                        value = eval.evaluate(this);
917
                    } catch (EvaluatorException e) {
918
                        throw new DataEvaluatorRuntimeException(e);
919
                    }
920
                    this.data.set(index, value);
921
                }
922
            }
923 43729 fdiaz
        }
924 44840 jjdelcerro
        value = get(attribute, value);
925 45581 fdiaz
        return value;
926 40435 jjdelcerro
    }
927
928 45581 fdiaz
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value) {
929 41335 jjdelcerro
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
930 45581 fdiaz
        if (emulator != null) {
931 44226 jjdelcerro
//            int index = featureAttributeDescriptor.getIndex();
932
//            value = this.data.get(index);
933
//            if( value==null ) {
934 46050 omartinez
            value = this.getExtraValue(featureAttributeDescriptor.getName());
935
            if (value==null) {
936
                value = emulator.get(this);
937
            }
938 44226 jjdelcerro
//                this.data.set(index,value);
939
//            }
940 44022 jjdelcerro
        } else {
941
            FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
942 45581 fdiaz
            if (getter != null) {
943 44022 jjdelcerro
                value = getter.getter(value);
944
            }
945 40435 jjdelcerro
        }
946 45993 omartinez
        value = coerce(featureAttributeDescriptor, value);
947
        return value;
948
    }
949
950
    private Object coerce(FeatureAttributeDescriptor attr, Object value) {
951
        DataType dataType = attr.getDataType();
952 45047 jjdelcerro
        Class<? extends DataType> theClass = dataType.getDefaultClass();
953 45581 fdiaz
        if (theClass != null && !theClass.isInstance(value)) {
954 44951 omartinez
            try {
955
                value = this.getDataTypesManager().coerce(dataType.getType(), value);
956
            } catch (CoercionException e) {
957 45581 fdiaz
                throw new IllegalArgumentException(
958
                        "Can't convert to " + theClass.getSimpleName()
959
                        + " from '" + value.getClass().getSimpleName()
960
                        + "' with value '" + value.toString() + "'.");
961 44951 omartinez
            }
962
        }
963 45993 omartinez
        if (attr.getType() == DataTypes.GEOMETRY) {
964 45581 fdiaz
            if (value != null) {
965
                Geometry geom = (Geometry) value;
966
                if (geom.getProjection() == null) {
967 45993 omartinez
                    IProjection proj = ((DefaultFeatureAttributeDescriptor) attr).getSRS(this.storeRef);
968 44022 jjdelcerro
                    geom.setProjection(proj);
969
                }
970
            }
971 41335 jjdelcerro
        }
972
        return value;
973 40435 jjdelcerro
    }
974
975 44297 jjdelcerro
    @Override
976
    public byte[] getByteArray(String name) {
977 46162 jjdelcerro
        return (byte[]) this.get(name);
978 44297 jjdelcerro
    }
979
980
    @Override
981
    public byte[] getByteArray(int index) {
982
        return (byte[]) this.get(index);
983
    }
984
985
    @Override
986 40435 jjdelcerro
    public Object[] getArray(String name) {
987 46162 jjdelcerro
        return (Object[]) this.get(name);
988 40435 jjdelcerro
    }
989
990 44297 jjdelcerro
    @Override
991 40435 jjdelcerro
    public Object[] getArray(int index) {
992
        return (Object[]) this.get(index);
993
    }
994
995 44297 jjdelcerro
    @Override
996 40435 jjdelcerro
    public boolean getBoolean(String name) {
997 46162 jjdelcerro
        Boolean value = ((Boolean) this.get(name, Boolean.class, DataTypes.BOOLEAN));
998
        if (value == null) {
999
            return false;
1000
        }
1001
        return value;
1002 40435 jjdelcerro
    }
1003
1004 44297 jjdelcerro
    @Override
1005 40435 jjdelcerro
    public boolean getBoolean(int index) {
1006 45581 fdiaz
        Boolean value = ((Boolean) this.get(index, Boolean.class, DataTypes.BOOLEAN));
1007 40435 jjdelcerro
        if (value == null) {
1008
            return false;
1009
        }
1010 44297 jjdelcerro
        return value;
1011 40435 jjdelcerro
    }
1012
1013 44297 jjdelcerro
    @Override
1014 40435 jjdelcerro
    public byte getByte(String name) {
1015 46162 jjdelcerro
        Byte value = ((Byte) this.get(name, Byte.class, DataTypes.BYTE));
1016
        if (value == null) {
1017
            return 0;
1018
        }
1019
        return value;
1020 40435 jjdelcerro
    }
1021
1022 44297 jjdelcerro
    @Override
1023 40435 jjdelcerro
    public byte getByte(int index) {
1024 45581 fdiaz
        Byte value = ((Byte) this.get(index, Byte.class, DataTypes.BYTE));
1025 40435 jjdelcerro
        if (value == null) {
1026
            return 0;
1027
        }
1028 44297 jjdelcerro
        return value;
1029 40435 jjdelcerro
    }
1030
1031 44297 jjdelcerro
    @Override
1032 45425 jjdelcerro
    public java.sql.Date getDate(String name) {
1033 46162 jjdelcerro
        java.sql.Date value = ((java.sql.Date) this.get(name, java.sql.Date.class, DataTypes.DATE));
1034
        return value;
1035 40435 jjdelcerro
    }
1036
1037 44297 jjdelcerro
    @Override
1038 45425 jjdelcerro
    public java.sql.Date getDate(int index) {
1039 45581 fdiaz
        java.sql.Date value = ((java.sql.Date) this.get(index, java.sql.Date.class, DataTypes.DATE));
1040 44767 jjdelcerro
        return value;
1041
    }
1042 40435 jjdelcerro
1043 44767 jjdelcerro
    @Override
1044 45425 jjdelcerro
    public java.sql.Time getTime(String name) {
1045 46162 jjdelcerro
        java.sql.Time value = ((java.sql.Time) this.get(name, java.sql.Time.class, DataTypes.TIME));
1046
        return value;
1047 44767 jjdelcerro
    }
1048
1049
    @Override
1050 45425 jjdelcerro
    public java.sql.Time getTime(int index) {
1051 45581 fdiaz
        java.sql.Time value = ((java.sql.Time) this.get(index, java.sql.Time.class, DataTypes.TIME));
1052 40435 jjdelcerro
        return value;
1053
    }
1054
1055 44297 jjdelcerro
    @Override
1056 45425 jjdelcerro
    public java.sql.Timestamp getTimestamp(String name) {
1057 46162 jjdelcerro
        java.sql.Timestamp value = ((java.sql.Timestamp) this.get(name, java.sql.Timestamp.class, DataTypes.TIMESTAMP));
1058
        return value;
1059 44767 jjdelcerro
    }
1060
1061
    @Override
1062 45425 jjdelcerro
    public java.sql.Timestamp getTimestamp(int index) {
1063 45581 fdiaz
        java.sql.Timestamp value = ((java.sql.Timestamp) this.get(index, java.sql.Timestamp.class, DataTypes.TIMESTAMP));
1064 44767 jjdelcerro
        return value;
1065
    }
1066
1067
    @Override
1068 40435 jjdelcerro
    public double getDouble(String name) {
1069 46162 jjdelcerro
        Double value = ((Double) this.get(name, Double.class, DataTypes.DOUBLE));
1070
        if (value == null) {
1071
            return 0;
1072
        }
1073
        return value;
1074 40435 jjdelcerro
    }
1075
1076 44297 jjdelcerro
    @Override
1077 40435 jjdelcerro
    public double getDouble(int index) {
1078 43729 fdiaz
1079 45581 fdiaz
        Double value = ((Double) this.get(index, Double.class, DataTypes.DOUBLE));
1080 40435 jjdelcerro
        if (value == null) {
1081
            return 0;
1082
        }
1083 44297 jjdelcerro
        return value;
1084 40435 jjdelcerro
    }
1085
1086 44297 jjdelcerro
    @Override
1087 44669 jjdelcerro
    public BigDecimal getDecimal(String name) {
1088 46162 jjdelcerro
        BigDecimal value = ((BigDecimal) this.get(name, BigDecimal.class, DataTypes.DECIMAL));
1089
        return value;
1090 44669 jjdelcerro
    }
1091
1092
    @Override
1093
    public BigDecimal getDecimal(int index) {
1094 45581 fdiaz
        BigDecimal value = ((BigDecimal) this.get(index, BigDecimal.class, DataTypes.DECIMAL));
1095 44669 jjdelcerro
        return value;
1096
    }
1097
1098
    @Override
1099 40435 jjdelcerro
    public Feature getFeature(String name) {
1100
        return this.getFeature(this.data.getType().getIndex(name));
1101
    }
1102
1103 44297 jjdelcerro
    @Override
1104 40435 jjdelcerro
    public Feature getFeature(int index) {
1105
        return (Feature) this.get(index);
1106
    }
1107
1108 44297 jjdelcerro
    @Override
1109 40435 jjdelcerro
    public float getFloat(String name) {
1110 46162 jjdelcerro
        Float value = ((Float) this.get(name, Float.class, DataTypes.FLOAT));
1111
        if (value == null) {
1112
            return 0;
1113
        }
1114
        return value;
1115 40435 jjdelcerro
    }
1116
1117 44297 jjdelcerro
    @Override
1118 40435 jjdelcerro
    public float getFloat(int index) {
1119 45581 fdiaz
        Float value = ((Float) this.get(index, Float.class, DataTypes.FLOAT));
1120 40435 jjdelcerro
        if (value == null) {
1121
            return 0;
1122
        }
1123 44297 jjdelcerro
        return value;
1124 40435 jjdelcerro
    }
1125
1126 44297 jjdelcerro
    @Override
1127 40435 jjdelcerro
    public Geometry getGeometry(String name) {
1128 46162 jjdelcerro
        return (Geometry) this.get(name, Geometry.class, DataTypes.GEOMETRY);
1129 40435 jjdelcerro
    }
1130
1131 44297 jjdelcerro
    @Override
1132 40435 jjdelcerro
    public Geometry getGeometry(int index) {
1133 45581 fdiaz
        return (Geometry) this.get(index, Geometry.class, DataTypes.GEOMETRY);
1134 40435 jjdelcerro
    }
1135
1136 44297 jjdelcerro
    @Override
1137 40435 jjdelcerro
    public int getInt(String name) {
1138 46162 jjdelcerro
        Integer value = ((Integer) this.get(name, Integer.class, DataTypes.INT));
1139
        if (value == null) {
1140
            return 0;
1141
        }
1142
        return value;
1143 40435 jjdelcerro
    }
1144
1145 44297 jjdelcerro
    @Override
1146 40435 jjdelcerro
    public int getInt(int index) {
1147 45581 fdiaz
        Integer value = ((Integer) this.get(index, Integer.class, DataTypes.INT));
1148 40435 jjdelcerro
        if (value == null) {
1149
            return 0;
1150
        }
1151 44297 jjdelcerro
        return value;
1152 40435 jjdelcerro
    }
1153
1154 44297 jjdelcerro
    @Override
1155 40435 jjdelcerro
    public long getLong(String name) {
1156 46162 jjdelcerro
        Long value = ((Long) this.get(name, Long.class, DataTypes.LONG));
1157
        if (value == null) {
1158
            return 0;
1159
        }
1160
        return value;
1161 40435 jjdelcerro
    }
1162
1163 44297 jjdelcerro
    @Override
1164 40435 jjdelcerro
    public long getLong(int index) {
1165 45581 fdiaz
        Long value = ((Long) this.get(index, Long.class, DataTypes.LONG));
1166 40435 jjdelcerro
        if (value == null) {
1167
            return 0;
1168
        }
1169 44297 jjdelcerro
        return value;
1170 40435 jjdelcerro
    }
1171
1172 44297 jjdelcerro
    @Override
1173 40435 jjdelcerro
    public String getString(String name) {
1174 46162 jjdelcerro
        return (String) this.get(name, String.class, DataTypes.STRING);
1175 40435 jjdelcerro
    }
1176
1177 44297 jjdelcerro
    @Override
1178 40435 jjdelcerro
    public String getString(int index) {
1179 45581 fdiaz
        return (String) this.get(index, String.class, DataTypes.STRING);
1180 40435 jjdelcerro
    }
1181
1182 44297 jjdelcerro
    @Override
1183 40435 jjdelcerro
    public Object getContextValue(String name) {
1184
        name = name.toLowerCase();
1185
        if (name.equals("store")) {
1186
            return this.getStore();
1187
        }
1188
1189
        if (name.equals("featuretype")) {
1190
            return this.data.getType();
1191
        }
1192
1193
        if (name.equals("feature")) {
1194
            return this;
1195
        }
1196
1197
        throw new IllegalArgumentException(name);
1198
    }
1199
1200 44297 jjdelcerro
    @Override
1201 40435 jjdelcerro
    public Iterator getDataNames() {
1202
        class DataNamesIterator implements Iterator {
1203 45581 fdiaz
1204 40435 jjdelcerro
            Iterator attributeIteraror;
1205
1206
            DataNamesIterator(DefaultFeature feature) {
1207
                this.attributeIteraror = feature.getType().iterator();
1208
            }
1209
1210 44297 jjdelcerro
            @Override
1211 40435 jjdelcerro
            public boolean hasNext() {
1212
                return this.attributeIteraror.hasNext();
1213
            }
1214
1215 44297 jjdelcerro
            @Override
1216 40435 jjdelcerro
            public Object next() {
1217
                return ((FeatureAttributeDescriptor) this.attributeIteraror
1218
                        .next()).getName();
1219
            }
1220
1221 44297 jjdelcerro
            @Override
1222 40435 jjdelcerro
            public void remove() {
1223
                throw new UnsupportedOperationException();
1224
            }
1225
1226
        }
1227
        return new DataNamesIterator(this);
1228
    }
1229
1230 44297 jjdelcerro
    @Override
1231 40435 jjdelcerro
    public Object getDataValue(String name) {
1232
        name = name.toLowerCase();
1233 41542 jjdelcerro
        try {
1234
            return get(name);
1235
        } catch (IllegalArgumentException ex) {
1236 45581 fdiaz
            if ("defaultgeometry".equalsIgnoreCase(name)) {
1237 41542 jjdelcerro
                return this.getDefaultGeometry();
1238
            }
1239
            throw ex;
1240
        }
1241 40435 jjdelcerro
    }
1242
1243 44297 jjdelcerro
    @Override
1244 40435 jjdelcerro
    public Iterator getDataValues() {
1245
        class DataValuesIterator implements Iterator {
1246 45581 fdiaz
1247 40435 jjdelcerro
            DefaultFeature feature;
1248
            int current = 0;
1249
1250
            DataValuesIterator(DefaultFeature feature) {
1251
                this.feature = feature;
1252
            }
1253
1254 44297 jjdelcerro
            @Override
1255 40435 jjdelcerro
            public boolean hasNext() {
1256
                return current < feature.getType().size() - 1;
1257
            }
1258
1259 44297 jjdelcerro
            @Override
1260 40435 jjdelcerro
            public Object next() {
1261
                return feature.get(current++);
1262
            }
1263
1264 44297 jjdelcerro
            @Override
1265 40435 jjdelcerro
            public void remove() {
1266
                throw new UnsupportedOperationException();
1267
            }
1268
1269
        }
1270
        return new DataValuesIterator(this);
1271
    }
1272
1273 44297 jjdelcerro
    @Override
1274 40435 jjdelcerro
    public boolean hasContextValue(String name) {
1275
        name = name.toLowerCase();
1276
        if (name.equals("store")) {
1277
            return true;
1278
        }
1279
1280
        if (name.equals("featuretype")) {
1281
            return true;
1282
        }
1283
1284 44297 jjdelcerro
        return name.equals("feature");
1285 40435 jjdelcerro
    }
1286
1287 44297 jjdelcerro
    @Override
1288 40435 jjdelcerro
    public boolean hasDataValue(String name) {
1289 45218 omartinez
        return this.hasValue(name);
1290 40435 jjdelcerro
    }
1291 43729 fdiaz
1292 44767 jjdelcerro
//    @Override
1293
//    public Time getTime(int index) {
1294
//        return ((Time) this.get(index,Time.class,DataTypes.INSTANT));
1295
//    }
1296
//
1297
//    @Override
1298
//    public Time getTime(String name) {
1299
//        return this.getInstant(this.data.getType().getIndex(name));
1300
//    }
1301
//
1302
//    @Override
1303
//    public Instant getInstant(int index) {
1304
//        return ((Instant) this.get(index,Instant.class,DataTypes.INSTANT));
1305
//    }
1306
//
1307
//    @Override
1308
//    public Instant getInstant(String name) {
1309
//        return this.getInstant(this.data.getType().getIndex(name));
1310
//    }
1311
//
1312
//    @Override
1313
//    public Interval getInterval(int index) {
1314
//        return ((Interval) this.get(index,Interval.class,DataTypes.INTERVAL));
1315
//    }
1316
//
1317
//    @Override
1318
//    public Interval getInterval(String name) {
1319
//        return this.getInterval(this.data.getType().getIndex(name));
1320
//    }
1321
//
1322 44297 jjdelcerro
    @Override
1323 40435 jjdelcerro
    public DynObject getAsDynObject() {
1324 42775 jjdelcerro
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
1325 40435 jjdelcerro
        return facade;
1326
    }
1327
1328 44297 jjdelcerro
    @Override
1329 40435 jjdelcerro
    public String toString() {
1330 45581 fdiaz
        StringBuilder builder = new StringBuilder();
1331
        FeatureAttributeDescriptor[] attributeDescriptors
1332
                = getType().getAttributeDescriptors();
1333 40435 jjdelcerro
        for (int i = 0; i < attributeDescriptors.length; i++) {
1334
            String name = attributeDescriptors[i].getName();
1335 44607 jjdelcerro
            Object value = get(name);
1336
            builder.append(value);
1337 40435 jjdelcerro
            if (i < attributeDescriptors.length - 1) {
1338 44297 jjdelcerro
                builder.append(", ");
1339 40435 jjdelcerro
            }
1340
        }
1341 44297 jjdelcerro
        return builder.toString();
1342 40435 jjdelcerro
    }
1343 40867 jbadia
1344 45581 fdiaz
    /**
1345 45785 fdiaz
     * It is a new feature that has already been inserted into the store but has not yet been saved to disk
1346
     *
1347 40435 jjdelcerro
     * @return the inserted
1348
     */
1349
    public boolean isInserted() {
1350
        return inserted;
1351
    }
1352
1353
    /**
1354 45785 fdiaz
     * If true, marks the feature as already inserted in the vault but has not yet been saved to disk
1355
     *
1356 40435 jjdelcerro
     * @param inserted the inserted to set
1357
     */
1358
    public void setInserted(boolean inserted) {
1359
        this.inserted = inserted;
1360 45640 jjdelcerro
//        this.data.setNew(!inserted);
1361 40435 jjdelcerro
    }
1362
1363 45581 fdiaz
    @Override
1364 40435 jjdelcerro
    public EvaluatorData getEvaluatorData() {
1365
        return this;
1366
    }
1367 43983 jjdelcerro
1368 45013 jjdelcerro
    @Override
1369 43983 jjdelcerro
    public int size() {
1370
        return this.data.getType().size();
1371
    }
1372 45581 fdiaz
1373 43983 jjdelcerro
    public boolean isEmpty() {
1374
        return false;
1375
    }
1376
1377
    public Iterator<String> iterator() {
1378
        final Iterator<FeatureAttributeDescriptor> x = this.data.getType().iterator();
1379
        return new Iterator<String>() {
1380
            @Override
1381
            public boolean hasNext() {
1382
                return x.hasNext();
1383
            }
1384
1385
            @Override
1386
            public String next() {
1387
                return x.next().getName();
1388
            }
1389
        };
1390
    }
1391 45581 fdiaz
1392 43983 jjdelcerro
    public boolean containsKey(String key) {
1393 45581 fdiaz
        return this.data.getType().get(key) != null;
1394 43983 jjdelcerro
    }
1395 44346 jjdelcerro
1396
    @Override
1397
    public String getLabelOfValue(String name) {
1398
        FeatureAttributeDescriptor attrdesc = this.data.getType().getAttributeDescriptor(name);
1399 46050 omartinez
        Object value;
1400
        if (attrdesc == null) { // extra column
1401
            FeatureExtraColumns extraColumns = this.data.getType().getExtraColumns();
1402
            if (extraColumns==null) {
1403
                return name;
1404
            }
1405
            attrdesc = extraColumns.get(name);
1406
            if(attrdesc==null) {
1407
                return name;
1408
            }
1409
           value = this.get(name);
1410
        } else {
1411
           value = this.get(attrdesc.getIndex());
1412 44346 jjdelcerro
        }
1413
        String label = attrdesc.getLabelOfValue(value);
1414
        return label;
1415
    }
1416 45581 fdiaz
1417 44858 jjdelcerro
    @Override
1418
    public void setExtraValue(String name, Object value) {
1419 45581 fdiaz
        if (this.extraValues == null) {
1420
            this.extraValues = new HashMap<>();
1421
        }
1422
        this.extraValues.put(name, value);
1423 44858 jjdelcerro
    }
1424 45581 fdiaz
1425 45155 omartinez
    public Object getExtraColumnValue(String name) {
1426 44779 omartinez
        Object value;
1427 45993 omartinez
        FeatureExtraColumns columns = this.getType().getExtraColumns();
1428
        int index = columns.getIndexOf(name);
1429 45162 omartinez
        if (this.extraValues != null) {
1430
            if (this.extraValues.containsKey(name)) {
1431 45993 omartinez
                value = this.extraValues.get(name);
1432
                if (index >= 0){
1433
                    EditableFeatureAttributeDescriptor attrdesc = columns.get(index);
1434
                    value = coerce(attrdesc, value);
1435
                }
1436
                return value;
1437 45162 omartinez
            }
1438 44858 jjdelcerro
        }
1439 45162 omartinez
        if (index < 0) {
1440
            throw new RuntimeException("Not extra column value found");
1441
        }
1442
        if (extraValuesData == null) {
1443 44779 omartinez
            extraValuesData = new Object[columns.size()];
1444 45162 omartinez
        }
1445
        EditableFeatureAttributeDescriptor attrdesc = columns.get(index);
1446
        value = extraValuesData[index];
1447 45581 fdiaz
        if (value != null) {
1448 45162 omartinez
            return value;
1449
        }
1450
        value = this.getExtraValue(name);
1451 45993 omartinez
        if (value == null && !this.hasExtraValue(name) && attrdesc.getFeatureAttributeEmulator() != null) {
1452
            value = attrdesc.getFeatureAttributeEmulator().get(this);
1453
            value = coerce(attrdesc, value);
1454
            extraValuesData[index] = value;
1455
        } else {
1456
            value = coerce(attrdesc, value);
1457
            extraValuesData[index] = value;
1458 44778 omartinez
        }
1459 45993 omartinez
1460 45162 omartinez
        return value;
1461 45155 omartinez
    }
1462
1463
    @Override
1464
    public Object getExtraValue(String name) {
1465
        Object value = this.data.getExtraValue(name);
1466 44773 jjdelcerro
        return value;
1467 44376 jjdelcerro
    }
1468 45581 fdiaz
1469 44773 jjdelcerro
    @Override
1470 44738 jjdelcerro
    public boolean hasExtraValue(String name) {
1471 45155 omartinez
        return this.data.hasExtraValue(name);
1472
    }
1473
1474
    private boolean hasExtraColumnValue(String name) {
1475 45581 fdiaz
        if (this.extraValues != null) {
1476
            if (this.extraValues.containsKey(name)) {
1477
                return true;
1478
            }
1479 44858 jjdelcerro
        }
1480 44829 omartinez
        FeatureExtraColumns columns = this.getType().getExtraColumns();
1481 44779 omartinez
        int index = columns.getIndexOf(name);
1482 45581 fdiaz
        if (index >= 0) {
1483
            return true;
1484 44779 omartinez
        }
1485 45155 omartinez
        return false;
1486 44738 jjdelcerro
    }
1487 45581 fdiaz
1488 45968 jjdelcerro
    private EditableFeatureAttributeDescriptor getExtraColumn(String name) {
1489
        FeatureExtraColumns columns = this.getType().getExtraColumns();
1490
        return columns.get(name);
1491
    }
1492
1493 44376 jjdelcerro
    @Override
1494 45218 omartinez
    public boolean hasValue(String name) {
1495
        name = name.toLowerCase();
1496 45581 fdiaz
        return this.data.getType().getIndex(name) >= 0
1497
                || hasExtraValue(name)
1498
                || hasExtraColumnValue(name);
1499 45218 omartinez
    }
1500 45581 fdiaz
1501 45218 omartinez
    @Override
1502 44376 jjdelcerro
    public Object getExtraValue(int index) {
1503
        return this.data.getExtraValue(index);
1504
    }
1505
1506 45425 jjdelcerro
    @Override
1507
    public JsonObject toJson() {
1508
        JsonObjectBuilder builder = this.toJsonBuilder();
1509
        return builder.build();
1510
    }
1511 45581 fdiaz
1512 45425 jjdelcerro
    @Override
1513
    public JsonObjectBuilder toJsonBuilder() {
1514 44655 jjdelcerro
        JsonObjectBuilder builder = Json.createObjectBuilder();
1515 45425 jjdelcerro
        Date date;
1516
        Geometry geom;
1517 44655 jjdelcerro
        FeatureType ft = this.getType();
1518
        for (FeatureAttributeDescriptor desc : ft) {
1519
            if (desc.isComputed()) {
1520
                continue;
1521
            }
1522 45738 fdiaz
            if(this.isNull(desc.getName())){
1523
                builder.addNull(desc.getName());
1524
                continue;
1525
            }
1526 45581 fdiaz
            switch (desc.getType()) {
1527 44655 jjdelcerro
                case DataTypes.GEOMETRY:
1528 45425 jjdelcerro
                    geom = this.getGeometry(desc.getIndex());
1529 45581 fdiaz
                    if (geom != null) {
1530 45425 jjdelcerro
                        builder.add(desc.getName(), geom.convertToHexWKBQuietly());
1531 44655 jjdelcerro
                    }
1532
                    break;
1533
                case DataTypes.BOOLEAN:
1534
                    builder.add(desc.getName(), this.getBoolean(desc.getIndex()));
1535
                    break;
1536
                case DataTypes.BYTE:
1537
                    builder.add(desc.getName(), this.getByte(desc.getIndex()));
1538
                    break;
1539
                case DataTypes.INT:
1540
                    builder.add(desc.getName(), this.getInt(desc.getIndex()));
1541
                    break;
1542
                case DataTypes.LONG:
1543
                    builder.add(desc.getName(), this.getLong(desc.getIndex()));
1544
                    break;
1545
                case DataTypes.DOUBLE:
1546
                    builder.add(desc.getName(), this.getDouble(desc.getIndex()));
1547
                    break;
1548
                case DataTypes.FLOAT:
1549
                    builder.add(desc.getName(), this.getFloat(desc.getIndex()));
1550
                    break;
1551
                case DataTypes.DATE:
1552
                    // Format date as ISO 8601
1553 45425 jjdelcerro
                    date = this.getDate(desc.getIndex());
1554 45581 fdiaz
                    if (date == null) {
1555 45003 jjdelcerro
                        builder.addNull(desc.getName());
1556
                    } else {
1557 45023 fdiaz
                        LocalDateTime localDateTime = LocalDateTime.ofInstant(new Date(date.getTime()).toInstant(), ZoneId.systemDefault());
1558 45425 jjdelcerro
                        String value = DateTimeFormatter.ISO_DATE.format(localDateTime);
1559
                        builder.add(desc.getName(), value);
1560
                    }
1561
                    break;
1562
                case DataTypes.TIMESTAMP:
1563
                    // Format date as ISO 8601
1564
                    date = this.getTimestamp(desc.getIndex());
1565 45581 fdiaz
                    if (date == null) {
1566 45425 jjdelcerro
                        builder.addNull(desc.getName());
1567
                    } else {
1568
                        LocalDateTime localDateTime = LocalDateTime.ofInstant(new Date(date.getTime()).toInstant(), ZoneId.systemDefault());
1569 45023 fdiaz
                        String value = DateTimeFormatter.ISO_DATE_TIME.format(localDateTime);
1570 45003 jjdelcerro
                        builder.add(desc.getName(), value);
1571
                    }
1572 44655 jjdelcerro
                    break;
1573 45425 jjdelcerro
                case DataTypes.TIME:
1574
                    // Format date as ISO 8601
1575
                    date = this.getTime(desc.getIndex());
1576 45581 fdiaz
                    if (date == null) {
1577 45425 jjdelcerro
                        builder.addNull(desc.getName());
1578
                    } else {
1579
                        LocalDateTime localDateTime = LocalDateTime.ofInstant(new Date(date.getTime()).toInstant(), ZoneId.systemDefault());
1580
                        String value = DateTimeFormatter.ISO_TIME.format(localDateTime);
1581
                        builder.add(desc.getName(), value);
1582
                    }
1583
                    break;
1584 44655 jjdelcerro
                default:
1585 45581 fdiaz
                    builder.add(desc.getName(), this.getStringOrDefault(desc.getIndex(), ""));
1586 44655 jjdelcerro
            }
1587 45581 fdiaz
        }
1588 45425 jjdelcerro
        return builder;
1589 44655 jjdelcerro
    }
1590 44376 jjdelcerro
1591 44923 jjdelcerro
    @Override
1592
    public List<String> getKeys() {
1593 45581 fdiaz
        List<String> l = new ArrayList<>();
1594
        for (FeatureAttributeDescriptor descriptor : this.getType()) {
1595
            l.add(descriptor.getName());
1596
        }
1597
        return l;
1598 44923 jjdelcerro
    }
1599
1600 45968 jjdelcerro
    @Override
1601
    public String format(String name) {
1602
        int index = this.data.getType().getIndex(name);
1603
        if (index < 0) {
1604
            // buscamos en los extra cols
1605
            FeatureAttributeDescriptor attribute = this.getExtraColumn(name);
1606
            if( attribute!=null ) {
1607
                Object value = getExtraColumnValue(name);
1608
                return attribute.format(value);
1609
            }
1610
            throw new IllegalArgumentException("Attribute name '" + name + "' not found in the feature.");
1611
        }
1612
        return this.format(index);
1613
    }
1614
1615
    @Override
1616
    public String format(int index) {
1617
        Object value = this.get(index);
1618
        FeatureType type = this.data.getType();
1619
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
1620
        return attribute.format(value);
1621
    }
1622
1623
1624 40435 jjdelcerro
}