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

History | View | Annotate | Download (26.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.util.ArrayList;
28
import java.util.Date;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Map;
32
import org.apache.commons.lang3.StringUtils;
33
import org.cresques.cts.IProjection;
34
import org.gvsig.fmap.dal.DALLocator;
35
import org.gvsig.fmap.dal.DataTypes;
36
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.feature.DataProfile;
39
import org.gvsig.fmap.dal.feature.EditableFeature;
40
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
44
import org.gvsig.fmap.dal.feature.FeatureReference;
45
import org.gvsig.fmap.dal.feature.FeatureStore;
46
import org.gvsig.fmap.dal.feature.FeatureType;
47
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
48
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
49
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
50
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
51
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
52
import org.gvsig.fmap.geom.Geometry;
53
import org.gvsig.fmap.geom.primitive.Envelope;
54
import org.gvsig.timesupport.Instant;
55
import org.gvsig.timesupport.Interval;
56
import org.gvsig.timesupport.Time;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dataTypes.CoercionException;
59
import org.gvsig.tools.dataTypes.DataTypesManager;
60
import org.gvsig.tools.dynobject.DynObject;
61
import org.gvsig.tools.evaluator.Evaluator;
62
import org.gvsig.tools.evaluator.EvaluatorData;
63
import org.gvsig.tools.evaluator.EvaluatorException;
64
import org.gvsig.tools.exception.BaseException;
65
import org.gvsig.tools.exception.BaseRuntimeException;
66
import org.gvsig.tools.lang.Cloneable;
67

    
68
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
69

    
70
        private static DataTypesManager dataTypesManager = null;
71
        protected FeatureProvider data;
72
        protected FeatureReference reference;
73
        private WeakReference storeRef;
74

    
75
        private boolean inserted = false;
76

    
77
    /*
78
         * Usar con mucha precaucion o mejor no usar. Lo precisa el
79
         * DefaultFeatureSet en la ordenacion.
80
         */
81
        public DefaultFeature(FeatureStore store) {
82
                this.storeRef = new WeakReference(store);
83
                this.reference = null;
84
        }
85

    
86
        public DefaultFeature(FeatureStore store, FeatureProvider data) {
87
                this.data = data;
88
                this.storeRef = new WeakReference(store);
89
                this.reference = null;
90
                this.inserted = !data.isNew();
91
        }
92

    
93
        DefaultFeature(DefaultFeature feature) {
94
                this.data = feature.data.getCopy();
95
                this.storeRef = feature.storeRef;
96
                this.reference = feature.reference;
97
                this.inserted = feature.isInserted();
98
        }
99

    
100
    public DefaultFeature(FeatureType targetType, Feature sourceFeature) {
101
        DefaultFeature defaultFeature = (DefaultFeature)sourceFeature;
102
        this.data = new DefaultFeatureProvider(targetType, (DefaultFeatureProvider)defaultFeature.getData());
103
        this.storeRef = defaultFeature.storeRef;
104
        this.reference = defaultFeature.reference;
105
        this.inserted = defaultFeature.isInserted();
106

    
107
        FeatureType sourceType = sourceFeature.getType();
108

    
109
        for (FeatureAttributeDescriptor targetAttrDescriptor : targetType) {
110
            if ( targetAttrDescriptor.isAutomatic() ||
111
                 targetAttrDescriptor.isReadOnly() ||
112
                 targetAttrDescriptor.getEvaluator() != null) {
113
                 continue;
114
            }
115
            int sourceIndex = sourceType.getIndex(targetAttrDescriptor.getName());
116
            if (sourceIndex<0){
117
                continue;
118
            }
119
            Object value = sourceFeature.get(sourceIndex);
120
            if (value == null && !targetAttrDescriptor.allowNull()) {
121
                continue;
122
            }
123
            this.set(targetAttrDescriptor,value);
124
        }
125
    }
126

    
127
        public void setData(FeatureProvider data) {
128
                this.data = data;
129
                this.reference = null;
130
                this.inserted = true;
131
        }
132

    
133
        public FeatureProvider getData() {
134
                return this.data;
135
        }
136

    
137
        protected DataTypesManager getDataTypesManager() {
138
                if( dataTypesManager==null ) {
139
                        dataTypesManager = ToolsLocator.getDataTypesManager();
140
                }
141
                return dataTypesManager;
142
        }
143

    
144
    void set(FeatureAttributeDescriptor attribute, Object value) {
145
        int i = attribute.getIndex();
146

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

    
156
        if ( value == null ) {
157
            if ( !attribute.allowNull() ) {
158
                if ( !attribute.isAutomatic() ) {
159
                    throw new IllegalValueException(attribute, value);
160
                }
161
            }
162
            this.data.set(i, null);
163
            return;
164

    
165
        }
166

    
167
        if ( attribute.getFeatureAttributeGetter() != null ) {
168
            value = attribute.getFeatureAttributeGetter().setter(value);
169
        }
170

    
171
        Class objectClass = attribute.getObjectClass();
172
        if( objectClass!=null ) {
173
            if ( objectClass.isInstance(value) ) {
174
                this.data.set(i, value);
175
                return;
176
            }
177

    
178
            if ( !objectClass.isInstance(value) ) {
179
                try {
180
                    value
181
                            = this.getDataTypesManager().coerce(attribute.getType(),
182
                                    value);
183
                } catch (CoercionException e) {
184
                    throw new IllegalArgumentException("Can't convert to "
185
                            + this.getDataTypesManager().getTypeName(
186
                                    attribute.getType()) + " from '"
187
                            + value.getClass().getName() + "' with value '"
188
                            + value.toString() + "'.");
189
                }
190
            }
191
        }
192
        this.data.set(i, value);
193
    }
194

    
195
    private Object get(int index,Class theClass, int type) {
196
        Object value = this.get(index);
197
        if( theClass.isInstance(value) ) {
198
            return value;
199
        }
200
        try {
201
            return this.getDataTypesManager().coerce(type, value);
202
        } catch (CoercionException e) {
203

    
204
            if (value == null) {
205
                return null;
206
            }
207
            throw new IllegalArgumentException(
208
                    "Can't convert to "+theClass.getName()+
209
                    " from '"+value.getClass().getName()+
210
                    "' with value '"+value.toString()+"'.");
211
        }
212
    }
213

    
214
    public void initializeValues() {
215
        FeatureType type = this.getType();
216
        for (FeatureAttributeDescriptor attribute : type) {
217
            if (attribute.isAutomatic() || attribute.isReadOnly()
218
                    || attribute.isComputed() ) {
219
                continue;
220
            }
221
            if (attribute.getDefaultValue() == null && !attribute.allowNull()) {
222
                continue;
223
            }
224
            this.set(attribute, attribute.getDefaultValue());
225
        }
226
    }
227

    
228
    public void clear() {
229
        initializeValues();
230
    }
231

    
232
    public void initializeValues(Feature feature) {
233
        FeatureType myType=this.getType();
234
        FeatureType type =feature.getType();
235
        for (FeatureAttributeDescriptor attribute : type) {
236
            FeatureAttributeDescriptor myAttribute=myType.getAttributeDescriptor(attribute.getName());
237
            if (myAttribute != null) {
238
                this.set(myAttribute, feature.get(attribute.getIndex()));
239
            }
240
        }
241
    }
242

    
243

    
244
    @Override
245
    public FeatureStore getStore() {
246
        return (FeatureStore) this.storeRef.get();
247
    }
248

    
249
    @Override
250
    public FeatureType getType() {
251
        return this.data.getType();
252
    }
253

    
254
    @Override
255
    public EditableFeature getEditable() {
256
        return new DefaultEditableFeature(this);
257
    }
258

    
259
    @Override
260
    public Feature getCopy() {
261
        return new DefaultFeature(this);
262
    }
263

    
264
    @Override
265
    @SuppressWarnings("CloneDoesntCallSuperClone")
266
    public Object clone() throws CloneNotSupportedException {
267
        return new DefaultFeature(this);
268
    }
269

    
270
    @Override
271
    public FeatureReference getReference() {
272
        if (this.reference == null) {
273
            if (!isInserted()) {
274
                return null;
275
            }
276
            reference = new DefaultFeatureReference(this);
277
        }
278
        return this.reference;
279
    }
280

    
281
    class UnableToGetReferenceException extends BaseRuntimeException {
282

    
283
        /**
284
         *
285
         */
286
        private static final long serialVersionUID = 1812805035204824163L;
287

    
288
        /**
289
         * @param exception
290
         */
291
        public UnableToGetReferenceException(BaseException exception) {
292
            super("Unable to get reference", "_UnableToGetReferenceException",
293
                serialVersionUID);
294
            this.initCause(exception);
295

    
296
        }
297

    
298
    }
299

    
300
    @Override
301
    public void validate(int mode) throws DataException  {
302
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, mode);
303
    }
