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

History | View | Annotate | Download (21.3 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

    
33
import org.cresques.cts.IProjection;
34
import org.gvsig.fmap.dal.DataTypes;
35
import org.gvsig.fmap.dal.exception.DataEvaluatorRuntimeException;
36
import org.gvsig.fmap.dal.exception.DataException;
37
import org.gvsig.fmap.dal.feature.EditableFeature;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
40
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeGetter;
42
import org.gvsig.fmap.dal.feature.FeatureReference;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.dal.feature.FeatureType;
45
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
46
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
47
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
48
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.primitive.Envelope;
51
import org.gvsig.timesupport.Instant;
52
import org.gvsig.timesupport.Interval;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.dataTypes.CoercionException;
55
import org.gvsig.tools.dataTypes.DataTypesManager;
56
import org.gvsig.tools.dynobject.DynObject;
57
import org.gvsig.tools.evaluator.Evaluator;
58
import org.gvsig.tools.evaluator.EvaluatorData;
59
import org.gvsig.tools.evaluator.EvaluatorException;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.exception.BaseRuntimeException;
62
import org.gvsig.tools.lang.Cloneable;
63

    
64
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
65

    
66
        private static DataTypesManager dataTypesManager = null; 
67
        protected FeatureProvider data;
68
        protected FeatureReference reference;
69
        private WeakReference storeRef;
70
        
71
        private boolean inserted = false;
72

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

    
82
        public DefaultFeature(FeatureStore store, FeatureProvider data) {
83
                this.data = data;
84
                this.storeRef = new WeakReference(store);
85
                this.reference = null;
86
                this.inserted = !data.isNew();
87
        }
88

    
89
        DefaultFeature(DefaultFeature feature) {
90
                this.data = feature.data.getCopy();
91
                this.storeRef = feature.storeRef;
92
                this.reference = feature.reference;
93
                this.inserted = feature.isInserted();
94
        }
95

    
96
        public void setData(FeatureProvider data) {
97
                this.data = data;
98
                this.reference = null;
99
                this.inserted = true; 
100
        }
101

    
102
        public FeatureProvider getData() {
103
                return this.data;
104
        }
105

    
106
        protected DataTypesManager getDataTypesManager() {
107
                if( dataTypesManager==null ) {
108
                        dataTypesManager = ToolsLocator.getDataTypesManager();
109
                }
110
                return dataTypesManager;
111
        }
112

    
113
    void set(FeatureAttributeDescriptor attribute, Object value) {
114
        int i = attribute.getIndex();
115

    
116
        if ( attribute.isReadOnly() ) {
117
            throw new SetReadOnlyAttributeException(attribute.getName(), this.getType());
118
        }
119
        FeatureAttributeEmulator emulator = attribute.getFeatureAttributeEmulator();
120
        if( emulator!= null ) {
121
            emulator.set((EditableFeature) this,value);
122
            return;
123
        }
124
        
125
        if ( value == null ) {
126
            if ( !attribute.allowNull() ) {
127
                if ( !attribute.isAutomatic() ) {
128
                    throw new IllegalValueException(attribute, value);
129
                }
130
            }
131
            this.data.set(i, null);
132
            return;
133

    
134
        }
135

    
136
        if ( attribute.getFeatureAttributeGetter() != null ) {
137
            value = attribute.getFeatureAttributeGetter().setter(value);
138
        }
139

    
140
        Class objectClass = attribute.getObjectClass();
141
        if( objectClass!=null ) {
142
            if ( objectClass.isInstance(value) ) {
143
                this.data.set(i, value);
144
                return;
145
            }
146

    
147
            if ( !objectClass.isInstance(value) ) {
148
                try {
149
                    value
150
                            = this.getDataTypesManager().coerce(attribute.getType(),
151
                                    value);
152
                } catch (CoercionException e) {
153
                    throw new IllegalArgumentException("Can't convert to "
154
                            + this.getDataTypesManager().getTypeName(
155
                                    attribute.getType()) + " from '"
156
                            + value.getClass().getName() + "' with value '"
157
                            + value.toString() + "'.");
158
                }
159
            }
160
        }
161
        this.data.set(i, value);
162
    }
163
        
164
    private Object get(int index,Class theClass, int type) {
165
        Object value = this.get(index);
166
        if( theClass.isInstance(value) ) {
167
            return value;
168
        }
169

    
170
        
171
        try {
172
            return this.getDataTypesManager().coerce(type, value);
173
        } catch (CoercionException e) {
174
            
175
            if (value == null) {
176
                return null;
177
            }
178
            throw new IllegalArgumentException(
179
                    "Can't convert to "+theClass.getName()+
180
                    " from '"+value.getClass().getName()+
181
                    "' with value '"+value.toString()+"'.");
182
        }
183
    }
184
    
185
//  private Object getNumberByType(Number value, int type) {
186
//      if (type==DataTypes.DOUBLE){
187
//          return new Double(value.doubleValue());
188
//      }else if (type==DataTypes.FLOAT){
189
//          return new Float(value.floatValue());
190
//      }else if (type==DataTypes.LONG){
191
//          return new Long(value.longValue());
192
//      }else if (type==DataTypes.INT){
193
//          return new Integer(value.intValue());
194
//      }else if (type==DataTypes.STRING){
195
//          return value.toString();
196
//      }
197
//      return value;
198
//  }
199

    
200
    public void initializeValues() {
201
        FeatureType type = this.getType();
202
        Iterator iterator = type.iterator();
203

    
204
        while (iterator.hasNext()) {
205
            FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor) iterator
206
            .next();
207
            if (attribute.isAutomatic() || attribute.isReadOnly()
208
                    || attribute.getEvaluator() != null) {
209
                continue;
210
            }
211
            if (attribute.getDefaultValue() == null && !attribute.allowNull()) {
212
                continue;
213
            }
214
            this.set(attribute, attribute.getDefaultValue());
215
        }
216
    }
