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

History | View | Annotate | Download (48.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.store.csv;
24

    
25
import java.io.File;
26
import java.io.FileInputStream;
27
import java.io.FileNotFoundException;
28
import java.io.FileReader;
29
import java.io.IOException;
30
import java.io.InputStreamReader;
31
import java.net.URI;
32
import java.net.URL;
33
import java.nio.charset.Charset;
34
import java.util.ArrayList;
35
import java.util.HashMap;
36
import java.util.Iterator;
37
import java.util.List;
38
import java.util.Locale;
39
import java.util.Map;
40
import javax.json.JsonArray;
41
import javax.json.JsonObject;
42
import javax.json.JsonValue;
43

    
44
import org.apache.commons.io.FilenameUtils;
45
import org.apache.commons.io.IOUtils;
46
import org.apache.commons.lang3.StringUtils;
47
import org.cresques.cts.IProjection;
48
import org.gvsig.fmap.dal.DALLocator;
49
import org.gvsig.fmap.dal.DataManager;
50
import org.gvsig.fmap.dal.DataServerExplorer;
51
import org.gvsig.fmap.dal.DataStore;
52
import org.gvsig.fmap.dal.DataStoreNotification;
53
import org.gvsig.fmap.dal.DataTypes;
54
import org.gvsig.fmap.dal.FileHelper;
55
import org.gvsig.fmap.dal.exception.DataException;
56
import org.gvsig.fmap.dal.exception.InitializeException;
57
import org.gvsig.fmap.dal.exception.OpenException;
58
import org.gvsig.fmap.dal.exception.ReadException;
59
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
60
import org.gvsig.fmap.dal.feature.EditableFeature;
61
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
62
import org.gvsig.fmap.dal.feature.EditableFeatureType;
63
import org.gvsig.fmap.dal.feature.Feature;
64
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
65
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
66
import org.gvsig.fmap.dal.feature.FeatureSet;
67
import org.gvsig.fmap.dal.feature.FeatureStore;
68
import org.gvsig.fmap.dal.feature.FeatureType;
69
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
70
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
71
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
72
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
73
import org.gvsig.fmap.dal.resource.ResourceAction;
74
import org.gvsig.fmap.dal.resource.file.FileResource;
75
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
76
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
77
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
78
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
79
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
80
import org.gvsig.fmap.dal.store.csv.AutomaticDetectionOfTypes.DetectedValue;
81
import org.gvsig.fmap.dal.store.csv.simplereaders.CSVReader;
82
import org.gvsig.fmap.dal.store.csv.simplereaders.FixedLenReader;
83
import org.gvsig.fmap.dal.store.csv.simplereaders.JSonReader;
84
import org.gvsig.fmap.dal.store.csv.simplereaders.SimpleReader;
85
import org.gvsig.fmap.geom.Geometry;
86
import org.gvsig.fmap.geom.GeometryLocator;
87
import org.gvsig.fmap.geom.GeometryManager;
88
import org.gvsig.fmap.geom.GeometryUtils;
89
import org.gvsig.fmap.geom.aggregate.MultiPoint;
90
import org.gvsig.fmap.geom.primitive.Envelope;
91
import org.gvsig.fmap.geom.primitive.Point;
92
import org.gvsig.fmap.geom.type.GeometryType;
93
import org.gvsig.json.Json;
94
import org.gvsig.json.JsonObjectBuilder;
95
import org.gvsig.tools.ToolsLocator;
96
import org.gvsig.tools.dataTypes.DataType;
97
import org.gvsig.tools.dataTypes.DataTypesManager;
98
import org.gvsig.tools.dataTypes.Coercion;
99
import org.gvsig.tools.dispose.DisposableIterator;
100
import org.gvsig.tools.dynobject.Tags;
101
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
102
import org.gvsig.tools.evaluator.AbstractEvaluator;
103
import org.gvsig.tools.evaluator.EvaluatorData;
104
import org.gvsig.tools.evaluator.EvaluatorException;
105
import org.gvsig.tools.exception.BaseException;
106
import org.gvsig.tools.exception.NotYetImplemented;
107
import org.gvsig.tools.persistence.PersistentState;
108
import org.gvsig.tools.persistence.exception.PersistenceException;
109
import org.gvsig.tools.task.SimpleTaskStatus;
110
import org.gvsig.tools.task.TaskStatusManager;
111
import org.gvsig.tools.visitor.VisitCanceledException;
112
import org.gvsig.tools.visitor.Visitor;
113
import org.slf4j.Logger;
114
import org.slf4j.LoggerFactory;
115
import org.supercsv.prefs.CsvPreference;
116
import org.gvsig.tools.dataTypes.CoercionContext;
117

    
118
@SuppressWarnings("UseSpecificCatch")
119
public class CSVStoreProvider extends AbstractMemoryStoreProvider implements
120
        ResourceConsumer {
121

    
122
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVStoreProvider.class);
123

    
124
    public static final String NAME = DataStore.CSV_PROVIDER_NAME;
125
    public static final String DESCRIPTION = "CSV file";
126

    
127
    public static final String METADATA_DEFINITION_NAME = NAME;
128

    
129
    private ResourceProvider resource;
130

    
131
    private long counterNewsOIDs = 0;
132
    private Envelope envelope;
133
    private boolean need_calculate_envelope = false;
134
    private final SimpleTaskStatus taskStatus;
135
    private final CSVFeatureWriter writer;
136
    private FeatureType featureType;
137

    
138
    public CSVStoreProvider(CSVStoreParameters parameters,
139
            DataStoreProviderServices storeServices) throws InitializeException {
140
        super(
141
                parameters,
142
                storeServices,
143
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
144
        );
145
        this.writer = new CSVFeatureWriter();
146
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
147
        this.taskStatus = manager.createDefaultSimpleTaskStatus("CSV");
148

    
149
        counterNewsOIDs = 0;
150

    
151
        File file = getCSVParameters().getFile();
152
        resource = this.createResource(
153
                FileResource.NAME,
154
                new Object[]{file.getAbsolutePath()}
155
        );
156

    
157
        resource.addConsumer(this);
158

    
159
        initializeFeatureTypes();
160
    }
161

    
162
    private CSVStoreParameters getCSVParameters() {
163
        return (CSVStoreParameters) this.getParameters();
164
    }
165

    
166
    @Override
167
    public String getProviderName() {
168
        return NAME;
169
    }
170

    
171
    @Override
172
    public boolean allowWrite() {
173
        return true;
174
    }
175

    
176
    private String getFullFileName() {
177
        // Usar solo para mostrar mensajes en el logger.
178
        String s;
179
        try {
180
            s = getCSVParameters().getFile().getAbsolutePath();
181
        } catch (Exception e2) {
182
            s = "(unknow)";
183
        }
184
        return s;
185
    }
186

    
187
    @Override
188
    public void open() throws OpenException {
189
        if (this.data != null) {
190
            return;
191
        }
192
        this.data = new ArrayList<>();
193
        resource.setData(new HashMap());
194
        counterNewsOIDs = 0;
195
        try {
196
            loadFeatures();
197
        } catch (RuntimeException e) {
198
            LOGGER.debug("Can't load features from CSV '" + getFullFileName() + "'.", e);
199
            throw e;
200
        } catch (Exception e) {
201
            LOGGER.debug("Can't load features from CSV '" + getFullFileName() + "'.", e);
202
            throw new RuntimeException(e);
203
        }
204
    }
205

    
206
    @Override
207
    public DataServerExplorer getExplorer() throws ReadException {
208
        DataManager manager = DALLocator.getDataManager();
209
        FilesystemServerExplorerParameters params;
210
        try {
211
            params = (FilesystemServerExplorerParameters) manager
212
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
213
            params.setRoot(this.getCSVParameters().getFile().getParent());
214
            return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
215
        } catch (DataException e) {
216
            throw new ReadException(this.getProviderName(), e);
217
        } catch (ValidateDataParametersException e) {
218
            throw new ReadException(this.getProviderName(), e);
219
        }
220

    
221
    }
222

    
223
    @Override
224
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
225

    
226
        try {
227
            this.taskStatus.add();
228
            taskStatus.message("_preparing");
229
            this.getResource().closeRequest();
230
            getResource().execute(new ResourceAction() {
231
                @Override
232
                public Object run() throws Exception {
233
                    FeatureSet features = null;
234
                    DisposableIterator it = null;
235
                    try {
236
                        File file = (File) resource.get();
237

    
238
                        features
239
                                = getStoreServices().getFeatureStore()
240
                                        .getFeatureSet();
241
                        List<FeatureProvider> newdata = new ArrayList<FeatureProvider>();
242
                        FeatureType ftype = getStoreServices().getDefaultFeatureType();
243
                        writer.initialize(getCSVParameters(), file, ftype, getCSVPreferences());
244
                        writer.begin();
245
                        it = features.fastIterator();
246
                        taskStatus.setRangeOfValues(0, 0);
247
                        long counter = 0;
248
                        while (it.hasNext()) {
249
                            taskStatus.setCurValue(counter++);
250
                            FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
251
                                    (org.gvsig.fmap.dal.feature.Feature) it.next());
252
                            writer.add(feature);
253
                            if (feature.getOID() == null) {
254
                                LOGGER.warn("feature without OID");
255
                                feature.setOID(createNewOID());
256
                            }
257
                            newdata.add(feature);
258
                        }
259
                        data = newdata;
260
                        if (writer.getEnvelope() != null) {
261
                            envelope = writer.getEnvelope().getGeometry().getEnvelope();
262
                        }
263
                        resource.notifyChanges();
264
                        writer.end();
265
                    } finally {
266
                        if (it != null) {
267
                            it.dispose();
268
                        }
269
                        if (features != null) {
270
                            features.dispose();
271
                        }
272
                    }
273
                    return null;
274
                }
275

    
276
            });
277
            this.taskStatus.terminate();
278
        } catch (Exception e) {
279
            this.taskStatus.abort();
280
            throw new PerformEditingException(getResource().toString(), e);
281
        } finally {
282
            this.taskStatus.remove();
283
        }
