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

History | View | Annotate | Download (34.4 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.time.format.DateTimeFormatter;
28
import java.util.ArrayList;
29
import java.util.Date;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Objects;
34
import javax.json.Json;
35
import javax.json.JsonObject;
36
import javax.json.JsonObjectBuilder;
37
import org.apache.commons.lang3.StringUtils;
38
import org.cresques.cts.IProjection;
39
import org.gvsig.fmap.dal.DALLocator;
40
import org.gvsig.fmap.dal.DataTypes;
41
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
42
import org.gvsig.fmap.dal.exception.DataException;
43
import org.gvsig.fmap.dal.feature.DataProfile;
44
import org.gvsig.fmap.dal.feature.EditableFeature;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
49
import org.gvsig.fmap.dal.feature.FeatureReference;
50
import org.gvsig.fmap.dal.feature.FeatureStore;
51
import org.gvsig.fmap.dal.feature.FeatureType;
52
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
53
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
54
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
55
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
56
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
57
import org.gvsig.fmap.geom.Geometry;
58
import org.gvsig.fmap.geom.primitive.Envelope;
59
import org.gvsig.timesupport.Instant;
60
import org.gvsig.timesupport.Interval;
61
import org.gvsig.timesupport.Time;
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
import org.gvsig.tools.lang.Cloneable;
72

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

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

    
80
        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
    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
            if ( targetAttrDescriptor.isComputed() ) {
116
                 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
            this.setforced(targetAttrDescriptor.getIndex(), targetAttrDescriptor,value);
127
        }
128
    }
129

    
130
        public void setData(FeatureProvider data) {
131
                this.data = data;
132
                this.reference = null;
133
                this.inserted = true;
134
        }
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
    protected void set(FeatureAttributeDescriptor attribute, Object value) {
148
        int i = attribute.getIndex();
149

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

    
159
        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

    
168
        }
169

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

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

    
178
        Class objectClass = attribute.getObjectClass();
179
        if( objectClass!=null ) {
180
            if ( objectClass.isInstance(value) ) {
181
                this.data.set(i, value);
182
                return;
183
            } 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
                try {
197
                    value= this.getDataTypesManager().coerce(attribute.getType(),value);
198
                } catch (CoercionException e) {
199
                    throw new IllegalArgumentException("Can't convert to "
200
                            + attribute.getDataType().getName()
201
                            + " from '"
202
                            + value.getClass().getName() + "' with value '"
203
                            + value.toString() + "'.");
204
                }
205
            }
206
        }
207
        this.data.set(i, value);
208
    }
209

    
210
    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

    
219
            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

    
