Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.lib / src / main / java / org / gvsig / fmap / dal / feature / spi / simpleprovider / BaseSimpleStoreProvider.java @ 44057

History | View | Annotate | Download (26.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.spi.simpleprovider;
25

    
26
import java.io.File;
27
import java.io.IOException;
28
import java.util.ArrayList;
29
import java.util.HashMap;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Locale;
33

    
34
import org.apache.commons.lang3.StringUtils;
35
import org.cresques.cts.IProjection;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.DataServerExplorer;
39
import org.gvsig.fmap.dal.DataStore;
40
import org.gvsig.fmap.dal.DataStoreNotification;
41
import org.gvsig.fmap.dal.DataTypes;
42
import org.gvsig.fmap.dal.FileHelper;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.InitializeException;
45
import org.gvsig.fmap.dal.exception.OpenException;
46
import org.gvsig.fmap.dal.exception.ReadException;
47
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
48
import org.gvsig.fmap.dal.feature.EditableFeature;
49
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
57
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
58
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
59
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
60
import org.gvsig.fmap.dal.resource.file.FileResource;
61
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
62
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
63
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
64
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
65
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
66
import org.gvsig.fmap.geom.Geometry;
67
import org.gvsig.fmap.geom.GeometryLocator;
68
import org.gvsig.fmap.geom.GeometryManager;
69
import org.gvsig.fmap.geom.aggregate.MultiPoint;
70
import org.gvsig.fmap.geom.primitive.Envelope;
71
import org.gvsig.fmap.geom.primitive.Point;
72
import org.gvsig.fmap.geom.type.GeometryType;
73
import org.gvsig.tools.ToolsLocator;
74
import org.gvsig.tools.dataTypes.CoercionException;
75
import org.gvsig.tools.dataTypes.DataType;
76
import org.gvsig.tools.dataTypes.DataTypesManager;
77
import org.gvsig.tools.dataTypes.DataTypesManager.Coercion;
78
import org.gvsig.tools.dataTypes.DataTypesManager.CoercionWithLocale;
79
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
80
import org.gvsig.tools.exception.BaseException;
81
import org.gvsig.tools.task.SimpleTaskStatus;
82
import org.gvsig.tools.task.TaskStatusManager;
83
import org.gvsig.tools.visitor.VisitCanceledException;
84
import org.gvsig.tools.visitor.Visitor;
85
import org.slf4j.Logger;
86
import org.slf4j.LoggerFactory;
87

    
88
public class BaseSimpleStoreProvider extends AbstractMemoryStoreProvider implements
89
        ResourceConsumer {
90

    
91
    private static final Logger LOGGER = LoggerFactory.getLogger(BaseSimpleStoreProvider.class);
92

    
93

    
94
    private final ResourceProvider resource;
95

    
96
    private long counterNewsOIDs = 0;
97
    private Envelope envelope;
98
    private boolean need_calculate_envelope = false;
99
    private final SimpleTaskStatus taskStatus;
100
    private String name = "";
101
    private final SimpleReaderFactory readerFactory;
102

    
103
    @SuppressWarnings("OverridableMethodCallInConstructor")
104
    public BaseSimpleStoreProvider(
105
            SimpleReaderFactory readerFactory,
106
            BaseSimpleStoreParameters parameters,
107
            DataStoreProviderServices storeServices
108
        ) throws InitializeException {
109
        super(
110
                parameters,
111
                storeServices,
112
                FileHelper.newMetadataContainer(readerFactory.getName())
113
        );
114
        this.readerFactory = readerFactory;
115
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
116
        this.taskStatus = manager.createDefaultSimpleTaskStatus(readerFactory.getName());
117

    
118
        counterNewsOIDs = 0;
119

    
120
        File file = getParameters().getFile();
121
        resource = this.createResource(
122
                FileResource.NAME,
123
                new Object[]{file.getAbsolutePath()}
124
        );
125

    
126
        resource.addConsumer(this);
127
        initializeFeatureTypes();
128
    }
129

    
130
    @Override
131
    public BaseSimpleStoreParameters getParameters() {
132
        return (BaseSimpleStoreParameters) super.getParameters();
133
    }
134

    
135
    @Override
136
    public String getProviderName() {
137
        return readerFactory.getName();
138
    }
139

    
140
    @Override
141
    public boolean allowWrite() {
142
        return false;
143
    }
144

    
145
    private String getFullFileName() {
146
        // Usar solo para mostrar mensajes en el logger.
147
        String s;
148
        try {
149
            s = getParameters().getFile().getAbsolutePath();
150
        } catch (Exception e2) {
151
            s = "(unknow)";
152
        }
153
        return s;
154
    }
155

    
156
    @Override
157
    @SuppressWarnings("UseSpecificCatch")
158
    public void open() throws OpenException {
159
        if ( this.data != null ) {
160
            return;
161
        }
162
        this.data = new ArrayList<>();
163
        resource.setData(new HashMap());
164
        counterNewsOIDs = 0;
165
        try {
166
            loadFeatures();
167
        } catch (RuntimeException e) {
168
            LOGGER.warn("Can't load features from JExcel '" + getFullFileName() + "'.", e);
169
            throw e;
170
        } catch (Exception e) {
171
            LOGGER.warn("Can't load features from JExcel '" + getFullFileName() + "'.", e);
172
            throw new RuntimeException(e);
173
        }
174
    }
175

    
176
    @Override
177
    public DataServerExplorer getExplorer() throws ReadException {
178
        DataManager manager = DALLocator.getDataManager();
179
        FilesystemServerExplorerParameters params;
180
        try {
181
            params = (FilesystemServerExplorerParameters) manager
182
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
183
            params.setRoot(this.getParameters().getFile().getParent());
184
            return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
185
        } catch (DataException | ValidateDataParametersException e) {
186
            throw new ReadException(this.getProviderName(), e);
187
        }
188

    
189
    }
190

    
191
    @Override
192
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
193
        throw new UnsupportedOperationException();
194
    }
195

    
196
    @Override
197
    public boolean closeResourceRequested(ResourceProvider resource) {
198
        return true;
199
    }
200

    
201
    @Override
202
    public int getOIDType() {
203
        return DataTypes.LONG;
204
    }
205

    
206
    @Override
207
    public boolean supportsAppendMode() {
208
        return false;
209
    }
210

    
211
    @Override
212
    public void append(FeatureProvider featureProvider) {
213
        throw new UnsupportedOperationException();
214
    }
215

    
216
    @Override
217
    public void beginAppend() {
218
        throw new UnsupportedOperationException();
219
    }
220

    
221
    @Override
222
    public void endAppend() {
223
        throw new UnsupportedOperationException();
224
    }
225

    
226
    @Override
227
    public Object createNewOID() {
228
        return counterNewsOIDs++;
229
    }
230

    
231
    protected void initializeFeatureTypes() throws InitializeException {
232
        try {
233
            this.open();
234
        } catch (OpenException e) {
235
            throw new InitializeException(this.getProviderName(), e);
236
        }
237
    }
238

    
239
    @Override
240
    public Envelope getEnvelope() throws DataException {
241
        this.open();
242
        if ( this.envelope != null ) {
243
            return this.envelope;
244
        }
245
        if ( !this.need_calculate_envelope ) {
246
            return null;
247
        }
248
        FeatureStore fs = this.getFeatureStore();
249
        FeatureType ft = fs.getDefaultFeatureType();
250
        FeatureAttributeDescriptor fad = ft.getAttributeDescriptor(ft.getDefaultGeometryAttributeIndex());
251

    
252
        try {
253
            this.envelope = GeometryLocator.getGeometryManager().createEnvelope(fad.getGeomType().getSubType());
254
            fs.accept(new Visitor() {
255
                @Override
256
                public void visit(Object obj) throws VisitCanceledException, BaseException {
257
                    Feature f = (Feature) obj;
258
                    Geometry geom = f.getDefaultGeometry();
259
                    if ( geom != null ) {
260
                        envelope.add(geom.getEnvelope());
261
                    }
262
                }
263
            });
264
        } catch (BaseException e) {
265
            LOGGER.warn("Can't calculate the envelope of JExcel file '" + this.getFullName() + "'.", e);
266
            this.envelope = null;
267
        }
268

    
269
        this.need_calculate_envelope = false;
270
        return this.envelope;
271
    }
272

    
273
    @Override
274
    public Object getDynValue(String name) throws DynFieldNotFoundException {
275
        if ( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
276
            try {
277
                return this.getEnvelope();
278
            } catch (DataException e) {
279
                return null;
280
            }
281
        } else {
282
            if ( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
283
                IProjection pro = this.getParameters().getCRS();
284
                if ( pro != null ) {
285
                    return pro;
286
                }
287
            }
288
        }
289
        return super.getDynValue(name);
290
    }
291

    
292
    @Override
293
    public void resourceChanged(ResourceProvider resource) {
294
        this.getStoreServices().notifyChange(
295
                DataStoreNotification.RESOURCE_CHANGED,
296
                resource);
297
    }
298

    
299
    @Override
300
    public Object getSourceId() {
301
        return this.getParameters().getFile();
302
    }
303

    
304
    @Override
305
    public String getName() {
306
        return this.name;
307
    }
308

    
309
    @Override
310
    public String getFullName() {
311
        return this.getParameters().getFile().getAbsolutePath();
312
    }
313

    
314
    @Override
315
    public ResourceProvider getResource() {
316
        return resource;
317
    }
318

    
319
    private class FieldTypeParser {
320

    
321
        public String name = null;
322
        public int type = DataTypes.STRING;
323
        public int size = 0;
324
        public boolean allowNulls = true;
325

    
326
        private String typename = "string";
327

    
328
        FieldTypeParser() {
329
        }
330

    
331
        private int getType(String value) {
332
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
333
            return dataTypesManager.getType(typename);
334
        }
335

    
336
        // El formato seria:
337
        //   name[:typename[:size[:notnull|null]]]
338
        //   name[__typename[__size[__notnull|null]]]
339
        //
340
        @SuppressWarnings("UseSpecificCatch")
341
        public boolean parse(String value) {
342
            String theTypename = null;
343
            String[] ss = null;
344
            if ( value.contains(":") ) {
345
                ss = value.split(":");
346
            } else if ( value.contains("__") ) {
347
                ss = value.split("__");
348
            }
349
            if ( ss == null ) {
350
                this.name = value;
351
                return true;
352
            }
353
            switch (ss.length) {
354
            case 4:
355
                if ( ss[3].length() > 0 ) {
356
                    if ( "notnull".equalsIgnoreCase(ss[3]) ) {
357
                        this.allowNulls = false;
358
                    } else {
359
                        this.allowNulls = true;
360
                    }
361
                }
362
            case 3:
363
                if ( ss[2].length() > 0 ) {
364
                    try {
365
                        this.size = Integer.parseInt(ss[2]);
366
                    } catch (Exception ex) {
367
                        LOGGER.warn("Ignore incorrect field size for field " + value + " in JExcel header of '" + getFullFileName() + "'.", ex);
368
                    }
369
                }
370
            case 2:
371
                if ( ss[1].length() > 0 ) {
372
                    this.typename = ss[1];
373
                    this.type = this.getType(this.typename);
374
                    if ( this.type == DataTypes.INVALID ) {
375
                        this.type = DataTypes.STRING;
376
                        LOGGER.info("Type '" + theTypename + "' not valid for attribute '" + value + "' in JExcel file '" + getFullFileName() + "'.");
377
                    }
378
                }
379
            case 1:
380
                this.name = ss[0];
381
                break;
382
            }
383

    
384
            if ( this.type != DataTypes.STRING ) {
385
                this.size = 0;
386
            }
387
            return true;
388
        }
389

    
390
    }
391

    
392
    @SuppressWarnings("UseSpecificCatch")
393
    private EditableFeatureType getFeatureType(List<String> headers, int automaticTypes[]) {
394
        EditableFeatureType fType = getStoreServices().createFeatureType(this.getName());
395
        fType.setHasOID(true);
396
        DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
397

    
398
        FieldTypeParser[] fieldTypes = new FieldTypeParser[headers.size()];
399
        //
400
        // Calculamos cuales pueden ser los tipos de datos
401
        //
402
        for ( int i = 0; i < fieldTypes.length; i++ ) {
403
            fieldTypes[i] = new FieldTypeParser();
404
        }
405

    
406
        // Asuminos los tipos pasados por parametro, que se supone
407
        // son los detectados automaticamente.
408
        if ( automaticTypes != null ) {
409
            for ( int i = 0; i < fieldTypes.length && i < automaticTypes.length; i++ ) {
410
                fieldTypes[i].type = automaticTypes[i];
411
            }
412
        }
413
        // Luego probamos con lo que diga las cabezeras del CVS, sobreescribiendo
414
        // los tipos anteriores en caso de definirse en la cabezara.
415
        for ( int i = 0; i < fieldTypes.length; i++ ) {
416
            if ( !fieldTypes[i].parse(headers.get(i)) ) {
417
                continue;
418
            }
419

    
420
        }
421

    
422
        // Y por ultimo hacemos caso a lo que se haya especificado en los parametros
423
        // de apertura del reader, teniendo esto prioridad sobre todo.
424
        int[] param_types = this.getParameters().getFieldTypes();
425
        if ( param_types != null ) {
426
            for ( int i = 0; i < fieldTypes.length && i < param_types.length; i++ ) {
427
                fieldTypes[i].type = param_types[i];
428
            }
429
        }
430

    
431
        int[] param_sizes = this.getParameters().getFieldSizes();
432
        if ( param_sizes != null ) {
433
            for ( int i = 0; i < param_sizes.length; i++ ) {
434
                if ( param_sizes[i] > 0 ) {
435
                    fieldTypes[i].size = param_sizes[i];
436
                }
437
            }
438
        }
439
        //
440
        // Una vez ya sabemos los tipos de datos rellenamos el feature-type
441
        //
442
        for (FieldTypeParser fieldType : fieldTypes) {
443
            EditableFeatureAttributeDescriptor fad = fType.add(fieldType.name, fieldType.type);
444
            fad.setSize(fieldType.size);
445
            fad.setAllowNull(fieldType.allowNulls);
446
            if (fieldType.type == DataTypes.GEOMETRY && fType.getDefaultGeometryAttributeName() == null) {
447
                fType.setDefaultGeometryAttributeName(fieldType.name);
448
            }
449
        }
450
        String[] pointDimensionNames = this.getParameters().getPointDimensionNames();
451
        if ( pointDimensionNames != null ) {
452
//            ToPointEvaluaror evaluator = new ToPointEvaluaror(pointDimensionNames);
453
            PointAttributeEmulator emulator = new PointAttributeEmulator(pointDimensionNames);
454
            EditableFeatureAttributeDescriptor attr = fType.add("the_geom", DataTypes.GEOMETRY, emulator);
455
            GeometryManager geommgr = GeometryLocator.getGeometryManager();
456
            GeometryType gt;
457
            try {
458
                if ( emulator.fieldNames != null && emulator.fieldNames.length <= 2 ) {
459
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
460
                } else {
461
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM3D);
462
                }
463
                attr.setGeometryType(gt);
464
            } catch (Exception e) {
465
                LOGGER.warn("Can't set geometry type for the calculated field in JExcel file '" + getFullFileName() + "'.", e);
466
            }
467
        }
468
        return fType;
469
    }
