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

History | View | Annotate | Download (26.9 KB)

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

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

    
35
import org.apache.commons.io.FilenameUtils;
36
import org.cresques.cts.IProjection;
37
import org.gvsig.fmap.dal.DALLocator;
38
import org.gvsig.fmap.dal.DataManager;
39
import org.gvsig.fmap.dal.DataServerExplorer;
40
import org.gvsig.fmap.dal.DataStore;
41
import org.gvsig.fmap.dal.DataStoreNotification;
42
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.FileHelper;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.exception.InitializeException;
46
import org.gvsig.fmap.dal.exception.OpenException;
47
import org.gvsig.fmap.dal.exception.ReadException;
48
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
49
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53
import org.gvsig.fmap.dal.feature.FeatureSet;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
57
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
58
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
59
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
60
import org.gvsig.fmap.dal.resource.ResourceAction;
61
import org.gvsig.fmap.dal.resource.file.FileResource;
62
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
63
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
64
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
65
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
66
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
67
import org.gvsig.fmap.geom.Geometry;
68
import org.gvsig.fmap.geom.GeometryLocator;
69
import org.gvsig.fmap.geom.GeometryManager;
70
import org.gvsig.fmap.geom.primitive.Envelope;
71
import org.gvsig.fmap.geom.primitive.Point;
72
import org.gvsig.fmap.geom.type.GeometryType;
73
import org.gvsig.tools.ToolsLocator;
74
import org.gvsig.tools.dataTypes.CoercionException;
75
import org.gvsig.tools.dataTypes.DataTypesManager;
76
import org.gvsig.tools.dataTypes.DataTypesManager.Coercion;
77
import org.gvsig.tools.dispose.DisposableIterator;
78
import org.gvsig.tools.dynobject.DynObject;
79
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
80
import org.gvsig.tools.evaluator.AbstractEvaluator;
81
import org.gvsig.tools.evaluator.EvaluatorData;
82
import org.gvsig.tools.evaluator.EvaluatorException;
83
import org.gvsig.tools.exception.BaseException;
84
import org.gvsig.tools.exception.NotYetImplemented;
85
import org.gvsig.tools.persistence.PersistentState;
86
import org.gvsig.tools.persistence.exception.PersistenceException;
87
import org.gvsig.tools.task.SimpleTaskStatus;
88
import org.gvsig.tools.task.TaskStatusManager;
89
import org.gvsig.tools.visitor.VisitCanceledException;
90
import org.gvsig.tools.visitor.Visitor;
91
import org.slf4j.Logger;
92
import org.slf4j.LoggerFactory;
93
import org.supercsv.comment.CommentStartsWith;
94
import org.supercsv.io.CsvListReader;
95
import org.supercsv.io.CsvListWriter;
96
import org.supercsv.prefs.CsvPreference;
97
import org.supercsv.quote.QuoteMode;
98

    
99
public class CSVStoreProvider extends AbstractMemoryStoreProvider implements
100
ResourceConsumer {
101
    private static final Logger logger = LoggerFactory.getLogger(CSVStoreProvider.class);
102

    
103
    public static final String NAME = "CSV";
104
    public static final String DESCRIPTION = "CSV file";
105

    
106
    public static final String METADATA_DEFINITION_NAME = NAME;
107

    
108
    private ResourceProvider resource;
109

    
110
    private long counterNewsOIDs = 0;
111
    private Envelope envelope;
112
    private boolean need_calculate_envelope = false;
113
    private SimpleTaskStatus taskStatus;
114

    
115

    
116
    public CSVStoreProvider(CSVStoreParameters parameters,
117
        DataStoreProviderServices storeServices) throws InitializeException {
118
        super(
119
            parameters, 
120
            storeServices,
121
            FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
122
        );
123

    
124
        TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
125
        this.taskStatus = manager.createDefaultSimpleTaskStatus("CSV");
126

    
127
        counterNewsOIDs = 0;
128

    
129
        File file = getCSVParameters().getFile();
130
        resource = this.createResource(
131
            FileResource.NAME,
132
            new Object[] { file.getAbsolutePath() }
133
        );
134

    
135
        resource.addConsumer(this);
136
        initializeFeatureTypes();
137
    }
138

    
139
    private CSVStoreParameters getCSVParameters() {
140
        return (CSVStoreParameters) this.getParameters();
141
    }
142

    
143
    public String getProviderName() {
144
        return NAME;
145
    }
146

    
147
    public boolean allowWrite() {
148
        return true;
149
    }
150

    
151
    private String getFullFileName() {
152
            // Usar solo para mostrar mensajes en el logger.
153
                String s = "(unknow)";
154
                try { 
155
                        s = getCSVParameters().getFile().getAbsolutePath();
156
                } catch(Exception e2) {
157
                        s = "(unknow)";
158
                }
159
                return s;
160
    }
161
    
162
    public void open() throws OpenException {
163
        if (this.data != null) {
164
            return;
165
        }
166
        this.data = new ArrayList<FeatureProvider>();
167
        resource.setData(new HashMap());
168
        counterNewsOIDs = 0;
169
                try {
170
                        loadFeatures();
171
                } catch (RuntimeException e) {
172
                        logger.warn("Can't load features from CSV '"+getFullFileName()+"'.", e);
173
                        throw e;
174
                } catch (Exception e) {
175
                        logger.warn("Can't load features from CSV '"+getFullFileName()+"'.", e);
176
                        throw new RuntimeException(e);
177
                }
178
    }
179

    
180
    public DataServerExplorer getExplorer() throws ReadException {
181
        DataManager manager = DALLocator.getDataManager();
182
        FilesystemServerExplorerParameters params;
183
        try {
184
            params = (FilesystemServerExplorerParameters) manager
185
            .createServerExplorerParameters(FilesystemServerExplorer.NAME);
186
            params.setRoot(this.getCSVParameters().getFile().getParent());
187
            return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
188
        } catch (DataException e) {
189
            throw new ReadException(this.getProviderName(), e);
190
        } catch (ValidateDataParametersException e) {
191
            throw new ReadException(this.getProviderName(), e);
192
        }
193

    
194
    }
195

    
196
    class Writer {
197
            private Envelope envelope = null;
198
                private boolean calculate_envelope = false;
199
                private CsvListWriter listWriter = null;
200
                private CsvPreference csvpreferences = null;
201
                private FileWriter fwriter = null;
202
                private FeatureType ftype;
203
                private File file;
204
                private String[] values;
205
                private FeatureAttributeDescriptor[] descriptors;
206
                private Coercion convert = null;
207
                private int errorcounts =0;
208
                private Throwable lasterror = null;
209
            
210
            public void initialize(File file, FeatureType ftype, CsvPreference csvpreferences) {
211
                    this.file = file;
212
                    this.ftype = ftype;
213
                        this.csvpreferences = csvpreferences;
214
                    if( csvpreferences == null ) {
215
                            this.csvpreferences = CsvPreference.STANDARD_PREFERENCE;
216
                    }
217
                    if( ftype.getDefaultGeometryAttributeName() != null ) {
218
                            this.calculate_envelope = true;
219
                    }
220
                    this.descriptors = this.ftype.getAttributeDescriptors();
221
                    this.convert = ToolsLocator.getDataTypesManager().getCoercion(org.gvsig.tools.dataTypes.DataTypes.STRING);
222
                    this.errorcounts = 0;
223
            }
224
            
225
            public void begin() {
226
                    try {
227
                                this.fwriter = new FileWriter(file);
228
                        } catch (IOException e) {
229
                                logger.warn("Can't open file for write ("+file.getAbsolutePath()+").",e);
230
                                throw new RuntimeException(e);
231
                        }
232
                    this.listWriter = new CsvListWriter(this.fwriter,this.csvpreferences);
233
                    int n = 0;
234
                    for(int i=0; i<descriptors.length; i++ ) {
235
                            FeatureAttributeDescriptor descriptor = descriptors[i];
236
                            if( descriptor.getEvaluator()== null ) {
237
                                    n++;
238
                            }
239
                    }
240
                            
241
                    String[] header = new String[n];
242
                    this.values = new String[n];
243
                    n = 0;
244
                    for(int i=0; i<descriptors.length; i++ ) {
245
                            FeatureAttributeDescriptor descriptor = descriptors[i];
246
                            if( descriptor.getEvaluator()== null ) {
247
                                    String name = descriptor.getName();
248
                                    String type = descriptor.getDataTypeName();
249
                                    header[n++] = name + "__" + type;
250
                            }
251
                    }
252
            try {
253
                                listWriter.writeHeader(header);
254
                        } catch (Exception e) {
255
                                logger.warn("Can't write header '"+header.toString()+"' file for write ("+file.getAbsolutePath()+").",e);
256
                                throw new RuntimeException(e);
257
                        }
258
            }
259
            
260
            public void add(FeatureProvider feature) {
261
                        if (this.calculate_envelope) {
262
                                Geometry geom = feature.getDefaultGeometry();
263
                                if (geom != null) {
264
                                        if (envelope == null) {
265
                                                try {
266
                                                        envelope = (Envelope) geom.getEnvelope().clone();
267
                                                } catch (CloneNotSupportedException e) {
268
                                                        logger.warn("Este error no deberia pasar, siempre se puede hacer un clone de un envelope.",e);
269
                                                }
270
                                        } else {
271
                                                envelope.add(geom.getEnvelope());
272
                                        }
273
                                }
274
                        }
275
                    int n = 0;
276
                    for(int i=0; i<descriptors.length; i++ ) {
277
                            FeatureAttributeDescriptor descriptor = descriptors[i];
278
                            if( descriptor.getEvaluator()== null ) {
279
                                        Object value = feature.get(i);
280
                                    try {
281
                                            n++;
282
                                                values[n] = (String) this.convert.coerce(value);
283
                                        } catch (CoercionException e) {
284
                                                try {
285
                                                        values[n] = value.toString();
286
                                                } catch(Exception ex) {
287
                                                        values[n] = "";
288
                                                }
289
                                                if( errorcounts++ <= 10 ) {
290
                                                        this.lasterror = e;
291
                                                        logger.warn("Can't convert value of field "+i+" to string in CVS file '"+getFullFileName()+"'.",e);
292
                                                        if( errorcounts == 10 ) {
293
                                                                logger.warn("Too many error writing CVS file '"+getFullFileName()+"', don't output more.");
294
                                                        }
295
                                                } 
296
                                        } 
297
                            }
298
                    }
299
                    try {
300
                                this.listWriter.writeHeader(values);
301
                        } catch (IOException e) {
302
                                if( errorcounts++ <= 10 ) {
303
                                        this.lasterror = e;
304
                                        logger.warn("Can't write values to CVS file '"+getFullFileName()+"'.",e);
305
                                        if( errorcounts == 10 ) {
306
                                                logger.warn("Too many error writing CVS file '"+getFullFileName()+"', don't output more.");
307
                                        }
308
                                } 
309
                        }
310
                        
311
            }
312
            
313
            public void end() throws PerformEditingException {
314
                    if( this.errorcounts>0 ) {
315
                            throw new PerformEditingException(this.file.getAbsolutePath(), lasterror);
316
                    }
317
                        if( listWriter!=null ) {
318
                            try {
319
                                    listWriter.close();
320
                            } catch(Exception ex) {
321
                                    // Ignore error
322
                            }
323
                                listWriter=null ;
324
                        }
325
                        if( fwriter!=null ) {
326
                            try {
327
                                    fwriter.close();
328
                            } catch(Exception ex) {
329
                                    // Ignore error
330
                            }
331
                                fwriter=null ;
332
                        }
333
            }
334
            
335
            public Envelope getEnvelope() {
336
                    return this.envelope;
337
            }
338
    }
339

    
340
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
341

    
342
        try {
343
            this.taskStatus.add();
344
            taskStatus.message("_preparing");
345
            getResource().execute(new ResourceAction() {
346
                public Object run() throws Exception {
347
                    FeatureSet features = null;
348
                    DisposableIterator it = null;
349
                    try {
350
                        File file = (File) resource.get();
351
                        
352
                        Writer writer = new Writer();
353
                        writer.initialize(file,getStoreServices().getDefaultFeatureType(),null);
354
                        features =
355
                            getStoreServices().getFeatureStore()
356
                            .getFeatureSet();
357
                        List<FeatureProvider> newdata = new ArrayList<FeatureProvider>();
358
                        writer.begin();
359
                        it = features.fastIterator();
360
                        taskStatus.setRangeOfValues(0,0);
361
                        long counter=0;
362
                        while (it.hasNext()) {
363
                            taskStatus.setCurValue(counter++);
364
                            FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
365
                                (org.gvsig.fmap.dal.feature.Feature) it.next());
366
                            writer.add(feature);
367
                            if (feature.getOID() == null){
368
                                logger.warn("feature without OID");
369
                                feature.setOID(createNewOID());
370
                            }
371
                            newdata.add(feature);
372
                        }
373
                        data = newdata;
374
                        if (writer.getEnvelope() != null){
375
                            envelope = writer.getEnvelope().getGeometry().getEnvelope();
376
                        }
377
                        resource.notifyChanges();
378
                        writer.end();
379
                    } finally {
380
                        if (it != null) {
381
                            it.dispose();
382
                        }
383
                        if (features != null) {
384
                            features.dispose();
385
                        }
386
                    }
387
                    return null;
388
                }
389
            });
390
            this.taskStatus.terminate();
391
        } catch (Exception e) {
392
            this.taskStatus.abort();
393
            throw new PerformEditingException(getResource().toString(), e);
394
        } finally {
395
            this.taskStatus.remove();
396
        }