229
    public void initializeValues() {
230
        FeatureType type = this.getType();
231
        for (FeatureAttributeDescriptor attribute : type) {
232
            if (attribute.isAutomatic() || attribute.isReadOnly()
233
                    || attribute.isComputed() ) {
234
                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
        for (FeatureAttributeDescriptor attribute : type) {
251
            FeatureAttributeDescriptor myAttribute=myType.getAttributeDescriptor(attribute.getName());
252
            if (myAttribute != null) {
253
                this.set(myAttribute, feature.get(attribute.getIndex()));
254
            }
255
        }
256
    }
257

    
258

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

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

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

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

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

    
285
    @Override
286
    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
    @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
    public Date getDateOrDefault(String name, Date defaultValue) {
372
        int index = this.data.getType().getIndex(name);
373
        if( index < 0 ) {
374
            return defaultValue;
375
        }
376
        try {
377
            return (Date) this.get(index);
378
        } catch(Throwable th) {
379
            return defaultValue;
380
        }
381
    }
382

    
383
    @Override
384
    public Object getOrDefault(int index, Object defaultValue) {
385
        if( index < 0 || index >= this.data.getType().size() ) {
386
            return defaultValue;
387
        }
388
        try {
389
            return this.get(index);
390
        } catch(Throwable th) {
391
            return defaultValue;
392
        }
393
    }
394

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

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

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

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

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

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

    
467
    class UnableToGetReferenceException extends BaseRuntimeException {
468

    
469
        /**
470
         *
471
         */
472
        private static final long serialVersionUID = 1812805035204824163L;
473

    
474
        /**
475
         * @param exception
476
         */
477
        public UnableToGetReferenceException(BaseException exception) {
478
            super("Unable to get reference", "_UnableToGetReferenceException",
479
                serialVersionUID);
480
            this.initCause(exception);
481

    
482
        }
483

    
484
    }
485

    
486
    @Override
487
    public void validate(int mode) throws DataException  {
488
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, mode);
489
    }
490

    
491
    @Override
492
    public List getSRSs() {
493
        // TODO Auto-generated method stub
494
        return null;
495
    }
496

    
497
    @Override
498
    public Envelope getDefaultEnvelope() {
499
        Envelope envelope = this.data.getDefaultEnvelope();
500
        if( envelope == null ) {
501
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
502
            if( i<0 ) {
503
                return null;
504
            }
505
            Geometry geom = this.getDefaultGeometry();
506
            if( geom!=null ) {
507
                envelope = geom.getEnvelope();
508
            }
509
        }
510
        return envelope;
511
    }
512

    
513
    @Override
514
    public Geometry getDefaultGeometry() {
515
            Geometry geom = this.data.getDefaultGeometry();
516
        if( geom == null ) {
517
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
518
            if( i<0 ) {
519
                return null;
520
            }
521
            Object x = this.get(i);
522
            if( x instanceof Geometry ) {
523
                geom = (Geometry) x;
524
            } else {
525
                geom = this.getGeometry(i);
526
            }
527
        }
528
        if( geom != null ) {
529
            if( geom.getProjection()==null ) {
530
                FeatureType type = this.getType();
531
                DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
532
                IProjection proj = attrdesc.getSRS(this.storeRef);
533
                geom.setProjection(proj);
534
            }
535
        }
536
        return geom;
537
    }
538

    
539
    @Override
540
    public Time getDefaultTime() {
541
            Time time = this.data.getDefaultTime();
542
        if( time == null ) {
543
            int i = this.data.getType().getDefaultTimeAttributeIndex();
544
            Object x = this.get(i);
545
            if( x instanceof Time ) {
546
                time = (Time) x;
547
            } else {
548
                time = this.getTime(i);
549
            }
550
        }
551
        return time;
552
    }
553

    
554
    @Override
555
    public IProjection getDefaultSRS() {
556
        IProjection srs = this.data.getType().getDefaultSRS();
557
        if( srs == null ) {
558
            FeatureType type = this.getType();
559
            DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
560
            srs = attrdesc.getSRS(this.storeRef);
561
        }
562
        return srs;
563
    }
564

    
565
    @Override
566
    public List getGeometries() {
567
        // TODO Auto-generated method stub
568
        return null;
569
    }
570

    
571
    @Override
572
    public Object getFromProfile(int index) {
573
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(index);
574
        Object value = this.get(index);
575
        String profileName = descriptor.getDataProfileName();
576
        if( StringUtils.isBlank(profileName) ) {
577
            return value;
578
        }
579
        DataProfile profile = DALLocator.getDataManager().getDataProfile(profileName);
580
        if( profile==null ) {
581
            return value;
582
        }
583
        return profile.createData(value, descriptor.getTags());
584
    }
585

    
586
    @Override
587
    public Object getFromProfile(String name) {
588
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(name);
589
        return this.getFromProfile(descriptor.getIndex());
590
    }
591

    
592
    @Override
593
    public Object get(String name) {
594
        int index = this.data.getType().getIndex(name);
595
        if( index < 0 ) {
596
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
597
        }
598
        return this.get(index);
599
    }
600

    
601
    public boolean has_key(String key) {
602
        Object x = this.getType().get(key);
603
        return x != null;
604
    }
605

    
606
    public List<String> keys() {
607
        List<String> ks = new ArrayList<>();
608
        for( FeatureAttributeDescriptor attr : this.getType()) {
609
            ks.add(attr.getName());
610
        }
611
        return ks;
612
    }
613

    
614
    public Iterator<String> iterkeys() {
615
        final Iterator it = this.getType().iterator();
616
        return new Iterator<String>() {
617
            @Override
618
            public boolean hasNext() {
619
                return it.hasNext();
620
            }
621

    
622
            @Override
623
            public String next() {
624
                return ((FeatureAttributeDescriptor)it.next()).getName();
625
            }
626

    
627
            @Override
628
            public void remove() {
629
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
630
            }
631
        };
632
    }
633

    
634
    public Iterator iteritems() {
635
        final Iterator it = this.getType().iterator();
636
        return new Iterator<Map.Entry>() {
637
            @Override
638
            public boolean hasNext() {
639
                return it.hasNext();
640
            }
641

    
642
            @Override
643
            public Map.Entry next() {
644
                final String name = ((FeatureAttributeDescriptor)it.next()).getName();
645
                return new Map.Entry<String, Object>() {
646
                    @Override
647
                    public String getKey() {
648
                        return name;
649
                    }
650

    
651
                    @Override
652
                    public Object getValue() {
653
                        return get(name);
654
                    }
655

    
656
                    @Override
657
                    public Object setValue(Object value) {
658
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
659
                    }
660

    
661
                };
662
            }
663

    
664
            @Override
665
            public void remove() {
666
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
667
            }
668
        };
669
    }
670

    
671
    @Override
672
    public Object get(int index) {
673
        FeatureType type = this.data.getType();
674
        if( index <0 || index >= type.size() ) {
675
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
676
        }
677
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
678
        if (!this.data.getType().hasEvaluators()) {
679
            return get(attribute, this.data.get(index));
680
        }
681
        Evaluator eval = attribute.getEvaluator();
682
        if (eval == null) {
683
            return this.data.get(index);
684
        } else {
685
            Object value = this.data.get(index);
686
            if (value != null) { // FIXME: para comprobar si esta calculado usar
687
                // un array
688
                // especifico.
689
                return get(attribute, this.data.get(index));
690
            }
691
            try {
692
                value = eval.evaluate(this);
693
            } catch (EvaluatorException e) {
694
                throw new DataEvaluatorRuntimeException(e);
695
            }
696
            this.data.set(index, value);
697
            return  get(attribute, value);
698
        }
699
    }
700

    
701
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
702
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
703
        if( emulator != null ) {
704
//            int index = featureAttributeDescriptor.getIndex();
705
//            value = this.data.get(index);
706
//            if( value==null ) {
707
                value = emulator.get(this);
708
//                this.data.set(index,value);
709
//            }
710
        } else {
711
            FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
712
            if( getter != null ) {
713
                value = getter.getter(value);
714
            }
715
        }
716
        if( featureAttributeDescriptor.getType()==DataTypes.GEOMETRY ) {
717
            if( value != null ) {
718
                Geometry geom = (Geometry)value;
719
                if( geom.getProjection()==null ) {
720
                    IProjection proj = ((DefaultFeatureAttributeDescriptor)featureAttributeDescriptor).getSRS(this.storeRef);
721
                    geom.setProjection(proj);
722
                }
723
            }
724
        }
725
        return value;
726
    }