284
    }
285

    
286
    private CsvPreference getCSVPreferences() {
287
        CSVReader reader = new CSVReader(getCSVParameters());
288
        return reader.getCSVPreferences();
289
    }
290

    
291
    @Override
292
    public boolean closeResourceRequested(ResourceProvider resource) {
293
        return true;
294
    }
295

    
296
    @Override
297
    public int getOIDType() {
298
        return DataTypes.LONG;
299
    }
300

    
301
    @Override
302
    public boolean supportsAppendMode() {
303
        return true;
304
    }
305

    
306
    @Override
307
    public void append(final FeatureProvider featureProvider) {
308
        //todo
309
        getResource().execute(new ResourceAction() {
310
            @Override
311
            public Object run() throws Exception {
312
                //writer.append(getStoreServices().createFeature(featureProvider));
313
                writer.add(featureProvider);
314
                return null;
315
            }
316
        });
317
    }
318

    
319
    @Override
320
    public void beginAppend() throws DataException {
321
        this.close();
322
        getResource().execute(new ResourceAction() {
323
            public Object run() throws Exception {
324
                writer.initialize(
325
                        getCSVParameters(),
326
                        getCSVParameters().getFile(),
327
                        getFeatureStore().getDefaultFeatureType(),
328
                        getCSVPreferences()
329
                );
330
                writer.beginAppend();
331
                return null;
332
            }
333
        });
334

    
335
    }
336

    
337
    @Override
338
    public void endAppend() {
339
        try {
340
            getResource().execute(new ResourceAction() {
341
                public Object run() throws Exception {
342
                    writer.end();
343
                    resource.notifyChanges(); //resourcesNotifyChanges();
344
                    counterNewsOIDs = -1;
345
                    return null;
346
                }
347
            });
348
            writer.end();
349
        } catch (PerformEditingException ex) {
350
            LOGGER.warn("Not been able to end append '" + this.getFullName() + "'.", ex);
351
        }
352
    }