217

    
218
    public void clear() {
219
        initializeValues();
220
    }
221

    
222
    public void initializeValues(Feature feature) {
223
        FeatureType myType=this.getType();
224
        FeatureType type =feature.getType();
225
        Iterator iterator = type.iterator();
226

    
227
        while (iterator.hasNext()) {
228
            FeatureAttributeDescriptor attribute = (FeatureAttributeDescriptor) iterator
229
            .next();
230
            FeatureAttributeDescriptor myAttribute=myType.getAttributeDescriptor(attribute.getName());
231
            if (myAttribute != null) {
232
                this.set(myAttribute, feature.get(attribute.getIndex()));
233
            }
234
        }
235
    }
236

    
237

    
238
    public FeatureStore getStore() {
239
        return (FeatureStore) this.storeRef.get();
240
    }
241

    
242
    public FeatureType getType() {
243
        return this.data.getType();
244
    }
245

    
246
    public EditableFeature getEditable() {
247
        return new DefaultEditableFeature(this);
248
    }
249

    
250
    public Feature getCopy() {
251
        return new DefaultFeature(this);
252
    }
253
    
254
    public Object clone() throws CloneNotSupportedException {
255
        return new DefaultFeature(this);
256
    }
257

    
258
    public FeatureReference getReference() {
259
        if (this.reference == null) {
260
            if (!isInserted()) {
261
                return null;
262
            }
263
            reference = new DefaultFeatureReference(this);
264
        }
265
        return this.reference;
266
    }
267

    
268
    class UnableToGetReferenceException extends BaseRuntimeException {
269

    
270
        /**
271
         * 
272
         */
273
        private static final long serialVersionUID = 1812805035204824163L;
274

    
275
        /**
276
         * @param exception
277
         */
278
        public UnableToGetReferenceException(BaseException exception) {
279
            super("Unable to get reference", "_UnableToGetReferenceException",
280
                serialVersionUID);
281
            this.initCause(exception);
282
            
283
        }
284
        
285
    }