397
    }
398

    
399
    public boolean closeResourceRequested(ResourceProvider resource) {
400
        return true;
401
    }
402

    
403
    public int getOIDType() {
404
        return DataTypes.LONG;
405
    }
406

    
407
    public boolean supportsAppendMode() {
408
        return false;
409
    }
410

    
411
    public void append(FeatureProvider featureProvider) {
412
            throw new UnsupportedOperationException();
413
    }
414

    
415
    public void beginAppend() {
416
            throw new UnsupportedOperationException();
417
    }
418

    
419
    public void endAppend() {
420
            throw new UnsupportedOperationException();
421
    }
422

    
423
    public void saveToState(PersistentState state) throws PersistenceException {
424
        throw new NotYetImplemented();
425
    }
426

    
427
    public void loadFromState(PersistentState state) throws PersistenceException {
428
        throw new NotYetImplemented();
429
    }
430

    
431
    public Object createNewOID() {
432
        return new Long(counterNewsOIDs++);
433
    }
434

    
435
    protected void initializeFeatureTypes() throws InitializeException {
436
        try {
437
            this.open();
438
        } catch (OpenException e) {
439
            throw new InitializeException(this.getProviderName(), e);
440
        }
441
    }
442

    
443
    public Envelope getEnvelope() throws DataException {
444
        this.open();
445
        if( this.envelope!= null )  {
446
                return this.envelope;
447
        }
448
        if( !this.need_calculate_envelope ) {
449
                return null;
450
        }
451
        FeatureStore fs = this.getFeatureStore();
452
        FeatureType ft = fs.getDefaultFeatureType();
453
        FeatureAttributeDescriptor fad = ft.getAttributeDescriptor(ft.getDefaultGeometryAttributeIndex());
454

    
455
        try {
456
            this.envelope = GeometryLocator.getGeometryManager().createEnvelope(fad.getGeomType().getSubType());
457
                        fs.accept(new Visitor() {
458
                                public void visit(Object obj) throws VisitCanceledException, BaseException {
459
                                        Feature f = (Feature) obj;
460
                                        Geometry geom = f.getDefaultGeometry();
461
                                        envelope.add(geom.getEnvelope());
462
                                }
463
                        });
464
                } catch (BaseException e) {
465
                        logger.warn("Can't calculate the envelope of CSV file '"+this.getFullName()+"'.",e);
466
                        this.envelope = null;
467
                }
468
        
469
        this.need_calculate_envelope = false;
470
        return this.envelope;
471
    }