353

    
354
    public void saveToState(PersistentState state) throws PersistenceException {
355
        throw new NotYetImplemented();
356
    }
357

    
358
    public void loadFromState(PersistentState state) throws PersistenceException {
359
        throw new NotYetImplemented();
360
    }
361

    
362
    @Override
363
    public Object createNewOID() {
364
        return counterNewsOIDs++;
365
    }
366

    
367
    protected void initializeFeatureTypes() throws InitializeException {
368
        try {
369
            this.open();
370
        } catch (OpenException e) {
371
            throw new InitializeException(this.getProviderName(), e);
372
        }
373
    }
374

    
375
    @Override
376
    public Envelope getEnvelope() throws DataException {
377
        this.open();
378
        if (this.envelope != null) {
379
            return this.envelope;
380
        }
381
        if (!this.need_calculate_envelope) {
382
            return null;
383
        }
384
        FeatureStore fs = this.getFeatureStore();
385
        FeatureType ft = fs.getDefaultFeatureType();
386
        FeatureAttributeDescriptor fad = ft.getAttributeDescriptor(ft.getDefaultGeometryAttributeIndex());
387

    
388
        try {
389
            this.envelope = GeometryLocator.getGeometryManager().createEnvelope(fad.getGeomType().getSubType());
390
            fs.accept(new Visitor() {
391
                @Override
392
                public void visit(Object obj) throws VisitCanceledException, BaseException {
393
                    Feature f = (Feature) obj;
394
                    Geometry geom = f.getDefaultGeometry();
395
                    if (geom != null) {
396
                        envelope.add(geom.getEnvelope());
397
                    }
398
                }
399
            });
400
        } catch (BaseException e) {
401
            LOGGER.warn("Can't calculate the envelope of CSV file '" + this.getFullName() + "'.", e);
402
            this.envelope = null;
403
        }
404

    
405
        this.need_calculate_envelope = false;
406
        return this.envelope;
407
    }
408

    
409
    @Override
410
    public Object getDynValue(String name) throws DynFieldNotFoundException {
411
        if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
412
            try {
413
                return this.getEnvelope();
414
            } catch (DataException e) {
415
                return null;
416
            }
417
        } else {
418
            if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
419
                IProjection pro = CSVStoreParameters.getCRS(this.getCSVParameters());
420
                if (pro != null) {
421
                    return pro;
422
                }
423
            }
424
        }
425
        return super.getDynValue(name);
426
    }
427

    
428
    @Override
429
    public void resourceChanged(ResourceProvider resource) {
430
        this.getStoreServices().notifyChange(
431
                DataStoreNotification.RESOURCE_CHANGED,
432
                resource);
433
    }
434

    
435
    @Override
436
    public Object getSourceId() {
437
        return this.getCSVParameters().getFile();
438
    }
439

    
440
    @Override
441
    public String getName() {
442
        String name = this.getCSVParameters().getFile().getName();
443
        return FilenameUtils.getBaseName(name);
444
    }
445

    
446
    @Override
447
    public String getFullName() {
448
        return this.getCSVParameters().getFile().getAbsolutePath();
449
    }
450

    
451
    @Override
452
    public ResourceProvider getResource() {
453
        return resource;
454
    }
455

    
456
    private boolean isEmpty(String s) {
457
        if (s == null) {
458
            return true;
459
        }
460
        return s.trim().length() == 0;
461
    }
462

    
463
    private void init(CSVStoreParameters parameters, DataStoreProviderServices storeServices) {
464
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
465
    }
466
    
