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

History | View | Annotate | Download (36.8 KB)

1
/**
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
package org.gvsig.fmap.dal.feature.impl;
25

    
26
import java.lang.ref.WeakReference;
27
import java.math.BigDecimal;
28
import java.time.format.DateTimeFormatter;
29
import java.util.ArrayList;
30
import java.util.Date;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.Map;
34
import java.util.Objects;
35
import javax.json.Json;
36
import javax.json.JsonObject;
37
import javax.json.JsonObjectBuilder;
38
import org.apache.commons.lang3.StringUtils;
39
import org.cresques.cts.IProjection;
40
import org.gvsig.fmap.dal.DALLocator;
41
import org.gvsig.fmap.dal.DataTypes;
42
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.feature.DataProfile;
45
import org.gvsig.fmap.dal.feature.EditableFeature;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
49
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
50
import org.gvsig.fmap.dal.feature.FeatureReference;
51
import org.gvsig.fmap.dal.feature.FeatureStore;
52
import org.gvsig.fmap.dal.feature.FeatureType;
53
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
54
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
55
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
56
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
57
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
58
import org.gvsig.fmap.geom.Geometry;
59
import org.gvsig.fmap.geom.primitive.Envelope;
60
import org.gvsig.timesupport.Instant;
61
import org.gvsig.timesupport.Interval;
62
import org.gvsig.timesupport.Time;
63
import org.gvsig.tools.ToolsLocator;
64
import org.gvsig.tools.dataTypes.CoercionException;
65
import org.gvsig.tools.dataTypes.DataTypesManager;
66
import org.gvsig.tools.dynobject.DynObject;
67
import org.gvsig.tools.evaluator.Evaluator;
68
import org.gvsig.tools.evaluator.EvaluatorData;
69
import org.gvsig.tools.evaluator.EvaluatorException;
70
import org.gvsig.tools.exception.BaseException;
71
import org.gvsig.tools.exception.BaseRuntimeException;
72
import org.gvsig.tools.lang.Cloneable;
73

    
74
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
75

    
76
        private static DataTypesManager dataTypesManager = null;
77
        protected FeatureProvider data;
78
        protected FeatureReference reference;
79
        private WeakReference storeRef;
80

    
81
        private boolean inserted = false;
82

    
83
    /*
84
         * Usar con mucha precaucion o mejor no usar. Lo precisa el
85
         * DefaultFeatureSet en la ordenacion.
86
         */
87
        public DefaultFeature(FeatureStore store) {
88
                this.storeRef = new WeakReference(store);
89
                this.reference = null;
90
        }
91

    
92
        public DefaultFeature(FeatureStore store, FeatureProvider data) {
93
                this.data = data;
94
                this.storeRef = new WeakReference(store);
95
                this.reference = null;
96
                this.inserted = !data.isNew();
97
        }
98

    
99
        DefaultFeature(DefaultFeature feature) {
100
                this.data = feature.data.getCopy();
101
                this.storeRef = feature.storeRef;
102
                this.reference = feature.reference;
103
                this.inserted = feature.isInserted();
104
        }
105

    
106
    public DefaultFeature(FeatureType targetType, Feature sourceFeature) {
107
        DefaultFeature defaultFeature = (DefaultFeature)sourceFeature;
108
        this.data = new DefaultFeatureProvider(targetType, (DefaultFeatureProvider)defaultFeature.getData());
109
        this.storeRef = defaultFeature.storeRef;
110
        this.reference = defaultFeature.reference;
111
        this.inserted = defaultFeature.isInserted();
112

    
113
        FeatureType sourceType = sourceFeature.getType();
114

    
115
        for (FeatureAttributeDescriptor targetAttrDescriptor : targetType) {
116
            if ( targetAttrDescriptor.isComputed() ) {
117
                 continue;
118
            }
119
            int sourceIndex = sourceType.getIndex(targetAttrDescriptor.getName());
120
            if (sourceIndex<0){
121
                continue;
122
            }
123
            Object value = sourceFeature.get(sourceIndex);
124
            if (value == null && !targetAttrDescriptor.allowNull()) {
125
                continue;
126
            }
127
            this.setforced(targetAttrDescriptor.getIndex(), targetAttrDescriptor,value);
128
        }
129
    }
130

    
131
        public void setData(FeatureProvider data) {
132
                this.data = data;
133
                this.reference = null;
134
                this.inserted = true;
135
        }
136

    
137
        public FeatureProvider getData() {
138
                return this.data;
139
        }