727

    
728
    @Override
729
    public byte[] getByteArray(String name) {
730
        return this.getByteArray(this.data.getType().getIndex(name));
731
    }
732

    
733
    @Override
734
    public byte[] getByteArray(int index) {
735
        return (byte[]) this.get(index);
736
    }
737

    
738
    @Override
739
    public Object[] getArray(String name) {
740
        return this.getArray(this.data.getType().getIndex(name));
741
    }
742

    
743
    @Override
744
    public Object[] getArray(int index) {
745
        return (Object[]) this.get(index);
746
    }
747

    
748
    @Override
749
    public boolean getBoolean(String name) {
750
        return this.getBoolean(this.data.getType().getIndex(name));
751
    }
752

    
753
    @Override
754
    public boolean getBoolean(int index) {
755
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
756
        if (value == null) {
757
            return false;
758
        }
759
        return value;
760
    }
761

    
762
    @Override
763
    public byte getByte(String name) {
764
        return this.getByte(this.data.getType().getIndex(name));
765
    }
766

    
767
    @Override
768
    public byte getByte(int index) {
769
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
770
        if (value == null) {
771
            return 0;
772
        }
773
        return value;
774
    }
775

    
776
    @Override
777
    public Date getDate(String name) {
778
        return this.getDate(this.data.getType().getIndex(name));
779
    }