467
    public static class FieldTypeParser {
468

    
469
        public String name = null;
470
        public int type = DataTypes.STRING;
471
        public int size = 0;
472
        public int geomType = Geometry.TYPES.GEOMETRY;
473
        public int geomSubtype = Geometry.SUBTYPES.GEOM2D;
474
        public Map<String,String> tags = new HashMap<>();
475
        public Map<String,String> assignments = new HashMap<>();
476
        
477
        // Valores obtenidos desde la deteccion automatica desde los datos
478
        public DetectedValue detectedValue = null ;
479

    
480
        private String typename = "string";
481

    
482
        private final String fullFileName;
483
        private final String providerName;
484
        
485
        FieldTypeParser(String providerName, String fullFileName) {
486
            this.providerName = providerName;
487
            this.fullFileName = fullFileName;
488
        }
489

    
490
        public String getProviderName() {
491
            return this.providerName;
492
        }
493
        
494
        public String getFullFileName() {
495
            return this.fullFileName;
496
        }
497
        
498
        public void clear() {
499
            this.name = null;
500
            this.type = DataTypes.STRING;
501
            this.size = 0;
502
            this.tags = new HashMap<>();
503
            this.assignments = new HashMap<>();
504
        }
505

    
506
        public void copyFrom(FieldTypeParser other) {
507
            this.name = other.name;
508
            this.type = other.type;
509
            this.size = other.size;
510
            this.tags = new HashMap<>();
511
            this.tags.putAll(other.tags);
512
            this.assignments = new HashMap<>();
513
            this.assignments.putAll(other.assignments);
514
        }
515

    
516
        private int getType(String value) {
517
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
518
            return dataTypesManager.getType(typename);
519
        }
520

    
521
        private String[] split(String value, String separators) {
522
            int firstSeparatorPosition = 1000000;
523
            Character sep = null;
524
            for (char ch : separators.toCharArray()) {
525
                int pos = value.indexOf(ch);
526
                if( pos>0 && pos<firstSeparatorPosition ) {
527
                    sep = ch;
528
                    firstSeparatorPosition = pos;
529
                }
530
            }
531
            if( sep == null ) {
532
                return new String[] { value };
533
            }
534
            return value.split("["+sep+"]");
535
        }
536

    
537
        @SuppressWarnings("UseSpecificCatch")
538
        public boolean parse(String value) {
539
            String[] args;
540
            if ( value.contains("__") ) {
541
                args = value.split("__");
542
            } else {
543
                args = split(value, ":/#@!;-");
544
                if( args.length == 1 ) {
545
                    this.name = value;
546
                    return true;
547
                }
548
            }                        
549
            int n = 0;
550
            this.name = StringUtils.trim(args[n++]);
551
            if( n >= args.length ) {
552
                return true;
553
            }
554
            this.typename = StringUtils.trim(args[n++]);
555
            this.type = this.getType(this.typename);
556
            if ( this.type == DataTypes.INVALID ) {
557
                this.geomType = GeometryUtils.getGeometryType(this.typename);
558
                if( this.geomType==Geometry.TYPES.UNKNOWN )  {
559
                    this.type = DataTypes.STRING;
560
                    LOGGER.info("Type '" + this.typename + "' not valid for attribute '" + value + "' in '"+getProviderName()+"' file '" + getFullFileName() + "'.");
561
                } else {
562
                    this.typename = "GEOMETRY";
563
                    this.type = DataTypes.GEOMETRY;
564
                }
565
            }
566
            this.size = 0;
567

    
568
            while (n < args.length) {
569
                String option = StringUtils.trim(args[n++].toLowerCase());
570
                switch (option) {
571
                    case "size":
572
                        try {
573
                            this.size = Integer.parseInt(args[n++]);
574
                        } catch (Exception ex) {
575
                            LOGGER.warn("Ignore incorrect field size for field " + value + " in '"+getProviderName()+"' file '" + getFullFileName() + "'.", ex);
576
                        }
577
                        break;
578
                    case "tag": {
579
                            String x = StringUtils.trim(args[n++]);
580
                            int pos = x.indexOf("=");
581
                            if( pos < 0 ) {
582
                                this.tags.put(x, null);
583
                            } else {
584
                                this.tags.put( 
585
                                        StringUtils.trim(StringUtils.substring(x, 0, pos)),
586
                                        StringUtils.trim(StringUtils.substring(x, pos+1))
587
                                );
588
                            }
589
                            break;
590
                        }
591
                    case "set": {
592
                            String x = StringUtils.trim(args[n++]);
593
                            int pos = x.indexOf("=");
594
                            if( pos < 0 ) {
595
                                this.assignments.put(x, null);
596
                            } else {
597
                                this.assignments.put( 
598
                                        StringUtils.trim(StringUtils.substring(x, 0, pos)),
599
                                        StringUtils.trim(StringUtils.substring(x, pos+1))
600
                                );
601
                            }
602
                            break;
603
                        }
604
                    default:
605
                        if( StringUtils.isNumeric(option) && this.size == 0 ) {
606
                          try {
607
                              this.size = Integer.parseInt(option);
608
                          } catch (Exception ex) {
609
                              LOGGER.warn("Ignore incorrect field size for field " + value + " in '"+getProviderName()+"' file '" + getFullFileName() + "'.", ex);
610
                          }
611
                          break;
612
                        }
613
                        LOGGER.warn("Illegal argumente '"+option+"' for field '"+this.name+"' in '"+getProviderName()+"' file '" + getFullFileName() + "' ("+value+").");
614
                }
615
            }
616
            return true;
617
        }
618

    
619
    }