140

    
141
        protected DataTypesManager getDataTypesManager() {
142
                if( dataTypesManager==null ) {
143
                        dataTypesManager = ToolsLocator.getDataTypesManager();
144
                }
145
                return dataTypesManager;
146
        }
147

    
148
    protected void set(FeatureAttributeDescriptor attribute, Object value) {
149
        int i = attribute.getIndex();
150

    
151
        if ( attribute.isReadOnly() ) {
152
            throw new SetReadOnlyAttributeException(attribute.getName(), this.getType());
153
        }
154
        FeatureAttributeEmulator emulator = attribute.getFeatureAttributeEmulator();
155
        if( emulator!= null ) {
156
            emulator.set((EditableFeature) this,value);
157
            return;
158
        }
159

    
160
        if ( value == null ) {
161
            if ( !attribute.allowNull() ) {
162
                if ( !attribute.isAutomatic() ) {
163
                    throw new IllegalValueException(attribute, value);
164
                }
165
            }
166
            this.data.set(i, null);
167
            return;
168

    
169
        }
170

    
171
        if ( attribute.getFeatureAttributeGetter() != null ) {
172
            value = attribute.getFeatureAttributeGetter().setter(value);
173
        }
174
        this.setforced(i, attribute, value);
175
    }
176

    
177
    private void setforced(int i, FeatureAttributeDescriptor attribute, Object value) {
178

    
179
        Class objectClass = attribute.getObjectClass();
180
        if( objectClass!=null ) {
181
            if ( objectClass.isInstance(value) ) {
182
                this.data.set(i, value);
183
                return;
184
            } else {
185
                DataProfile dataProfile = attribute.getDataProfile();
186
                if( dataProfile!=null ) {
187
                    try {
188
                        value = dataProfile.coerce(
189
                                attribute.getDataType(),
190
                                value, 
191
                                attribute.getTags()
192
                        );
193
                    } catch (CoercionException e) {
194
                        
195
                    }
196
                } 
197
                try {
198
                    value= attribute.getDataType().coerce(value);
199
                } catch (CoercionException e) {
200
                    throw new IllegalArgumentException("Can't convert to "
201
                            + attribute.getDataType().getName()
202
                            + " from '"
203
                            + value.getClass().getName() + "' with value '"
204
                            + value.toString() + "'.");
205
                }
206
            }
207
        }
208
        this.data.set(i, value);
209
    }
210

    
211
    private Object get(int index,Class theClass, int type) {
212
        Object value = this.get(index);
213
        if( theClass.isInstance(value) ) {
214
            return value;
215
        }
216
        try {
217
            return this.getDataTypesManager().coerce(type, value);
218
        } catch (CoercionException e) {
219

    
220
            if (value == null) {
221
                return null;
222
            }
223
            throw new IllegalArgumentException(
224
                    "Can't convert to "+theClass.getName()+
225
                    " from '"+value.getClass().getName()+
226
                    "' with value '"+value.toString()+"'.");
227
        }
228
    }
229

    
230
    public void initializeValues() {
231
        FeatureType type = this.getType();
232
        for (FeatureAttributeDescriptor attribute : type) {
233
            if (attribute.isAutomatic() || attribute.isReadOnly()
234
                    || attribute.isComputed() ) {
235
                continue;
236
            }
237
            if (attribute.getDefaultValue() == null && !attribute.allowNull()) {
238
                continue;
239
            }
240
            this.set(attribute, attribute.getDefaultValue());
241
        }
242
    }
243

    
244
    public void clear() {
245
        initializeValues();
246
    }
247

    
248
    public void initializeValues(Feature feature) {
249
        FeatureType myType=this.getType();
250
        FeatureType type =feature.getType();
251
        for (FeatureAttributeDescriptor attribute : type) {
252
            FeatureAttributeDescriptor myAttribute=myType.getAttributeDescriptor(attribute.getName());
253
            if (myAttribute != null) {
254
                this.set(myAttribute, feature.get(attribute.getIndex()));
255
            }
256
        }
257
    }
258

    
259

    
260
    @Override
261
    public FeatureStore getStore() {
262
        return (FeatureStore) this.storeRef.get();
263
    }
264

    
265
    @Override
266
    public FeatureType getType() {
267
        return this.data.getType();
268
    }
269

    
270
    @Override
271
    public EditableFeature getEditable() {
272
        return new DefaultEditableFeature(this);
273
    }
274

    
275
    @Override
276
    public Feature getCopy() {
277
        return new DefaultFeature(this);
278
    }
279

    
280
    @Override
