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

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