304

    
305
    @Override
306
    public List getSRSs() {
307
        // TODO Auto-generated method stub
308
        return null;
309
    }
310

    
311
    @Override
312
    public Envelope getDefaultEnvelope() {
313
        Envelope envelope = this.data.getDefaultEnvelope();
314
        if( envelope == null ) {
315
            Geometry geom = this.getDefaultGeometry();
316
            if( geom!=null ) {
317
                envelope = geom.getEnvelope();
318
            }
319
        }
320
        return envelope;
321
    }
322

    
323
    @Override
324
    public Geometry getDefaultGeometry() {
325
            Geometry geom = this.data.getDefaultGeometry();
326
        if( geom == null ) {
327
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
328
            Object x = this.get(i);
329
            if( x instanceof Geometry ) {
330
                geom = (Geometry) x;
331
            } else {
332
                geom = this.getGeometry(i);
333
            }
334
        }
335
        if( geom != null ) {
336
            if( geom.getProjection()==null ) {
337
                FeatureType type = this.getType();
338
                DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
339
                IProjection proj = attrdesc.getSRS(this.storeRef);
340
                geom.setProjection(proj);
341
            }
342
        }
343
        return geom;
344
    }
345

    
346
    @Override
347
    public Time getDefaultTime() {
348
            Time time = this.data.getDefaultTime();
349
        if( time == null ) {
350
            int i = this.data.getType().getDefaultTimeAttributeIndex();
351
            Object x = this.get(i);
352
            if( x instanceof Time ) {
353
                time = (Time) x;
354
            } else {
355
                time = this.getTime(i);
356
            }
357
        }
358
        return time;
359
    }