286
    
287
    public void validate(int mode) throws DataException  {
288
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, mode);
289
    }
290

    
291
    public List getSRSs() {
292
        // TODO Auto-generated method stub
293
        return null;
294
    }
295

    
296
    public Envelope getDefaultEnvelope() {
297
        Envelope envelope = this.data.getDefaultEnvelope();
298
        if( envelope == null ) {
299
            Geometry geom = this.getDefaultGeometry();
300
            if( geom!=null ) {
301
                envelope = geom.getEnvelope();
302
            }
303
        }
304
        return envelope;
305
    }
306

    
307
    public Geometry getDefaultGeometry() {
308
            Geometry geom = this.data.getDefaultGeometry();
309
            if( geom!=null ) {
310
                    return geom;
311
            }
312
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
313
        Object x = this.get(i);
314
        if( x instanceof Geometry ) {
315
            return (Geometry) x;
316
        }
317
        return this.getGeometry(i);
318
    }
319

    
320
    public IProjection getDefaultSRS() {
321
        return this.data.getType().getDefaultSRS();
322
    }
323

    
324
    public List getGeometries() {
325
        // TODO Auto-generated method stub
326
        return null;
327
    }
328

    
329
    public Object get(String name) {
330
        int index = this.data.getType().getIndex(name);
331
        if( index < 0 ) {
332
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
333
        }
334
        return this.get(index);
335
    }
336
    
337
    public boolean has_key(String key) {
338
        Object x = this.getType().get(key);
339
        return x != null;
340
    }
341
    
342
    public List<String> keys() {
343
        List<String> ks = new ArrayList<>();
344
        for( FeatureAttributeDescriptor attr : this.getType()) {
345
            ks.add(attr.getName());
346
        }
347
        return ks;
348
    }
349
    
350
    public Iterator<String> iterkeys() {
351
        final Iterator it = this.getType().iterator();
352
        return new Iterator<String>() {
353
            @Override
354
            public boolean hasNext() {
355
                return it.hasNext();
356
            }
357

    
358
            @Override
359
            public String next() {
360
                return ((FeatureAttributeDescriptor)it.next()).getName();
361
            }
362
        };
363
    }
364

    
365
    public Iterator iteritems() {
366
        final Iterator it = this.getType().iterator();
367
        return new Iterator<Map.Entry>() {
368
            @Override
369
            public boolean hasNext() {
370
                return it.hasNext();
371
            }
372

    
373
            @Override
374
            public Map.Entry next() {
375
                final String name = ((FeatureAttributeDescriptor)it.next()).getName();
376
                return new Map.Entry<String, Object>() {
377
                    @Override
378
                    public String getKey() {
379
                        return name;
380
                    }
381

    
382
                    @Override
383
                    public Object getValue() {
384
                        return get(name);
385
                    }
386

    
387
                    @Override
388
                    public Object setValue(Object value) {
389
                        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
390
                    }
391
                    
392
                };
393
            }
394
        };        
395
    }
396

    
397
    @Override
398
    public Object get(int index) {
399
        FeatureType type = this.data.getType();
400
        if( index <0 || index >= type.size() ) {
401
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
402
        }
403
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
404
        if (!this.data.getType().hasEvaluators()) {
405
            return get(attribute, this.data.get(index));                
406
        }                
407
        Evaluator eval = attribute.getEvaluator();
408
        if (eval == null) {
409
            return this.data.get(index);
410
        } else {
411
            Object value = this.data.get(index);
412
            if (value != null) { // FIXME: para comprobar si esta calculado usar
413
                // un array
414
                // especifico.
415
                return get(attribute, this.data.get(index));
416
            }
417
            try {
418
                value = eval.evaluate(this);
419
            } catch (EvaluatorException e) {
420
                throw new DataEvaluatorRuntimeException(e);
421
            }
422
            this.data.set(index, value);
423
            return  get(attribute, value);
424
        }                
425
    }