281
    @SuppressWarnings("CloneDoesntCallSuperClone")
282
    public Object clone() throws CloneNotSupportedException {
283
        return new DefaultFeature(this);
284
    }
285

    
286
    @Override
287
    public FeatureReference getReference() {
288
        if (this.reference == null) {
289
            if (!isInserted()) {
290
                return null;
291
            }
292
            reference = new DefaultFeatureReference(this);
293
        }
294
        return this.reference;
295
    }
296

    
297
    @Override
298
    public Object getOrDefault(String name, Object defaultValue) {
299
        int index = this.data.getType().getIndex(name);
300
        if( index < 0 ) {
301
            return defaultValue;
302
        }
303
        return this.get(index);
304
    }
305

    
306
    @Override
307
    public String getStringOrDefault(String name, String defaultValue) {
308
        int index = this.data.getType().getIndex(name);
309
        if( index < 0 ) {
310
            return defaultValue;
311
        }
312
        try {
313
            return (String) this.get(index);
314
        } catch(Throwable th) {
315
            return defaultValue;
316
        }
317
    }
318

    
319
    @Override
320
    public int getIntOrDefault(String name, int defaultValue) {
321
        int index = this.data.getType().getIndex(name);
322
        if( index < 0 ) {
323
            return defaultValue;
324
        }
325
        try {
326
            return (int) this.get(index);
327
        } catch(Throwable th) {
328
            return defaultValue;
329
        }
330
    }
331

    
332
    @Override
333
    public long getLongOrDefault(String name, long defaultValue) {
334
        int index = this.data.getType().getIndex(name);
335
        if( index < 0 ) {
336
            return defaultValue;
337
        }
338
        try {
339
            return (long) this.get(index);
340
        } catch(Throwable th) {
341
            return defaultValue;
342
        }
343
    }
344

    
345
    @Override
346
    public float getFloatOrDefault(String name, float defaultValue) {
347
        int index = this.data.getType().getIndex(name);
348
        if( index < 0 ) {
349
            return defaultValue;
350
        }
351
        try {
352
            return (float) this.get(index);
353
        } catch(Throwable th) {
354
            return defaultValue;
355
        }
356
    }
357

    
358
    @Override
359
    public double getDoubleOrDefault(String name, double defaultValue) {
360
        int index = this.data.getType().getIndex(name);
361
        if( index < 0 ) {
362
            return defaultValue;
363
        }
364
        try {
365
            return (double) this.get(index);
366
        } catch(Throwable th) {
367
            return defaultValue;
368
        }
369
    }
370

    
371
    @Override
372
    public BigDecimal getDecimalOrDefault(String name, BigDecimal defaultValue) {
373
        int index = this.data.getType().getIndex(name);
374
        if( index < 0 ) {
375
            return defaultValue;
376
        }
377
        try {
378
            return (BigDecimal) this.get(index);
379
        } catch(Throwable th) {
380
            return defaultValue;
381
        }
382
    }
383

    
384
    @Override
385
    public Date getDateOrDefault(String name, Date defaultValue) {
386
        int index = this.data.getType().getIndex(name);
387
        if( index < 0 ) {
388
            return defaultValue;
389
        }
390
        try {
391
            return (Date) this.get(index);
392
        } catch(Throwable th) {
393
            return defaultValue;
394
        }
395
    }
396

    
397
    @Override
398
    public Object getOrDefault(int index, Object defaultValue) {
399
        if( index < 0 || index >= this.data.getType().size() ) {
400
            return defaultValue;
401
        }
402
        try {
403
            return this.get(index);
404
        } catch(Throwable th) {
405
            return defaultValue;
406
        }
407
    }
408

    
409
    @Override
410
    public String getStringOrDefault(int index, String defaultValue) {
411
        if( index < 0 || index >= this.data.getType().size() ) {
412
            return defaultValue;
413
        }
414
        try {
415
            return (String) this.get(index);
416
        } catch(Throwable th) {
417
            return defaultValue;
418
        }
419
    }
420

    
421
    @Override
422
    public int getIntOrDefault(int index, int defaultValue) {
423
        if( index < 0 || index >= this.data.getType().size() ) {
424
            return defaultValue;
425
        }
426
        try {
427
            return (int) this.get(index);
428
        } catch(Throwable th) {
429
            return defaultValue;
430
        }
431
    }
432

    
433
    @Override
434
    public long getLongOrDefault(int index, long defaultValue) {
435
        if( index < 0 || index >= this.data.getType().size() ) {
436
            return defaultValue;
437
        }
438
        try {
439
            return (long) this.get(index);
440
        } catch(Throwable th) {
441
            return defaultValue;
442
        }
443
    }