472

    
473
    public Object getDynValue(String name) throws DynFieldNotFoundException {
474
        if( DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name) ) {
475
            try {
476
                return this.getEnvelope();
477
            } catch (DataException e) {
478
                return null;
479
            }
480
        } else {
481
            if( DataStore.METADATA_CRS.equalsIgnoreCase(name) ) {
482
                IProjection pro = CSVStoreParameters.getCRS(this.getCSVParameters());
483
                if (pro != null){
484
                    return pro;
485
                }
486
            }
487
        }
488
        return super.getDynValue(name);
489
    }
490

    
491

    
492
    public void resourceChanged(ResourceProvider resource) {
493
        this.getStoreServices().notifyChange(
494
            DataStoreNotification.RESOURCE_CHANGED,
495
            resource);
496
    }
497

    
498

    
499
    public Object getSourceId() {
500
        return this.getCSVParameters().getFile();
501
    }
502

    
503
    public String getName() {
504
        String name = this.getCSVParameters().getFile().getName();
505
        return FilenameUtils.getBaseName(name);
506
    }
507

    
508
    public String getFullName() {
509
        return this.getCSVParameters().getFile().getAbsolutePath();
510
    }
511

    
512
    public ResourceProvider getResource() {
513
        return resource;
514
    }
515

    
516
    private boolean isEmpty(String s) {
517
            if( s==null ) {
518
                    return true;
519
            }
520
            return s.trim().length()==0;
521
    }
