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.csv / src / main / java / org / gvsig / fmap / dal / store / csv / CSVStoreProvider.java @ 44749

History | View | Annotate | Download (44.6 KB)

1 40846 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 42775 jjdelcerro
 * 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 40846 jjdelcerro
 *
11 42775 jjdelcerro
 * 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 40846 jjdelcerro
 *
16 42775 jjdelcerro
 * 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 40846 jjdelcerro
 *
20 42775 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40846 jjdelcerro
 */
23
package org.gvsig.fmap.dal.store.csv;
24
25
import java.io.File;
26 43283 jjdelcerro
import java.io.FileInputStream;
27
import java.io.FileNotFoundException;
28 40846 jjdelcerro
import java.io.FileReader;
29
import java.io.IOException;
30 43283 jjdelcerro
import java.io.InputStreamReader;
31 43425 jjdelcerro
import java.net.URI;
32 41062 jjdelcerro
import java.net.URL;
33 43283 jjdelcerro
import java.nio.charset.Charset;
34 40846 jjdelcerro
import java.util.ArrayList;
35
import java.util.HashMap;
36 41006 jjdelcerro
import java.util.Iterator;
37 40846 jjdelcerro
import java.util.List;
38 41069 jjdelcerro
import java.util.Locale;
39 44408 jjdelcerro
import java.util.Map;
40 40846 jjdelcerro
41 41006 jjdelcerro
import org.apache.commons.io.FilenameUtils;
42 42775 jjdelcerro
import org.apache.commons.io.IOUtils;
43 41876 jjdelcerro
import org.apache.commons.lang3.StringUtils;
44 40846 jjdelcerro
import org.cresques.cts.IProjection;
45
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47
import org.gvsig.fmap.dal.DataServerExplorer;
48
import org.gvsig.fmap.dal.DataStore;
49
import org.gvsig.fmap.dal.DataStoreNotification;
50
import org.gvsig.fmap.dal.DataTypes;
51
import org.gvsig.fmap.dal.FileHelper;
52
import org.gvsig.fmap.dal.exception.DataException;
53
import org.gvsig.fmap.dal.exception.InitializeException;
54
import org.gvsig.fmap.dal.exception.OpenException;
55
import org.gvsig.fmap.dal.exception.ReadException;
56
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
57 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
58 41006 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
59 40846 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureType;
60 41059 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
61 41006 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
62 41335 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
63 41006 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureSet;
64 41059 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStore;
65 40846 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
66 41006 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
67 40846 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
68
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
69
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
70 41006 jjdelcerro
import org.gvsig.fmap.dal.resource.ResourceAction;
71 40846 jjdelcerro
import org.gvsig.fmap.dal.resource.file.FileResource;
72
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
73
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
74
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
75
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
76
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
77 41617 jjdelcerro
import org.gvsig.fmap.dal.store.csv.simplereaders.CSVReader;
78
import org.gvsig.fmap.dal.store.csv.simplereaders.FixedLenReader;
79
import org.gvsig.fmap.dal.store.csv.simplereaders.SimpleReader;
80 40846 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
81
import org.gvsig.fmap.geom.GeometryLocator;
82
import org.gvsig.fmap.geom.GeometryManager;
83 44408 jjdelcerro
import org.gvsig.fmap.geom.GeometryUtils;
84 41335 jjdelcerro
import org.gvsig.fmap.geom.aggregate.MultiPoint;
85 40846 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
86 41006 jjdelcerro
import org.gvsig.fmap.geom.primitive.Point;
87
import org.gvsig.fmap.geom.type.GeometryType;
88 40846 jjdelcerro
import org.gvsig.tools.ToolsLocator;
89 41335 jjdelcerro
import org.gvsig.tools.dataTypes.DataType;
90 41006 jjdelcerro
import org.gvsig.tools.dataTypes.DataTypesManager;
91 44669 jjdelcerro
import org.gvsig.tools.dataTypes.Coercion;
92 41006 jjdelcerro
import org.gvsig.tools.dispose.DisposableIterator;
93 44408 jjdelcerro
import org.gvsig.tools.dynobject.Tags;
94 40846 jjdelcerro
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
95 41006 jjdelcerro
import org.gvsig.tools.evaluator.AbstractEvaluator;
96
import org.gvsig.tools.evaluator.EvaluatorData;
97
import org.gvsig.tools.evaluator.EvaluatorException;
98 41059 jjdelcerro
import org.gvsig.tools.exception.BaseException;
99 40846 jjdelcerro
import org.gvsig.tools.exception.NotYetImplemented;
100
import org.gvsig.tools.persistence.PersistentState;
101
import org.gvsig.tools.persistence.exception.PersistenceException;
102
import org.gvsig.tools.task.SimpleTaskStatus;
103
import org.gvsig.tools.task.TaskStatusManager;
104 41059 jjdelcerro
import org.gvsig.tools.visitor.VisitCanceledException;
105
import org.gvsig.tools.visitor.Visitor;
106 40846 jjdelcerro
import org.slf4j.Logger;
107
import org.slf4j.LoggerFactory;
108 40878 jjdelcerro
import org.supercsv.prefs.CsvPreference;
109 44669 jjdelcerro
import org.gvsig.tools.dataTypes.CoercionContext;
110 40846 jjdelcerro
111 44309 omartinez
@SuppressWarnings("UseSpecificCatch")
112 40846 jjdelcerro
public class CSVStoreProvider extends AbstractMemoryStoreProvider implements
113 41617 jjdelcerro
        ResourceConsumer {
114
115 44408 jjdelcerro
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVStoreProvider.class);
116 40846 jjdelcerro
117 44669 jjdelcerro
    public static final String NAME = DataStore.CSV_PROVIDER_NAME;
118 40846 jjdelcerro
    public static final String DESCRIPTION = "CSV file";
119
120
    public static final String METADATA_DEFINITION_NAME = NAME;
121
122
    private ResourceProvider resource;
123
124
    private long counterNewsOIDs = 0;
125
    private Envelope envelope;
126 41059 jjdelcerro
    private boolean need_calculate_envelope = false;
127 44309 omartinez
    private final SimpleTaskStatus taskStatus;
128
    private final CSVFeatureWriter writer;
129 40846 jjdelcerro
130
    public CSVStoreProvider(CSVStoreParameters parameters,
131 41617 jjdelcerro
            DataStoreProviderServices storeServices) throws InitializeException {
132 40846 jjdelcerro
        super(
133 41617 jjdelcerro
                parameters,
134
                storeServices,
135
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
136 40846 jjdelcerro
        );
137 44309 omartinez
        this.writer = new CSVFeatureWriter();
138 40846 jjdelcerro
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
139
        this.taskStatus = manager.createDefaultSimpleTaskStatus("CSV");
140
141
        counterNewsOIDs = 0;
142
143
        File file = getCSVParameters().getFile();
144
        resource = this.createResource(
145 41617 jjdelcerro
                FileResource.NAME,
146
                new Object[]{file.getAbsolutePath()}
147 40846 jjdelcerro
        );
148
149
        resource.addConsumer(this);
150 44309 omartinez
151 41006 jjdelcerro
        initializeFeatureTypes();
152 40846 jjdelcerro
    }