444

    
445
    @Override
446
    public float getFloatOrDefault(int index, float defaultValue) {
447
        if( index < 0 || index >= this.data.getType().size() ) {
448
            return defaultValue;
449
        }
450
        try {
451
            return (float) this.get(index);
452
        } catch(Throwable th) {
453
            return defaultValue;
454
        }
455
    }
456

    
457
    @Override
458
    public double getDoubleOrDefault(int index, double defaultValue) {
459
        if( index < 0 || index >= this.data.getType().size() ) {
460
            return defaultValue;
461
        }
462
        try {
463
            return (double) this.get(index);
464
        } catch(Throwable th) {
465
            return defaultValue;
466
        }
467
    }
468

    
469
    @Override
470
    public BigDecimal getDecimalOrDefault(int index, BigDecimal defaultValue) {
471
        if( index < 0 || index >= this.data.getType().size() ) {
472
            return defaultValue;
473
        }
474
        try {
475
            return (BigDecimal) this.get(index);
476
        } catch(Throwable th) {
477
            return defaultValue;
478
        }
479
    }
480

    
481
    @Override
482
    public Date getDateOrDefault(int index, Date defaultValue) {
483
        if( index < 0 || index >= this.data.getType().size() ) {
484
            return defaultValue;
485
        }
486
        try {
487
            return (Date) this.get(index);
488
        } catch(Throwable th) {
489
            return defaultValue;
490
        }
491
    }
492

    
493
    class UnableToGetReferenceException extends BaseRuntimeException {
494

    
495
        /**
496
         *
497
         */
498
        private static final long serialVersionUID = 1812805035204824163L;
499

    
500
        /**
501
         * @param exception
502
         */
503
        public UnableToGetReferenceException(BaseException exception) {
504
            super("Unable to get reference", "_UnableToGetReferenceException",
505
                serialVersionUID);
506
            this.initCause(exception);
507

    
508
        }
509

    
510
    }
511

    
512
    @Override
513
    public void validate(int mode) throws DataException  {
514
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, mode);
515
    }
516

    
517
    @Override
518
    public List getSRSs() {
519
        // TODO Auto-generated method stub
520
        return null;
521
    }
522

    
523
    @Override
524
    public Envelope getDefaultEnvelope() {
525
        Envelope envelope = this.data.getDefaultEnvelope();
526
        if( envelope == null ) {
527
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
528
            if( i<0 ) {
529
                return null;
530
            }
531
            Geometry geom = this.getDefaultGeometry();
532
            if( geom!=null ) {
533
                envelope = geom.getEnvelope();
534
            }
535
        }
536
        return envelope;
537
    }
538

    
539
    @Override
540
    public Geometry getDefaultGeometry() {
541
            Geometry geom = this.data.getDefaultGeometry();
542
        if( geom == null ) {
543
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
544
            if( i<0 ) {
545
                return null;
546
            }
547
            Object x = this.get(i);
548
            if( x instanceof Geometry ) {
549
                geom = (Geometry) x;
550
            } else {
551
                geom = this.getGeometry(i);
552
            }
553
        }
554
        if( geom != null ) {
555
            if( geom.getProjection()==null ) {
556
                FeatureType type = this.getType();
557
                DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
558
                IProjection proj = attrdesc.getSRS(this.storeRef);
559
                geom.setProjection(proj);
560
            }
561
        }
562
        return geom;
563
    }
564

    
565
    @Override
566
    public Time getDefaultTime() {
567
            Time time = this.data.getDefaultTime();
568
        if( time == null ) {
569
            int i = this.data.getType().getDefaultTimeAttributeIndex();
570
            Object x = this.get(i);
571
            if( x instanceof Time ) {
572
                time = (Time) x;
573
            } else {
574
                time = this.getTime(i);
575
            }
576
        }
577
        return time;
578
    }
579

    
580
    @Override
581
    public IProjection getDefaultSRS() {
582
        IProjection srs = this.data.getType().getDefaultSRS();
583
        if( srs == null ) {
584
            FeatureType type = this.getType();
585
            DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
586
            srs = attrdesc.getSRS(this.storeRef);
587
        }
588
        return srs;
589
    }
590

    
591
    @Override
592
    public List getGeometries() {
593
        // TODO Auto-generated method stub
594
        return null;
595
    }
596

    
597
    @Override