522
    
523
        private CsvPreference getCSVPreferences() {
524
                try {
525
                        String s = null;
526
                        char quoteChar;
527
                        int delimiterChar;
528
                        String endOfLineSymbols;
529

    
530
                        DynObject params = this.getParameters();
531

    
532
                        CsvPreference.Builder builder = null;
533

    
534
                        CsvPreference defaultPreference = CSVStoreParameters
535
                                        .getPredefinedCSVPreferences(params);
536
                        if (defaultPreference == null) {
537
                                defaultPreference = CsvPreference.STANDARD_PREFERENCE;
538
                        }
539

    
540
                        endOfLineSymbols = CSVStoreParameters.getRecordSeparator(params);
541
                        if (isEmpty(endOfLineSymbols)) {
542
                                endOfLineSymbols = defaultPreference.getEndOfLineSymbols();
543
                        }
544
                        s = CSVStoreParameters.getQuoteCharacter(params);
545
                        if (isEmpty(s)) {
546
                                quoteChar = (char) defaultPreference.getQuoteChar();
547
                        } else {
548
                                quoteChar = s.charAt(0);
549
                        }
550
                        s = CSVStoreParameters.getDelimiter(params);
551
                        if (isEmpty(s)) {
552
                                delimiterChar = defaultPreference.getDelimiterChar();
553
                        } else {
554
                                delimiterChar = s.charAt(0);
555
                        }
556

    
557
                        builder = new CsvPreference.Builder(quoteChar, delimiterChar,
558
                                        endOfLineSymbols);
559

    
560
                        s = CSVStoreParameters.getCommentStartMarker(params);
561
                        if (!isEmpty(s)) {
562
                                CommentStartsWith cs = new CommentStartsWith(s);
563
                                builder.skipComments(cs);
564
                        }
565

    
566
                        builder.surroundingSpacesNeedQuotes(CSVStoreParameters
567
                                        .getSurroundingSpacesNeedQuotes(params));
568
                        QuoteMode quoteMode = CSVStoreParameters.getQuoteMode(params);
569
                        if( quoteMode != null ) {
570
                                builder.useQuoteMode(quoteMode);
571
                        }
572
                        return builder.build();
573
                } catch (Exception e) {
574
                        logger.warn("Can't make preferences for CSV '" + getFullFileName()
575
                                        + "'.", e);
576
                        return null;
577
                }
578
        }