153
154
    private CSVStoreParameters getCSVParameters() {
155
        return (CSVStoreParameters) this.getParameters();
156
    }
157
158 44309 omartinez
    @Override
159 40846 jjdelcerro
    public String getProviderName() {
160
        return NAME;
161
    }
162
163 44309 omartinez
    @Override
164 40846 jjdelcerro
    public boolean allowWrite() {
165 44309 omartinez
        return true;
166 40846 jjdelcerro
    }
167
168 41006 jjdelcerro
    private String getFullFileName() {
169 41617 jjdelcerro
        // Usar solo para mostrar mensajes en el logger.
170 44309 omartinez
        String s;
171 41617 jjdelcerro
        try {
172
            s = getCSVParameters().getFile().getAbsolutePath();
173
        } catch (Exception e2) {
174
            s = "(unknow)";
175
        }
176
        return s;
177 41006 jjdelcerro
    }
178 41617 jjdelcerro
179 44309 omartinez
    @Override
180 40846 jjdelcerro
    public void open() throws OpenException {
181 42775 jjdelcerro
        if (this.data != null) {
182 40846 jjdelcerro
            return;
183
        }
184 43215 jjdelcerro
        this.data = new ArrayList<>();
185 41006 jjdelcerro
        resource.setData(new HashMap());
186
        counterNewsOIDs = 0;
187 41617 jjdelcerro
        try {
188
            loadFeatures();
189
        } catch (RuntimeException e) {
190 44408 jjdelcerro
            LOGGER.debug("Can't load features from CSV '" + getFullFileName() + "'.", e);
191 41617 jjdelcerro
            throw e;
192
        } catch (Exception e) {
193 44408 jjdelcerro
            LOGGER.debug("Can't load features from CSV '" + getFullFileName() + "'.", e);
194 41617 jjdelcerro
            throw new RuntimeException(e);
195
        }
196 40846 jjdelcerro
    }
197
198 44309 omartinez
    @Override
199 40846 jjdelcerro
    public DataServerExplorer getExplorer() throws ReadException {
200
        DataManager manager = DALLocator.getDataManager();
201 41006 jjdelcerro
        FilesystemServerExplorerParameters params;
202 40846 jjdelcerro
        try {
203
            params = (FilesystemServerExplorerParameters) manager
204 41617 jjdelcerro
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
205 40846 jjdelcerro
            params.setRoot(this.getCSVParameters().getFile().getParent());
206 41617 jjdelcerro
            return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
207 40846 jjdelcerro
        } catch (DataException e) {
208
            throw new ReadException(this.getProviderName(), e);
209
        } catch (ValidateDataParametersException e) {
210
            throw new ReadException(this.getProviderName(), e);
211
        }
212
213
    }
214
215 44309 omartinez
    @Override
216 40846 jjdelcerro
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
217
218
        try {
219
            this.taskStatus.add();
220
            taskStatus.message("_preparing");
221 44309 omartinez
            this.getResource().closeRequest();
222 40846 jjdelcerro
            getResource().execute(new ResourceAction() {
223 44309 omartinez
                @Override
224 40846 jjdelcerro
                public Object run() throws Exception {
225
                    FeatureSet features = null;
226
                    DisposableIterator it = null;
227
                    try {
228
                        File file = (File) resource.get();
229 41617 jjdelcerro
230
                        features
231
                                = getStoreServices().getFeatureStore()
232 44309 omartinez
                                        .getFeatureSet();
233 41006 jjdelcerro
                        List<FeatureProvider> newdata = new ArrayList<FeatureProvider>();
234 44309 omartinez
                        FeatureType ftype = getStoreServices().getDefaultFeatureType();
235
                        writer.initialize(getCSVParameters(), file, ftype, getCSVPreferences());
236
                        writer.beginAppend();
237 40846 jjdelcerro
                        it = features.fastIterator();
238 41617 jjdelcerro
                        taskStatus.setRangeOfValues(0, 0);
239
                        long counter = 0;
240 42775 jjdelcerro
                        while (it.hasNext()) {
241 40846 jjdelcerro
                            taskStatus.setCurValue(counter++);
242
                            FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
243 41617 jjdelcerro
                                    (org.gvsig.fmap.dal.feature.Feature) it.next());
244 40846 jjdelcerro
                            writer.add(feature);
245 42775 jjdelcerro
                            if (feature.getOID() == null) {
246 44408 jjdelcerro
                                LOGGER.warn("feature without OID");
247 40846 jjdelcerro
                                feature.setOID(createNewOID());
248
                            }
249
                            newdata.add(feature);
250
                        }
251
                        data = newdata;
252 42775 jjdelcerro
                        if (writer.getEnvelope() != null) {
253 40846 jjdelcerro
                            envelope = writer.getEnvelope().getGeometry().getEnvelope();
254
                        }
255
                        resource.notifyChanges();
256 41006 jjdelcerro
                        writer.end();
257 40846 jjdelcerro
                    } finally {
258 42775 jjdelcerro
                        if (it != null) {
259 40846 jjdelcerro
                            it.dispose();
260
                        }
261 42775 jjdelcerro
                        if (features != null) {
262 40846 jjdelcerro
                            features.dispose();
263
                        }
264
                    }
265
                    return null;
266
                }
267 41617 jjdelcerro
268 40846 jjdelcerro
            });
269
            this.taskStatus.terminate();
270
        } catch (Exception e) {
271
            this.taskStatus.abort();
272
            throw new PerformEditingException(getResource().toString(), e);
273
        } finally {
274
            this.taskStatus.remove();
275
        }
276
    }
277
278 44309 omartinez
    private CsvPreference getCSVPreferences() {
279
        CSVReader reader = new CSVReader(getCSVParameters());
280
        return reader.getCSVPreferences();
281
    }
282
283
    @Override
284 40846 jjdelcerro
    public boolean closeResourceRequested(ResourceProvider resource) {
285
        return true;
286
    }
287
288 44309 omartinez
    @Override
289 40846 jjdelcerro
    public int getOIDType() {
290
        return DataTypes.LONG;
291
    }
292
293 44309 omartinez
    @Override
294 40846 jjdelcerro
    public boolean supportsAppendMode() {
295 44309 omartinez
        return true;
296 40846 jjdelcerro
    }
297
298 44309 omartinez
    @Override
299
    public void append(final FeatureProvider featureProvider) {
300
        //todo
301
        getResource().execute(new ResourceAction() {
302
            @Override
303
            public Object run() throws Exception {
304
                //writer.append(getStoreServices().createFeature(featureProvider));
305
                writer.add(featureProvider);
306
                return null;
307
            }
308
        });
309 40846 jjdelcerro
    }
