Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / feature / spi / DefaultFeatureProvider.java @ 47436

History | View | Annotate | Download (12.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 modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.feature.spi;
24

    
25
import java.math.BigDecimal;
26
import org.apache.commons.lang3.ArrayUtils;
27
import org.apache.commons.lang3.StringUtils;
28
import org.gvsig.fmap.dal.DataTypes;
29
import org.gvsig.fmap.dal.feature.EditableFeatureType;
30
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
31
import org.gvsig.fmap.dal.feature.FeatureType;
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.primitive.Envelope;
34
import org.gvsig.timesupport.Time;
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dataTypes.Coercion;
37
import org.gvsig.tools.dataTypes.CoercionException;
38
import org.gvsig.tools.math.BigDecimalUtils;
39

    
40
/**
41
 * Default implementation for {@link FeatureProvider}
42
 *
43
 */
44
public class DefaultFeatureProvider implements FeatureProvider {
45

    
46
    protected FeatureType featureType;
47
    protected boolean[] nulls;
48
    protected Object[] values;
49
    protected Geometry defaultGeometry;
50
    protected Envelope envelope;
51
    private Object oid;
52
    private boolean isNew = false;
53
    
54
    private String[] extraValuesNames;
55
    private Object[] extraValues;
56
    
57
    protected boolean broken;
58

    
59
    public DefaultFeatureProvider(FeatureType type) {
60
//        if (type instanceof EditableFeatureType) {
61
//            throw new IllegalArgumentException("type can't be editable.");
62
//        }
63
        this.featureType = type;
64
        this.values = new Object[featureType.size()];
65
        this.nulls = new boolean[featureType.size()];
66

    
67
        this.envelope = null;
68
        this.defaultGeometry = null;
69
        this.oid = null;
70
        this.broken = false;
71
    }
72

    
73
    public DefaultFeatureProvider(FeatureType type, Object oid) {
74
        this(type);
75
        this.oid = oid;
76
    }
77

    
78
    public DefaultFeatureProvider(FeatureType type, DefaultFeatureProvider data) {
79
        this(type);
80
        this.oid = data.oid;
81
        this.defaultGeometry = data.defaultGeometry;
82
        this.envelope = data.envelope;
83
        this.isNew = data.isNew;
84
    }
85

    
86
    public boolean isReadOnly(int i) {
87
        FeatureAttributeDescriptor attribute = featureType.getAttributeDescriptor(i);
88
        if (attribute.getEvaluator() != null) {
89
            return true;
90
        }
91
        return false;
92
    }
93

    
94
    @Override
95
    public void set(int i, Object value) {
96
        FeatureAttributeDescriptor attribute = featureType.getAttributeDescriptor(i);
97
//        if (this.isReadOnly(i)) {
98
//            return;
99
//        }
100
        if (featureType.getDefaultGeometryAttributeIndex() == i) {
101
            if (value instanceof Geometry) {
102
                defaultGeometry = (Geometry) value;
103
            } else {
104
                try {
105
                    defaultGeometry = (Geometry) ToolsLocator.getDataTypesManager().coerce(DataTypes.GEOMETRY, value);
106
                } catch (CoercionException ex) {
107

    
108
                }
109
            }
110
            envelope = null;
111
        } else if(value != null) {
112
            Class objectClass = attribute.getObjectClass();
113
            if (objectClass != null) {
114
                if (!objectClass.isInstance(value)) {
115
                    try {
116
                        Coercion coercer = attribute.getDataType().getCoercion();
117
                        if (attribute.getType() == DataTypes.STRING && value instanceof Boolean) {
118
                            value = coercer.coerce(value, attribute.getCoercionContext());
119
                            value = StringUtils.left((String) value, attribute.getSize());
120
                        } else {
121
                            value = coercer.coerce(value, attribute.getCoercionContext());
122
                        }
123
                    } catch (CoercionException e) {
124
                        throw new IllegalArgumentException("Can't convert to "
125
                                + attribute.getDataType().getName()
126
                                + " from '"
127
                                + value.getClass().getName()
128
                                + "' with value '"
129
                                + value.toString()
130
                                + "' and context '"
131
                                + attribute.getCoercionContext()
132
                                + "' to assign to '"
133
                                + attribute.getName()
134
                                + "'.",e);
135
                    }
136
                } else {
137
                    try {
138
                        switch(attribute.getType()){
139
                            case DataTypes.DECIMAL:
140
                                value = BigDecimalUtils.force((BigDecimal) value, attribute.getScale(), attribute.getPrecision());
141
                                break;
142
                        }
143
                    } catch(Throwable th) {
144
                            throw new IllegalArgumentException("Can't assign "
145
                                + value.toString()
146
                                + " to '"
147
                                + attribute.getName()
148
                                + "'.",th);
149

    
150
                    }
151
                }
152
            }
153
        }
154
        if (value == null) {
155
            values[i] = attribute.getDefaultValue();
156
            nulls[i] = true;
157
        } else {
158
            values[i] = value;
159
            nulls[i] = false;
160
        }
161
    }
162

    
163
    /*
164
     * (non-Javadoc)
165
     *
166
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#set(java.lang.String,
167
     * java.lang.Object)
168
     */
169
    public void set(String name, Object value) {
170
        set(featureType.getIndex(name), value);
171
    }
172

    
173
    /*
174
     * (non-Javadoc)
175
     *
176
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#get(int)
177
     */
178
    public Object get(int i) {
179
        return values[i];
180
    }
181

    
182
    /*
183
     * (non-Javadoc)
184
     *
185
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#get(java.lang.String)
186
     */
187
    public Object get(String name) {
188
        FeatureAttributeDescriptor featureAttributeDescriptor = featureType.getAttributeDescriptor(name);
189
        if(featureAttributeDescriptor == null){
190
            throw new IllegalStateException("Can't get attribute '"+name+"'");
191
        }
192
        return values[featureAttributeDescriptor.getIndex()];
193
    }
194

    
195
    /*
196
     * (non-Javadoc)
197
     *
198
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#getType()
199
     */
200
    public FeatureType getType() {
201
        return featureType;
202
    }
203

    
204
    /*
205
     * (non-Javadoc)
206
     *
207
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#getCopy()
208
     */
209
    public FeatureProvider getCopy() {
210
        DefaultFeatureProvider data = new DefaultFeatureProvider(
211
                this.getType());
212
        return getCopy(data);
213
    }
214

    
215
    /**
216
     * Copy values from current instance to <code>data</code>
217
     */
218
    protected FeatureProvider getCopy(DefaultFeatureProvider data) {
219
        data.oid = this.oid;
220
        System.arraycopy(this.values, 0, data.values, 0, this.values.length);
221
        data.defaultGeometry = this.defaultGeometry;
222
        data.envelope = this.envelope;
223
        data.isNew = this.isNew;
224
        if (this.extraValues!=null) {
225
            data.extraValues = new Object[this.extraValues.length];
226
            System.arraycopy(this.extraValues, 0, data.extraValues, 0, this.extraValues.length);
227
        } else {
228
            data.extraValues = null;
229
        }
230
        if (this.extraValuesNames!=null) {
231
            data.extraValuesNames = new String[this.extraValuesNames.length];
232
            System.arraycopy(this.extraValuesNames, 0, data.extraValuesNames, 0, this.extraValuesNames.length);
233
        } else {
234
            data.extraValuesNames = null;
235
        }
236
        data.broken = this.broken;
237
        return data;
238
    }
239

    
240
    /*
241
     * (non-Javadoc)
242
     *
243
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#getDefaultEnvelope()
244
     */
245
    public Envelope getDefaultEnvelope() {
246
        if (envelope == null && getDefaultGeometry() != null) {
247
            envelope = getDefaultGeometry().getEnvelope();
248
        }
249
        return envelope;
250
    }
251

    
252
    /*
253
     * (non-Javadoc)
254
     *
255
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#getDefaultGeometry()
256
     */
257
    public Geometry getDefaultGeometry() {
258
        return this.defaultGeometry;
259
    }
260

    
261
    @Override
262
    public Time getDefaultTime() {
263
        int index = featureType.getDefaultTimeAttributeIndex();
264
        Object value = this.get(index);
265
        if (! (value instanceof Time) ) {
266
            try {
267
                value = (Time) ToolsLocator.getDataTypesManager().coerce(DataTypes.INSTANT, value);
268
            } catch (CoercionException ex) {
269

    
270
            }
271
        }
272
        return (Time) value;
273
    }
274

    
275
    /*
276
     * (non-Javadoc)
277
     *
278
     * @see
279
     * org.gvsig.fmap.dal.feature.spi.FeatureProvider#setDefaultEnvelope(org
280
     * .gvsig.fmap.geom.primitive.Envelope)
281
     */
282
    public void setDefaultEnvelope(Envelope envelope) {
283
        this.envelope = envelope;
284
    }
285

    
286
    @Override
287
    public void setDefaultGeometry(Geometry geom) {
288
        int i = featureType.getDefaultGeometryAttributeIndex();
289
        this.set(i, geom);
290
    }
291

    
292
    @Override
293
    public void setDefaultTime(Time time) {
294
        int i = featureType.getDefaultTimeAttributeIndex();
295
        this.set(i, time);
296
    }
297

    
298

    
299
    public boolean isNull(int i) {
300
        return nulls[i];
301
    }
302

    
303
    /*
304
     * (non-Javadoc)
305
     *
306
     * @see
307
     * org.gvsig.fmap.dal.feature.spi.FeatureProvider#isNull(java.lang.String)
308
     */
309
    public boolean isNull(String name) {
310
        int i = featureType.getIndex(name);
311
        return isNull(i);
312
    }
313

    
314
    /*
315
     * (non-Javadoc)
316
     *
317
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#getOID()
318
     */
319
    public Object getOID() {
320
        return this.oid;
321
    }
322

    
323
    /*
324
     * (non-Javadoc)
325
     *
326
     * @see
327
     * org.gvsig.fmap.dal.feature.spi.FeatureProvider#setOID(java.lang.Object)
328
     */
329
    public void setOID(Object oid) {
330
        this.oid = oid;
331
    }
332

    
333
    /*
334
     * (non-Javadoc)
335
     *
336
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#isNew()
337
     */
338
    public boolean isNew() {
339
        return isNew;
340
    }
341

    
342
    /*
343
     * (non-Javadoc)
344
     *
345
     * @see org.gvsig.fmap.dal.feature.spi.FeatureProvider#setNew(boolean)
346
     */
347
    public void setNew(boolean isNew) {
348
        this.isNew = isNew;
349
    }
350

    
351
    @Override
352
    public void setExtraValue(int index, Object value) {
353
        this.extraValues[index] = value;
354
    }
355

    
356
    @Override
357
    public Object getExtraValue(int index) {
358
        if( this.extraValues == null ) {
359
            return null;
360
        }
361
        return this.extraValues[index];
362
    }
363

    
364
    @Override
365
    public Object getExtraValue(String name) {
366
        if( this.extraValuesNames == null || this.extraValues == null) {
367
            return null;
368
        }
369
        for (int i = 0; i < this.extraValuesNames.length; i++) {
370
            if( StringUtils.equalsIgnoreCase(this.extraValuesNames[i], name) ) {
371
                return this.extraValues[i];
372
            }
373
        }
374
        return null;
375
    }
376

    
377
    @Override
378
    public boolean hasExtraValue(String name) {
379
        if( this.extraValuesNames == null ) {
380
            return false;
381
        }
382
        for (int i = 0; i < this.extraValuesNames.length; i++) {
383
            if( StringUtils.equalsIgnoreCase(this.extraValuesNames[i], name) ) {
384
                return true;
385
            }
386
        }
387
        return false;
388
    }
389

    
390
    @Override
391
    public void setExtraValueNames(String[] extraValueNames) {
392
        this.extraValuesNames = extraValueNames;
393
        this.extraValues = new Object[this.extraValuesNames.length];
394
    }
395

    
396
    @Override
397
    public boolean isBroken() {
398
        return this.broken;
399
    }
400
    
401
    
402
}