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

History | View | Annotate | Download (19 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.Date;
28
import java.util.Iterator;
29
import java.util.List;
30

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

    
62
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
63

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

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

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

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

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

    
100
        public FeatureProvider getData() {
101
                return this.data;
102
        }
103

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

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

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

    
132
        }
133

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

    
138
        if ( attribute.getObjectClass().isInstance(value) ) {
139
            this.data.set(i, value);
140
            return;
141
        }
142

    
143
        if ( !attribute.getObjectClass().isInstance(value) ) {
144
            try {
145
                value
146
                        = this.getDataTypesManager().coerce(attribute.getType(),
147
                                value);
148
            } catch (CoercionException e) {
149
                throw new IllegalArgumentException("Can't convert to "
150
                        + this.getDataTypesManager().getTypeName(
151
                                attribute.getType()) + " from '"
152
                        + value.getClass().getName() + "' with value '"
153
                        + value.toString() + "'.");
154
            }
155
        }
156

    
157
        this.data.set(i, value);
158
    }
159
        
160
    private Object get(int index,Class theClass, int type) {
161
        Object value = this.get(index);
162
        if( theClass.isInstance(value) ) {
163
            return value;
164
        }
165

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

    
196
    public void initializeValues() {
197
        FeatureType type = this.getType();
198
        Iterator iterator = type.iterator();
199

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

    
214
    public void clear() {
215
        initializeValues();
216
    }
217

    
218
    public void initializeValues(Feature feature) {
219
        FeatureType myType=this.getType();
220
        FeatureType type =feature.getType();
221
        Iterator iterator = type.iterator();
222

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

    
233

    
234
    public FeatureStore getStore() {
235
        return (FeatureStore) this.storeRef.get();
236
    }
237

    
238
    public FeatureType getType() {
239
        return this.data.getType();
240
    }
241

    
242
    public EditableFeature getEditable() {
243
        return new DefaultEditableFeature(this);
244
    }
245

    
246
    public Feature getCopy() {
247
        return new DefaultFeature(this);
248
    }
249
    
250
    public Object clone() throws CloneNotSupportedException {
251
        return new DefaultFeature(this);
252
    }
253

    
254
    public FeatureReference getReference() {
255
        if (this.reference == null) {
256
            if (!isInserted()) {
257
                return null;
258
            }
259
            reference = new DefaultFeatureReference(this);
260
        }
261
        return this.reference;
262
    }
263

    
264
    class UnableToGetReferenceException extends BaseRuntimeException {
265

    
266
        /**
267
         * 
268
         */
269
        private static final long serialVersionUID = 1812805035204824163L;
270

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

    
287
    public List getSRSs() {
288
        // TODO Auto-generated method stub
289
        return null;
290
    }
291

    
292
    public Envelope getDefaultEnvelope() {
293
        Envelope envelope = this.data.getDefaultEnvelope();
294
        if( envelope == null ) {
295
            Geometry geom = this.getDefaultGeometry();
296
            if( geom!=null ) {
297
                envelope = geom.getEnvelope();
298
            }
299
        }
300
        return envelope;
301
    }
302

    
303
    public Geometry getDefaultGeometry() {
304
            Geometry geom = this.data.getDefaultGeometry();
305
            if( geom!=null ) {
306
                    return geom;
307
            }
308
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
309
            geom = (Geometry) this.get(i);
310
        return geom;
311
    }
312

    
313
    public IProjection getDefaultSRS() {
314
        return this.data.getType().getDefaultSRS();
315
    }
316

    
317
    public List getGeometries() {
318
        // TODO Auto-generated method stub
319
        return null;
320
    }
321

    
322
    public Object get(String name) {
323
        int index = this.data.getType().getIndex(name);
324
        if( index < 0 ) {
325
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
326
        }
327
        return this.get(index);
328
    }
329

    
330

    
331
    public Object get(int index) {
332
        FeatureType type = this.data.getType();
333
        if( index <0 || index >= type.size() ) {
334
            throw new IllegalArgumentException("Attribute index '"+index+"' out of range (0 to "+this.data.getType().size()+".");
335
        }
336
        FeatureAttributeDescriptor attribute = type.getAttributeDescriptor(index);
337
        if (!this.data.getType().hasEvaluators()) {
338
            return get(attribute, this.data.get(index));                
339
        }                
340
        Evaluator eval = attribute.getEvaluator();
341
        if (eval == null) {
342
            return this.data.get(index);
343
        } else {
344
            Object value = this.data.get(index);
345
            if (value != null) { // FIXME: para comprobar si esta calculado usar
346
                // un array
347
                // especifico.
348
                return get(attribute, this.data.get(index));
349
            }
350
            try {
351
                value = eval.evaluate(this);
352
            } catch (EvaluatorException e) {
353
                throw new DataEvaluatorRuntimeException(e);
354
            }
355
            this.data.set(index, value);
356
            return  get(attribute, value);
357
        }                
358
    }
359

    
360
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
361
        FeatureAttributeEmulator emulator = featureAttributeDescriptor.getFeatureAttributeEmulator();
362
        if( emulator != null ) {
363
            return emulator.get(this);
364
        }
365
        FeatureAttributeGetter getter = featureAttributeDescriptor.getFeatureAttributeGetter();
366
        if( getter != null ) {
367
            return getter.getter(value);
368
        }
369
        return value;
370
    }
371

    
372
    public Object[] getArray(String name) {
373
        return this.getArray(this.data.getType().getIndex(name));
374
    }
375

    
376
    public Object[] getArray(int index) {
377
        return (Object[]) this.get(index);
378
    }
379

    
380
    public boolean getBoolean(String name) {
381
        return this.getBoolean(this.data.getType().getIndex(name));
382
    }
383

    
384
    public boolean getBoolean(int index) {
385
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
386
        if (value == null) {
387
            return false;
388
        }
389
        return value.booleanValue();
390
    }
391

    
392
    public byte getByte(String name) {
393
        return this.getByte(this.data.getType().getIndex(name));
394
    }
395

    
396
    public byte getByte(int index) {
397
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
398
        if (value == null) {
399
            return 0;
400
        }
401
        return value.byteValue();
402
    }
403

    
404
    public Date getDate(String name) {
405
        return this.getDate(this.data.getType().getIndex(name));
406
    }
407

    
408
    public Date getDate(int index) {
409
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
410

    
411
        return value;
412
    }
413

    
414
    public double getDouble(String name) {
415
        return this.getDouble(this.data.getType().getIndex(name));
416
    }
417

    
418
    public double getDouble(int index) {
419
        
420
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
421
        if (value == null) {
422
            return 0;
423
        }
424
        return value.doubleValue();
425
    }
426

    
427
    public Feature getFeature(String name) {
428
        return this.getFeature(this.data.getType().getIndex(name));
429
    }
430

    
431
    public Feature getFeature(int index) {
432
        return (Feature) this.get(index);
433
    }
434

    
435
    public float getFloat(String name) {
436
        return this.getFloat(this.data.getType().getIndex(name));
437
    }
438

    
439
    public float getFloat(int index) {
440
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
441
        if (value == null) {
442
            return 0;
443
        }
444
        return value.floatValue();
445
    }
446

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

    
451
    public Geometry getGeometry(int index) {
452
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
453
    }
454

    
455
    public int getInt(String name) {
456
        return this.getInt(this.data.getType().getIndex(name));
457
    }
458

    
459
    public int getInt(int index) {
460
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
461
        if (value == null) {
462
            return 0;
463
        }
464
        return ((Integer)value).intValue();
465
    }
466

    
467
    public long getLong(String name) {
468
        return this.getLong(this.data.getType().getIndex(name));
469
    }
470

    
471
    public long getLong(int index) {
472
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
473
        if (value == null) {
474
            return 0;
475
        }
476
        return value.longValue();
477
    }
478

    
479
    public String getString(String name) {
480
        return this.getString(this.data.getType().getIndex(name));
481
    }
482

    
483
    public String getString(int index) {
484
        return (String) this.get(index,String.class,DataTypes.STRING);
485
    }
486

    
487
    public Object getContextValue(String name) {
488
        name = name.toLowerCase();
489
        if (name.equals("store")) {
490
            return this.getStore();
491
        }
492

    
493
        if (name.equals("featuretype")) {
494
            return this.data.getType();
495
        }
496

    
497
        if (name.equals("feature")) {
498
            return this;
499
        }
500

    
501
        throw new IllegalArgumentException(name);
502
    }
503

    
504
    public Iterator getDataNames() {
505
        class DataNamesIterator implements Iterator {
506
            Iterator attributeIteraror;
507

    
508
            DataNamesIterator(DefaultFeature feature) {
509
                this.attributeIteraror = feature.getType().iterator();
510
            }
511

    
512
            public boolean hasNext() {
513
                return this.attributeIteraror.hasNext();
514
            }
515

    
516
            public Object next() {
517
                return ((FeatureAttributeDescriptor) this.attributeIteraror
518
                        .next()).getName();
519
            }
520

    
521
            public void remove() {
522
                throw new UnsupportedOperationException();
523
            }
524

    
525
        }
526
        return new DataNamesIterator(this);
527
    }
528

    
529
    public Object getDataValue(String name) {
530
        name = name.toLowerCase();
531
        return get(name);
532
    }
533

    
534
    public Iterator getDataValues() {
535
        class DataValuesIterator implements Iterator {
536
            DefaultFeature feature;
537
            int current = 0;
538

    
539
            DataValuesIterator(DefaultFeature feature) {
540
                this.feature = feature;
541
            }
542

    
543
            public boolean hasNext() {
544
                return current < feature.getType().size() - 1;
545
            }
546

    
547
            public Object next() {
548
                return feature.get(current++);
549
            }
550

    
551
            public void remove() {
552
                throw new UnsupportedOperationException();
553
            }
554

    
555
        }
556
        return new DataValuesIterator(this);
557
    }
558

    
559
    public boolean hasContextValue(String name) {
560
        name = name.toLowerCase();
561
        if (name.equals("store")) {
562
            return true;
563
        }
564

    
565
        if (name.equals("featuretype")) {
566
            return true;
567
        }
568

    
569
        if (name.equals("feature")) {
570
            return true;
571
        }
572
        return false;
573
    }
574

    
575
    public boolean hasDataValue(String name) {
576
        name = name.toLowerCase();
577
        return this.data.getType().getIndex(name) >= 0;
578
    }
579
    
580
    public Instant getInstant(int index) {
581
        return ((Instant) this.get(index,Date.class,DataTypes.INSTANT));
582
    }
583

    
584
    public Instant getInstant(String name) {
585
        return this.getInstant(this.data.getType().getIndex(name));
586
    }
587

    
588
    public Interval getInterval(int index) {
589
        return ((Interval) this.get(index,Date.class,DataTypes.INTERVAL));
590
    }
591

    
592
    public Interval getInterval(String name) {
593
        return this.getInterval(this.data.getType().getIndex(name));
594
    }
595

    
596
    public DynObject getAsDynObject() {
597
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade();
598
        facade.setFeature(this);
599
        return facade;
600
    }
601

    
602
    public String toString() {
603
       // StringBuffer buffer = new StringBuffer("Feature with values: ");
604
            StringBuffer buffer = new StringBuffer("");
605
        FeatureAttributeDescriptor[] attributeDescriptors =
606
            getType().getAttributeDescriptors();
607
        for (int i = 0; i < attributeDescriptors.length; i++) {
608
            String name = attributeDescriptors[i].getName();
609
            //buffer.append(name).append("=").append(get(name));
610
            buffer.append(get(name));
611
            if (i < attributeDescriptors.length - 1) {
612
                buffer.append(", ");
613
            }
614
        }
615
        return buffer.toString();
616
    }
617
    
618
    
619

    
620

    
621
        /**
622
     * @return the inserted
623
     */
624
    public boolean isInserted() {
625
        return inserted;
626
    }
627

    
628
    
629
    /**
630
     * @param inserted the inserted to set
631
     */
632
    public void setInserted(boolean inserted) {
633
        this.inserted = inserted;
634
    }
635

    
636
    public EvaluatorData getEvaluatorData() {
637
        return this;
638
    }
639
}