310
311 44309 omartinez
    @Override
312
    public void beginAppend() throws DataException {
313
        this.close();
314
        getResource().execute(new ResourceAction() {
315
            public Object run() throws Exception {
316
                writer.initialize(
317
                        getCSVParameters(),
318
                        getCSVParameters().getFile(),
319
                        getFeatureStore().getDefaultFeatureType(),
320 44388 omartinez
                        getCSVPreferences()
321 44309 omartinez
                );
322
                writer.beginAppend();
323
                return null;
324
            }
325
        });
326
327 40846 jjdelcerro
    }
328
329 44309 omartinez
    @Override
330 40846 jjdelcerro
    public void endAppend() {
331 44309 omartinez
        try {
332
            getResource().execute(new ResourceAction() {
333
                public Object run() throws Exception {
334
                    writer.end();
335
                    resource.notifyChanges(); //resourcesNotifyChanges();
336
                    counterNewsOIDs = -1;
337
                    return null;
338
                }
339
            });
340
            writer.end();
341
        } catch (PerformEditingException ex) {
342 44408 jjdelcerro
            LOGGER.warn("Not been able to end append '" + this.getFullName() + "'.", ex);
343 44309 omartinez
        }
344 40846 jjdelcerro
    }
345
346
    public void saveToState(PersistentState state) throws PersistenceException {
347
        throw new NotYetImplemented();
348
    }
349
350
    public void loadFromState(PersistentState state) throws PersistenceException {
351
        throw new NotYetImplemented();
352
    }
353
354 44309 omartinez
    @Override
355 40846 jjdelcerro
    public Object createNewOID() {
356 44309 omartinez
        return counterNewsOIDs++;
357 40846 jjdelcerro
    }
358
359
    protected void initializeFeatureTypes() throws InitializeException {
360
        try {
361
            this.open();
362
        } catch (OpenException e) {
363
            throw new InitializeException(this.getProviderName(), e);
364
        }
365
    }
366
367 44309 omartinez
    @Override
368 40846 jjdelcerro
    public Envelope getEnvelope() throws DataException {
369
        this.open();
370 42775 jjdelcerro
        if (this.envelope != null) {
371 41617 jjdelcerro
            return this.envelope;
372 41059 jjdelcerro
        }
373 42775 jjdelcerro
        if (!this.need_calculate_envelope) {
374 41617 jjdelcerro
            return null;
375 41059 jjdelcerro
        }
376
        FeatureStore fs = this.getFeatureStore();
377
        FeatureType ft = fs.getDefaultFeatureType();
378
        FeatureAttributeDescriptor fad = ft.getAttributeDescriptor(ft.getDefaultGeometryAttributeIndex());
379
380
        try {
381
            this.envelope = GeometryLocator.getGeometryManager().createEnvelope(fad.getGeomType().getSubType());
382 41617 jjdelcerro
            fs.accept(new Visitor() {
383 44309 omartinez
                @Override
384 41617 jjdelcerro
                public void visit(Object obj) throws VisitCanceledException, BaseException {
385
                    Feature f = (Feature) obj;
386
                    Geometry geom = f.getDefaultGeometry();
387 42775 jjdelcerro
                    if (geom != null) {
388 41617 jjdelcerro
                        envelope.add(geom.getEnvelope());
389
                    }
390
                }
391
            });
392
        } catch (BaseException e) {
393 44408 jjdelcerro
            LOGGER.warn("Can't calculate the envelope of CSV file '" + this.getFullName() + "'.", e);
394 41617 jjdelcerro
            this.envelope = null;
395
        }
396
397 41059 jjdelcerro
        this.need_calculate_envelope = false;
398 40846 jjdelcerro
        return this.envelope;
399
    }
400
401 44309 omartinez
    @Override
402 40846 jjdelcerro
    public Object getDynValue(String name) throws DynFieldNotFoundException {
403 42775 jjdelcerro
        if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
404 40846 jjdelcerro
            try {
405
                return this.getEnvelope();
406
            } catch (DataException e) {
407
                return null;
408
            }
409
        } else {
410 42775 jjdelcerro
            if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
411 40878 jjdelcerro
                IProjection pro = CSVStoreParameters.getCRS(this.getCSVParameters());
412 42775 jjdelcerro
                if (pro != null) {
413 40846 jjdelcerro
                    return pro;
414
                }
415
            }
416
        }
417
        return super.getDynValue(name);
418
    }
419
420 44309 omartinez
    @Override
421 40846 jjdelcerro
    public void resourceChanged(ResourceProvider resource) {
422
        this.getStoreServices().notifyChange(
423 41617 jjdelcerro
                DataStoreNotification.RESOURCE_CHANGED,
424
                resource);
425 40846 jjdelcerro
    }
426
427 44309 omartinez
    @Override
428 40846 jjdelcerro
    public Object getSourceId() {
429
        return this.getCSVParameters().getFile();
430
    }
431
432 44309 omartinez
    @Override
433 40846 jjdelcerro
    public String getName() {
434 40878 jjdelcerro
        String name = this.getCSVParameters().getFile().getName();
435 41006 jjdelcerro
        return FilenameUtils.getBaseName(name);
436 40846 jjdelcerro
    }
437
438 44309 omartinez
    @Override
439 40846 jjdelcerro
    public String getFullName() {
440
        return this.getCSVParameters().getFile().getAbsolutePath();
441
    }
442
443 44309 omartinez
    @Override
444 40846 jjdelcerro
    public ResourceProvider getResource() {
445
        return resource;
446
    }
447
448
    private boolean isEmpty(String s) {
449 42775 jjdelcerro
        if (s == null) {
450 41617 jjdelcerro
            return true;
451
        }
452
        return s.trim().length() == 0;
453 40846 jjdelcerro
    }
454 40878 jjdelcerro
455 44309 omartinez
    private void init(CSVStoreParameters parameters, DataStoreProviderServices storeServices) {
456
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
457
    }