620

    
621
    private EditableFeatureType getFeatureType(String headers[], AutomaticDetectionOfTypes.DetectedValue automaticTypes[]) {
622
        EditableFeatureType fType = getStoreServices().createFeatureType(this.getName());
623
        fType.setHasOID(true);
624

    
625
        FieldTypeParser[] fieldTypes = new FieldTypeParser[headers.length];
626
        //
627
        // Calculamos cuales pueden ser los tipos de datos
628
        //
629
        for (int i = 0; i < fieldTypes.length; i++) {
630
            fieldTypes[i] = new FieldTypeParser(getProviderName(), getFullFileName());
631
        }
632

    
633
        // Asuminos los tipos pasados por parametro, que se supone
634
        // son los detectados automaticamente.
635
        if (automaticTypes != null) {
636
            for (int i = 0; i < fieldTypes.length && i < automaticTypes.length; i++) {
637
                fieldTypes[i].detectedValue = automaticTypes[i];
638
                fieldTypes[i].type = automaticTypes[i].getType();
639
            }
640
        }
641
        // Luego probamos con lo que diga las cabezeras del CVS, sobreescribiendo
642
        // los tipos anteriores en caso de definirse en la cabezara.
643
        for (int i = 0; i < fieldTypes.length; i++) {
644
            if (!fieldTypes[i].parse(headers[i])) {
645
                continue;
646
            }
647

    
648
        }
649

    
650
        // Y por ultimo hacemos caso a lo que se haya especificado en los parametros
651
        // de apertura del CSV, teniendo esto prioridad sobre todo.
652
        String param_types_def = CSVStoreParameters.getRawFieldTypes(this.getParameters());
653
        if (StringUtils.isNotBlank(param_types_def)) {
654
            String sep = CSVStoreParameters.getDelimiter(param_types_def);
655
            if (StringUtils.isNotBlank(sep)) {
656
                String[] param_types = param_types_def.split(sep);
657
                FieldTypeParser parser = new FieldTypeParser(getProviderName(), getFullFileName());
658
                for (String param_type : param_types) {
659
                    parser.clear();
660
                    parser.parse(param_type);
661
                    for (FieldTypeParser fieldType : fieldTypes) {
662
                        if (StringUtils.equalsIgnoreCase(fieldType.name, parser.name)) {
663
                            fieldType.copyFrom(parser);
664
                            break;
665
                        }
666
                    }
667
                }
668
            }
669
        }
670
        //
671
        // Una vez ya sabemos los tipos de datos rellenamos el feature-type
672
        //
673
        for (FieldTypeParser fieldType : fieldTypes) {
674
            EditableFeatureAttributeDescriptor fad = fType.add(fieldType.name, fieldType.type);
675
            if( fieldType.detectedValue!=null ) {
676
                fad.setDisplaySize(Math.max(fieldType.detectedValue.getDisplaySize(), fieldType.size));
677
                fad.setSize(Math.max(fieldType.detectedValue.getDisplaySize(), fieldType.size));
678
                if( fad.getPrecision()<fieldType.detectedValue.getPrecision() ) {
679
                    fad.setPrecision(fieldType.detectedValue.getPrecision());
680
                }
681
                if( fad.getScale()<fieldType.detectedValue.getScale()) {
682
                    fad.setScale(fieldType.detectedValue.getScale());
683
                }
684
            } else {
685
                fad.setDisplaySize(fieldType.size);
686
            }
687
            if (fieldType.type == DataTypes.GEOMETRY ) {
688
                fad.setGeometryType(fieldType.geomType, fieldType.geomSubtype);
689
                if( fType.getDefaultGeometryAttributeName() == null ) {
690
                    fType.setDefaultGeometryAttributeName(fieldType.name);
691
                }
692
            }
693
            Locale locale = CSVStoreParameters.getLocale(this.getParameters());
694
            fad.setLocale(locale);
695
            for (Map.Entry<String, String> entry : fieldType.assignments.entrySet()) {
696
                try {
697
                    switch(entry.getKey().toLowerCase()) {
698
                        case "expression":
699
                            // Los campos calculados los procesamos en una segunda
700
                            // pasada, cuando ya estan definidos el resto de los campos
701
                            // ya que pueden requerir campos que aun no se han definido.
702
                            break;
703
                        default:
704
                                fad.set(entry.getKey(), entry.getValue());
705
                            }
706
                } catch (Exception ex) {
707
                    LOGGER.warn("Can't set property '"+entry.getKey()+"' of '"+fad.getName()+"'.", ex);
708
                }
709
            }            
710
            Tags tags = fad.getTags();
711
            for (Map.Entry<String, String> entry : fieldType.tags.entrySet()) {
712
                tags.set(entry.getKey(), entry.getValue());
713
            }
714
        }
715
        // Processamos ahora los campos calculados
716
        for (FieldTypeParser fieldType : fieldTypes) {
717
            EditableFeatureAttributeDescriptor fad = fType.getEditableAttributeDescriptor(fieldType.name);
718
            for (Map.Entry<String, String> entry : fieldType.assignments.entrySet()) {
719
                try {
720
                    switch(entry.getKey().toLowerCase()) {
721
                        case "expression":
722
                            fad.set(entry.getKey(), entry.getValue());
723
                            break;
724
                    }
725
                } catch (Exception ex) {
726
                    LOGGER.warn("Can't set property '"+entry.getKey()+"' in '"+fad.getName()+"' of '"+getFullFileName()+"'.", ex);
727
                }
728
            }
729
        }
730
        String[] pointDimensionNames = CSVStoreParameters.getPointDimensionNames(this.getParameters());
731
        if ( pointDimensionNames != null ) {
732
            PointAttributeEmulator emulator = new PointAttributeEmulator(pointDimensionNames);
733
            String columnName = CSVStoreParameters.getPointColumnName(this.getParameters());
734
            if( StringUtils.isBlank(columnName) ) {
735
                columnName = "the_geom";
736
            }
737
            EditableFeatureAttributeDescriptor attr = fType.add(columnName, DataTypes.GEOMETRY, emulator);
738
            GeometryManager geommgr = GeometryLocator.getGeometryManager();
739
            GeometryType gt;
740
            try {
741
                if ( emulator.fieldNames != null && emulator.fieldNames.length <= 2 ) {
742
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
743
                } else {
744
                        gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM3D);
745
                }
746
                attr.setGeometryType(gt);
747
            } catch (Exception e) {
748
                LOGGER.warn("Can't set geometry type for the calculated field in '"+getProviderName()+"' file '" + getFullFileName() + "'.", e);
749
            }
750
        }        
751
        
752
        String geometry_column = CSVStoreParameters.getGeometryColumn(this.getParameters());
753
        if (!StringUtils.isEmpty(geometry_column)) {
754
            EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor) fType.get(geometry_column);
755
            if (attr != null && attr.getType() != DataTypes.GEOMETRY) {
756
                attr.setDataType(DataTypes.GEOMETRY);
757
                GeometryManager geommgr = GeometryLocator.getGeometryManager();
758
                GeometryType gt;
759
                try {
760
                    gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.UNKNOWN);
761
                    attr.setGeometryType(gt);
762
                } catch (Exception e) {
763
                    LOGGER.warn("Can't set geometry type for the calculated field in CSV file '" + getFullFileName() + "'.", e);
764
                }
765
                fType.setDefaultGeometryAttributeName(geometry_column);
766
            }
767
        }
768
        return fType;
769
    }