360

    
361
    @Override
362
    public IProjection getDefaultSRS() {
363
        IProjection srs = this.data.getType().getDefaultSRS();
364
        if( srs == null ) {
365
            FeatureType type = this.getType();
366
            DefaultFeatureAttributeDescriptor attrdesc = (DefaultFeatureAttributeDescriptor) type.get(type.getDefaultGeometryAttributeIndex());
367
            srs = attrdesc.getSRS(this.storeRef);
368
        }
369
        return srs;
370
    }
371

    
372
    @Override
373
    public List getGeometries() {
374
        // TODO Auto-generated method stub
375
        return null;
376
    }
377

    
378
    @Override
379
    public Object getFromProfile(int index) {
380
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(index);
381
        Object value = this.get(index);
382
        String profileName = descriptor.getDataProfileName();
383
        if( StringUtils.isBlank(profileName) ) {
384
            return value;
385
        }
386
        DataProfile profile = DALLocator.getDataManager().getDataProfile(profileName);
387
        if( profile==null ) {
388
            return value;
389
        }
390
        return profile.createData(value, descriptor.getTags());
391
    }
392

    
393
    @Override
394
    public Object getFromProfile(String name) {
395
        FeatureAttributeDescriptor descriptor = this.data.getType().getAttributeDescriptor(name);
396
        return this.getFromProfile(descriptor.getIndex());
397
    }
398

    
399
    @Override
400
    public Object get(String name) {
401
        int index = this.data.getType().getIndex(name);
402
        if( index < 0 ) {
403
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
404
        }
405
        return this.get(index);
406
    }
407

    
408
    public boolean has_key(String key) {
409
        Object x = this.getType().get(key);
410
        return x != null;
411
    }