458 41335 jjdelcerro
    private class FieldTypeParser {
459 41617 jjdelcerro
460 41335 jjdelcerro
        public String name = null;
461
        public int type = DataTypes.STRING;
462
        public int size = 0;
463 44408 jjdelcerro
        public int geomType = Geometry.TYPES.GEOMETRY;
464
        public int geomSubtype = Geometry.SUBTYPES.GEOM2D;
465
        public Map<String,String> tags = new HashMap<>();
466
        public Map<String,String> assignments = new HashMap<>();
467 41335 jjdelcerro
468
        private String typename = "string";
469 41617 jjdelcerro
470 41335 jjdelcerro
        FieldTypeParser() {
471
        }
472 41617 jjdelcerro
473 44408 jjdelcerro
        public void clear() {
474
            this.name = null;
475
            this.type = DataTypes.STRING;
476
            this.size = 0;
477
            this.tags = new HashMap<>();
478
            this.assignments = new HashMap<>();
479
        }
480
481
        public void copyFrom(FieldTypeParser other) {
482
            this.name = other.name;
483
            this.type = other.type;
484
            this.size = other.size;
485
            this.tags = new HashMap<>();
486
            this.tags.putAll(other.tags);
487
            this.assignments = new HashMap<>();
488
            this.assignments.putAll(other.assignments);
489
        }
490
491 41335 jjdelcerro
        private int getType(String value) {
492 41617 jjdelcerro
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
493 41335 jjdelcerro
            return dataTypesManager.getType(typename);
494
        }
495 41617 jjdelcerro
496 44408 jjdelcerro
        private String[] split(String value, String separators) {
497
            int firstSeparatorPosition = 1000000;
498
            Character sep = null;
499
            for (char ch : separators.toCharArray()) {
500
                int pos = value.indexOf(ch);
501
                if( pos>0 && pos<firstSeparatorPosition ) {
502
                    sep = ch;
503
                    firstSeparatorPosition = pos;
504
                }
505
            }
506
            if( sep == null ) {
507
                return new String[] { value };
508
            }
509
            return value.split("["+sep+"]");
510 42775 jjdelcerro
        }
511
512 44408 jjdelcerro
        @SuppressWarnings("UseSpecificCatch")
513 41335 jjdelcerro
        public boolean parse(String value) {
514 44408 jjdelcerro
            String[] args;
515
            if ( value.contains("__") ) {
516
                args = value.split("__");
517
            } else {
518
                args = split(value, ":/#@!;-");
519
                if( args.length == 1 ) {
520
                    this.name = value;
521
                    return true;
522
                }
523
            }
524
            int n = 0;
525 44445 jjdelcerro
            this.name = StringUtils.trim(args[n++]);
526 44408 jjdelcerro
            if( n >= args.length ) {
527 41335 jjdelcerro
                return true;
528
            }
529 44445 jjdelcerro
            this.typename = StringUtils.trim(args[n++]);
530 44408 jjdelcerro
            this.type = this.getType(this.typename);
531
            if ( this.type == DataTypes.INVALID ) {
532
                this.geomType = GeometryUtils.getGeometryType(this.typename);
533
                if( this.geomType==Geometry.TYPES.UNKNOWN )  {
534
                    this.type = DataTypes.STRING;
535
                    LOGGER.info("Type '" + this.typename + "' not valid for attribute '" + value + "' in '"+getProviderName()+"' file '" + getFullFileName() + "'.");
536
                } else {
537
                    this.typename = "GEOMETRY";
538
                    this.type = DataTypes.GEOMETRY;
539
                }
540
            }
541 44669 jjdelcerro
            this.size = 0;
542 44498 omartinez
543 44408 jjdelcerro
            while (n < args.length) {
544 44445 jjdelcerro
                String option = StringUtils.trim(args[n++].toLowerCase());
545 44408 jjdelcerro
                switch (option) {
546
                    case "size":
547
                        try {
548
                            this.size = Integer.parseInt(args[n++]);
549
                        } catch (Exception ex) {
550
                            LOGGER.warn("Ignore incorrect field size for field " + value + " in '"+getProviderName()+"' file '" + getFullFileName() + "'.", ex);
551 42775 jjdelcerro
                        }
552 44408 jjdelcerro
                        break;
553
                    case "tag": {
554 44445 jjdelcerro
                            String x = StringUtils.trim(args[n++]);
555 44408 jjdelcerro
                            int pos = x.indexOf("=");
556
                            if( pos < 0 ) {
557
                                this.tags.put(x, null);
558
                            } else {
559
                                this.tags.put(
560 44445 jjdelcerro
                                        StringUtils.trim(StringUtils.substring(x, 0, pos)),
561
                                        StringUtils.trim(StringUtils.substring(x, pos+1))
562 44408 jjdelcerro
                                );
563
                            }
564
                            break;
565 42775 jjdelcerro
                        }
566 44408 jjdelcerro
                    case "set": {
567 44445 jjdelcerro
                            String x = StringUtils.trim(args[n++]);
568 44408 jjdelcerro
                            int pos = x.indexOf("=");
569
                            if( pos < 0 ) {
570
                                this.assignments.put(x, null);
571
                            } else {
572
                                this.assignments.put(
573 44445 jjdelcerro
                                        StringUtils.trim(StringUtils.substring(x, 0, pos)),
574
                                        StringUtils.trim(StringUtils.substring(x, pos+1))
575 44408 jjdelcerro
                                );
576 42775 jjdelcerro
                            }
577 44408 jjdelcerro
                            break;
578 41876 jjdelcerro
                        }
579 44408 jjdelcerro
                    default:
580 44738 jjdelcerro
                        if( StringUtils.isNumeric(option) && this.size == 0 ) {
581
                          try {
582
                              this.size = Integer.parseInt(option);
583
                          } catch (Exception ex) {
584
                              LOGGER.warn("Ignore incorrect field size for field " + value + " in '"+getProviderName()+"' file '" + getFullFileName() + "'.", ex);
585
                          }
586
                          break;
587
                        }
588 44408 jjdelcerro
                        LOGGER.warn("Illegal argumente '"+option+"' for field '"+this.name+"' in '"+getProviderName()+"' file '" + getFullFileName() + "' ("+value+").");
589
                }
590 41335 jjdelcerro
            }
591
            return true;
592
        }
593 41617 jjdelcerro
594 41335 jjdelcerro
    }