780

    
781
    @Override
782
    public Date getDate(int index) {
783
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
784

    
785
        return value;
786
    }
787

    
788
    @Override
789
    public double getDouble(String name) {
790
        return this.getDouble(this.data.getType().getIndex(name));
791
    }
792

    
793
    @Override
794
    public double getDouble(int index) {
795

    
796
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
797
        if (value == null) {
798
            return 0;
799
        }
800
        return value;
801
    }
802

    
803
    @Override
804
    public Feature getFeature(String name) {
805
        return this.getFeature(this.data.getType().getIndex(name));
806
    }
807

    
808
    @Override
809
    public Feature getFeature(int index) {
810
        return (Feature) this.get(index);
811
    }
812

    
813
    @Override
814
    public float getFloat(String name) {
815
        return this.getFloat(this.data.getType().getIndex(name));
816
    }
817

    
818
    @Override
819
    public float getFloat(int index) {
820
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
821
        if (value == null) {
822
            return 0;
823
        }
824
        return value;
825
    }
826

    
827
    @Override
828
    public Geometry getGeometry(String name) {
829
        return this.getGeometry(this.data.getType().getIndex(name));
830
    }
831

    
832
    @Override
833
    public Geometry getGeometry(int index) {
834
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
835
    }
836

    
837
    @Override
838
    public int getInt(String name) {
839
        return this.getInt(this.data.getType().getIndex(name));
840
    }
841

    
842
    @Override
843
    public int getInt(int index) {
844
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
845
        if (value == null) {
846
            return 0;
847
        }
848
        return value;
849
    }
850

    
851
    @Override
852
    public long getLong(String name) {
853
        return this.getLong(this.data.getType().getIndex(name));
854
    }
855

    
856
    @Override
857
    public long getLong(int index) {
858
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
859
        if (value == null) {
860
            return 0;
861
        }
862
        return value;
863
    }
864

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

    
870
    @Override
871
    public String getString(int index) {
872
        return (String) this.get(index,String.class,DataTypes.STRING);
873
    }
874

    
875
    @Override
876
    public Object getContextValue(String name) {
877
        name = name.toLowerCase();
878
        if (name.equals("store")) {
879
            return this.getStore();
880
        }
881

    
882
        if (name.equals("featuretype")) {
883
            return this.data.getType();
884
        }
885

    
886
        if (name.equals("feature")) {
887
            return this;
888
        }
889

    
890
        throw new IllegalArgumentException(name);
891
    }
892

    
893
    @Override
894
    public Iterator getDataNames() {
895
        class DataNamesIterator implements Iterator {
896
            Iterator attributeIteraror;
897

    
898
            DataNamesIterator(DefaultFeature feature) {
899
                this.attributeIteraror = feature.getType().iterator();
900
            }
901

    
902
            @Override
903
            public boolean hasNext() {
904
                return this.attributeIteraror.hasNext();
905
            }
906

    
907
            @Override
908
            public Object next() {
909
                return ((FeatureAttributeDescriptor) this.attributeIteraror
910
                        .next()).getName();
911
            }
912

    
913
            @Override
914
            public void remove() {
915
                throw new UnsupportedOperationException();
916
            }
917

    
918
        }
919
        return new DataNamesIterator(this);
920
    }