598
    public Object getFromProfile(int index) {
599
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(index);
600
        Object value = this.get(index);
601
        String profileName = descriptor.getDataProfileName();
602
        if( StringUtils.isBlank(profileName) ) {
603
            return value;
604
        }
605
        DataProfile profile = DALLocator.getDataManager().getDataProfile(profileName);
606
        if( profile==null ) {
607
            return value;
608
        }
609
        return profile.createData(value, descriptor.getTags());
610
    }
611

    
612
    @Override
613
    public Object getFromProfile(String name) {
614
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(name);
615
        return this.getFromProfile(descriptor.getIndex());
616
    }
617

    
618
    @Override
619
    public Object get(String name) {
620
        int index = this.data.getType().getIndex(name);
621
        if( index < 0 ) {
622
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
623
        }
624
        return this.get(index);
625
    }
626
    
627
    @Override
628
    public boolean isNull(int index) {
629
        FeatureType type = this.data.getType();
630
        if( index <0 || index >= type.size() ) {
631
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
632
        }
633
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
634
        if (!this.data.getType().hasEvaluators()) {
635
            return this.data.get(index)==null;
636
        }
637
        Evaluator eval = attribute.getEvaluator();
638
        if (eval == null) {
639
            return this.data.get(index)==null;
640
        }
641
        Object value = this.data.get(index);
642
        if (value != null) {
643
            return true;
644
        }
645
        try {
646
            value = eval.evaluate(this);
647
        } catch (EvaluatorException e) {
648
            throw new DataEvaluatorRuntimeException(e);
649
        }
650
        this.data.set(index, value);
651
        return value==null;
652
    }
653
    
654
    @Override
655
    public boolean isNull(String name) {
656
        int index = this.data.getType().getIndex(name);
657
        if( index < 0 ) {
658
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
659
        }
660
        return this.isNull(index);
661
    }
662

    
663
    public boolean has_key(String key) {
664
        Object x = this.getType().get(key);
665
        return x != null;
666
    }
667

    
668
    public List<String> keys() {
669
        List<String> ks = new ArrayList<>();
670
        for( FeatureAttributeDescriptor attr : this.getType()) {
671
            ks.add(attr.getName());
672
        }
673
        return ks;
674
    }
675

    
676
    public Iterator<String> iterkeys() {
677
        final Iterator it = this.getType().iterator();
678
        return new Iterator<String>() {
679
            @Override
680
            public boolean hasNext() {
681
                return it.hasNext();
682
            }
683

    
684
            @Override
685
            public String next() {
686
                return ((FeatureAttributeDescriptor)it.next()).getName();
687
            }
688

    
689
            @Override
690
            public void remove() {
691
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
692
            }
693
        };
694
    }
695

    
696
    public Iterator iteritems() {
697
        final Iterator it = this.getType().iterator();
698
        return new Iterator<Map.Entry>() {
699
            @Override
700
            public boolean hasNext() {
701
                return it.hasNext();
702
            }
703

    
704
            @Override
705
            public Map.Entry next() {
706
                final String name = ((FeatureAttributeDescriptor)it.next()).getName();
707
                return new Map.Entry<String, Object>() {
708
                    @Override
709
                    public String getKey() {
710
                        return name;
711
                    }
712

    
713
                    @Override
714
                    public Object getValue() {
715
                        return get(name);
716
                    }
717

    
718
                    @Override
719
                    public Object setValue(Object value) {
720
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
721
                    }
722

    
723
                };
724
            }
725

    
726
            @Override
727
            public void remove() {
728
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
729
            }
730
        };
731
    }
732

    
733
    @Override
734
    public Object get(int index) {
735
        FeatureType type = this.data.getType();
736
        if( index <0 || index >= type.size() ) {
737
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
738
        }
739
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
740
        if (!this.data.getType().hasEvaluators()) {
741
            return get(attribute, this.data.get(index));
742
        }
743
        Evaluator eval = attribute.getEvaluator();
744
        if (eval == null) {
745
            return this.data.get(index);
746
        } else {
747
            Object value = this.data.get(index);
748
            if (value != null) { // FIXME: para comprobar si esta calculado usar
749
                // un array
750
                // especifico.
751
                return get(attribute, this.data.get(index));
752
            }
753
            try {
754
                value = eval.evaluate(this);
755
            } catch (EvaluatorException e) {
756
                throw new DataEvaluatorRuntimeException(e);
757
            }
758
            this.data.set(index, value);
759
            return  get(attribute, value);
760
        }
761
    }