595 41617 jjdelcerro
596 41062 jjdelcerro
    private EditableFeatureType getFeatureType(String headers[], int automaticTypes[]) {
597 41335 jjdelcerro
        EditableFeatureType fType = getStoreServices().createFeatureType(this.getName());
598
        fType.setHasOID(true);
599
600
        FieldTypeParser[] fieldTypes = new FieldTypeParser[headers.length];
601 41617 jjdelcerro
        //
602 41335 jjdelcerro
        // Calculamos cuales pueden ser los tipos de datos
603
        //
604 42775 jjdelcerro
        for (int i = 0; i < fieldTypes.length; i++) {
605 41335 jjdelcerro
            fieldTypes[i] = new FieldTypeParser();
606
        }
607
608 41617 jjdelcerro
        // Asuminos los tipos pasados por parametro, que se supone
609 41335 jjdelcerro
        // son los detectados automaticamente.
610 42775 jjdelcerro
        if (automaticTypes != null) {
611
            for (int i = 0; i < fieldTypes.length && i < automaticTypes.length; i++) {
612 41335 jjdelcerro
                fieldTypes[i].type = automaticTypes[i];
613
            }
614
        }
615
        // Luego probamos con lo que diga las cabezeras del CVS, sobreescribiendo
616
        // los tipos anteriores en caso de definirse en la cabezara.
617 42775 jjdelcerro
        for (int i = 0; i < fieldTypes.length; i++) {
618
            if (!fieldTypes[i].parse(headers[i])) {
619 41335 jjdelcerro
                continue;
620
            }
621
622
        }
623
624 41617 jjdelcerro
        // Y por ultimo hacemos caso a lo que se haya especificado en los parametros
625 41335 jjdelcerro
        // de apertura del CSV, teniendo esto prioridad sobre todo.
626 41876 jjdelcerro
        String param_types_def = CSVStoreParameters.getRawFieldTypes(this.getParameters());
627 41901 jjdelcerro
        if (StringUtils.isNotBlank(param_types_def)) {
628
            String sep = CSVStoreParameters.getDelimiter(param_types_def);
629 42775 jjdelcerro
            if (StringUtils.isNotBlank(sep)) {
630 41901 jjdelcerro
                String[] param_types = param_types_def.split(sep);
631 42775 jjdelcerro
                FieldTypeParser parser = new FieldTypeParser();
632
                for (String param_type : param_types) {
633
                    parser.clear();
634
                    parser.parse(param_type);
635
                    for (FieldTypeParser fieldType : fieldTypes) {
636
                        if (StringUtils.equalsIgnoreCase(fieldType.name, parser.name)) {
637
                            fieldType.copyFrom(parser);
638
                            break;
639
                        }
640 41901 jjdelcerro
                    }
641 41335 jjdelcerro
                }
642
            }
643
        }
644 41617 jjdelcerro
        //
645 41335 jjdelcerro
        // Una vez ya sabemos los tipos de datos rellenamos el feature-type
646
        //
647 44408 jjdelcerro
        for (FieldTypeParser fieldType : fieldTypes) {
648
            EditableFeatureAttributeDescriptor fad = fType.add(fieldType.name, fieldType.type);
649
            fad.setSize(fieldType.size);
650
            if (fieldType.type == DataTypes.GEOMETRY ) {
651
                fad.setGeometryType(fieldType.geomType, fieldType.geomSubtype);
652
                if( fType.getDefaultGeometryAttributeName() == null ) {
653
                    fType.setDefaultGeometryAttributeName(fieldType.name);
654 41876 jjdelcerro
                }
655 41335 jjdelcerro
            }
656 44408 jjdelcerro
            for (Map.Entry<String, String> entry : fieldType.assignments.entrySet()) {
657
                try {
658
                    switch(entry.getKey().toLowerCase()) {
659
                        case "expression":
660
                            // Los campos calculados los procesamos en una segunda
661
                            // pasada, cuando ya estan definidos el resto de los campos
662
                            // ya que pueden requerir campos que aun no se han definido.
663
                            break;
664
                        default:
665
                            fad.set(entry.getKey(), entry.getValue());
666
                    }
667
                } catch (Exception ex) {
668
                    LOGGER.warn("Can't set property '"+entry.getKey()+"' of '"+fad.getName()+"'.", ex);
669
                }
670
            }
671
            Tags tags = fad.getTags();
672
            for (Map.Entry<String, String> entry : fieldType.tags.entrySet()) {
673
                tags.set(entry.getKey(), entry.getValue());
674
            }
675 41335 jjdelcerro
        }
676 44408 jjdelcerro
        // Processamos ahora los campos calculados
677
        for (FieldTypeParser fieldType : fieldTypes) {
678
            EditableFeatureAttributeDescriptor fad = fType.getEditableAttributeDescriptor(fieldType.name);
679
            for (Map.Entry<String, String> entry : fieldType.assignments.entrySet()) {
680
                try {
681
                    switch(entry.getKey().toLowerCase()) {
682
                        case "expression":
683
                            fad.set(entry.getKey(), entry.getValue());
684
                            break;
685
                    }
686
                } catch (Exception ex) {
687
                    LOGGER.warn("Can't set property '"+entry.getKey()+"' in '"+fad.getName()+"' of '"+getFullFileName()+"'.", ex);
688
                }
689
            }
690
        }
691 41335 jjdelcerro
        String[] pointDimensionNames = CSVStoreParameters.getPointDimensionNames(this.getParameters());
692 44408 jjdelcerro
        if ( pointDimensionNames != null ) {
693 41335 jjdelcerro
            PointAttributeEmulator emulator = new PointAttributeEmulator(pointDimensionNames);
694 44408 jjdelcerro
            EditableFeatureAttributeDescriptor attr = fType.add("the_geom", DataTypes.GEOMETRY, emulator);
695 41335 jjdelcerro
            GeometryManager geommgr = GeometryLocator.getGeometryManager();
696
            GeometryType gt;
697
            try {
698 44408 jjdelcerro
                if ( emulator.fieldNames != null && emulator.fieldNames.length <= 2 ) {
699
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
700
                } else {
701
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM3D);
702
                }
703 41335 jjdelcerro
                attr.setGeometryType(gt);
704
            } catch (Exception e) {
705 44408 jjdelcerro
                LOGGER.warn("Can't set geometry type for the calculated field in '"+getProviderName()+"' file '" + getFullFileName() + "'.", e);
706 41335 jjdelcerro
            }
707 44408 jjdelcerro
        }
708
709 43283 jjdelcerro
        String geometry_column = CSVStoreParameters.getGeometryColumn(this.getParameters());
710 44309 omartinez
        if (!StringUtils.isEmpty(geometry_column)) {
711 43283 jjdelcerro
            EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor) fType.get(geometry_column);
712 44309 omartinez
            if (attr != null && attr.getType() != DataTypes.GEOMETRY) {
713 43283 jjdelcerro
                attr.setDataType(DataTypes.GEOMETRY);
714
                GeometryManager geommgr = GeometryLocator.getGeometryManager();
715
                GeometryType gt;
716
                try {
717
                    gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.UNKNOWN);
718
                    attr.setGeometryType(gt);
719
                } catch (Exception e) {
720 44408 jjdelcerro
                    LOGGER.warn("Can't set geometry type for the calculated field in CSV file '" + getFullFileName() + "'.", e);
721 43283 jjdelcerro
                }
722
                fType.setDefaultGeometryAttributeName(geometry_column);
723
            }
724
        }
725 41335 jjdelcerro
        return fType;
726 40846 jjdelcerro
    }