770

    
771
    static class PointAttributeEmulator implements FeatureAttributeEmulator {
772

    
773
        private static final Logger logger = LoggerFactory.getLogger(ToPointEvaluaror.class);
774

    
775
        private static final int XNAME = 0;
776
        private static final int YNAME = 1;
777
        private static final int ZNAME = 2;
778

    
779
        private GeometryManager geommgr;
780
        private String[] fieldNames;
781
        private Coercion toDouble;
782
        private DataType dataType;
783
        private int errorcount = 0;
784

    
785
        public PointAttributeEmulator() {
786
            
787
        }
788
        
789
        public PointAttributeEmulator(String[] pointDimensionNames) {
790
            if (pointDimensionNames.length > 2) {
791
                this.fieldNames = new String[3];
792
                this.fieldNames[ZNAME] = pointDimensionNames[2];
793
            } else {
794
                this.fieldNames = new String[2];
795
            }
796
            this.fieldNames[XNAME] = pointDimensionNames[0];
797
            this.fieldNames[YNAME] = pointDimensionNames[1];
798
            this.geommgr = GeometryLocator.getGeometryManager();
799
            DataTypesManager datatypeManager = ToolsLocator.getDataTypesManager();
800

    
801
            this.toDouble = datatypeManager.getCoercion(DataTypes.DOUBLE);
802
            this.dataType = datatypeManager.get(DataTypes.GEOMETRY);
803
        }
804

    
805
        @Override
806
        public Object get(Feature feature) {
807
            try {
808
                Object valueX = feature.get(this.fieldNames[XNAME]);
809
                valueX = toDouble.coerce(valueX);
810
                if (valueX == null) {
811
                    return null;
812
                }
813
                Object valueY = feature.get(this.fieldNames[YNAME]);
814
                valueY = toDouble.coerce(valueY);
815
                if (valueY == null) {
816
                    return null;
817
                }
818
                Object valueZ = null;
819
                if (this.fieldNames.length > 2) {
820
                    valueZ = toDouble.coerce(feature.get(this.fieldNames[ZNAME]));
821
                    if (valueZ == null) {
822
                        return null;
823
                    }
824
                }
825

    
826
                double x = ((Double) valueX);
827
                double y = ((Double) valueY);
828
                Point point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
829
                if (this.fieldNames.length > 2) {
830
                    double z = ((Double) valueZ);
831
                    point.setCoordinateAt(2, z);
832
                }
833
                return point;
834
            } catch (Exception ex) {
835
                if (++errorcount < 5) {
836
                    logger.warn("[" + errorcount + "] Can't create point in CSV provider. XNAME='"
837
                            + this.fieldNames[XNAME] + "', YNAME='" + this.fieldNames[XNAME] + "' feature=" + feature.toString(), ex);
838
                }
839
                return null;
840
            }
841
        }
842

    
843
        public void set(EditableFeature feature, Object value) {
844
            if (value == null) {
845
                return;
846
            }
847
            Point point = null;
848
            if (value instanceof MultiPoint) {
849
                point = (Point) ((MultiPoint) value).getPrimitiveAt(0);
850
            } else {
851
                point = (Point) value;
852
            }
853
            feature.set(this.fieldNames[XNAME], point.getX());
854
            feature.set(this.fieldNames[YNAME], point.getY());
855
            if (this.fieldNames.length > 2) {
856
                feature.set(this.fieldNames[ZNAME], point.getCoordinateAt(2));
857
            }
858
        }
859

    
860
        @Override
861
        public boolean allowSetting() {
862
            return true;
863
        }
864

    
865
        @Override
866
        public String[] getRequiredFieldNames() {
867
            return this.fieldNames;
868
        }
869

    
870
        @Override
871
        public JsonObject toJson() {
872
            return this.toJsonBuilder().build();
873
        }
874

    
875
        @Override
876
        public JsonObjectBuilder toJsonBuilder() {
877
            JsonObjectBuilder builder = Json.createObjectBuilder();
878
            builder.add_class(this);
879
            builder.add("fieldNames", fieldNames);
880
            return builder;
881
        }
882

    
883
        @Override
884
        public void fromJson(JsonObject json) {
885
            JsonArray jsonFieldNames = json.getJsonArray("fieldNames");
886
            this.fieldNames = new String[jsonFieldNames.size()];
887
            for (int i = 0; i < jsonFieldNames.size(); i++) {
888
                this.fieldNames[XNAME] = jsonFieldNames.getString(i);
889
            }
890
            this.geommgr = GeometryLocator.getGeometryManager();
891
            DataTypesManager datatypeManager = ToolsLocator.getDataTypesManager();
892

    
893
            this.toDouble = datatypeManager.getCoercion(DataTypes.DOUBLE);
894
            this.dataType = datatypeManager.get(DataTypes.GEOMETRY);
895
        }
896

    
897
    }
898

    
899
    static class ToPointEvaluaror extends AbstractEvaluator {
900

    
901
        private static final Logger logger = LoggerFactory.getLogger(ToPointEvaluaror.class);
902

    
903
        private GeometryManager geommgr = null;
904
        private String xname = null;
905
        private String yname = null;
906
        private String zname = null;
907
        private Coercion toDouble;
908
        private int errorcount = 0;
909

    
910
        ToPointEvaluaror(String[] pointDimensionNames) {
911
            this.xname = pointDimensionNames[0];
912
            this.yname = pointDimensionNames[1];
913
            if (pointDimensionNames.length > 2) {
914
                this.zname = pointDimensionNames[2];
915
            }
916
            this.geommgr = GeometryLocator.getGeometryManager();
917
            this.toDouble = ToolsLocator.getDataTypesManager().getCoercion(DataTypes.DOUBLE);
918
        }
919

    
920
        @Override
921
        public Object evaluate(EvaluatorData data) throws EvaluatorException {
922
            try {
923
                double x = ((Double) toDouble.coerce(data.getDataValue(xname))).doubleValue();
924
                double y = ((Double) toDouble.coerce(data.getDataValue(yname))).doubleValue();
925
                Point point = geommgr.createPoint(x, y, Geometry.SUBTYPES.GEOM3D);
926
                if (zname != null) {
927
                    double z = ((Double) toDouble.coerce(data.getDataValue(zname))).doubleValue();
928
                    point.setCoordinateAt(2, z);
929
                }
930
                return point;
931
            } catch (Exception ex) {
932
                if (++errorcount < 5) {
933
                    logger.warn("[" + errorcount + "] Can't create point in CSV provider. XNAME='"
934
                            + xname + "', YNAME='" + yname + "', ZNAME='" + zname + "', data=" + data.toString());
935
                }
936
                return null;
937
            }
938
        }
939

    
940
        @Override
941
        public String getName() {
942
            return "ToPointEvaluaror";
943
        }
944

    
945
    }
946

    
947
    private SimpleReader getSimpleReader(InputStreamReader in) throws IOException {
948
        SimpleReader reader;
949
        String filename = CSVStoreParameters.getFileName(getCSVParameters());
950
        if (FilenameUtils.isExtension(filename, "json")){
951
//            reader= new JSonReader(in);
952
            reader= new JSonReader(in,getCSVParameters());
953
        } else if (CSVStoreParameters.getRawFieldsDefinition(getCSVParameters()) != null) {
954
            reader = new FixedLenReader(in, getCSVParameters());
955
        } else {
956
            reader = new CSVReader(in, getCSVParameters());
957
        }
958
        return reader;
959
    }