426

    
427
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
428
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
429
        if( emulator != null ) {
430
            return emulator.get(this);
431
        }
432
        FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
433
        if( getter != null ) {
434
            return getter.getter(value);
435
        }
436
        return value;
437
    }
438

    
439
    public Object[] getArray(String name) {
440
        return this.getArray(this.data.getType().getIndex(name));
441
    }
442

    
443
    public Object[] getArray(int index) {
444
        return (Object[]) this.get(index);
445
    }
446

    
447
    public boolean getBoolean(String name) {
448
        return this.getBoolean(this.data.getType().getIndex(name));
449
    }
450

    
451
    public boolean getBoolean(int index) {
452
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
453
        if (value == null) {
454
            return false;
455
        }
456
        return value.booleanValue();
457
    }
458

    
459
    public byte getByte(String name) {
460
        return this.getByte(this.data.getType().getIndex(name));
461
    }
462

    
463
    public byte getByte(int index) {
464
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
465
        if (value == null) {
466
            return 0;
467
        }
468
        return value.byteValue();
469
    }
470

    
471
    public Date getDate(String name) {
472
        return this.getDate(this.data.getType().getIndex(name));
473
    }
474

    
475
    public Date getDate(int index) {
476
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
477

    
478
        return value;
479
    }
480

    
481
    public double getDouble(String name) {
482
        return this.getDouble(this.data.getType().getIndex(name));
483
    }
484

    
485
    public double getDouble(int index) {
486
        
487
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
488
        if (value == null) {
489
            return 0;
490
        }
491
        return value.doubleValue();
492
    }
493

    
494
    public Feature getFeature(String name) {
495
        return this.getFeature(this.data.getType().getIndex(name));
496
    }
497

    
498
    public Feature getFeature(int index) {
499
        return (Feature) this.get(index);
500
    }
501

    
502
    public float getFloat(String name) {
503
        return this.getFloat(this.data.getType().getIndex(name));
504
    }
505

    
506
    public float getFloat(int index) {
507
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
508
        if (value == null) {
509
            return 0;
510
        }
511
        return value.floatValue();
512
    }
513

    
514
    public Geometry getGeometry(String name) {
515
        return this.getGeometry(this.data.getType().getIndex(name));
516
    }
517

    
518
    public Geometry getGeometry(int index) {
519
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
520
    }
521

    
522
    public int getInt(String name) {
523
        return this.getInt(this.data.getType().getIndex(name));
524
    }
525

    
526
    public int getInt(int index) {
527
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
528
        if (value == null) {
529
            return 0;
530
        }
531
        return ((Integer)value).intValue();
532
    }
533

    
534
    public long getLong(String name) {
535
        return this.getLong(this.data.getType().getIndex(name));
536
    }
537

    
538
    public long getLong(int index) {
539
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
540
        if (value == null) {
541
            return 0;
542
        }
543
        return value.longValue();
544
    }
545

    
546
    public String getString(String name) {
547
        return this.getString(this.data.getType().getIndex(name));
548
    }
549

    
550
    public String getString(int index) {
551
        return (String) this.get(index,String.class,DataTypes.STRING);
552
    }
553

    
554
    public Object getContextValue(String name) {
555
        name = name.toLowerCase();
556
        if (name.equals("store")) {
557
            return this.getStore();
558
        }
559

    
560
        if (name.equals("featuretype")) {
561
            return this.data.getType();
562
        }
563

    
564
        if (name.equals("feature")) {
565
            return this;
566
        }
567

    
568
        throw new IllegalArgumentException(name);
569
    }