921

    
922
    @Override
923
    public Object getDataValue(String name) {
924
        name = name.toLowerCase();
925
        try {
926
            return get(name);
927
        } catch (IllegalArgumentException ex) {
928
            if( "defaultgeometry".equalsIgnoreCase(name )) {
929
                return this.getDefaultGeometry();
930
            }
931
            throw ex;
932
        }
933
    }
934

    
935
    @Override
936
    public Iterator getDataValues() {
937
        class DataValuesIterator implements Iterator {
938
            DefaultFeature feature;
939
            int current = 0;
940

    
941
            DataValuesIterator(DefaultFeature feature) {
942
                this.feature = feature;
943
            }
944

    
945
            @Override
946
            public boolean hasNext() {
947
                return current < feature.getType().size() - 1;
948
            }
949

    
950
            @Override
951
            public Object next() {
952
                return feature.get(current++);
953
            }
954

    
955
            @Override
956
            public void remove() {
957
                throw new UnsupportedOperationException();
958
            }
959

    
960
        }
961
        return new DataValuesIterator(this);
962
    }
963

    
964
    @Override
965
    public boolean hasContextValue(String name) {
966
        name = name.toLowerCase();
967
        if (name.equals("store")) {
968
            return true;
969
        }
970

    
971
        if (name.equals("featuretype")) {
972
            return true;
973
        }
974

    
975
        return name.equals("feature");
976
    }
977

    
978
    @Override
979
    public boolean hasDataValue(String name) {
980
        name = name.toLowerCase();
981
        return this.data.getType().getIndex(name) >= 0;
982
    }
983

    
984
    @Override
985
    public Time getTime(int index) {
986
        return ((Time) this.get(index,Time.class,DataTypes.INSTANT));
987
    }
988

    
989
    @Override
990
    public Time getTime(String name) {
991
        return this.getInstant(this.data.getType().getIndex(name));
992
    }
993

    
994
    @Override
995
    public Instant getInstant(int index) {
996
        return ((Instant) this.get(index,Instant.class,DataTypes.INSTANT));
997
    }
998

    
999
    @Override
1000
    public Instant getInstant(String name) {
1001
        return this.getInstant(this.data.getType().getIndex(name));
1002
    }
1003

    
1004
    @Override
1005
    public Interval getInterval(int index) {
1006
        return ((Interval) this.get(index,Interval.class,DataTypes.INTERVAL));
1007
    }
1008

    
1009
    @Override
1010
    public Interval getInterval(String name) {
1011
        return this.getInterval(this.data.getType().getIndex(name));
1012
    }
1013

    
1014
    @Override
1015
    public DynObject getAsDynObject() {
1016
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
1017
        return facade;
1018
    }
1019

    
1020
    @Override
1021
    public String toString() {
1022
            StringBuilder builder = new StringBuilder();
1023
        FeatureAttributeDescriptor[] attributeDescriptors =
1024
            getType().getAttributeDescriptors();
1025
        for (int i = 0; i < attributeDescriptors.length; i++) {
1026
            String name = attributeDescriptors[i].getName();
1027
            Object value = get(name);
1028
            builder.append(value);
1029
            if (i < attributeDescriptors.length - 1) {
1030
                builder.append(", ");
1031
            }
1032
        }
1033
        return builder.toString();
1034
    }
1035

    
1036

    
1037

    
1038

    
1039
        /**
1040
     * @return the inserted
1041
     */
1042
    public boolean isInserted() {
1043
        return inserted;
1044
    }
1045

    
1046

    
1047
    /**
1048
     * @param inserted the inserted to set
1049
     */