412

    
413
    public List<String> keys() {
414
        List<String> ks = new ArrayList<>();
415
        for( FeatureAttributeDescriptor attr : this.getType()) {
416
            ks.add(attr.getName());
417
        }
418
        return ks;
419
    }
420

    
421
    public Iterator<String> iterkeys() {
422
        final Iterator it = this.getType().iterator();
423
        return new Iterator<String>() {
424
            @Override
425
            public boolean hasNext() {
426
                return it.hasNext();
427
            }
428

    
429
            @Override
430
            public String next() {
431
                return ((FeatureAttributeDescriptor)it.next()).getName();
432
            }
433

    
434
            @Override
435
            public void remove() {
436
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
437
            }
438
        };
439
    }
440

    
441
    public Iterator iteritems() {
442
        final Iterator it = this.getType().iterator();
443
        return new Iterator<Map.Entry>() {
444
            @Override
445
            public boolean hasNext() {
446
                return it.hasNext();
447
            }
448

    
449
            @Override
450
            public Map.Entry next() {
451
                final String name = ((FeatureAttributeDescriptor)it.next()).getName();
452
                return new Map.Entry<String, Object>() {
453
                    @Override
454
                    public String getKey() {
455
                        return name;
456
                    }
457

    
458
                    @Override
459
                    public Object getValue() {
460
                        return get(name);
461
                    }
462

    
463
                    @Override
464
                    public Object setValue(Object value) {
465
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
466
                    }
467

    
468
                };
469
            }
470

    
471
            @Override
472
            public void remove() {
473
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
474
            }
475
        };
476
    }
477

    
478
    @Override
479
    public Object get(int index) {
480
        FeatureType type = this.data.getType();
481
        if( index <0 || index >= type.size() ) {
482
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
483
        }
484
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
485
        if (!this.data.getType().hasEvaluators()) {
486
            return get(attribute, this.data.get(index));
487
        }
488
        Evaluator eval = attribute.getEvaluator();
489
        if (eval == null) {
490
            return this.data.get(index);
491
        } else {
492
            Object value = this.data.get(index);
493
            if (value != null) { // FIXME: para comprobar si esta calculado usar
494
                // un array
495
                // especifico.
496
                return get(attribute, this.data.get(index));
497
            }
498
            try {
499
                value = eval.evaluate(this);
500
            } catch (EvaluatorException e) {
501
                throw new DataEvaluatorRuntimeException(e);
502
            }
503
            this.data.set(index, value);
504
            return  get(attribute, value);
505
        }
506
    }
507

    
508
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
509
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
510
        if( emulator != null ) {
511
//            int index = featureAttributeDescriptor.getIndex();
512
//            value = this.data.get(index);
513
//            if( value==null ) {
514
                value = emulator.get(this);
515
//                this.data.set(index,value);
516
//            }
517
        } else {
518
            FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
519
            if( getter != null ) {
520
                value = getter.getter(value);
521
            }
522
        }
523
        if( featureAttributeDescriptor.getType()==DataTypes.GEOMETRY ) {
524
            if( value != null ) {
525
                Geometry geom = (Geometry)value;
526
                if( geom.getProjection()==null ) {
527
                    IProjection proj = ((DefaultFeatureAttributeDescriptor)featureAttributeDescriptor).getSRS(this.storeRef);
528
                    geom.setProjection(proj);
529
                }
530
            }
531
        }
532
        return value;
533
    }
534

    
535
    @Override
536
    public byte[] getByteArray(String name) {
537
        return this.getByteArray(this.data.getType().getIndex(name));
538
    }
539

    
540
    @Override
541
    public byte[] getByteArray(int index) {
542
        return (byte[]) this.get(index);
543
    }
544

    
545
    @Override
546
    public Object[] getArray(String name) {
547
        return this.getArray(this.data.getType().getIndex(name));
548
    }
549

    
550
    @Override
551
    public Object[] getArray(int index) {
552
        return (Object[]) this.get(index);
553
    }
554

    
555
    @Override
556
    public boolean getBoolean(String name) {
557
        return this.getBoolean(this.data.getType().getIndex(name));
558
    }
