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

History | View | Annotate | Download (38.9 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.ArrayUtils;
39
import org.apache.commons.lang3.StringUtils;
40
import org.cresques.cts.IProjection;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.feature.DataProfile;
46
import org.gvsig.fmap.dal.feature.EditableFeature;
47
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.Feature;
49
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
51
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
52
import org.gvsig.fmap.dal.feature.FeatureExtraColumn;
53
import org.gvsig.fmap.dal.feature.FeatureReference;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
57
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
58
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
59
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
60
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
61
import org.gvsig.fmap.geom.Geometry;
62
import org.gvsig.fmap.geom.primitive.Envelope;
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
        private Object[] extraValuesData;
83

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

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

    
101
        DefaultFeature(DefaultFeature feature) {
102
                this.data = feature.data.getCopy();
103
                this.extraValuesData = ArrayUtils.clone(feature.extraValuesData);
104
                this.storeRef = feature.storeRef;
105
                this.reference = feature.reference;
106
                this.inserted = feature.isInserted();
107
        }
108

    
109
    public DefaultFeature(FeatureType targetType, Feature sourceFeature) {
110
        DefaultFeature defaultFeature = (DefaultFeature)sourceFeature;
111
        this.data = new DefaultFeatureProvider(targetType, (DefaultFeatureProvider)defaultFeature.getData());
112
        this.extraValuesData = null;
113
        this.storeRef = defaultFeature.storeRef;
114
        this.reference = defaultFeature.reference;
115
        this.inserted = defaultFeature.isInserted();
116

    
117
        FeatureType sourceType = sourceFeature.getType();
118

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

    
135
        public void setData(FeatureProvider data) {
136
                this.data = data;
137
                this.extraValuesData = null;
138
                this.reference = null;
139
                this.inserted = true;
140
        }
141

    
142
        public FeatureProvider getData() {
143
                return this.data;
144
        }
145

    
146
        protected DataTypesManager getDataTypesManager() {
147
                if( dataTypesManager==null ) {
148
                        dataTypesManager = ToolsLocator.getDataTypesManager();
149
                }
150
                return dataTypesManager;
151
        }
152

    
153
    protected void set(FeatureAttributeDescriptor attribute, Object value) {
154
        int i = attribute.getIndex();
155

    
156
        if ( attribute.isReadOnly() ) {
157
            throw new SetReadOnlyAttributeException(attribute.getName(), this.getType());
158
        }
159
        FeatureAttributeEmulator emulator = attribute.getFeatureAttributeEmulator();
160
        if( emulator!= null ) {
161
            emulator.set((EditableFeature) this,value);
162
            return;
163
        }
164

    
165
        if ( value == null ) {
166
            if ( !attribute.allowNull() ) {
167
                if ( !attribute.isAutomatic() ) {
168
                    throw new IllegalValueException(attribute, value);
169
                }
170
            }
171
            this.data.set(i, null);
172
            return;
173

    
174
        }
175

    
176
        if ( attribute.getFeatureAttributeGetter() != null ) {
177
            value = attribute.getFeatureAttributeGetter().setter(value);
178
        }
179
        this.setforced(i, attribute, value);
180
    }
181

    
182
    private void setforced(int i, FeatureAttributeDescriptor attribute, Object value) {
183

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

    
216
    private Object get(int index,Class theClass, int type) {
217
        Object value = this.get(index);
218
        if( theClass.isInstance(value) ) {
219
            return value;
220
        }
221
        try {
222
            return this.getDataTypesManager().coerce(type, value);
223
        } catch (CoercionException e) {
224

    
225
            if (value == null) {
226
                return null;
227
            }
228
            throw new IllegalArgumentException(
229
                    "Can't convert to "+theClass.getName()+
230
                    " from '"+value.getClass().getName()+
231
                    "' with value '"+value.toString()+"'.");
232
        }
233
    }
234

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

    
249
    public void clear() {
250
        initializeValues();
251
    }
252

    
253
    public void initializeValues(Feature feature) {
254
        FeatureType myType=this.getType();
255
        FeatureType type =feature.getType();
256
        extraValuesData = null;
257
        for (FeatureAttributeDescriptor attribute : type) {
258
            FeatureAttributeDescriptor myAttribute=myType.getAttributeDescriptor(attribute.getName());
259
            if (myAttribute != null) {
260
                this.set(myAttribute, feature.get(attribute.getIndex()));
261
            }
262
        }
263
    }
264

    
265

    
266
    @Override
267
    public FeatureStore getStore() {
268
        return (FeatureStore) this.storeRef.get();
269
    }
270

    
271
    @Override
272
    public FeatureType getType() {
273
        return this.data.getType();
274
    }
275

    
276
    @Override
277
    public EditableFeature getEditable() {
278
        return new DefaultEditableFeature(this);
279
    }
280

    
281
    @Override
282
    public Feature getCopy() {
283
        return new DefaultFeature(this);
284
    }
285

    
286
    @Override
287
    @SuppressWarnings("CloneDoesntCallSuperClone")
288
    public Object clone() throws CloneNotSupportedException {
289
        return new DefaultFeature(this);
290
    }
291

    
292
    @Override
293
    public FeatureReference getReference() {
294
        if (this.reference == null) {
295
            if (!isInserted()) {
296
                return null;
297
            }
298
            reference = new DefaultFeatureReference(this);
299
        }
300
        return this.reference;
301
    }
302

    
303
    @Override
304
    public Object getOrDefault(String name, Object defaultValue) {
305
        int index = this.data.getType().getIndex(name);
306
        if( index < 0 ) {
307
            return defaultValue;
308
        }
309
        return this.get(index);
310
    }
311

    
312
    @Override
313
    public String getStringOrDefault(String name, String defaultValue) {
314
        int index = this.data.getType().getIndex(name);
315
        if( index < 0 ) {
316
            return defaultValue;
317
        }
318
        try {
319
            return (String) this.get(index);
320
        } catch(Throwable th) {
321
            return defaultValue;
322
        }
323
    }
324

    
325
    @Override
326
    public int getIntOrDefault(String name, int defaultValue) {
327
        int index = this.data.getType().getIndex(name);
328
        if( index < 0 ) {
329
            return defaultValue;
330
        }
331
        try {
332
            return (int) this.get(index);
333
        } catch(Throwable th) {
334
            return defaultValue;
335
        }
336
    }
337

    
338
    @Override
339
    public long getLongOrDefault(String name, long defaultValue) {
340
        int index = this.data.getType().getIndex(name);
341
        if( index < 0 ) {
342
            return defaultValue;
343
        }
344
        try {
345
            return (long) this.get(index);
346
        } catch(Throwable th) {
347
            return defaultValue;
348
        }
349
    }
350

    
351
    @Override
352
    public float getFloatOrDefault(String name, float defaultValue) {
353
        int index = this.data.getType().getIndex(name);
354
        if( index < 0 ) {
355
            return defaultValue;
356
        }
357
        try {
358
            return (float) this.get(index);
359
        } catch(Throwable th) {
360
            return defaultValue;
361
        }
362
    }
363

    
364
    @Override
365
    public double getDoubleOrDefault(String name, double defaultValue) {
366
        int index = this.data.getType().getIndex(name);
367
        if( index < 0 ) {
368
            return defaultValue;
369
        }
370
        try {
371
            return (double) this.get(index);
372
        } catch(Throwable th) {
373
            return defaultValue;
374
        }
375
    }
376

    
377
    @Override
378
    public BigDecimal getDecimalOrDefault(String name, BigDecimal defaultValue) {
379
        int index = this.data.getType().getIndex(name);
380
        if( index < 0 ) {
381
            return defaultValue;
382
        }
383
        try {
384
            return (BigDecimal) this.get(index);
385
        } catch(Throwable th) {
386
            return defaultValue;
387
        }
388
    }
389

    
390
    @Override
391
    public Date getDateOrDefault(String name, Date defaultValue) {
392
        int index = this.data.getType().getIndex(name);
393
        if( index < 0 ) {
394
            return defaultValue;
395
        }
396
        try {
397
            return (Date) this.get(index);
398
        } catch(Throwable th) {
399
            return defaultValue;
400
        }
401
    }
402

    
403
    @Override
404
    public Object getOrDefault(int index, Object defaultValue) {
405
        if( index < 0 || index >= this.data.getType().size() ) {
406
            return defaultValue;
407
        }
408
        try {
409
            return this.get(index);
410
        } catch(Throwable th) {
411
            return defaultValue;
412
        }
413
    }
414

    
415
    @Override
416
    public String getStringOrDefault(int index, String defaultValue) {
417
        if( index < 0 || index >= this.data.getType().size() ) {
418
            return defaultValue;
419
        }
420
        try {
421
            return (String) this.get(index);
422
        } catch(Throwable th) {
423
            return defaultValue;
424
        }
425
    }
426

    
427
    @Override
428
    public int getIntOrDefault(int index, int defaultValue) {
429
        if( index < 0 || index >= this.data.getType().size() ) {
430
            return defaultValue;
431
        }
432
        try {
433
            return (int) this.get(index);
434
        } catch(Throwable th) {
435
            return defaultValue;
436
        }
437
    }
438

    
439
    @Override
440
    public long getLongOrDefault(int index, long defaultValue) {
441
        if( index < 0 || index >= this.data.getType().size() ) {
442
            return defaultValue;
443
        }
444
        try {
445
            return (long) this.get(index);
446
        } catch(Throwable th) {
447
            return defaultValue;
448
        }
449
    }
450

    
451
    @Override
452
    public float getFloatOrDefault(int index, float defaultValue) {
453
        if( index < 0 || index >= this.data.getType().size() ) {
454
            return defaultValue;
455
        }
456
        try {
457
            return (float) this.get(index);
458
        } catch(Throwable th) {
459
            return defaultValue;
460
        }
461
    }
462

    
463
    @Override
464
    public double getDoubleOrDefault(int index, double defaultValue) {
465
        if( index < 0 || index >= this.data.getType().size() ) {
466
            return defaultValue;
467
        }
468
        try {
469
            return (double) this.get(index);
470
        } catch(Throwable th) {
471
            return defaultValue;
472
        }
473
    }
474

    
475
    @Override
476
    public BigDecimal getDecimalOrDefault(int index, BigDecimal defaultValue) {
477
        if( index < 0 || index >= this.data.getType().size() ) {
478
            return defaultValue;
479
        }
480
        try {
481
            return (BigDecimal) this.get(index);
482
        } catch(Throwable th) {
483
            return defaultValue;
484
        }
485
    }
486

    
487
    @Override
488
    public Date getDateOrDefault(int index, Date defaultValue) {
489
        if( index < 0 || index >= this.data.getType().size() ) {
490
            return defaultValue;
491
        }
492
        try {
493
            return (Date) this.get(index);
494
        } catch(Throwable th) {
495
            return defaultValue;
496
        }
497
    }
498

    
499
    class UnableToGetReferenceException extends BaseRuntimeException {
500

    
501
        /**
502
         *
503
         */
504
        private static final long serialVersionUID = 1812805035204824163L;
505

    
506
        /**
507
         * @param exception
508
         */
509
        public UnableToGetReferenceException(BaseException exception) {
510
            super("Unable to get reference", "_UnableToGetReferenceException",
511
                serialVersionUID);
512
            this.initCause(exception);
513

    
514
        }
515

    
516
    }
517

    
518
    @Override
519
    public void validate(int mode) throws DataException  {
520
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, mode);
521
    }
522

    
523
    @Override
524
    public List getSRSs() {
525
        // TODO Auto-generated method stub
526
        return null;
527
    }
528

    
529
    @Override
530
    public Envelope getDefaultEnvelope() {
531
        Envelope envelope = this.data.getDefaultEnvelope();
532
        if( envelope == null ) {
533
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
534
            if( i<0 ) {
535
                return null;
536
            }
537
            Geometry geom = this.getDefaultGeometry();
538
            if( geom!=null ) {
539
                envelope = geom.getEnvelope();
540
            }
541
        }
542
        return envelope;
543
    }
544

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

    
571
//    @Override
572
//    public Time getDefaultTime() {
573
//            Time time = this.data.getDefaultTime();
574
//        if( time == null ) {
575
//            int i = this.data.getType().getDefaultTimeAttributeIndex();
576
//            Object x = this.get(i);
577
//            if( x instanceof Time ) {
578
//                time = (Time) x;
579
//            } else {
580
//                time = this.getTime(i);
581
//            }
582
//        }
583
//        return time;
584
//    }
585
//
586
    @Override
587
    public IProjection getDefaultSRS() {
588
        IProjection srs = this.data.getType().getDefaultSRS();
589
        if( srs == null ) {
590
            FeatureType type = this.getType();
591
            DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
592
            srs = attrdesc.getSRS(this.storeRef);
593
        }
594
        return srs;
595
    }
596

    
597
    @Override
598
    public List getGeometries() {
599
        // TODO Auto-generated method stub
600
        return null;
601
    }
602

    
603
    @Override
604
    public Object getFromProfile(int index) {
605
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(index);
606
        Object value = this.get(index);
607
        String profileName = descriptor.getDataProfileName();
608
        if( StringUtils.isBlank(profileName) ) {
609
            return value;
610
        }
611
        DataProfile profile = DALLocator.getDataManager().getDataProfile(profileName);
612
        if( profile==null ) {
613
            return value;
614
        }
615
        return profile.createData(value, descriptor.getTags());
616
    }
617

    
618
    @Override
619
    public Object getFromProfile(String name) {
620
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(name);
621
        return this.getFromProfile(descriptor.getIndex());
622
    }
623

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

    
669
    public boolean has_key(String key) {
670
        Object x = this.getType().get(key);
671
        return x != null;
672
    }
673

    
674
    public List<String> keys() {
675
        List<String> ks = new ArrayList<>();
676
        for( FeatureAttributeDescriptor attr : this.getType()) {
677
            ks.add(attr.getName());
678
        }
679
        return ks;
680
    }
681

    
682
    public Iterator<String> iterkeys() {
683
        final Iterator it = this.getType().iterator();
684
        return new Iterator<String>() {
685
            @Override
686
            public boolean hasNext() {
687
                return it.hasNext();
688
            }
689

    
690
            @Override
691
            public String next() {
692
                return ((FeatureAttributeDescriptor)it.next()).getName();
693
            }
694

    
695
            @Override
696
            public void remove() {
697
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
698
            }
699
        };
700
    }
701

    
702
    public Iterator iteritems() {
703
        final Iterator it = this.getType().iterator();
704
        return new Iterator<Map.Entry>() {
705
            @Override
706
            public boolean hasNext() {
707
                return it.hasNext();
708
            }
709

    
710
            @Override
711
            public Map.Entry next() {
712
                final String name = ((FeatureAttributeDescriptor)it.next()).getName();
713
                return new Map.Entry<String, Object>() {
714
                    @Override
715
                    public String getKey() {
716
                        return name;
717
                    }
718

    
719
                    @Override
720
                    public Object getValue() {
721
                        return get(name);
722
                    }
723

    
724
                    @Override
725
                    public Object setValue(Object value) {
726
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
727
                    }
728

    
729
                };
730
            }
731

    
732
            @Override
733
            public void remove() {
734
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
735
            }
736
        };
737
    }
738

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

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

    
796
    @Override
797
    public byte[] getByteArray(String name) {
798
        return this.getByteArray(this.data.getType().getIndex(name));
799
    }
800

    
801
    @Override
802
    public byte[] getByteArray(int index) {
803
        return (byte[]) this.get(index);
804
    }
805

    
806
    @Override
807
    public Object[] getArray(String name) {
808
        return this.getArray(this.data.getType().getIndex(name));
809
    }
810

    
811
    @Override
812
    public Object[] getArray(int index) {
813
        return (Object[]) this.get(index);
814
    }
815

    
816
    @Override
817
    public boolean getBoolean(String name) {
818
        return this.getBoolean(this.data.getType().getIndex(name));
819
    }
820

    
821
    @Override
822
    public boolean getBoolean(int index) {
823
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
824
        if (value == null) {
825
            return false;
826
        }
827
        return value;
828
    }
829

    
830
    @Override
831
    public byte getByte(String name) {
832
        return this.getByte(this.data.getType().getIndex(name));
833
    }
834

    
835
    @Override
836
    public byte getByte(int index) {
837
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
838
        if (value == null) {
839
            return 0;
840
        }
841
        return value;
842
    }
843

    
844
    @Override
845
    public Date getDate(String name) {
846
        return this.getDate(this.data.getType().getIndex(name));
847
    }
848

    
849
    @Override
850
    public Date getDate(int index) {
851
        Date value = ((Date) this.get(index,java.sql.Date.class,DataTypes.DATE));
852
        return value;
853
    }
854

    
855
    @Override
856
    public Date getTime(String name) {
857
        return this.getTime(this.data.getType().getIndex(name));
858
    }
859

    
860
    @Override
861
    public Date getTime(int index) {
862
        Date value = ((Date) this.get(index,java.sql.Time.class,DataTypes.TIME));
863
        return value;
864
    }
865

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

    
871
    @Override
872
    public Date getTimestamp(int index) {
873
        Date value = ((Date) this.get(index,java.sql.Timestamp.class,DataTypes.TIMESTAMP));
874
        return value;
875
    }
876

    
877
    @Override
878
    public double getDouble(String name) {
879
        return this.getDouble(this.data.getType().getIndex(name));
880
    }
881

    
882
    @Override
883
    public double getDouble(int index) {
884

    
885
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
886
        if (value == null) {
887
            return 0;
888
        }
889
        return value;
890
    }
891

    
892
    @Override
893
    public BigDecimal getDecimal(String name) {
894
        return this.getDecimal(this.data.getType().getIndex(name));
895
    }
896

    
897
    @Override
898
    public BigDecimal getDecimal(int index) {
899

    
900
        BigDecimal value = ((BigDecimal) this.get(index,BigDecimal.class,DataTypes.DECIMAL));
901
        if (value == null) {
902
            return BigDecimal.ZERO;
903
        }
904
        return value;
905
    }
906

    
907
    @Override
908
    public Feature getFeature(String name) {
909
        return this.getFeature(this.data.getType().getIndex(name));
910
    }
911

    
912
    @Override
913
    public Feature getFeature(int index) {
914
        return (Feature) this.get(index);
915
    }
916

    
917
    @Override
918
    public float getFloat(String name) {
919
        return this.getFloat(this.data.getType().getIndex(name));
920
    }
921

    
922
    @Override
923
    public float getFloat(int index) {
924
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
925
        if (value == null) {
926
            return 0;
927
        }
928
        return value;
929
    }
930

    
931
    @Override
932
    public Geometry getGeometry(String name) {
933
        return this.getGeometry(this.data.getType().getIndex(name));
934
    }
935

    
936
    @Override
937
    public Geometry getGeometry(int index) {
938
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
939
    }
940

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

    
946
    @Override
947
    public int getInt(int index) {
948
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
949
        if (value == null) {
950
            return 0;
951
        }
952
        return value;
953
    }
954

    
955
    @Override
956
    public long getLong(String name) {
957
        return this.getLong(this.data.getType().getIndex(name));
958
    }
959

    
960
    @Override
961
    public long getLong(int index) {
962
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
963
        if (value == null) {
964
            return 0;
965
        }
966
        return value;
967
    }
968

    
969
    @Override
970
    public String getString(String name) {
971
        return this.getString(this.data.getType().getIndex(name));
972
    }
973

    
974
    @Override
975
    public String getString(int index) {
976
        return (String) this.get(index,String.class,DataTypes.STRING);
977
    }
978

    
979
    @Override
980
    public Object getContextValue(String name) {
981
        name = name.toLowerCase();
982
        if (name.equals("store")) {
983
            return this.getStore();
984
        }
985

    
986
        if (name.equals("featuretype")) {
987
            return this.data.getType();
988
        }
989

    
990
        if (name.equals("feature")) {
991
            return this;
992
        }
993

    
994
        throw new IllegalArgumentException(name);
995
    }
996

    
997
    @Override
998
    public Iterator getDataNames() {
999
        class DataNamesIterator implements Iterator {
1000
            Iterator attributeIteraror;
1001

    
1002
            DataNamesIterator(DefaultFeature feature) {
1003
                this.attributeIteraror = feature.getType().iterator();
1004
            }
1005

    
1006
            @Override
1007
            public boolean hasNext() {
1008
                return this.attributeIteraror.hasNext();
1009
            }
1010

    
1011
            @Override
1012
            public Object next() {
1013
                return ((FeatureAttributeDescriptor) this.attributeIteraror
1014
                        .next()).getName();
1015
            }
1016

    
1017
            @Override
1018
            public void remove() {
1019
                throw new UnsupportedOperationException();
1020
            }
1021

    
1022
        }
1023
        return new DataNamesIterator(this);
1024
    }
1025

    
1026
    @Override
1027
    public Object getDataValue(String name) {
1028
        name = name.toLowerCase();
1029
        try {
1030
            return get(name);
1031
        } catch (IllegalArgumentException ex) {
1032
            if( "defaultgeometry".equalsIgnoreCase(name )) {
1033
                return this.getDefaultGeometry();
1034
            }
1035
            throw ex;
1036
        }
1037
    }
1038

    
1039
    @Override
1040
    public Iterator getDataValues() {
1041
        class DataValuesIterator implements Iterator {
1042
            DefaultFeature feature;
1043
            int current = 0;
1044

    
1045
            DataValuesIterator(DefaultFeature feature) {
1046
                this.feature = feature;
1047
            }
1048

    
1049
            @Override
1050
            public boolean hasNext() {
1051
                return current < feature.getType().size() - 1;
1052
            }
1053

    
1054
            @Override
1055
            public Object next() {
1056
                return feature.get(current++);
1057
            }
1058

    
1059
            @Override
1060
            public void remove() {
1061
                throw new UnsupportedOperationException();
1062
            }
1063

    
1064
        }
1065
        return new DataValuesIterator(this);
1066
    }
1067

    
1068
    @Override
1069
    public boolean hasContextValue(String name) {
1070
        name = name.toLowerCase();
1071
        if (name.equals("store")) {
1072
            return true;
1073
        }
1074

    
1075
        if (name.equals("featuretype")) {
1076
            return true;
1077
        }
1078

    
1079
        return name.equals("feature");
1080
    }
1081

    
1082
    @Override
1083
    public boolean hasDataValue(String name) {
1084
        name = name.toLowerCase();
1085
        return this.data.getType().getIndex(name) >= 0;
1086
    }
1087

    
1088
//    @Override
1089
//    public Time getTime(int index) {
1090
//        return ((Time) this.get(index,Time.class,DataTypes.INSTANT));
1091
//    }
1092
//
1093
//    @Override
1094
//    public Time getTime(String name) {
1095
//        return this.getInstant(this.data.getType().getIndex(name));
1096
//    }
1097
//
1098
//    @Override
1099
//    public Instant getInstant(int index) {
1100
//        return ((Instant) this.get(index,Instant.class,DataTypes.INSTANT));
1101
//    }
1102
//
1103
//    @Override
1104
//    public Instant getInstant(String name) {
1105
//        return this.getInstant(this.data.getType().getIndex(name));
1106
//    }
1107
//
1108
//    @Override
1109
//    public Interval getInterval(int index) {
1110
//        return ((Interval) this.get(index,Interval.class,DataTypes.INTERVAL));
1111
//    }
1112
//
1113
//    @Override
1114
//    public Interval getInterval(String name) {
1115
//        return this.getInterval(this.data.getType().getIndex(name));
1116
//    }
1117
//
1118
    @Override
1119
    public DynObject getAsDynObject() {
1120
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
1121
        return facade;
1122
    }
1123

    
1124
    @Override
1125
    public String toString() {
1126
            StringBuilder builder = new StringBuilder();
1127
        FeatureAttributeDescriptor[] attributeDescriptors =
1128
            getType().getAttributeDescriptors();
1129
        for (int i = 0; i < attributeDescriptors.length; i++) {
1130
            String name = attributeDescriptors[i].getName();
1131
            Object value = get(name);
1132
            builder.append(value);
1133
            if (i < attributeDescriptors.length - 1) {
1134
                builder.append(", ");
1135
            }
1136
        }
1137
        return builder.toString();
1138
    }
1139

    
1140

    
1141

    
1142

    
1143
        /**
1144
     * @return the inserted
1145
     */
1146
    public boolean isInserted() {
1147
        return inserted;
1148
    }
1149

    
1150

    
1151
    /**
1152
     * @param inserted the inserted to set
1153
     */
1154
    public void setInserted(boolean inserted) {
1155
        this.inserted = inserted;
1156
    }
1157

    
1158
        @Override
1159
    public EvaluatorData getEvaluatorData() {
1160
        return this;
1161
    }
1162

    
1163
    public int size() {
1164
        return this.data.getType().size();
1165
    }
1166
    
1167
    public boolean isEmpty() {
1168
        return false;
1169
    }
1170

    
1171
    public Iterator<String> iterator() {
1172
        final Iterator<FeatureAttributeDescriptor> x = this.data.getType().iterator();
1173
        return new Iterator<String>() {
1174
            @Override
1175
            public boolean hasNext() {
1176
                return x.hasNext();
1177
            }
1178

    
1179
            @Override
1180
            public String next() {
1181
                return x.next().getName();
1182
            }
1183
        };
1184
    }
1185
    
1186
    public boolean containsKey(String key) {
1187
        return this.data.getType().get(key)!=null;
1188
    }
1189

    
1190
    @Override
1191
    public String getLabelOfValue(String name) {
1192
        FeatureAttributeDescriptor attrdesc = this.data.getType().getAttributeDescriptor(name);
1193
        if( attrdesc==null ) {
1194
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
1195
        }
1196
        Object value = this.get(attrdesc.getIndex());
1197
        String label = attrdesc.getLabelOfValue(value);
1198
        return label;
1199
    }
1200

    
1201
    
1202
      @Override
1203
    public Object getExtraValue(String name) {
1204
        Object value;
1205
        FeatureExtraColumn columns = this.getType().getExtraColumn();
1206
        int index = columns.getIndexOf(name);
1207
        if( index >= 0 ) {
1208
          if( extraValuesData==null ) {
1209
            extraValuesData = new Object[columns.size()];
1210
            EditableFeatureAttributeDescriptor attrdesc = columns.get(index);
1211
            value = attrdesc.getFeatureAttributeEmulator().get(this);
1212
            extraValuesData[index] = value;
1213
          } else {
1214
            value = extraValuesData[index];
1215
            if( value == null ) {
1216
              EditableFeatureAttributeDescriptor attrdesc = columns.get(index);
1217
              value = attrdesc.getFeatureAttributeEmulator().get(this);
1218
              extraValuesData[index] = value;
1219
            }
1220
          }
1221
          return value;
1222
        }
1223
        value = this.data.getExtraValue(name);
1224
        return value;
1225
    }
1226

    
1227
    @Override
1228
    public boolean hasExtraValue(String name) {
1229
        FeatureExtraColumn columns = this.getType().getExtraColumn();
1230
        int index = columns.getIndexOf(name);
1231
        if( index >= 0 ) {
1232
          return true;
1233
        }
1234
        return this.data.hasExtraValue(name);
1235
    }
1236
    
1237
    @Override
1238
    public Object getExtraValue(int index) {
1239
        return this.data.getExtraValue(index);
1240
    }
1241

    
1242
    public JsonObject toJSON() {
1243
        JsonObjectBuilder builder = Json.createObjectBuilder();
1244
        
1245
        FeatureType ft = this.getType();
1246
        for (FeatureAttributeDescriptor desc : ft) {
1247
            if (desc.isComputed()) {
1248
                continue;
1249
            }
1250
            switch(desc.getType()) {
1251
                case DataTypes.GEOMETRY:
1252
                    {
1253
                        try {
1254
                            builder.add(desc.getName(), this.getGeometry(desc.getIndex()).convertToWKT());
1255
                        } catch (Exception ex) {
1256
                            throw new RuntimeException("Can't convert geometry to WKT.", ex);
1257
                        }
1258
                    }
1259
                    break;
1260
                case DataTypes.BOOLEAN:
1261
                    builder.add(desc.getName(), this.getBoolean(desc.getIndex()));
1262
                    break;
1263
                case DataTypes.BYTE:
1264
                    builder.add(desc.getName(), this.getByte(desc.getIndex()));
1265
                    break;
1266
                case DataTypes.INT:
1267
                    builder.add(desc.getName(), this.getInt(desc.getIndex()));
1268
                    break;
1269
                case DataTypes.LONG:
1270
                    builder.add(desc.getName(), this.getLong(desc.getIndex()));
1271
                    break;
1272
                case DataTypes.DOUBLE:
1273
                    builder.add(desc.getName(), this.getDouble(desc.getIndex()));
1274
                    break;
1275
                case DataTypes.FLOAT:
1276
                    builder.add(desc.getName(), this.getFloat(desc.getIndex()));
1277
                    break;
1278
                case DataTypes.DATE:
1279
                    // Format date as ISO 8601
1280
                    Date date = this.getDate(desc.getIndex());
1281
                    String value = DateTimeFormatter.ISO_DATE_TIME.format(date.toInstant());
1282
                    builder.add(desc.getName(), value);
1283
                    break;
1284
                default:
1285
                    builder.add(desc.getName(), Objects.toString(this.get(desc.getIndex()),""));
1286
            }
1287
        }        
1288
        return builder.build();
1289
    }
1290

    
1291
}