470

    
471
    static class PointAttributeEmulator implements FeatureAttributeEmulator {
472

    
473
        private static final Logger LOGGER = LoggerFactory.getLogger(PointAttributeEmulator.class);
474

    
475
        private static final int XNAME = 0;
476
        private static final int YNAME = 1;
477
        private static final int ZNAME = 2;
478

    
479
        private final GeometryManager geommgr;
480
        private final String[] fieldNames;
481
        private final Coercion toDouble;
482
        private final DataType dataType;
483
        private int errorcount = 0;
484

    
485
        public PointAttributeEmulator(String[] pointDimensionNames) {
486
            if ( pointDimensionNames.length > 2 ) {
487
                this.fieldNames = new String[3];
488
                this.fieldNames[ZNAME] = pointDimensionNames[2];
489
            } else {
490
                this.fieldNames = new String[2];
491
            }
492
            this.fieldNames[XNAME] = pointDimensionNames[0];
493
            this.fieldNames[YNAME] = pointDimensionNames[1];
494
            this.geommgr = GeometryLocator.getGeometryManager();
495
            DataTypesManager datatypeManager = ToolsLocator.getDataTypesManager();
496

    
497
            this.toDouble = datatypeManager.getCoercion(DataTypes.DOUBLE);
498
            this.dataType = datatypeManager.get(DataTypes.GEOMETRY);
499
        }
500

    
501
        @Override
502
        @SuppressWarnings("UseSpecificCatch")
503
        public Object get(Feature feature) {
504
            try {
505
                Object valueX = feature.get(this.fieldNames[XNAME]);
506
                valueX = toDouble.coerce(valueX);
507
                if ( valueX == null ) {
508
                    return null;
509
                }
510
                Object valueY = feature.get(this.fieldNames[YNAME]);
511
                valueY = toDouble.coerce(valueY);
512
                if ( valueY == null ) {
513
                    return null;
514
                }
515
                Object valueZ = null;
516
                if ( this.fieldNames.length > 2 ) {
517
                    valueZ = toDouble.coerce(feature.get(this.fieldNames[ZNAME]));
518
                    if ( valueZ == null ) {
519
                        return null;
520
                    }
521
                }
522

    
523
                double x = ((Double) valueX);
524
                double y = ((Double) valueY);
525
                Point point;
526
                if ( this.fieldNames.length > 2 ) {
527
                    point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
528
                    double z = ((Double) valueZ);
529
                    point.setCoordinateAt(2, z);
530
                } else {
531
                    point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM2D);
532
                }
533
                return point;
534
            } catch (Exception ex) {
535
                if ( ++errorcount < 5 ) {
536
                    LOGGER.warn("[" + errorcount + "] Can't create point in ODS provider."+
537
                            "XNAME='" + this.fieldNames[XNAME] + 
538
                            "', YNAME='" + this.fieldNames[YNAME] + 
539
                            "', ZNAME='" + ((this.fieldNames.length > 2)? this.fieldNames[ZNAME]: "(2D)") +
540
                            "' feature=" + feature.toString(), ex);
541
                }
542
                return null;
543
            }
544
        }