727 41617 jjdelcerro
728 41335 jjdelcerro
    static class PointAttributeEmulator implements FeatureAttributeEmulator {
729
730
        private static final Logger logger = LoggerFactory.getLogger(ToPointEvaluaror.class);
731
732 41342 jjdelcerro
        private static final int XNAME = 0;
733
        private static final int YNAME = 1;
734
        private static final int ZNAME = 2;
735 41617 jjdelcerro
736 41335 jjdelcerro
        private final GeometryManager geommgr;
737 41342 jjdelcerro
        private final String[] fieldNames;
738 41335 jjdelcerro
        private final Coercion toDouble;
739
        private final DataType dataType;
740
        private int errorcount = 0;
741
742
        public PointAttributeEmulator(String[] pointDimensionNames) {
743 42775 jjdelcerro
            if (pointDimensionNames.length > 2) {
744 41342 jjdelcerro
                this.fieldNames = new String[3];
745
                this.fieldNames[ZNAME] = pointDimensionNames[2];
746 41335 jjdelcerro
            } else {
747 41342 jjdelcerro
                this.fieldNames = new String[2];
748 41335 jjdelcerro
            }
749 41342 jjdelcerro
            this.fieldNames[XNAME] = pointDimensionNames[0];
750
            this.fieldNames[YNAME] = pointDimensionNames[1];
751 41335 jjdelcerro
            this.geommgr = GeometryLocator.getGeometryManager();
752
            DataTypesManager datatypeManager = ToolsLocator.getDataTypesManager();
753
754
            this.toDouble = datatypeManager.getCoercion(DataTypes.DOUBLE);
755
            this.dataType = datatypeManager.get(DataTypes.GEOMETRY);
756
        }
757 41617 jjdelcerro
758 44309 omartinez
        @Override
759 41335 jjdelcerro
        public Object get(Feature feature) {
760
            try {
761 41348 jjdelcerro
                Object valueX = feature.get(this.fieldNames[XNAME]);
762
                valueX = toDouble.coerce(valueX);
763 42775 jjdelcerro
                if (valueX == null) {
764 41348 jjdelcerro
                    return null;
765
                }
766
                Object valueY = feature.get(this.fieldNames[YNAME]);
767
                valueY = toDouble.coerce(valueY);
768 42775 jjdelcerro
                if (valueY == null) {
769 41348 jjdelcerro
                    return null;
770
                }
771
                Object valueZ = null;
772 42775 jjdelcerro
                if (this.fieldNames.length > 2) {
773 41348 jjdelcerro
                    valueZ = toDouble.coerce(feature.get(this.fieldNames[ZNAME]));
774 42775 jjdelcerro
                    if (valueZ == null) {
775 41348 jjdelcerro
                        return null;
776
                    }
777
                }
778 41617 jjdelcerro
779 44309 omartinez
                double x = ((Double) valueX);
780
                double y = ((Double) valueY);
781 41335 jjdelcerro
                Point point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
782 42775 jjdelcerro
                if (this.fieldNames.length > 2) {
783 44309 omartinez
                    double z = ((Double) valueZ);
784 41335 jjdelcerro
                    point.setCoordinateAt(2, z);
785
                }
786
                return point;
787
            } catch (Exception ex) {
788 42775 jjdelcerro
                if (++errorcount < 5) {
789 41335 jjdelcerro
                    logger.warn("[" + errorcount + "] Can't create point in CSV provider. XNAME='"
790 41617 jjdelcerro
                            + this.fieldNames[XNAME] + "', YNAME='" + this.fieldNames[XNAME] + "' feature=" + feature.toString(), ex);
791 41335 jjdelcerro
                }
792
                return null;
793
            }
794
        }
795
796
        public void set(EditableFeature feature, Object value) {
797 42775 jjdelcerro
            if (value == null) {
798 41335 jjdelcerro
                return;
799
            }
800
            Point point = null;
801 42775 jjdelcerro
            if (value instanceof MultiPoint) {
802 41617 jjdelcerro
                point = (Point) ((MultiPoint) value).getPrimitiveAt(0);
803 41335 jjdelcerro
            } else {
804
                point = (Point) value;
805
            }
806 41342 jjdelcerro
            feature.set(this.fieldNames[XNAME], point.getX());
807
            feature.set(this.fieldNames[YNAME], point.getY());
808 42775 jjdelcerro
            if (this.fieldNames.length > 2) {
809 41342 jjdelcerro
                feature.set(this.fieldNames[ZNAME], point.getCoordinateAt(2));
810 41335 jjdelcerro
            }
811
        }
812
813 44309 omartinez
        @Override
814 41335 jjdelcerro
        public boolean allowSetting() {
815
            return true;
816
        }
817 41342 jjdelcerro
818 44309 omartinez
        @Override
819 41342 jjdelcerro
        public String[] getRequiredFieldNames() {
820
            return this.fieldNames;
821
        }
822 41617 jjdelcerro
823 41335 jjdelcerro
    }
824 41617 jjdelcerro
825 41006 jjdelcerro
    static class ToPointEvaluaror extends AbstractEvaluator {
826 40846 jjdelcerro
827 41335 jjdelcerro
        private static final Logger logger = LoggerFactory.getLogger(ToPointEvaluaror.class);
828 40846 jjdelcerro
829 41335 jjdelcerro
        private GeometryManager geommgr = null;
830
        private String xname = null;
831
        private String yname = null;
832
        private String zname = null;
833
        private Coercion toDouble;
834
        private int errorcount = 0;
835
836
        ToPointEvaluaror(String[] pointDimensionNames) {
837
            this.xname = pointDimensionNames[0];
838
            this.yname = pointDimensionNames[1];
839 42775 jjdelcerro
            if (pointDimensionNames.length > 2) {
840 41335 jjdelcerro
                this.zname = pointDimensionNames[2];
841
            }
842
            this.geommgr = GeometryLocator.getGeometryManager();
843
            this.toDouble = ToolsLocator.getDataTypesManager().getCoercion(DataTypes.DOUBLE);
844
        }
845
846 44309 omartinez
        @Override
847 41335 jjdelcerro
        public Object evaluate(EvaluatorData data) throws EvaluatorException {
848
            try {
849
                double x = ((Double) toDouble.coerce(data.getDataValue(xname))).doubleValue();
850
                double y = ((Double) toDouble.coerce(data.getDataValue(yname))).doubleValue();
851
                Point point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
852 42775 jjdelcerro
                if (zname != null) {
853 41335 jjdelcerro
                    double z = ((Double) toDouble.coerce(data.getDataValue(zname))).doubleValue();
854
                    point.setCoordinateAt(2, z);
855
                }
856
                return point;
857
            } catch (Exception ex) {
858 42775 jjdelcerro
                if (++errorcount < 5) {
859 41335 jjdelcerro
                    logger.warn("[" + errorcount + "] Can't create point in CSV provider. XNAME='"
860
                            + xname + "', YNAME='" + yname + "', ZNAME='" + zname + "', data=" + data.toString());
861
                }
862
                return null;
863
            }
864
        }
865
866 44309 omartinez
        @Override
867 41335 jjdelcerro
        public String getName() {
868
            return "ToPointEvaluaror";
869
        }
870
871 40846 jjdelcerro
    }
872 41335 jjdelcerro
873 43283 jjdelcerro
    private SimpleReader getSimpleReader(InputStreamReader in) {
874 41617 jjdelcerro
        SimpleReader reader;
875 42775 jjdelcerro
        if (CSVStoreParameters.getRawFieldsDefinition(getCSVParameters()) != null) {
876 41617 jjdelcerro
            reader = new FixedLenReader(in, getCSVParameters());
877
        } else {
878
            reader = new CSVReader(in, getCSVParameters());
879
        }
880
        return reader;
881
    }