579
    
580
    private EditableFeatureType getFeatureType(String headers[]) {
581
                EditableFeatureType fType =        getStoreServices().createFeatureType(this.getName());
582
                fType.setHasOID(true);
583
                DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
584
                
585
            int[] types = new int[headers.length];
586
            for( int i=0; i<types.length; i++) {
587
                    String s = headers[i];
588
                    String typename = null;
589
                    if( s.contains(":") ) {
590
                            String[] ss = s.split(":");
591
                            headers[i] = ss[0];
592
                            typename = ss[1];
593
                            types[i] = dataTypesManager.getType(typename); 
594
                    } else if( s.contains("__") ) {
595
                                String[] ss = s.split("__");
596
                                headers[i] = ss[0];
597
                                typename = ss[1];
598
                                types[i] = dataTypesManager.getType(typename); 
599
                    } else {
600
                            types[i] = DataTypes.STRING;
601
                            typename = "string";
602
                    }
603
                        if( types[i]==DataTypes.INVALID ) {
604
                                types[i] = DataTypes.STRING;
605
                                logger.info("Type '"+typename+"' not valid for attribute '"+headers[i]+"' in CSV file '"+this.getFullFileName()+"'.");
606
                        }
607
            }
608
            
609
            int[] param_types = CSVStoreParameters.getFieldTypes(this.getParameters());
610
            if( param_types != null ) {
611
                for( int i=0; i<types.length && i<param_types.length; i++) {
612
                        types[i] = param_types[i];
613
                }
614
            }
615
            int[] param_sizes = CSVStoreParameters.getFieldSizes(this.getParameters());
616
            for(int i=0; i<types.length; i++) {
617
                        int fieldType = types[i];
618
                        String fieldName = headers[i];
619
                        EditableFeatureAttributeDescriptor fad = fType.add(fieldName, fieldType);
620
                        if( param_sizes!=null && param_sizes[i]>0 ) {
621
                                fad.setSize(param_sizes[i]);
622
                        }
623
                        if( fieldType == DataTypes.GEOMETRY && fType.getDefaultGeometryAttributeName() == null) {
624
                                fType.setDefaultGeometryAttributeName(fieldName);
625
                        }
626
                }
627
            String[] pointDimensionNames = CSVStoreParameters.getPointDimensionNames(this.getParameters());
628
            if( pointDimensionNames!= null ) {
629
                    EditableFeatureAttributeDescriptor attr = fType.add("GEOM", DataTypes.GEOMETRY, new ToPointEvaluaror(pointDimensionNames));
630
                    GeometryManager geommgr = GeometryLocator.getGeometryManager();
631
                    GeometryType gt;
632
                        try {
633
                                gt = geommgr.getGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM3D);
634
                            attr.setGeometryType(gt);
635
                        } catch (Exception e) {
636
                                logger.warn("Can't set geometry type for the calculated field in CSV file '"+getFullFileName()+"'.",e);
637
                        }
638
            }
