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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
231

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

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

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

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

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

    
262
    class UnableToGetReferenceException extends BaseRuntimeException {
263

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

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

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

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

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

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

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

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

    
321

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

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

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

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

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

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

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

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

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

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

    
398
        return value;
399
    }
400

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
488
        throw new IllegalArgumentException(name);
489
    }
490

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
607

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

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

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