882 41006 jjdelcerro
883 42775 jjdelcerro
    private String getFixedHeader(int column) {
884
        char[] header = new char[3];
885
886
        String s = String.format("%03d", column);
887
        header[0] = (char) (s.charAt(0) + 17);
888
        header[1] = (char) (s.charAt(1) + 17);
889
        header[2] = (char) (s.charAt(2) + 17);
890
        return String.valueOf(header);
891
    }
892
893
    private String[] getFixedHeaders(int count) {
894
        String[] headers = new String[count];
895
        for (int i = 0; i < headers.length; i++) {
896
            headers[i] = getFixedHeader(i);
897
        }
898
        return headers;
899
    }
900
901 43283 jjdelcerro
    private InputStreamReader openFile(File f, String charsetName) throws FileNotFoundException {
902
        Charset charset = Charset.defaultCharset();
903
        FileInputStream fis = new FileInputStream(f);
904 44309 omartinez
        if (!StringUtils.isEmpty(charsetName)) {
905
            if (Charset.isSupported(charsetName)) {
906 43283 jjdelcerro
                try {
907
                    charset = Charset.forName(charsetName);
908 44309 omartinez
                } catch (Throwable th) {
909 44408 jjdelcerro
                    LOGGER.warn("Can't use charset '" + charsetName + "' for read csv '" + this.getFullFileName() + "'.", th);
910 43283 jjdelcerro
                }
911
            } else {
912 44408 jjdelcerro
                LOGGER.warn("charset '" + charsetName + "' not supported for read csv '" + this.getFullFileName() + "'.");
913 43283 jjdelcerro
            }
914
        }
915
        InputStreamReader isr = new InputStreamReader(fis, charset);
916
        return isr;
917
    }
918 44309 omartinez
919 42775 jjdelcerro
    private void loadFeatures() {
920 43283 jjdelcerro
        InputStreamReader in = null;
921 41617 jjdelcerro
        SimpleReader reader = null;
922
        try {
923
            String headers[] = null;
924
            FeatureStoreProviderServices store = this.getStoreServices();
925 41006 jjdelcerro
926 41617 jjdelcerro
            boolean ignore_errors = CSVStoreParameters.getIgnoreErrors(getCSVParameters());
927 42220 fdiaz
928 43283 jjdelcerro
            in = openFile(
929 44309 omartinez
                    this.getCSVParameters().getFile(),
930
                    CSVStoreParameters.getCharset(this.getCSVParameters())
931 43283 jjdelcerro
            );
932 41006 jjdelcerro
933 41617 jjdelcerro
            reader = getSimpleReader(in);
934 41006 jjdelcerro
935 41617 jjdelcerro
            headers = CSVStoreParameters.getHeaders(getCSVParameters());
936 42775 jjdelcerro
            if (headers == null) {
937
                if (CSVStoreParameters.isFirstLineHeader(getCSVParameters())) {
938
                    headers = reader.getHeader();
939
                    if (headers == null) {
940
                        if (CSVStoreParameters.getIgnoreErrors(getCSVParameters())) {
941
                            headers = getFixedHeaders(reader.getColumnsCount());
942
                        } else {
943
                            String msg = "Can't retrieve header from csv file '"
944
                                    + this.getCSVParameters().getFile()
945 44309 omartinez
                                            .getAbsolutePath()
946 42775 jjdelcerro
                                    + "' and not specified in the parameters.";
947 44408 jjdelcerro
                            LOGGER.warn(msg);
948 42775 jjdelcerro
                            throw new RuntimeException(msg);
949
                        }
950
                    }
951
                } else {
952
                    headers = getFixedHeaders(reader.getColumnsCount());
953 41617 jjdelcerro
                }
954 42775 jjdelcerro
            } else {
955
                if (CSVStoreParameters.isFirstLineHeader(getCSVParameters())) {
956
                    reader.getHeader(); // Skip and ignore the header of file
957
                }
958 41617 jjdelcerro
            }
959 41006 jjdelcerro
960 42775 jjdelcerro
            int[] detectedTypes = automaticDetectionOfTypes(headers);
961 44309 omartinez
            if (detectedTypes != null && detectedTypes.length > headers.length) {
962 42775 jjdelcerro
                // Se han detectado mas columnas que las que hay en la cabezera,
963
                // a?adimos mas columnas a la cabezera.
964
                String[] headers2 = new String[detectedTypes.length];
965 44309 omartinez
                for (int i = 0; i < headers2.length; i++) {
966
                    if (i < headers.length) {
967 42775 jjdelcerro
                        headers2[i] = headers[i];
968
                    } else {
969
                        headers2[i] = getFixedHeader(i);
970
                    }
971
                }
972
                headers = headers2;
973
            }
974 44309 omartinez
            for (int i = 0; i < headers.length; i++) {
975
                if (StringUtils.isEmpty(headers[i])) {
976 44272 jjdelcerro
                    headers[i] = getFixedHeader(i);
977
                }
978
            }
979 41617 jjdelcerro
            // Initialize the feature types
980 42775 jjdelcerro
            EditableFeatureType edftype = this.getFeatureType(headers, detectedTypes);
981 41617 jjdelcerro
            FeatureType ftype = edftype.getNotEditableCopy();
982 42775 jjdelcerro
            List<FeatureType> ftypes = new ArrayList<>();
983 41617 jjdelcerro
            ftypes.add(ftype);
984
            store.setFeatureTypes(ftypes, ftype);
985 41059 jjdelcerro
986 41617 jjdelcerro
            Coercion coercion[] = new Coercion[ftype.size()];
987 44669 jjdelcerro
            CoercionContext coercionContext[] = new CoercionContext[ftype.size()];
988 41617 jjdelcerro
            int sizes[] = new int[ftype.size()];
989 42775 jjdelcerro
            for (int i = 0; i < ftype.size(); i++) {
990 41617 jjdelcerro
                sizes[i] = -1;
991
                FeatureAttributeDescriptor ad = ftype.getAttributeDescriptor(i);
992 44669 jjdelcerro
                coercion[i] = ad.getCoercion();
993
                coercionContext[i] = ad.getCoercionContext();
994 44309 omartinez
                switch (ad.getDataType().getType()) {
995
                    case DataTypes.INT:
996 44669 jjdelcerro
                        sizes[i] = 0;
997 44309 omartinez
                        break;
998
                    case DataTypes.LONG:
999 44669 jjdelcerro
                        sizes[i] = 0;
1000 44309 omartinez
                        break;
1001
                    case DataTypes.STRING:
1002
                        if (ad.getSize() == 0) {
1003
                            // Es un string y no tiene un size asignado.
1004
                            // Lo ponemos a cero para calcularlo.
1005
                            sizes[i] = 0;
1006
                        }
1007
                        break;
1008
                    case DataTypes.URL:
1009
                    case DataTypes.URI:
1010
                    case DataTypes.FILE:
1011 41617 jjdelcerro
                        sizes[i] = 0;
1012
                }
1013
            }
1014 42775 jjdelcerro
            if (ftype.getDefaultGeometryAttributeName() != null) {
1015 41617 jjdelcerro
                this.need_calculate_envelope = true;
1016
            }
1017 41006 jjdelcerro
1018 41617 jjdelcerro
            Locale locale = CSVStoreParameters.getLocale(getCSVParameters());
1019
            taskStatus.message("_loading");
1020
            int count = 0;
1021 41062 jjdelcerro
1022 41617 jjdelcerro
            int count_errors = 0;
1023 41062 jjdelcerro
1024 41617 jjdelcerro
            List<String> row = reader.read();
1025 41062 jjdelcerro
1026 41617 jjdelcerro
            int skipLines = CSVStoreParameters.getSkipLines(getCSVParameters());
1027 42775 jjdelcerro
            if (skipLines > 0) {
1028 41617 jjdelcerro
                row = reader.skip(skipLines);
1029
            }
1030 42775 jjdelcerro
            int limit = CSVStoreParameters.getLimit(getCSVParameters());
1031
            while (row != null) {
1032 41617 jjdelcerro
                taskStatus.setCurValue(++count);
1033
                FeatureProvider feature = this.createFeatureProvider(ftype);
1034 42775 jjdelcerro
                for (int i = 0; i < row.size(); i++) {
1035 41617 jjdelcerro
                    Object rawvalue = row.get(i);
1036
                    try {
1037
                        Object value = null;
1038 44749 jjdelcerro
                        if( coercion[i]!=null ) {
1039
                          value = coercion[i].coerce(rawvalue, coercionContext[i]);
1040
                        }
1041 41617 jjdelcerro
                        feature.set(i, value);
1042 44309 omartinez
                        if (sizes[i] >= 0
1043
                                && (value instanceof String || value instanceof URL
1044
                                || value instanceof URI || value instanceof File)) {
1045 43425 jjdelcerro
                            int x = value.toString().length();
1046 42775 jjdelcerro
                            if (sizes[i] < x) {
1047 41617 jjdelcerro
                                sizes[i] = x;
1048
                            }
1049
                        }
1050 42775 jjdelcerro
                    } catch (Exception ex) {
1051
                        if (!ignore_errors) {
1052 41617 jjdelcerro
                            throw ex;
1053
                        }
1054 42775 jjdelcerro
                        if (count_errors++ < 10) {
1055 44408 jjdelcerro
                            LOGGER.warn("Can't load value of attribute " + i + " in row " + count + ".", ex);
1056 41617 jjdelcerro
                        }
1057 42775 jjdelcerro
                        if (count_errors == 10) {
1058 44408 jjdelcerro
                            LOGGER.info("Too many errors, suppress messages.");
1059 41617 jjdelcerro
                        }
1060
                    }
1061
                }
1062
                this.addFeatureProvider(feature);
1063 44309 omartinez
                if (limit > 0) {
1064
                    if (limit < this.data.size()) {
1065 42775 jjdelcerro
                        break;
1066
                    }
1067
                }
1068 41617 jjdelcerro
                row = reader.read();
1069
            }
1070 42775 jjdelcerro
            for (int i = 0; i < ftype.size(); i++) {
1071
                if (sizes[i] > 0) {
1072 41617 jjdelcerro
                    EditableFeatureAttributeDescriptor efad = ((EditableFeatureAttributeDescriptor) edftype.getAttributeDescriptor(i));
1073
                    efad.setSize(sizes[i]);
1074
                }
1075
            }
1076
            // Volvemos a asignar al store el featuretype, ya que puede
1077
            // haber cambiado.
1078
            ftype = edftype.getNotEditableCopy();
1079 42775 jjdelcerro
            ftypes = new ArrayList<>();
1080 41617 jjdelcerro
            ftypes.add(ftype);
1081
            store.setFeatureTypes(ftypes, ftype);
1082 41062 jjdelcerro
1083 41617 jjdelcerro
            taskStatus.terminate();
1084 42775 jjdelcerro
        } catch (Exception ex) {
1085 41643 jjdelcerro
            int lineno = 0;
1086 42775 jjdelcerro
            if (reader != null) {
1087 41643 jjdelcerro
                lineno = reader.getLine();
1088
            }
1089 42775 jjdelcerro
            throw new RuntimeException("Problems reading file '" + getFullFileName() + "' near line " + lineno + ".", ex);
1090 41643 jjdelcerro
1091 41617 jjdelcerro
        } finally {
1092 42775 jjdelcerro
            if (reader != null) {
1093 41617 jjdelcerro
                try {
1094
                    reader.close();
1095
                } catch (Exception ex) {
1096
                    // Do nothing
1097
                }
1098
                reader = null;
1099
            }
1100 42775 jjdelcerro
            if (in != null) {
1101 41617 jjdelcerro
                try {
1102
                    in.close();
1103
                } catch (Exception ex) {
1104
                    // Do nothing
1105
                }
1106
                in = null;
1107
            }
1108
        }
1109
    }