960

    
961
    private String getFixedHeader(int column) {
962
        char[] header = new char[3];
963

    
964
        String s = String.format("%03d", column);
965
        header[0] = (char) (s.charAt(0) + 17);
966
        header[1] = (char) (s.charAt(1) + 17);
967
        header[2] = (char) (s.charAt(2) + 17);
968
        return String.valueOf(header);
969
    }
970

    
971
    private String[] getFixedHeaders(int count) {
972
        String[] headers = new String[count];
973
        for (int i = 0; i < headers.length; i++) {
974
            headers[i] = getFixedHeader(i);
975
        }
976
        return headers;
977
    }
978

    
979
    private InputStreamReader openFile(File f, String charsetName) throws FileNotFoundException {
980
        Charset charset = Charset.defaultCharset();
981
        FileInputStream fis = new FileInputStream(f);
982
        if (!StringUtils.isEmpty(charsetName)) {
983
            if (Charset.isSupported(charsetName)) {
984
                try {
985
                    charset = Charset.forName(charsetName);
986
                } catch (Throwable th) {
987
                    LOGGER.warn("Can't use charset '" + charsetName + "' for read csv '" + this.getFullFileName() + "'.", th);
988
                }
989
            } else {
990
                LOGGER.warn("charset '" + charsetName + "' not supported for read csv '" + this.getFullFileName() + "'.");
991
            }
992
        }
993
        InputStreamReader isr = new InputStreamReader(fis, charset);
994
        return isr;
995
    }
996

    
997
    private void loadFeatures() {
998
        InputStreamReader in = null;
999
        SimpleReader reader = null;
1000
        try {
1001
            String headers[] = null;
1002
            FeatureStoreProviderServices store = this.getStoreServices();
1003

    
1004
            boolean ignore_errors = CSVStoreParameters.getIgnoreErrors(getCSVParameters());
1005

    
1006
            in = openFile(
1007
                    this.getCSVParameters().getFile(),
1008
                    CSVStoreParameters.getCharset(this.getCSVParameters())
1009
            );
1010

    
1011
            reader = getSimpleReader(in);
1012

    
1013
            headers = CSVStoreParameters.getHeaders(getCSVParameters());
1014
            if (headers == null) {
1015
                if (CSVStoreParameters.isFirstLineHeader(getCSVParameters())) {
1016
                    headers = reader.getHeader();
1017
                    if (headers == null) {
1018
                        if (CSVStoreParameters.getIgnoreErrors(getCSVParameters())) {
1019
                            headers = getFixedHeaders(reader.getColumnsCount());
1020
                        } else {
1021
                            String msg = "Can't retrieve header from csv file '"
1022
                                    + this.getCSVParameters().getFile()
1023
                                            .getAbsolutePath()
1024
                                    + "' and not specified in the parameters.";
1025
                            LOGGER.warn(msg);
1026
                            throw new RuntimeException(msg);
1027
                        }
1028
                    }
1029
                } else {
1030
                    headers = getFixedHeaders(reader.getColumnsCount());
1031
                }
1032
            } else {
1033
                if (CSVStoreParameters.isFirstLineHeader(getCSVParameters())) {
1034
                    reader.getHeader(); // Skip and ignore the header of file
1035
                }
1036
            }
1037

    
1038
            AutomaticDetectionOfTypes.DetectedValue[] detectedTypes = automaticDetectionOfTypes(headers);
1039
            if (detectedTypes != null && detectedTypes.length > headers.length) {
1040
                // Se han detectado mas columnas que las que hay en la cabezera,
1041
                // a?adimos mas columnas a la cabezera.
1042
                String[] headers2 = new String[detectedTypes.length];
1043
                for (int i = 0; i < headers2.length; i++) {
1044
                    if (i < headers.length) {
1045
                        headers2[i] = headers[i];
1046
                    } else {
1047
                        headers2[i] = getFixedHeader(i);
1048
                    }
1049
                }
1050
                headers = headers2;
1051
            }
1052
            for (int i = 0; i < headers.length; i++) {
1053
                if (StringUtils.isEmpty(headers[i])) {
1054
                    headers[i] = getFixedHeader(i);
1055
                }
1056
            }
1057
            // Initialize the feature types
1058
            EditableFeatureType edftype = this.getFeatureType(headers, detectedTypes);
1059
            FeatureType ftype = edftype.getNotEditableCopy();
1060
            this.setFeatureType(ftype);
1061

    
1062
            Coercion coercion[] = new Coercion[ftype.size()];
1063
            CoercionContext coercionContext[] = new CoercionContext[ftype.size()];
1064
            int sizes[] = new int[ftype.size()];
1065
            for (int i = 0; i < ftype.size(); i++) {
1066
                sizes[i] = -1;
1067
                FeatureAttributeDescriptor ad = ftype.getAttributeDescriptor(i);
1068
                coercion[i] = ad.getCoercion();
1069
                coercionContext[i] = ad.getCoercionContext();
1070
                switch (ad.getDataType().getType()) {
1071
                    case DataTypes.INT:
1072
                        sizes[i] = 0;
1073
                        break;
1074
                    case DataTypes.LONG:
1075
                        sizes[i] = 0;
1076
                        break;
1077
                    case DataTypes.STRING:
1078
                        if (ad.getSize() == 0) {
1079
                            // Es un string y no tiene un size asignado.
1080
                            // Lo ponemos a cero para calcularlo.
1081
                            sizes[i] = 0;
1082
                        }
1083
                        break;
1084
                    case DataTypes.URL:
1085
                    case DataTypes.URI:
1086
                    case DataTypes.FILE:
1087
                        sizes[i] = 0;
1088
                }
1089
            }
1090
            if (ftype.getDefaultGeometryAttributeName() != null) {
1091
                this.need_calculate_envelope = true;
1092
            }
1093

    
1094
            Locale locale = CSVStoreParameters.getLocale(getCSVParameters());
1095
            taskStatus.message("_loading");
1096
            int count = 0;
1097

    
1098
            int count_errors = 0;
1099

    
1100
            List<String> row = reader.read();
1101

    
1102
            int skipLines = CSVStoreParameters.getSkipLines(getCSVParameters());
1103
            if (skipLines > 0) {
1104
                row = reader.skip(skipLines);
1105
            }
1106
            int limit = CSVStoreParameters.getLimit(getCSVParameters());
1107
            while (row != null) {
1108
                taskStatus.setCurValue(++count);
1109
                FeatureProvider feature = this.createFeatureProvider(ftype);
1110
                for (int i = 0; i < row.size(); i++) {
1111
                    Object rawvalue = row.get(i);
1112
                    try {
1113
                        Object value = null;
1114
                        if( coercion[i]!=null ) {
1115
                          value = coercion[i].coerce(rawvalue, coercionContext[i]);
1116
                        }
1117
                        feature.set(i, value);
1118
                        if (sizes[i] >= 0
1119
                                && (value instanceof String || value instanceof URL
1120
                                || value instanceof URI || value instanceof File)) {
1121
                            int x = value.toString().length();
1122
                            if (sizes[i] < x) {
1123
                                sizes[i] = x;
1124
                            }
1125
                        }
1126
                    } catch (Exception ex) {
1127
                        if (!ignore_errors) {
1128
                            throw ex;
1129
                        }
1130
                        if (count_errors++ < 10) {
1131
                            LOGGER.warn("Can't load value of attribute " + i + " in row " + count + ".", ex);
1132
                        }
1133
                        if (count_errors == 10) {
1134
                            LOGGER.info("Too many errors, suppress messages.");
1135
                        }
1136
                    }
1137
                }
1138
                this.addFeatureProvider(feature);
1139
                if (limit > 0) {
1140
                    if (limit < this.data.size()) {
1141
                        break;
1142
                    }
1143
                }
1144
                row = reader.read();
1145
            }
1146
            for (int i = 0; i < ftype.size(); i++) {
1147
                if (sizes[i] > 0) {
1148
                    EditableFeatureAttributeDescriptor efad = ((EditableFeatureAttributeDescriptor) edftype.getAttributeDescriptor(i));
1149
                    efad.setSize(sizes[i]);
1150
                }
1151
            }
1152
            // Volvemos a asignar al store el featuretype, ya que puede
1153
            // haber cambiado.
1154
            ftype = edftype.getNotEditableCopy();
1155
            this.setFeatureType(ftype);
1156
            
1157

    
1158
            taskStatus.terminate();
1159
        } catch (Throwable ex) {
1160
            int lineno = 0;
1161
            if (reader != null) {
1162
                lineno = reader.getLine();
1163
            }
1164
            throw new RuntimeException("Problems reading file '" + getFullFileName() + "' near line " + lineno + ".", ex);
1165

    
1166
        } finally {
1167
            if (reader != null) {
1168
                try {
1169
                    reader.close();
1170
                } catch (Exception ex) {
1171
                    // Do nothing
1172
                }
1173
                reader = null;
1174
            }
1175
            if (in != null) {
1176
                try {
1177
                    in.close();
1178
                } catch (Exception ex) {
1179
                    // Do nothing
1180
                }
1181
                in = null;
1182
            }
1183
        }
1184
    }