559

    
560
    @Override
561
    public boolean getBoolean(int index) {
562
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
563
        if (value == null) {
564
            return false;
565
        }
566
        return value;
567
    }
568

    
569
    @Override
570
    public byte getByte(String name) {
571
        return this.getByte(this.data.getType().getIndex(name));
572
    }
573

    
574
    @Override
575
    public byte getByte(int index) {
576
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
577
        if (value == null) {
578
            return 0;
579
        }
580
        return value;
581
    }
582

    
583
    @Override
584
    public Date getDate(String name) {
585
        return this.getDate(this.data.getType().getIndex(name));
586
    }
587

    
588
    @Override
589
    public Date getDate(int index) {
590
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
591

    
592
        return value;
593
    }
594

    
595
    @Override
596
    public double getDouble(String name) {
597
        return this.getDouble(this.data.getType().getIndex(name));
598
    }
599

    
600
    @Override
601
    public double getDouble(int index) {
602

    
603
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
604
        if (value == null) {
605
            return 0;
606
        }
607
        return value;
608
    }
609

    
610
    @Override
611
    public Feature getFeature(String name) {
612
        return this.getFeature(this.data.getType().getIndex(name));
613
    }
614

    
615
    @Override
616
    public Feature getFeature(int index) {
617
        return (Feature) this.get(index);
618
    }
619

    
620
    @Override
621
    public float getFloat(String name) {
622
        return this.getFloat(this.data.getType().getIndex(name));
623
    }
624

    
625
    @Override
626
    public float getFloat(int index) {
627
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
628
        if (value == null) {
629
            return 0;
630
        }
631
        return value;
632
    }
633

    
634
    @Override
635
    public Geometry getGeometry(String name) {
636
        return this.getGeometry(this.data.getType().getIndex(name));
637
    }
638

    
639
    @Override
640
    public Geometry getGeometry(int index) {
641
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
642
    }
643

    
644
    @Override
645
    public int getInt(String name) {
646
        return this.getInt(this.data.getType().getIndex(name));
647
    }
648

    
649
    @Override
650
    public int getInt(int index) {
651
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
652
        if (value == null) {
653
            return 0;
654
        }
655
        return value;
656
    }
657

    
658
    @Override
659
    public long getLong(String name) {
660
        return this.getLong(this.data.getType().getIndex(name));
661
    }
662

    
663
    @Override
664
    public long getLong(int index) {
665
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
666
        if (value == null) {
667
            return 0;
668
        }
669
        return value;
670
    }
671

    
672
    @Override
673
    public String getString(String name) {
674
        return this.getString(this.data.getType().getIndex(name));
675
    }
676

    
677
    @Override
678
    public String getString(int index) {
679
        return (String) this.get(index,String.class,DataTypes.STRING);
680
    }
681

    
682
    @Override
683
    public Object getContextValue(String name) {
684
        name = name.toLowerCase();
685
        if (name.equals("store")) {
686
            return this.getStore();
687
        }
688

    
689
        if (name.equals("featuretype")) {
690
            return this.data.getType();
691
        }
692

    
693
        if (name.equals("feature")) {
694
            return this;
695
        }
696

    
697
        throw new IllegalArgumentException(name);
698
    }
699

    
700
    @Override
701
    public Iterator getDataNames() {
702
        class DataNamesIterator implements Iterator {
703
            Iterator attributeIteraror;
704

    
705
            DataNamesIterator(DefaultFeature feature) {
706
                this.attributeIteraror = feature.getType().iterator();
707
            }
708

    
709
            @Override
710
            public boolean hasNext() {
711
                return this.attributeIteraror.hasNext();
712
            }
713

    
714
            @Override
715
            public Object next() {
716
                return ((FeatureAttributeDescriptor) this.attributeIteraror
717
                        .next()).getName();
718
            }
719

    
720
            @Override
721
            public void remove() {
722
                throw new UnsupportedOperationException();
723
            }
724

    
725
        }
726
        return new DataNamesIterator(this);
727
    }
728

    
729
    @Override