570

    
571
    public Iterator getDataNames() {
572
        class DataNamesIterator implements Iterator {
573
            Iterator attributeIteraror;
574

    
575
            DataNamesIterator(DefaultFeature feature) {
576
                this.attributeIteraror = feature.getType().iterator();
577
            }
578

    
579
            public boolean hasNext() {
580
                return this.attributeIteraror.hasNext();
581
            }
582

    
583
            public Object next() {
584
                return ((FeatureAttributeDescriptor) this.attributeIteraror
585
                        .next()).getName();
586
            }
587

    
588
            public void remove() {
589
                throw new UnsupportedOperationException();
590
            }
591

    
592
        }
593
        return new DataNamesIterator(this);
594
    }
595

    
596
    public Object getDataValue(String name) {
597
        name = name.toLowerCase();
598
        try {
599
            return get(name);
600
        } catch (IllegalArgumentException ex) {
601
            if( "defaultgeometry".equalsIgnoreCase(name )) {
602
                return this.getDefaultGeometry();
603
            }
604
            throw ex;
605
        }
606
    }
607

    
608
    public Iterator getDataValues() {
609
        class DataValuesIterator implements Iterator {
610
            DefaultFeature feature;
611
            int current = 0;
612

    
613
            DataValuesIterator(DefaultFeature feature) {
614
                this.feature = feature;
615
            }
616

    
617
            public boolean hasNext() {
618
                return current < feature.getType().size() - 1;
619
            }
620

    
621
            public Object next() {
622
                return feature.get(current++);
623
            }
624

    
625
            public void remove() {
626
                throw new UnsupportedOperationException();
627
            }
628

    
629
        }
630
        return new DataValuesIterator(this);
631
    }
632

    
633
    public boolean hasContextValue(String name) {
634
        name = name.toLowerCase();
635
        if (name.equals("store")) {
636
            return true;
637
        }
638

    
639
        if (name.equals("featuretype")) {
640
            return true;
641
        }
642

    
643
        if (name.equals("feature")) {
644
            return true;
645
        }
646
        return false;
647
    }
648

    
649
    public boolean hasDataValue(String name) {
650
        name = name.toLowerCase();
651
        return this.data.getType().getIndex(name) >= 0;
652
    }
653
    
654
    public Instant getInstant(int index) {
655
        return ((Instant) this.get(index,Date.class,DataTypes.INSTANT));
656
    }
657

    
658
    public Instant getInstant(String name) {
659
        return this.getInstant(this.data.getType().getIndex(name));
660
    }
661

    
662
    public Interval getInterval(int index) {
663
        return ((Interval) this.get(index,Date.class,DataTypes.INTERVAL));
664
    }
665

    
666
    public Interval getInterval(String name) {
667
        return this.getInterval(this.data.getType().getIndex(name));
668
    }
669

    
670
    @Override
671
    public DynObject getAsDynObject() {
672
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade(this);
673
        return facade;
674
    }
675

    
676
    public String toString() {
677
       // StringBuffer buffer = new StringBuffer("Feature with values: ");
678
            StringBuffer buffer = new StringBuffer("");
679
        FeatureAttributeDescriptor[] attributeDescriptors =
680
            getType().getAttributeDescriptors();
681
        for (int i = 0; i < attributeDescriptors.length; i++) {
682
            String name = attributeDescriptors[i].getName();
683
            //buffer.append(name).append("=").append(get(name));
684
            buffer.append(get(name));
685
            if (i < attributeDescriptors.length - 1) {
686
                buffer.append(", ");
687
            }
688
        }
689
        return buffer.toString();
690
    }
691
    
692
    
693

    
694

    
695
        /**
696
     * @return the inserted
697
     */
698
    public boolean isInserted() {
699
        return inserted;
700
    }
701

    
702
    
703
    /**
704
     * @param inserted the inserted to set
705
     */
706
    public void setInserted(boolean inserted) {
707
        this.inserted = inserted;
708
    }
709

    
710
    public EvaluatorData getEvaluatorData() {
711
        return this;
712
    }
713
}