1185

    
1186
    private AutomaticDetectionOfTypes.DetectedValue[] automaticDetectionOfTypes(String[] headers) throws IOException {
1187
        boolean automatic_types_detection = CSVStoreParameters.getAutomaticTypesDetection(getCSVParameters());
1188
        if (!automatic_types_detection) {
1189
            return null;
1190
        }
1191
        AutomaticDetectionOfTypes.DetectedValue[] types = null;
1192

    
1193
        FileReader in = null;
1194
        SimpleReader reader = null;
1195

    
1196
        try {
1197
            in = new FileReader(this.getCSVParameters().getFile());
1198
            reader = getSimpleReader(in);
1199
            AutomaticDetectionOfTypes x = new AutomaticDetectionOfTypes(
1200
                    this.getFullFileName()
1201
            );
1202
            types = x.detect(
1203
                    headers.length,
1204
                    reader,
1205
                    CSVStoreParameters.isFirstLineHeader(getCSVParameters()),
1206
                    CSVStoreParameters.getLocale(getCSVParameters())
1207
            );
1208
        } catch (Exception ex) {
1209
            int lineno = 0;
1210
            if (reader != null) {
1211
                lineno = reader.getLine();
1212
            }
1213
            throw new RuntimeException("Problems reading file '" + getFullFileName() + "' near line " + lineno + ".", ex);
1214

    
1215
        } finally {
1216
            IOUtils.closeQuietly(reader);
1217
            IOUtils.closeQuietly(in);
1218
        }
1219
        return types;
1220
    }
1221
    
1222
    @Override
1223
    public void fixFeatureTypeFromParameters() {
1224
        String param_types_def = CSVStoreParameters.getRawFieldTypes(this.getParameters());
1225
        String[] pointDimensionNames = CSVStoreParameters.getPointDimensionNames(this.getParameters());
1226
        String geometry_column = CSVStoreParameters.getGeometryColumn(this.getParameters());
1227
        if (StringUtils.isNotBlank(param_types_def) || 
1228
                pointDimensionNames != null || 
1229
                !StringUtils.isBlank(geometry_column)) {
1230
            this.setFeatureType(featureType);
1231
        }
1232
    }
1233
    
1234
    private void setFeatureType(FeatureType ftype) {
1235
        FeatureStoreProviderServices store = this.getStoreServices();
1236
        List<FeatureType> ftypes = new ArrayList<>();
1237
        ftypes.add(ftype);
1238
        this.featureType = ftype;
1239
        store.setFeatureTypes(ftypes, ftype);
1240
    }
1241

    
1242
}