762

    
763
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
764
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
765
        if( emulator != null ) {
766
//            int index = featureAttributeDescriptor.getIndex();
767
//            value = this.data.get(index);
768
//            if( value==null ) {
769
                value = emulator.get(this);
770
//                this.data.set(index,value);
771
//            }
772
        } else {
773
            FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
774
            if( getter != null ) {
775
                value = getter.getter(value);
776
            }
777
        }
778
        if( featureAttributeDescriptor.getType()==DataTypes.GEOMETRY ) {
779
            if( value != null ) {
780
                Geometry geom = (Geometry)value;
781
                if( geom.getProjection()==null ) {
782
                    IProjection proj = ((DefaultFeatureAttributeDescriptor)featureAttributeDescriptor).getSRS(this.storeRef);
783
                    geom.setProjection(proj);
784
                }
785
            }
786
        }
787
        return value;
788
    }
789

    
790
    @Override
791
    public byte[] getByteArray(String name) {
792
        return this.getByteArray(this.data.getType().getIndex(name));
793
    }
794

    
795
    @Override
796
    public byte[] getByteArray(int index) {
797
        return (byte[]) this.get(index);
798
    }
799

    
800
    @Override
801
    public Object[] getArray(String name) {
802
        return this.getArray(this.data.getType().getIndex(name));
803
    }
804

    
805
    @Override
806
    public Object[] getArray(int index) {
807
        return (Object[]) this.get(index);
808
    }
809

    
810
    @Override
811
    public boolean getBoolean(String name) {
812
        return this.getBoolean(this.data.getType().getIndex(name));
813
    }
814

    
815
    @Override
816
    public boolean getBoolean(int index) {
817
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
818
        if (value == null) {
819
            return false;
820
        }
821
        return value;
822
    }
823

    
824
    @Override
825
    public byte getByte(String name) {
826
        return this.getByte(this.data.getType().getIndex(name));
827
    }
828

    
829
    @Override
830
    public byte getByte(int index) {
831
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
832
        if (value == null) {
833
            return 0;
834
        }
835
        return value;
836
    }
837

    
838
    @Override
839
    public Date getDate(String name) {
840
        return this.getDate(this.data.getType().getIndex(name));
841
    }
842

    
843
    @Override
844
    public Date getDate(int index) {
845
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
846

    
847
        return value;
848
    }
849

    
850
    @Override
851
    public double getDouble(String name) {
852
        return this.getDouble(this.data.getType().getIndex(name));
853
    }
854

    
855
    @Override
856
    public double getDouble(int index) {
857

    
858
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
859
        if (value == null) {
860
            return 0;
861
        }
862
        return value;
863
    }
864

    
865
    @Override
866
    public BigDecimal getDecimal(String name) {
867
        return this.getDecimal(this.data.getType().getIndex(name));
868
    }
869

    
870
    @Override
871
    public BigDecimal getDecimal(int index) {
872

    
873
        BigDecimal value = ((BigDecimal) this.get(index,BigDecimal.class,DataTypes.DECIMAL));
874
        if (value == null) {
875
            return BigDecimal.ZERO;
876
        }
877
        return value;
878
    }
879

    
880
    @Override
881
    public Feature getFeature(String name) {
882
        return this.getFeature(this.data.getType().getIndex(name));
883
    }
884

    
885
    @Override
886
    public Feature getFeature(int index) {
887
        return (Feature) this.get(index);
888
    }
889

    
890
    @Override
891
    public float getFloat(String name) {
892
        return this.getFloat(this.data.getType().getIndex(name));
893
    }
894

    
895
    @Override
896
    public float getFloat(int index) {
897
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
898
        if (value == null) {
899
            return 0;
900
        }
901
        return value;
902
    }
903

    
904
    @Override
905
    public Geometry getGeometry(String name) {
906
        return this.getGeometry(this.data.getType().getIndex(name));
907
    }
908

    
909
    @Override
910
    public Geometry getGeometry(int index) {
911
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
912
    }
913

    
914
    @Override
915
    public int getInt(String name) {
916
        return this.getInt(this.data.getType().getIndex(name));
917
    }
918

    
919
    @Override
920
    public int getInt(int index) {
921
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
922
        if (value == null) {
923
            return 0;
924
        }
925
        return value;
926
    }
927

    
928
    @Override
929
    public long getLong(String name) {
930
        return this.getLong(this.data.getType().getIndex(name));
931
    }
932

    
933
    @Override
934
    public long getLong(int index) {
935
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
936
        if (value == null) {
937
            return 0;
938
        }
939
        return value;
940
    }
941

    
942
    @Override
