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 / DefaultEditableFeature.java @ 46875

History | View | Annotate | Download (22.4 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.math.BigDecimal;
27
import java.time.LocalDate;
28
import java.time.LocalDateTime;
29
import java.time.LocalTime;
30
import java.time.format.DateTimeFormatter;
31
import java.time.temporal.TemporalAccessor;
32
import java.util.Date;
33
import java.util.Set;
34
import java.util.function.Predicate;
35
import javax.json.JsonNumber;
36
import javax.json.JsonObject;
37
import javax.json.JsonString;
38
import javax.json.JsonValue;
39
import org.gvsig.fmap.dal.DataTypeUtils;
40
import org.gvsig.fmap.dal.DataTypes;
41
import org.gvsig.fmap.dal.exception.DataException;
42

    
43
import org.gvsig.fmap.dal.feature.EditableFeature;
44
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
49
import org.gvsig.fmap.geom.Geometry;
50
import org.gvsig.fmap.geom.GeometryUtils;
51
import org.gvsig.timesupport.Instant;
52
import org.gvsig.timesupport.Interval;
53
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.geom.type.GeometryType;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58

    
59
public class DefaultEditableFeature extends DefaultFeature implements
60
        EditableFeature {
61

    
62
    private static final Logger LOG = LoggerFactory.getLogger(DefaultEditableFeature.class);
63

    
64
    private DefaultFeature source;
65
//    private boolean inserted;
66
    private boolean modified;
67

    
68
    protected DefaultEditableFeature(DefaultFeature feature) {
69
        super(feature);
70
        this.source = feature;
71
//        this.inserted = this.source!=null;
72
        this.modified = false;
73
    }
74

    
75
    protected DefaultEditableFeature(DefaultEditableFeature feature) {
76
        super(feature);
77
        this.source = (DefaultFeature) feature.getSource();
78
//        this.inserted = this.source!=null;
79
        this.modified = feature.modified;
80
    }
81

    
82
    public DefaultEditableFeature(DefaultFeatureStore store, FeatureProvider data) {
83
        // Se trata de un editable feature sobre una ya existente
84
        super(store, data);
85
        this.source = null;
86
//        this.inserted = this.source!=null;
87
        this.modified = false;
88
    }
89

    
90
    @Override
91
    public Feature getSource() {
92
        return this.source;
93
    }
94

    
95
    @Override
96
    public boolean isUpdatable() {
97
        return super.isInserted();
98
    }
99
    
100
    @Override
101
    public void setUpdatable(boolean updatable) {
102
        super.setInserted(updatable);
103
    }
104
    
105
    @Override
106
    public EditableFeature getEditable() {
107
        return this;
108
    }
109

    
110
    @Override
111
    public Feature getCopy() {
112
        return new DefaultEditableFeature(this);
113
    }
114

    
115
    @Override
116
    public Feature getNotEditableCopy() {
117
        return new DefaultFeature(this);
118
    }
119

    
120
    @Override
121
    public void setDefaultGeometry(Geometry geometry) {
122
        FeatureAttributeDescriptor attribute = this.getType()
123
                .getAttributeDescriptor(
124
                        this.getType().getDefaultGeometryAttributeIndex());
125
        modified = true;
126
        this.set(attribute, geometry);
127
    }
128

    
129
    public void __setitem__(String name, Object value) {
130
        this.set(name, value);
131
    }
132
    
133
    @Override
134
    public void set(String name, Object value) {
135
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
136
        if ( attribute == null ) {
137
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
138
        }
139
        modified = true;
140
        this.set(attribute, value);
141
    }
142

    
143
    @Override
144
    public void set(int index, Object value) {
145
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
146
        modified = true;
147
        this.set(attribute, value);
148
    }
149

    
150
    @Override
151
    public void setArray(String name, Object[] value) {
152
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
153
        if ( attribute == null ) {
154
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
155
        }
156
        modified = true;
157
        this.set(attribute, value);
158
    }
159

    
160
    @Override
161
    public void setArray(int index, Object[] value) {
162
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
163
        modified = true;
164
        this.set(attribute, value);
165
    }
166
    
167
    @Override
168
    public void setBoolean(String name, boolean value) {
169
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
170
        if ( attribute == null ) {
171
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
172
        }
173
        modified = true;
174
        this.set(attribute, Boolean.valueOf(value));
175
    }
176

    
177
    @Override
178
    public void setBoolean(int index, boolean value) {
179
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
180
        modified = true;
181
        this.set(attribute, value);
182
    }
183

    
184
    @Override
185
    public void setByte(String name, byte value) {
186
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
187
        if ( attribute == null ) {
188
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
189
        }
190
        modified = true;
191
        this.set(attribute, value);
192
    }
193

    
194
    @Override
195
    public void setByte(int index, byte value) {
196
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
197
        modified = true;
198
        this.set(attribute, value);
199
    }
200

    
201
    @Override
202
    public void setDate(String name, Date value) {
203
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
204
        if ( attribute == null ) {
205
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
206
        }
207
        modified = true;
208
        this.set(attribute, value);
209
    }
210

    
211
    @Override
212
    public void setDate(int index, Date value) {
213
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
214
        modified = true;
215
        this.set(attribute, value);
216
    }
217

    
218
    @Override
219
    public void setDouble(String name, double value) {
220
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
221
        if ( attribute == null ) {
222
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
223
        }
224
        modified = true;
225
        this.set(attribute, value);
226
    }
227

    
228
    @Override
229
    public void setDouble(int index, double value) {
230
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
231
        modified = true;
232
        this.set(attribute, value);
233
    }
234

    
235
    @Override
236
    public void setDecimal(String name, BigDecimal value) {
237
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
238
        if ( attribute == null ) {
239
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
240
        }
241
        modified = true;
242
        this.set(attribute, value);
243
    }
244

    
245
    @Override
246
    public void setDecimal(int index, BigDecimal value) {
247
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
248
        modified = true;
249
        this.set(attribute, value);
250
    }
251

    
252
    @Override
253
    public void setFeature(String name, Feature value) {
254
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
255
        if ( attribute == null ) {
256
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
257
        }
258
        modified = true;
259
        this.set(attribute, value);
260
    }
261

    
262
    @Override
263
    public void setFeature(int index, Feature value) {
264
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
265
        modified = true;
266
        this.set(attribute, value);
267
    }
268

    
269
    @Override
270
    public void setFloat(String name, float value) {
271
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
272
        if ( attribute == null ) {
273
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
274
        }
275
        modified = true;
276
        this.set(attribute, value);
277
    }
278

    
279
    @Override
280
    public void setFloat(int index, float value) {
281
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
282
        modified = true;
283
        this.set(attribute, value);
284
    }
285

    
286
    @Override
287
    public void setGeometry(String name, Geometry value) {
288
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
289
        if ( attribute == null ) {
290
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
291
        }
292
        modified = true;
293
        this.set(attribute, value);
294
    }
295

    
296
    @Override
297
    public void setGeometry(int index, Geometry value) {
298
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
299
        modified = true;
300
        this.set(attribute, value);
301
    }
302

    
303
    @Override
304
    public void setInt(String name, int value) {
305
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
306
        if ( attribute == null ) {
307
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
308
        }
309
        modified = true;
310
        this.set(attribute, value);
311
    }
312

    
313
    @Override
314
    public void setInt(int index, int value) {
315
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
316
        modified = true;
317
        this.set(attribute, value);
318
    }
319

    
320
    @Override
321
    public void setLong(String name, long value) {
322
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
323
        if ( attribute == null ) {
324
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
325
        }
326
        modified = true;
327
        this.set(attribute, value);
328
    }
329

    
330
    @Override
331
    public void setLong(int index, long value) {
332
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
333
        modified = true;
334
        this.set(attribute, value);
335
    }
336

    
337
    @Override
338
    public void setString(String name, String value) {
339
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
340
        if ( attribute == null ) {
341
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
342
        }
343
        modified = true;
344
        this.set(attribute, value);
345
    }
346

    
347
    @Override
348
    public void setString(int index, String value) {
349
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
350
        modified = true;
351
        this.set(attribute, value);
352
    }
353

    
354
    @Override
355
    public void copyFrom(JsonObject values) {
356
        this.copyFrom(values, null);    
357
    }
358

    
359
//    private boolean notCopyAttribute(FeatureAttributeDescriptor attr,Predicate<FeatureAttributeDescriptor> filter) {
360
//        // helper function to use in copyFrom
361
//        if (attr==null  ) {
362
//            return true;
363
//        }
364
//        if (attr.isAutomatic()  || attr.isComputed() ) {
365
//            return true;
366
//        }
367
//        if( this.isInserted() &&  attr.isReadOnly()) {
368
//            return true;
369
//        }
370
//        if( filter!=null && !filter.test(attr) ) {
371
//            return true;
372
//        }
373
//        return false;
374
//    }
375
    
376
    @Override
377
    public void copyFrom(JsonObject values, Predicate<FeatureAttributeDescriptor> filter) {
378
      // iterate over the attributes and copy one by one
379
      if( values == null ) {
380
          throw new IllegalArgumentException("'values' argument can't be null");
381
      }
382
      boolean geometryCopied = false;
383
        for (FeatureAttributeDescriptor attr : this.getType()) {
384
            if( !canSetValue(attr, filter) ) {
385
                continue;
386
            }
387
            String attrname = attr.getName();
388
            if( !values.containsKey(attrname) ) {
389
                continue;
390
            }           
391
            Object value;
392
            JsonValue jsonValue = values.get(attrname);
393
            if(jsonValue == null){
394
                value = null;
395
            } else {
396
                try {
397
                    switch( jsonValue.getValueType() ) {
398
                        case STRING:
399
                            String s = ((JsonString)jsonValue).getString();
400
                            switch(attr.getType()) {
401
                                case DataTypes.GEOMETRY:
402
                                    value = GeometryUtils.createFrom(s);
403
                                    geometryCopied = true;
404
                                    break;
405
                                case DataTypes.TIMESTAMP:
406
                                    try {
407
                                        TemporalAccessor x = DateTimeFormatter.ISO_DATE_TIME.parse(s);
408
                                        LocalDateTime date = LocalDateTime.from(x);
409
                                        value = java.sql.Timestamp.valueOf(date);
410
                                    } catch(Exception ex) {
411
                                        value = s;
412
                                    }
413
                                    break;
414
                                case DataTypes.DATE:
415
                                    try {
416
                                        TemporalAccessor x = DateTimeFormatter.ISO_DATE.parse(s);
417
                                        LocalDate date = LocalDate.from(x);
418
                                        value = java.sql.Date.valueOf(date);
419
                                    } catch(Exception ex) {
420
                                        value = s;
421
                                    }
422
                                    break;
423
                                case DataTypes.TIME:
424
                                    try {
425
                                        TemporalAccessor x = DateTimeFormatter.ISO_TIME.parse(s);
426
                                        LocalTime date = LocalTime.from(x);
427
                                        value = java.sql.Time.valueOf(date);
428
                                    } catch(Exception ex) {
429
                                        value = s;
430
                                    }
431
                                    break;
432
                                case DataTypes.BYTEARRAY:
433
                                    value = DataTypeUtils.coerce(DataTypes.BYTEARRAY, s, null);
434
                                    break;
435
                                case DataTypes.STRING:
436
                                default:
437
                                    value = s;
438
                                    break;
439
                            }
440
                            break;
441
                        case NUMBER:
442
                            JsonNumber n =  (JsonNumber) jsonValue;
443
                            switch(attr.getType()) {
444
                                case DataTypes.DECIMAL:
445
                                    value = n.bigDecimalValue();
446
                                    break;
447
                                case DataTypes.BYTE:
448
                                    value = n.bigDecimalValue();
449
                                    break;
450
                                case DataTypes.FLOAT:
451
                                case DataTypes.DOUBLE:
452
                                    value = n.doubleValue();
453
                                    break;
454
                                case DataTypes.INT:
455
                                    value = n.intValue();
456
                                    break;
457
                                case DataTypes.LONG:
458
                                    value = n.longValue();
459
                                    break;
460
                                default:
461
                                    value = n.toString();
462
                                    break;
463
                            }
464
                            break;
465
                        case TRUE:
466
                            value = true;
467
                            break;
468
                        case FALSE:
469
                            value = false;
470
                            break;
471
                        case NULL:
472
                            value = null;
473
                            break;
474
                        default:
475
                            value = values.getString(attrname);
476
                            break;
477
                    }
478
                } catch(Exception ex) {
479
                    continue;
480
                }
481
            }
482
            if (value == null && !attr.allowNull()) {
483
                continue;
484
            }
485
            try {
486
                set(attr.getIndex(), value);
487
            } catch(Throwable th) {
488
                // Ignore
489
            }
490
        }
491
        FeatureAttributeDescriptor attr = this.getType().getDefaultGeometryAttribute();
492
        if (attr!=null && !geometryCopied) {
493
            if( filter==null || filter.test(attr) ) {
494
                GeometryType geomType = this.getType().getDefaultGeometryAttribute().getGeomType();
495
                Set<String> keys = values.keySet();
496
                for (String key : keys) {
497
                    try {
498
                        String wkt = values.getString(key);
499
                        Geometry geometry = GeometryUtils.createFrom(wkt);
500
                        if (GeometryUtils.isSubtype(geomType.getType(), geometry.getType()) || GeometryUtils.canAggregate(geomType.getType(), geometry.getType())) {
501
                            this.setDefaultGeometry(geometry);
502
                            break;
503
                        }
504
                    } catch (Throwable tr) {
505
                        LOG.trace("Can't get geometry from field {}.", new Object[]{key});
506
                    };
507
                }
508
            }
509
        }
510
    }
511
    
512
    @Override
513
    public void copyFrom(Feature source) {
514
        this.copyFrom(source, null);
515
    }
516
    
517
    @Override
518
    public void copyFrom(Feature source, Predicate<FeatureAttributeDescriptor> filter) {
519
      // iterate over the attributes and copy one by one
520
        if( source == null ) {
521
            throw new IllegalArgumentException("'source' argument can't be null");
522
        }
523
        FeatureType sourceType = source.getType();
524
        for (FeatureAttributeDescriptor attrTarget : this.getType()) {
525
            if( !canSetValue(attrTarget, filter) ) {
526
                continue;
527
            }
528
            String attrname = attrTarget.getName();
529
            FeatureAttributeDescriptor attrSource = sourceType.getAttributeDescriptorFromAll(attrname);
530
            if( attrSource==null ) {
531
              continue;
532
            }
533
            Object value;
534
            if( attrSource.hasDataProfile() ) {
535
                value = source.getFromProfile(attrname);
536
                if( value == null ) {
537
                    value = source.get(attrname);
538
                }
539
            } else {
540
                value = source.get(attrname);
541
            }
542
            if (value == null && !attrTarget.allowNull()) {
543
                continue;
544
            }
545
            try {
546
                set(attrTarget.getIndex(), value);
547
            } catch(Throwable th) {
548
                LOG.trace("The exception thrown is: ", th);
549
            }
550
        }
551
        
552
    }
553
    
554

    
555

    
556
    @Override
557
    public void setInstant(String name, Instant value) {
558
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
559
        if ( attribute == null ) {
560
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
561
        }
562
        modified = true;
563
        this.set(attribute, value);
564
    }
565

    
566
    @Override
567
    public void setInstant(int index, Instant value) {
568
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
569
        modified = true;
570
        this.set(attribute, value);
571
    }
572

    
573
    @Override
574
    public void setInterval(String name, Interval value) {
575
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(name);
576
        if ( attribute == null ) {
577
            throw new IllegalArgumentException("Attribute '" + name + "' does not exits in the feature.");
578
        }
579
        modified = true;
580
        this.set(attribute, value);
581
    }
582

    
583
    @Override
584
    public void setInterval(int index, Interval value) {
585
        FeatureAttributeDescriptor attribute = this.getType().getAttributeDescriptor(index);
586
        modified = true;
587
        this.set(attribute, value);
588
    }
589
    
590
    @Override
591
    public Object getExtraValue(String name) {
592
        Object value;
593
        FeatureExtraColumns columns = this.getType().getExtraColumns();
594
        int index = columns.getIndexOf(name);
595
        if (index >= 0) {
596
            EditableFeatureAttributeDescriptor attrdesc = columns.get(index);
597
            value = attrdesc.getFeatureAttributeEmulator().get(this);
598
            return value;
599
        }
600
        value = this.data.getExtraValue(name);
601
        return value;
602
    }
603

    
604
    @Override
605
    public void validate(int check) throws DataException {
606
        ((DefaultFeatureType) this.data.getType()).validateFeature(this, check);
607
    }
608
    
609
    public boolean isModified() {
610
        return modified;
611
    }
612

    
613
    @Override
614
    public Feature getOriginal() {
615
        FeatureStore store = this.getStore();
616
        if( store == null ) {
617
            return null;
618
        }
619
        Feature original = store.getOriginalFeature(this);
620
        return original;
621
    }
622

    
623
}