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

History | View | Annotate | Download (18.2 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.FeatureReference;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.feature.exception.IllegalValueException;
42
import org.gvsig.fmap.dal.feature.exception.SetReadOnlyAttributeException;
43
import org.gvsig.fmap.dal.feature.impl.featureset.DynObjectFeatureFacade;
44
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
45
import org.gvsig.fmap.geom.Geometry;
46
import org.gvsig.fmap.geom.primitive.Envelope;
47
import org.gvsig.timesupport.Instant;
48
import org.gvsig.timesupport.Interval;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.dataTypes.CoercionException;
51
import org.gvsig.tools.dataTypes.DataTypesManager;
52
import org.gvsig.tools.dynobject.DynObject;
53
import org.gvsig.tools.evaluator.Evaluator;
54
import org.gvsig.tools.evaluator.EvaluatorData;
55
import org.gvsig.tools.evaluator.EvaluatorException;
56
import org.gvsig.tools.exception.BaseException;
57
import org.gvsig.tools.exception.BaseRuntimeException;
58
import org.gvsig.tools.lang.Cloneable;
59

    
60
public class DefaultFeature implements Feature, EvaluatorData, Cloneable {
61

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

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

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

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

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

    
98
        public FeatureProvider getData() {
99
                return this.data;
100
        }
101

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

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

    
112
                if (attribute.isReadOnly()) {
113
                        throw new SetReadOnlyAttributeException();
114
                }
115

    
116
                if (attribute.getEvaluator() != null) {
117
                        throw new SetReadOnlyAttributeException();
118
                }
119

    
120
                if (value == null) {
121
                        if (!attribute.allowNull()) {
122
                                if (!attribute.isAutomatic()) {
123
                                        throw new IllegalValueException(attribute, value);
124
                                }
125
                        }
126
                        this.data.set(i, null);
127
                        return;
128

    
129
        }
130
                
131
        if (attribute.getFeatureAttributeGetter() != null){
132
            value = attribute.getFeatureAttributeGetter().setter(value);                    
133
        }
134
        
135
        if (attribute.getObjectClass().isInstance(value)) {
136
            this.data.set(i, value);
137
            return;
138
        }
139

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

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

    
193
    public void initializeValues() {
194
        FeatureType type = this.getType();
195
        Iterator iterator = type.iterator();
196

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

    
211
    public void clear() {
212
        initializeValues();
213
    }
214

    
215
    public void initializeValues(Feature feature) {
216
        FeatureType myType=this.getType();
217
        FeatureType type =feature.getType();
218
        Iterator iterator = type.iterator();
219

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

    
230

    
231
    public FeatureStore getStore() {
232
        return (FeatureStore) this.storeRef.get();
233
    }
234

    
235
    public FeatureType getType() {
236
        return this.data.getType();
237
    }
238

    
239
    public EditableFeature getEditable() {
240
        return new DefaultEditableFeature(this);
241
    }
242

    
243
    public Feature getCopy() {
244
        return new DefaultFeature(this);
245
    }
246
    
247
    public Object clone() throws CloneNotSupportedException {
248
        return new DefaultFeature(this);
249
    }
250

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

    
261
    class UnableToGetReferenceException extends BaseRuntimeException {
262

    
263
        /**
264
         * 
265
         */
266
        private static final long serialVersionUID = 1812805035204824163L;
267

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

    
284
    public List getSRSs() {
285
        // TODO Auto-generated method stub
286
        return null;
287
    }
288

    
289
    public Envelope getDefaultEnvelope() {
290
        return this.data.getDefaultEnvelope();
291
    }
292

    
293
    public Geometry getDefaultGeometry() {
294
            Geometry geom = this.data.getDefaultGeometry();
295
            if( geom!=null ) {
296
                    return geom;
297
            }
298
            int i = this.data.getType().getDefaultGeometryAttributeIndex();
299
            geom = (Geometry) this.get(i);
300
        return geom;
301
    }
302

    
303
    public IProjection getDefaultSRS() {
304
        return this.data.getType().getDefaultSRS();
305
    }
306

    
307
    public List getGeometries() {
308
        // TODO Auto-generated method stub
309
        return null;
310
    }
311

    
312
    public Object get(String name) {
313
        int index = this.data.getType().getIndex(name);
314
        if( index < 0 ) {
315
            throw new IllegalArgumentException("Attribute name '"+name+"' not found in the feature.");
316
        }
317
        return this.get(index);
318
    }
319

    
320

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

    
350
    private Object get(FeatureAttributeDescriptor featureAttributeDescriptor, Object value){
351
        if (featureAttributeDescriptor.getFeatureAttributeGetter() == null){
352
            return value;
353
        }else{
354
            return featureAttributeDescriptor.getFeatureAttributeGetter().getter(value);
355
        }
356
    }
357

    
358
    public Object[] getArray(String name) {
359
        return this.getArray(this.data.getType().getIndex(name));
360
    }
361

    
362
    public Object[] getArray(int index) {
363
        return (Object[]) this.get(index);
364
    }
365

    
366
    public boolean getBoolean(String name) {
367
        return this.getBoolean(this.data.getType().getIndex(name));
368
    }
369

    
370
    public boolean getBoolean(int index) {
371
        Boolean value = ((Boolean) this.get(index,Boolean.class,DataTypes.BOOLEAN));
372
        if (value == null) {
373
            return false;
374
        }
375
        return value.booleanValue();
376
    }
377

    
378
    public byte getByte(String name) {
379
        return this.getByte(this.data.getType().getIndex(name));
380
    }
381

    
382
    public byte getByte(int index) {
383
        Byte value = ((Byte) this.get(index,Byte.class,DataTypes.BYTE));
384
        if (value == null) {
385
            return 0;
386
        }
387
        return value.byteValue();
388
    }
389

    
390
    public Date getDate(String name) {
391
        return this.getDate(this.data.getType().getIndex(name));
392
    }
393

    
394
    public Date getDate(int index) {
395
        Date value = ((Date) this.get(index,Date.class,DataTypes.DATE));
396

    
397
        return value;
398
    }
399

    
400
    public double getDouble(String name) {
401
        return this.getDouble(this.data.getType().getIndex(name));
402
    }
403

    
404
    public double getDouble(int index) {
405
        
406
        Double value = ((Double) this.get(index,Double.class,DataTypes.DOUBLE));
407
        if (value == null) {
408
            return 0;
409
        }
410
        return value.doubleValue();
411
    }
412

    
413
    public Feature getFeature(String name) {
414
        return this.getFeature(this.data.getType().getIndex(name));
415
    }
416

    
417
    public Feature getFeature(int index) {
418
        return (Feature) this.get(index);
419
    }
420

    
421
    public float getFloat(String name) {
422
        return this.getFloat(this.data.getType().getIndex(name));
423
    }
424

    
425
    public float getFloat(int index) {
426
        Float value = ((Float) this.get(index,Float.class,DataTypes.FLOAT));
427
        if (value == null) {
428
            return 0;
429
        }
430
        return value.floatValue();
431
    }
432

    
433
    public Geometry getGeometry(String name) {
434
        return this.getGeometry(this.data.getType().getIndex(name));
435
    }
436

    
437
    public Geometry getGeometry(int index) {
438
        return (Geometry) this.get(index,Geometry.class,DataTypes.GEOMETRY);
439
    }
440

    
441
    public int getInt(String name) {
442
        return this.getInt(this.data.getType().getIndex(name));
443
    }
444

    
445
    public int getInt(int index) {
446
        Integer value = ((Integer) this.get(index,Integer.class,DataTypes.INT));
447
        if (value == null) {
448
            return 0;
449
        }
450
        return ((Integer)value).intValue();
451
    }
452

    
453
    public long getLong(String name) {
454
        return this.getLong(this.data.getType().getIndex(name));
455
    }
456

    
457
    public long getLong(int index) {
458
        Long value = ((Long) this.get(index,Long.class,DataTypes.LONG));
459
        if (value == null) {
460
            return 0;
461
        }
462
        return value.longValue();
463
    }
464

    
465
    public String getString(String name) {
466
        return this.getString(this.data.getType().getIndex(name));
467
    }
468

    
469
    public String getString(int index) {
470
        return (String) this.get(index,String.class,DataTypes.STRING);
471
    }
472

    
473
    public Object getContextValue(String name) {
474
        name = name.toLowerCase();
475
        if (name.equals("store")) {
476
            return this.getStore();
477
        }
478

    
479
        if (name.equals("featuretype")) {
480
            return this.data.getType();
481
        }
482

    
483
        if (name.equals("feature")) {
484
            return this;
485
        }
486

    
487
        throw new IllegalArgumentException(name);
488
    }
489

    
490
    public Iterator getDataNames() {
491
        class DataNamesIterator implements Iterator {
492
            Iterator attributeIteraror;
493

    
494
            DataNamesIterator(DefaultFeature feature) {
495
                this.attributeIteraror = feature.getType().iterator();
496
            }
497

    
498
            public boolean hasNext() {
499
                return this.attributeIteraror.hasNext();
500
            }
501

    
502
            public Object next() {
503
                return ((FeatureAttributeDescriptor) this.attributeIteraror
504
                        .next()).getName();
505
            }
506

    
507
            public void remove() {
508
                throw new UnsupportedOperationException();
509
            }
510

    
511
        }
512
        return new DataNamesIterator(this);
513
    }
514

    
515
    public Object getDataValue(String name) {
516
        name = name.toLowerCase();
517
        return get(name);
518
    }
519

    
520
    public Iterator getDataValues() {
521
        class DataValuesIterator implements Iterator {
522
            DefaultFeature feature;
523
            int current = 0;
524

    
525
            DataValuesIterator(DefaultFeature feature) {
526
                this.feature = feature;
527
            }
528

    
529
            public boolean hasNext() {
530
                return current < feature.getType().size() - 1;
531
            }
532

    
533
            public Object next() {
534
                return feature.get(current++);
535
            }
536

    
537
            public void remove() {
538
                throw new UnsupportedOperationException();
539
            }
540

    
541
        }
542
        return new DataValuesIterator(this);
543
    }
544

    
545
    public boolean hasContextValue(String name) {
546
        name = name.toLowerCase();
547
        if (name.equals("store")) {
548
            return true;
549
        }
550

    
551
        if (name.equals("featuretype")) {
552
            return true;
553
        }
554

    
555
        if (name.equals("feature")) {
556
            return true;
557
        }
558
        return false;
559
    }
560

    
561
    public boolean hasDataValue(String name) {
562
        name = name.toLowerCase();
563
        return this.data.getType().getIndex(name) >= 0;
564
    }
565
    
566
    public Instant getInstant(int index) {
567
        return ((Instant) this.get(index,Date.class,DataTypes.INSTANT));
568
    }
569

    
570
    public Instant getInstant(String name) {
571
        return this.getInstant(this.data.getType().getIndex(name));
572
    }
573

    
574
    public Interval getInterval(int index) {
575
        return ((Interval) this.get(index,Date.class,DataTypes.INTERVAL));
576
    }
577

    
578
    public Interval getInterval(String name) {
579
        return this.getInterval(this.data.getType().getIndex(name));
580
    }
581

    
582
    public DynObject getAsDynObject() {
583
        DynObjectFeatureFacade facade = new DynObjectFeatureFacade();
584
        facade.setFeature(this);
585
        return facade;
586
    }
587

    
588
    public String toString() {
589
       // StringBuffer buffer = new StringBuffer("Feature with values: ");
590
            StringBuffer buffer = new StringBuffer("");
591
        FeatureAttributeDescriptor[] attributeDescriptors =
592
            getType().getAttributeDescriptors();
593
        for (int i = 0; i < attributeDescriptors.length; i++) {
594
            String name = attributeDescriptors[i].getName();
595
            //buffer.append(name).append("=").append(get(name));
596
            buffer.append(get(name));
597
            if (i < attributeDescriptors.length - 1) {
598
                buffer.append(", ");
599
            }
600
        }
601
        return buffer.toString();
602
    }
603
    
604
    
605

    
606

    
607
        /**
608
     * @return the inserted
609
     */
610
    public boolean isInserted() {
611
        return inserted;
612
    }
613

    
614
    
615
    /**
616
     * @param inserted the inserted to set
617
     */
618
    public void setInserted(boolean inserted) {
619
        this.inserted = inserted;
620
    }
621

    
622
    public EvaluatorData getEvaluatorData() {
623
        return this;
624
    }
625
}