1050
    public void setInserted(boolean inserted) {
1051
        this.inserted = inserted;
1052
    }
1053

    
1054
        @Override
1055
    public EvaluatorData getEvaluatorData() {
1056
        return this;
1057
    }
1058

    
1059
    public int size() {
1060
        return this.data.getType().size();
1061
    }
1062
    
1063
    public boolean isEmpty() {
1064
        return false;
1065
    }
1066

    
1067
    public Iterator<String> iterator() {
1068
        final Iterator<FeatureAttributeDescriptor> x = this.data.getType().iterator();
1069
        return new Iterator<String>() {
1070
            @Override
1071
            public boolean hasNext() {
1072
                return x.hasNext();
1073
            }
1074

    
1075
            @Override
1076
            public String next() {
1077
                return x.next().getName();
1078
            }
1079
        };
1080
    }
1081
    
1082
    public boolean containsKey(String key) {
1083
        return this.data.getType().get(key)!=null;
1084
    }
1085

    
1086
    @Override
1087
    public String getLabelOfValue(String name) {
1088
        FeatureAttributeDescriptor attrdesc = this.data.getType().getAttributeDescriptor(name);
1089
        if( attrdesc==null ) {
1090
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
1091
        }
1092
        Object value = this.get(attrdesc.getIndex());
1093
        String label = attrdesc.getLabelOfValue(value);
1094
        return label;
1095
    }
1096

    
1097
    @Override
1098
    public Object getExtraValue(String name) {
1099
        return this.data.getExtraValue(name);
1100
    }
1101

    
1102
    @Override
1103
    public Object getExtraValue(int index) {
1104
        return this.data.getExtraValue(index);
1105
    }
1106

    
1107
    public JsonObject toJSON() {
1108
        JsonObjectBuilder builder = Json.createObjectBuilder();
1109
        
1110
        FeatureType ft = this.getType();
1111
        for (FeatureAttributeDescriptor desc : ft) {
1112
            if (desc.isComputed()) {
1113
                continue;
1114
            }
1115
            switch(desc.getType()) {
1116
                case DataTypes.GEOMETRY:
1117
                    {
1118
                        try {
1119
                            builder.add(desc.getName(), this.getGeometry(desc.getIndex()).convertToWKT());
1120
                        } catch (Exception ex) {
1121
                            throw new RuntimeException("Can't convert geometry to WKT.", ex);
1122
                        }
1123
                    }
1124
                    break;
1125
                case DataTypes.BOOLEAN:
1126
                    builder.add(desc.getName(), this.getBoolean(desc.getIndex()));
1127
                    break;
1128
                case DataTypes.BYTE:
1129
                    builder.add(desc.getName(), this.getByte(desc.getIndex()));
1130
                    break;
1131
                case DataTypes.INT:
1132
                    builder.add(desc.getName(), this.getInt(desc.getIndex()));
1133
                    break;
1134
                case DataTypes.LONG:
1135
                    builder.add(desc.getName(), this.getLong(desc.getIndex()));
1136
                    break;
1137
                case DataTypes.DOUBLE:
1138
                    builder.add(desc.getName(), this.getDouble(desc.getIndex()));
1139
                    break;
1140
                case DataTypes.FLOAT:
1141
                    builder.add(desc.getName(), this.getFloat(desc.getIndex()));
1142
                    break;
1143
                case DataTypes.DATE:
1144
                    // Format date as ISO 8601
1145
                    Date date = this.getDate(desc.getIndex());
1146
                    String value = DateTimeFormatter.ISO_DATE_TIME.format(date.toInstant());
1147
                    builder.add(desc.getName(), value);
1148
                    break;
1149
                default:
1150
                    builder.add(desc.getName(), Objects.toString(this.get(desc.getIndex()),""));
1151
            }
1152
        }        
1153
        return builder.build();
1154
    }
1155

    
1156
}