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

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