1110 41062 jjdelcerro
1111 42775 jjdelcerro
    private int[] automaticDetectionOfTypes(String[] headers) throws IOException {
1112 41617 jjdelcerro
        boolean automatic_types_detection = CSVStoreParameters.getAutomaticTypesDetection(getCSVParameters());
1113 42775 jjdelcerro
        if (!automatic_types_detection) {
1114 41617 jjdelcerro
            return null;
1115
        }
1116
        int[] types = null;
1117
1118
        FileReader in = null;
1119
        SimpleReader reader = null;
1120
1121
        try {
1122
            in = new FileReader(this.getCSVParameters().getFile());
1123
            reader = getSimpleReader(in);
1124 43983 jjdelcerro
            AutomaticDetectionOfTypes x = new AutomaticDetectionOfTypes(
1125
                    this.getFullFileName()
1126
            );
1127
            types = x.detect(
1128 44309 omartinez
                    headers.length,
1129
                    reader,
1130
                    CSVStoreParameters.isFirstLineHeader(getCSVParameters()),
1131 43983 jjdelcerro
                    CSVStoreParameters.getLocale(getCSVParameters())
1132
            );
1133 42775 jjdelcerro
        } catch (Exception ex) {
1134 41643 jjdelcerro
            int lineno = 0;
1135 42775 jjdelcerro
            if (reader != null) {
1136 41643 jjdelcerro
                lineno = reader.getLine();
1137
            }
1138 42775 jjdelcerro
            throw new RuntimeException("Problems reading file '" + getFullFileName() + "' near line " + lineno + ".", ex);
1139 41643 jjdelcerro
1140 41617 jjdelcerro
        } finally {
1141 42775 jjdelcerro
            IOUtils.closeQuietly(reader);
1142
            IOUtils.closeQuietly(in);
1143
        }
1144
        return types;
1145
    }
1146
1147 40846 jjdelcerro
}