639
                return fType;
640
    }
641
    
642
    static class ToPointEvaluaror extends AbstractEvaluator {
643

    
644
            private static final Logger logger = LoggerFactory.getLogger(ToPointEvaluaror.class);
645
            
646
            private GeometryManager geommgr = null;
647
            private String xname = null;
648
            private String yname = null;
649
            private String zname = null;
650
                private Coercion toDouble;
651
                private int errorcount = 0;
652
            ToPointEvaluaror(String[] pointDimensionNames) {
653
                    this.xname = pointDimensionNames[0];
654
                    this.yname = pointDimensionNames[1];
655
                    if( pointDimensionNames.length >2 ) {
656
                            this.yname = pointDimensionNames[2];
657
                    }
658
                    this.geommgr = GeometryLocator.getGeometryManager();
659
                    this.toDouble = ToolsLocator.getDataTypesManager().getCoercion(DataTypes.DOUBLE);
660
            }
661
            
662
                public Object evaluate(EvaluatorData data) throws EvaluatorException {
663
                        try {
664
                                double x = ((Double) toDouble.coerce(data.getDataValue(xname))).doubleValue();
665
                                double y = ((Double) toDouble.coerce(data.getDataValue(yname))).doubleValue();
666
                                Point point = geommgr.createPoint(x, y,Geometry.SUBTYPES.GEOM3D);
667
                                if (zname != null) {
668
                                        double z = ((Double) toDouble.coerce(data.getDataValue(zname))).doubleValue();
669
                                        point.setCoordinateAt(2, z);
670
                                }
671
                                return point;
672
                        } catch (Exception ex) {
673
                                if( ++errorcount <5 ) {
674
                                        logger.warn("["+errorcount+"] Can't create point in CSV provider. XNAME='"+
675
                                                        xname + "', YNAME='"+yname+"', ZNAME='"+zname+"', data="+data.toString());
676
                                }
677
                                return null;
678
                        }
679
                }
680

    
681
                public String getName() {
682
                        return "ToPointEvaluaror";
683
                }
684
            
685
    }
686
    
687
        private void loadFeatures() throws IOException, DataException,