730
    public Object getDataValue(String name) {
731
        name = name.toLowerCase();
732
        try {
733
            return get(name);
734
        } catch (IllegalArgumentException ex) {
735
            if( "defaultgeometry".equalsIgnoreCase(name )) {
736
                return this.getDefaultGeometry();
737
            }
738
            throw ex;
739
        }
740
    }
741

    
742
    @Override
743
    public Iterator getDataValues() {
744
        class DataValuesIterator implements Iterator {
745
            DefaultFeature feature;
746
            int current = 0;
747

    
748
            DataValuesIterator(DefaultFeature feature) {
749
                this.feature = feature;
750
            }
751

    
752
            @Override
753
            public boolean hasNext() {
754
                return current < feature.getType().size() - 1;
755
            }
756

    
757
            @Override
758
            public Object next() {
759
                return feature.get(current++);
760
            }
761

    
762
            @Override
763
            public void remove() {
764
                throw new UnsupportedOperationException();
765
            }
766

    
767
        }
768
        return new DataValuesIterator(this);
769
    }
770

    
771
    @Override
772
    public boolean hasContextValue(String name) {
773
        name = name.toLowerCase();
774
        if (name.equals("store")) {
775
            return true;
776
        }
777

    
778
        if (name.equals("featuretype")) {
779
            return true;
780
        }
781

    
782
        return name.equals("feature");
783
    }
784

    
785
    @Override
786
    public boolean hasDataValue(String name) {
787
        name = name.toLowerCase();
788
        return this.data.getType().getIndex(name) >= 0;
789
    }
790

    
791
    @Override
792
    public Time getTime(int index) {
793
        return ((Time) this.get(index,Time.class,DataTypes.INSTANT));
794
    }
795

    
796
    @Override
797
    public Time getTime(String name) {
798
        return this.getInstant(this.data.getType().getIndex(name));
799
    }
800

    
801
    @Override
802
    public Instant getInstant(int index) {
803
        return ((Instant) this.get(index,Instant.class,DataTypes.INSTANT));
804
    }
805

    
806
    @Override
807
    public Instant getInstant(String name) {
808
        return this.getInstant(this.data.getType().getIndex(name));
809
    }
810

    
811
    @Override
812
    public Interval getInterval(int index) {
813
        return ((Interval) this.get(index,Interval.class,DataTypes.INTERVAL));
814
    }
815

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

    
821
    @Override
822
    public DynObject getAsDynObject() {
823
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
824
        return facade;
825
    }
826

    
827
    @Override
828
    public String toString() {
829
            StringBuilder builder = new StringBuilder();
830
        FeatureAttributeDescriptor[] attributeDescriptors =
831
            getType().getAttributeDescriptors();
832
        for (int i = 0; i < attributeDescriptors.length; i++) {
833
            String name = attributeDescriptors[i].getName();
834
            builder.append(get(name));
835
            if (i < attributeDescriptors.length - 1) {
836
                builder.append(", ");
837
            }
838
        }
839
        return builder.toString();
840
    }
841

    
842

    
843

    
844

    
845
        /**
846
     * @return the inserted
847
     */
848
    public boolean isInserted() {
849
        return inserted;
850
    }
851

    
852

    
853
    /**
854
     * @param inserted the inserted to set
855
     */
856
    public void setInserted(boolean inserted) {
857
        this.inserted = inserted;
858
    }
859

    
860
        @Override
861
    public EvaluatorData getEvaluatorData() {
862
        return this;
863
    }
864

    
865
    public int size() {
866
        return this.data.getType().size();
867
    }
868
    
869
    public boolean isEmpty() {
870
        return false;
871
    }
872

    
873
    public Iterator<String> iterator() {
874
        final Iterator<FeatureAttributeDescriptor> x = this.data.getType().iterator();
875
        return new Iterator<String>() {
876
            @Override
877
            public boolean hasNext() {
878
                return x.hasNext();
879
            }
880

    
881
            @Override
882
            public String next() {
883
                return x.next().getName();
884
            }
885
        };
886
    }
887
    
888
    public boolean containsKey(String key) {
889
        return this.data.getType().get(key)!=null;
890
    }
891
}