943
    public String getString(String name) {
944
        return this.getString(this.data.getType().getIndex(name));
945
    }
946

    
947
    @Override
948
    public String getString(int index) {
949
        return (String) this.get(index,String.class,DataTypes.STRING);
950
    }
951

    
952
    @Override
953
    public Object getContextValue(String name) {
954
        name = name.toLowerCase();
955
        if (name.equals("store")) {
956
            return this.getStore();
957
        }
958

    
959
        if (name.equals("featuretype")) {
960
            return this.data.getType();
961
        }
962

    
963
        if (name.equals("feature")) {
964
            return this;
965
        }
966

    
967
        throw new IllegalArgumentException(name);
968
    }
969

    
970
    @Override
971
    public Iterator getDataNames() {
972
        class DataNamesIterator implements Iterator {
973
            Iterator attributeIteraror;
974

    
975
            DataNamesIterator(DefaultFeature feature) {
976
                this.attributeIteraror = feature.getType().iterator();
977
            }
978

    
979
            @Override
980
            public boolean hasNext() {
981
                return this.attributeIteraror.hasNext();
982
            }
983

    
984
            @Override
985
            public Object next() {
986
                return ((FeatureAttributeDescriptor) this.attributeIteraror
987
                        .next()).getName();
988
            }
989

    
990
            @Override
991
            public void remove() {
992
                throw new UnsupportedOperationException();
993
            }
994

    
995
        }
996
        return new DataNamesIterator(this);
997
    }
998

    
999
    @Override
1000
    public Object getDataValue(String name) {
1001
        name = name.toLowerCase();
1002
        try {
1003
            return get(name);
1004
        } catch (IllegalArgumentException ex) {
1005
            if( "defaultgeometry".equalsIgnoreCase(name )) {
1006
                return this.getDefaultGeometry();
1007
            }
1008
            throw ex;
1009
        }
1010
    }
1011

    
1012
    @Override
1013
    public Iterator getDataValues() {
1014
        class DataValuesIterator implements Iterator {
1015
            DefaultFeature feature;
1016
            int current = 0;
1017

    
1018
            DataValuesIterator(DefaultFeature feature) {
1019
                this.feature = feature;
1020
            }
1021

    
1022
            @Override
1023
            public boolean hasNext() {
1024
                return current < feature.getType().size() - 1;
1025
            }
1026

    
1027
            @Override
1028
            public Object next() {
1029
                return feature.get(current++);
1030
            }
1031

    
1032
            @Override
1033
            public void remove() {
1034
                throw new UnsupportedOperationException();
1035
            }
1036

    
1037
        }
1038
        return new DataValuesIterator(this);
1039
    }
1040

    
1041
    @Override
1042
    public boolean hasContextValue(String name) {
1043
        name = name.toLowerCase();
1044
        if (name.equals("store")) {
1045
            return true;
1046
        }
1047

    
1048
        if (name.equals("featuretype")) {
1049
            return true;
1050
        }
1051

    
1052
        return name.equals("feature");
1053
    }
1054

    
1055
    @Override
1056
    public boolean hasDataValue(String name) {
1057
        name = name.toLowerCase();
1058
        return this.data.getType().getIndex(name) >= 0;
1059
    }
1060

    
1061
    @Override
1062
    public Time getTime(int index) {
1063
        return ((Time) this.get(index,Time.class,DataTypes.INSTANT));
1064
    }
1065

    
1066
    @Override
1067
    public Time getTime(String name) {
1068
        return this.getInstant(this.data.getType().getIndex(name));
1069
    }
1070

    
1071
    @Override
1072
    public Instant getInstant(int index) {
1073
        return ((Instant) this.get(index,Instant.class,DataTypes.INSTANT));
1074
    }
1075

    
1076
    @Override
1077
    public Instant getInstant(String name) {
1078
        return this.getInstant(this.data.getType().getIndex(name));
1079
    }
1080

    
1081
    @Override
1082
    public Interval getInterval(int index) {
1083
        return ((Interval) this.get(index,Interval.class,DataTypes.INTERVAL));
1084
    }
1085

    
1086
    @Override
1087
    public Interval getInterval(String name) {
1088
        return this.getInterval(this.data.getType().getIndex(name));
1089
    }
1090

    
1091
    @Override
1092
    public DynObject getAsDynObject() {
1093
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
1094
        return facade;
1095
    }
1096

    
1097
    @Override