545

    
546
        @Override
547
        public void set(EditableFeature feature, Object value) {
548
            if ( value == null ) {
549
                return;
550
            }
551
            Point point;
552
            if ( value instanceof MultiPoint ) {
553
                point = (Point) ((MultiPoint) value).getPrimitiveAt(0);
554
            } else {
555
                point = (Point) value;
556
            }
557
            feature.set(this.fieldNames[XNAME], point.getX());
558
            feature.set(this.fieldNames[YNAME], point.getY());
559
            if ( this.fieldNames.length > 2 ) {
560
                feature.set(this.fieldNames[ZNAME], point.getCoordinateAt(2));
561
            }
562
        }
563

    
564
        @Override
565
        public boolean allowSetting() {
566
            return true;
567
        }
568

    
569
        @Override
570
        public String[] getRequiredFieldNames() {
571
            return this.fieldNames;
572
        }
573

    
574
    }
575

    
576

    
577
    @SuppressWarnings("UseSpecificCatch")
578
    private void loadFeatures() throws IOException, DataException,
579
            CoercionException, CloneNotSupportedException {
580
        SimpleReader reader = null;
581

    
582
        try {
583
            List<String> headers;
584
            FeatureStoreProviderServices store = this.getStoreServices();
585

    
586
            boolean ignore_errors = getParameters().getIgnoreErrors();
587

    
588
            reader = this.readerFactory.createReader(this.getParameters());
589
            this.name = reader.getName();
590
            
591
            headers = getParameters().getFieldNames();
592
            if ( headers == null ) {
593
                headers = reader.getFieldNames();
594
            }
595

    
596
            // Initialize the feature types
597
            EditableFeatureType edftype = this.getFeatureType(headers, automaticDetectionOfTypes(reader));
598
            FeatureType ftype = edftype.getNotEditableCopy();
599
            List<FeatureType> ftypes = new ArrayList<>();
600
            ftypes.add(ftype);
601
            store.setFeatureTypes(ftypes, ftype);
602

    
603
            Coercion coercion[] = new Coercion[ftype.size()];
604
            int sizes[] = new int[ftype.size()];
605
            for ( int i = 0; i < ftype.size(); i++ ) {
606
                sizes[i] = -1;
607
                FeatureAttributeDescriptor ad = ftype.getAttributeDescriptor(i);
608
                coercion[i] = ad.getDataType().getCoercion();
609
                if ( ad.getDataType().getType() == DataTypes.STRING ) {
610
                    if ( ad.getSize() == 0 ) {
611
                        // Es un string y no tiene un size asignado.
612
                        // Lo ponemos a cero para calcularlo.
613
                        sizes[i] = 0;
614
                    }
615
                }
616
            }
617
            if ( ftype.getDefaultGeometryAttributeName() != null ) {
618
                this.need_calculate_envelope = true;
619
            }
620

    
621
            Locale locale = getParameters().getLocale();
622
            taskStatus.message("_loading");
623
            int count = 0;
624

    
625
            int count_errors = 0;
626
            
627
            reader.rewind();
628
            List<Object> row = reader.read();
629

    
630
            Object rawvalue;
631
            while ( row != null ) {
632
                taskStatus.setCurValue(++count);
633
                FeatureProvider feature = this.createFeatureProvider(ftype);
634
                for ( int i = 0; i < row.size(); i++ ) {
635
                    rawvalue = row.get(i);
636
                    if( rawvalue instanceof String && StringUtils.isBlank((String)rawvalue) ) {
637
                        rawvalue = null;
638
                    }
639
                    try {
640
                        Object value;
641
                        if ( locale != null && coercion[i] instanceof CoercionWithLocale ) {
642
                            value = ((CoercionWithLocale) (coercion[i])).coerce(rawvalue, locale);
643
                        } else {
644
                            value = coercion[i].coerce(rawvalue);
645
                        }
646
                        feature.set(i, value);
647
                        if ( sizes[i] >= 0 && value != null ) {
648
                            int x = ((String) value).length();
649
                            if ( sizes[i] < x ) {
650
                                sizes[i] = x;
651
                            }
652
                        }
653
                    } catch (RuntimeException ex) {
654
                        if ( !ignore_errors ) {
655
                            throw ex;
656
                        }
657
                        if ( count_errors++ < 10 ) {
658
                            LOGGER.warn("Can't load value of attribute " + i + " in row " + count + ".", ex);
659
                        }
660
                        if ( count_errors == 10 ) {
661
                            LOGGER.info("Too many errors, suppress messages.");
662
                        }
663
                    }
664
                }
665
                this.addFeatureProvider(feature);
666
                row = reader.read();
667
            }
668
            for ( int i = 0; i < ftype.size(); i++ ) {
669
                if ( sizes[i] > 0 ) {
670
                    EditableFeatureAttributeDescriptor efad = ((EditableFeatureAttributeDescriptor) edftype.getAttributeDescriptor(i));
671
                    efad.setSize(sizes[i]);
672
                }
673
            }
674
            // Volvemos a asignar al store el featuretype, ya que puede
675
            // haber cambiado.
676
            ftype = edftype.getNotEditableCopy();
677
            ftypes = new ArrayList<>();
678
            ftypes.add(ftype);
679
            store.setFeatureTypes(ftypes, ftype);
680

    
681
            taskStatus.terminate();
682
        } catch (Exception ex) {
683
            LOGGER.warn("Can't load features from '"+this.readerFactory.getName()+"' file '" + getFullFileName() + "'.", ex);
684
        } finally {
685
            if ( reader != null ) {
686
                try {
687
                    reader.close();
688
                } catch (Exception ex) {
689
                    // Do nothing
690
                }
691
            }
692

    
693
        }
694
    }
695
    
696
    private int[] automaticDetectionOfTypes(SimpleReader reader) throws IOException {
697
        boolean automatic_types_detection = getParameters().getAutomaticTypesDetection();
698
        if ( !automatic_types_detection ) {
699
            return null;
700
        }
701
        int[] types = null;
702
        try {
703
            reader.rewind();
704
            List<String> fieldNames = reader.getFieldNames();
705
            if ( fieldNames == null ) {
706
                fieldNames = getParameters().getFieldNames();
707
            }
708

    
709
            AutomaticDetectionOfTypes x = new AutomaticDetectionOfTypes(
710
                    this.getFullFileName()
711
            );
712
            types = x.detect(
713
                    fieldNames.size(), 
714
                    reader, 
715
                    false, 
716
                    getParameters().getLocale()
717
            );
718
        } catch (Exception ex) {
719
            throw new RuntimeException("Problems reading file '" + getFullFileName() + "'.", ex);
720
        }
721
        return types;
722
    }
723
}