688
                        CoercionException, CloneNotSupportedException {
689
                //
690
                // http://supercsv.sourceforge.net/examples_reading.html
691
                // http://supercsv.sourceforge.net/apidocs/index.html
692
                //
693
                FileReader in = null;
694
                CsvListReader reader = null;
695
                try {
696
                        Envelope envelope = null;
697
                        String headers[] = null;
698
                        FeatureStoreProviderServices store = this.getStoreServices();
699

    
700
                        boolean ignore_errors = CSVStoreParameters.getIgnoreErrors(getCSVParameters());
701
                        
702
                        // Initiaize the CSV parser
703
                        CsvPreference preferences = getCSVPreferences();
704
                        in = new FileReader(this.getCSVParameters().getFile());
705

    
706
                        reader = new CsvListReader(in, preferences);
707
                        headers = CSVStoreParameters.getHeaders(getCSVParameters());
708
                        if (headers == null) {
709
                                headers = reader.getHeader(true);
710
                                if (headers == null) {
711
                                        String msg = "Can't retrieve header from csv file '"
712
                                                        + this.getCSVParameters().getFile()
713
                                                                        .getAbsolutePath()
714
                                                        + "' and not specified in the parameters.";
715
                                        logger.warn(msg);
716
                                        throw new RuntimeException(msg);
717
                                }
718
                        }
719

    
720
                        // Initialize the feature types
721
                        EditableFeatureType edftype = this.getFeatureType(headers);
722
                        FeatureType ftype = edftype.getNotEditableCopy();
723
                        List<FeatureType> ftypes = new ArrayList<FeatureType>();
724
                        ftypes.add(ftype);
725
                        store.setFeatureTypes(ftypes, ftype);
726

    
727
                        Coercion coercion[] = new Coercion[ftype.size()];
728
                        int sizes[] = new int[ftype.size()];
729
                        for (int i = 0; i < ftype.size(); i++) {
730
                                sizes[i] = -1;
731
                                FeatureAttributeDescriptor ad = ftype.getAttributeDescriptor(i);
732
                                coercion[i] = ad.getDataType().getCoercion();
733
                                if( ad.getDataType().getType() == DataTypes.STRING ) {
734
                                        if( ad.getSize() == 0 ) {
735
                                                // Es un string y no tiene un size asignado.
736
                                                // Lo ponemos a cero para calcularlo.
737
                                                sizes[i] = 0;
738
                                        }
739
                                }
740
                        }
741
                        if( ftype.getDefaultGeometryAttributeName() != null) {
742
                                this.need_calculate_envelope = true;
743
                        }
744
                        taskStatus.message("_loading");
745
                        int count = 0;
746

    
747
                        int count_errors = 0;
748
                        List<String> row = reader.read();
749
                        while (row != null) {
750
                                taskStatus.setCurValue(++count);
751
                                FeatureProvider feature = this.createFeatureProvider(ftype);
752
                                for (int i = 0; i < row.size(); i++) {
753
                                        Object rawvalue = row.get(i);
754
                                        try {
755
                                                Object value = coercion[i].coerce(rawvalue);
756
                                                feature.set(i, value);
757
                                                if (sizes[i] >= 0 && value != null) {
758
                                                        int x = ((String) value).length();
759
                                                        if (sizes[i] < x) {
760
                                                                sizes[i] = x;
761
                                                        }
762
                                                }
763
                                        } catch (RuntimeException ex) {
764
                                                if (!ignore_errors) {
765
                                                        throw ex;
766
                                                }
767
                                                if( count_errors++ <10 ) {
768
                                                        logger.warn("Can't load value of attribute "+i+" in row "+count+".",ex);
769
                                                }
770
                                                if( count_errors==10 ) {
771
                                                        logger.info("Too many errors, suppress messages.");
772
                                                }
773
                                        }
774
                                }
775
                                this.addFeatureProvider(feature);
776
                                row = reader.read();
777
                        }
778
                        for (int i = 0; i < ftype.size(); i++) {
779
                                if( sizes[i]>0 ) {
780
                                        EditableFeatureAttributeDescriptor efad = ((EditableFeatureAttributeDescriptor)edftype.getAttributeDescriptor(i));
781
                                        efad.setSize(sizes[i]);
782
                                }
783
                        }
784
                        // Volvemos a asignar al store el featuretype, ya que puede
785
                        // haber cambiado.
786
                        ftype = edftype.getNotEditableCopy();
787
                        ftypes = new ArrayList<FeatureType>();
788
                        ftypes.add(ftype);
789
                        store.setFeatureTypes(ftypes, ftype);
790

    
791
                        taskStatus.terminate();
792
                } finally {
793
                        if( reader != null ) {
794
                                try { 
795
                                        reader.close();
796
                                } catch(Exception ex) {
797
                                        // Do nothing
798
                                }
799
                                reader = null;
800
                        }
801
                        if( in != null ) {
802
                                try { 
803
                                        in.close();
804
                                } catch(Exception ex) {
805
                                        // Do nothing
806
                                }
807
                                in = null;
808
                        }
809
                }
810
        }
811

    
812
}