1098
    public String toString() {
1099
            StringBuilder builder = new StringBuilder();
1100
        FeatureAttributeDescriptor[] attributeDescriptors =
1101
            getType().getAttributeDescriptors();
1102
        for (int i = 0; i < attributeDescriptors.length; i++) {
1103
            String name = attributeDescriptors[i].getName();
1104
            Object value = get(name);
1105
            builder.append(value);
1106
            if (i < attributeDescriptors.length - 1) {
1107
                builder.append(", ");
1108
            }
1109
        }
1110
        return builder.toString();
1111
    }
1112

    
1113

    
1114

    
1115

    
1116
        /**
1117
     * @return the inserted
1118
     */
1119
    public boolean isInserted() {
1120
        return inserted;
1121
    }
1122

    
1123

    
1124
    /**
1125
     * @param inserted the inserted to set
1126
     */
1127
    public void setInserted(boolean inserted) {
1128
        this.inserted = inserted;
1129
    }
1130

    
1131
        @Override
1132
    public EvaluatorData getEvaluatorData() {
1133
        return this;
1134
    }
1135

    
1136
    public int size() {
1137
        return this.data.getType().size();
1138
    }
1139
    
1140
    public boolean isEmpty() {
1141
        return false;
1142
    }
1143

    
1144
    public Iterator<String> iterator() {
1145
        final Iterator<FeatureAttributeDescriptor> x = this.data.getType().iterator();
1146
        return new Iterator<String>() {
1147
            @Override
1148
            public boolean hasNext() {
1149
                return x.hasNext();
1150
            }
1151

    
1152
            @Override
1153
            public String next() {
1154
                return x.next().getName();
1155
            }
1156
        };
1157
    }
1158
    
1159
    public boolean containsKey(String key) {
1160
        return this.data.getType().get(key)!=null;
1161
    }
1162

    
1163
    @Override
1164
    public String getLabelOfValue(String name) {
1165
        FeatureAttributeDescriptor attrdesc = this.data.getType().getAttributeDescriptor(name);
1166
        if( attrdesc==null ) {
1167
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
1168
        }
1169
        Object value = this.get(attrdesc.getIndex());
1170
        String label = attrdesc.getLabelOfValue(value);
1171
        return label;
1172
    }
1173

    
1174
    @Override
1175
    public Object getExtraValue(String name) {
1176
        return this.data.getExtraValue(name);
1177
    }
1178

    
1179
    @Override
1180
    public Object getExtraValue(int index) {
1181
        return this.data.getExtraValue(index);
1182
    }
1183

    
1184
    public JsonObject toJSON() {
1185
        JsonObjectBuilder builder = Json.createObjectBuilder();
1186
        
1187
        FeatureType ft = this.getType();
1188
        for (FeatureAttributeDescriptor desc : ft) {
1189
            if (desc.isComputed()) {
1190
                continue;
1191
            }
1192
            switch(desc.getType()) {
1193
                case DataTypes.GEOMETRY:
1194
                    {
1195
                        try {
1196
                            builder.add(desc.getName(), this.getGeometry(desc.getIndex()).convertToWKT());
1197
                        } catch (Exception ex) {
1198
                            throw new RuntimeException("Can't convert geometry to WKT.", ex);
1199
                        }
1200
                    }
1201
                    break;
1202
                case DataTypes.BOOLEAN:
1203
                    builder.add(desc.getName(), this.getBoolean(desc.getIndex()));
1204
                    break;
1205
                case DataTypes.BYTE:
1206
                    builder.add(desc.getName(), this.getByte(desc.getIndex()));
1207
                    break;
1208
                case DataTypes.INT:
1209
                    builder.add(desc.getName(), this.getInt(desc.getIndex()));
1210
                    break;
1211
                case DataTypes.LONG:
1212
                    builder.add(desc.getName(), this.getLong(desc.getIndex()));
1213
                    break;
1214
                case DataTypes.DOUBLE:
1215
                    builder.add(desc.getName(), this.getDouble(desc.getIndex()));
1216
                    break;
1217
                case DataTypes.FLOAT:
1218
                    builder.add(desc.getName(), this.getFloat(desc.getIndex()));
1219
                    break;
1220
                case DataTypes.DATE:
1221
                    // Format date as ISO 8601
1222
                    Date date = this.getDate(desc.getIndex());
1223
                    String value = DateTimeFormatter.ISO_DATE_TIME.format(date.toInstant());
1224
                    builder.add(desc.getName(), value);
1225
                    break;
1226
                default:
1227
                    builder.add(desc.getName(), Objects.toString(this.get(desc.getIndex()),""));
1228
            }
1229
        }        
1230
        return builder.build();
1231
    }
1232

    
1233
}