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 / CSVStoreParameters.java @ 45904

History | View | Annotate | Download (19.8 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.util.Locale;
28
import org.apache.commons.lang3.BooleanUtils;
29

    
30
import org.apache.commons.lang3.StringEscapeUtils;
31
import org.apache.commons.lang3.StringUtils;
32
import org.cresques.cts.IProjection;
33
import org.gvsig.basicformats.CPGFile;
34
import org.gvsig.basicformats.FormatsFile;
35
import org.gvsig.basicformats.PRJFile;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.FileHelper;
38
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
39
import org.gvsig.fmap.dal.feature.EditableFeatureType;
40
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.feature.OpenFeatureStoreParameters;
43
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
44
import org.gvsig.fmap.dal.spi.AbstractDataParameters;
45
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.tools.dynobject.DelegatedDynObject;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.dynobject.Tags;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52
import org.supercsv.prefs.CsvPreference;
53
import org.supercsv.quote.AlwaysQuoteMode;
54
import org.supercsv.quote.NormalQuoteMode;
55
import org.supercsv.quote.QuoteMode;
56

    
57
@SuppressWarnings("UseSpecificCatch")
58
public class CSVStoreParameters extends AbstractDataParameters implements
59
        OpenFeatureStoreParameters, FilesystemStoreParameters {
60

    
61
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVStoreParameters.class);
62

    
63
    public static final String PARAMETERS_DEFINITION_NAME = "CSVStoreParameters";
64

    
65
    private static final String FILE = "file";
66
    private static final String IGNOREERRORS = "ignoreErrors";
67
    private static final String PROFILE = "profile";
68
    private static final String QUOTEPOLICY = "quotePolicy";
69
    private static final String QUOTECHAR = "quoteCharacter";
70
    private static final String RECORDSEPARATOR = "recordSeparator";
71
    private static final String DELIMITER = "delimiter";
72
    private static final String COMMENTSTARTMARKER = "commentStartMarker";
73
    private static final String AUTOMATICTYPESDETECTION = "automaticTypesDetection";
74

    
75
    private static final String ESCAPECHARACTER = "escapeCharacter";
76
    public static final String FIRST_LINE_HEADER = "firstLineHeader";
77
    public static final String HEADER = "header";
78
    private static final String SURROUNDINGSPACESNEEDQUOTES = "surroundingSpacesNeedQuotes";
79

    
80
    //private static final String IGNOREEMPTYLINES = "ignoreEmptyLines";
81
    private static final String CRS = CRS_PARAMTER_NAME;
82
    private static final String FIELDTYPES = "fieldtypes";
83
//    private static final String NULLTO = "nullTo";
84
    private static final String CHARSET = "charset"; // Default "UTF-8"
85
    private static final String LOCALE = "locale";
86
    private static final String POINT_COLUMN_NAME = "pointColumnName";
87
    private static final String LIMIT = "limit";
88
    private static final String INCLUDE_METADATA_IN_HEADER = "includeMetadataInHeader";
89
    private static final String GEOMETRY_COLUMN = "geometry_column";
90
    private static final String GEOMETRY_TYPE = "GeometryType";
91
    private static final String GEOMETRY_SUBTYPE = "GeometrySubtype";
92
    private static final String GEOMETRY_FORMAT = "GeometryFormat";
93

    
94
    private DelegatedDynObject parameters;
95
    private FeatureType featureType;
96
    private boolean defaultValueOfAutomaticTypesDetection = true;
97

    
98
    public CSVStoreParameters() {
99
        this(PARAMETERS_DEFINITION_NAME);
100
    }
101

    
102
    protected CSVStoreParameters(String parametersDefinitionName) {
103
        this(parametersDefinitionName, CSVStoreProvider.NAME);
104
    }
105

    
106
    @SuppressWarnings("OverridableMethodCallInConstructor")
107
    public CSVStoreParameters(String parametersDefinitionName, String name) {
108
        super();
109
        this.parameters = (DelegatedDynObject) FileHelper.newParameters(parametersDefinitionName);
110
        this.setDynValue(DataStoreProviderServices.PROVIDER_PARAMTER_NAME, name);
111
    }
112

    
113
    private FeatureType getFeatureType() {
114
        if( this.featureType==null ) {
115
            try {
116
                EditableFeatureType ftype = DALLocator.getDataManager().createFeatureType();
117
                boolean all_fields_declare_type = CSVUtils.loadFeatureType(this, ftype, false);
118
                defaultValueOfAutomaticTypesDetection = !all_fields_declare_type;
119
                this.featureType = ftype;
120
            } catch (Exception ex) {
121
                LOGGER.debug("Can't detect feature type from csv header", ex);
122
                // Do nothing, continue
123
            }
124
        }
125
        return this.featureType;
126
    }
127
    
128
    @Override
129
    protected DelegatedDynObject getDelegatedDynObject() {
130
        return parameters;
131
    }
132

    
133
    @Override
134
    public void setDynValue(String name, Object value) {
135
        super.setDynValue(name, value);
136
    }
137

    
138
    @Override
139
    public void validate() throws ValidateDataParametersException {
140
        File f = this.getFile();
141
        if( f!=null ) {
142
            IProjection proj = null;
143
            FeatureType ftype = this.getFeatureType();
144
            if( ftype!=null ) {
145
                this.setDynValue(AUTOMATICTYPESDETECTION, defaultValueOfAutomaticTypesDetection);
146
                proj = ftype.getDefaultSRS();
147
                if( proj!=null ) {
148
                    this.setDynValue(CRS_PARAMTER_NAME, proj);
149
                }
150
                FeatureAttributeDescriptor attrgeom = ftype.getDefaultGeometryAttribute();
151
                if( attrgeom!=null ) {
152
                    this.setDynValue(GEOMETRY_COLUMN, attrgeom.getName());
153
                    this.setDynValue(GEOMETRY_TYPE, attrgeom.getGeomType().getType());
154
                    this.setDynValue(GEOMETRY_SUBTYPE, attrgeom.getGeomType().getSubType());
155
                } else {
156
                    this.setDynValue(GEOMETRY_COLUMN, null);
157
                    this.setDynValue(GEOMETRY_TYPE, Geometry.TYPES.UNKNOWN);
158
                    this.setDynValue(GEOMETRY_SUBTYPE, Geometry.SUBTYPES.UNKNOWN);
159
                }
160
                Tags ftypeTags = ftype.getTags();
161
                for (String tagname : ftypeTags) {
162
                    if( StringUtils.startsWithIgnoreCase(tagname, "csvparameters.") ) {
163
                        String paramname = tagname.substring(14);
164
                        String paramvalue = ftypeTags.getString(tagname,null);
165
                        if( paramvalue!=null ) {
166
                            this.setDynValue(paramname, paramvalue);
167
                        }
168
                    }
169
                }
170
            }
171
            if( proj==null ) {
172
                PRJFile prjfile = FormatsFile.getPRJFile(f);
173
                if( prjfile!= null ) {
174
                    this.setDynValue(CRS_PARAMTER_NAME, prjfile.getCRS());
175
                }
176
            }
177
            String charsetName = getCharset(this);
178
            if( StringUtils.isBlank(charsetName) ) {
179
                CPGFile cpgfile = FormatsFile.getCPGFile(f);
180
                if( cpgfile!=null ) {
181
                    this.setDynValue(CHARSET, cpgfile.getCharsetName());
182
                }
183
            }
184
        }
185
        super.validate();
186
    }
187
    
188
    @Override
189
    public boolean isValid() {
190
        if ( getFileName(this) == null ) {
191
            return false;
192
        }
193
        return true;
194
    }
195

    
196
    @Override
197
    public File getFile() {
198
        return (File) this.getDynValue(FILE);
199
    }
200

    
201
    @Override
202
    public void setFile(File file) {
203
        this.setDynValue(FILE, file);
204
    }
205

    
206
    public static CsvPreference getPredefinedCSVPreferences(DynObject dynobj) {
207
        String s = (String) dynobj.getDynValue(PROFILE);
208
        if ( "NONE".equalsIgnoreCase(s) ) {
209
            return null;
210
        }
211
        if ( "STANDARD_PREFERENCE".equalsIgnoreCase(s) ) {
212
            return CsvPreference.STANDARD_PREFERENCE;
213
        }
214
        if ( "EXCEL_PREFERENCE".equalsIgnoreCase(s) ) {
215
            return CsvPreference.EXCEL_PREFERENCE;
216
        }
217
        if ( "EXCEL_NORTH_EUROPE_PREFERENCE".equalsIgnoreCase(s) ) {
218
            return CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE;
219
        }
220
        if ( "TAB_PREFERENCE".equalsIgnoreCase(s) ) {
221
            return CsvPreference.TAB_PREFERENCE;
222
        }
223
        return null;
224
    }
225

    
226
    public static QuoteMode getQuoteMode(DynObject dynobj) {
227
        String s = (String) dynobj.getDynValue(QUOTEPOLICY);
228
        if ( "AlwaysQuoteMode".equalsIgnoreCase(s) ) {
229
            return new AlwaysQuoteMode();
230
        }
231
        if ( "NormalQuoteMode".equalsIgnoreCase(s) ) {
232
            return new NormalQuoteMode();
233
        }
234
        return null;
235
    }
236

    
237
    public static IProjection getCRS(DynObject dynobj) {
238
        return (IProjection) dynobj.getDynValue(CRS);
239
    }
240

    
241
    public static String getFileName(DynObject dynobj) {
242
        File f = (File) dynobj.getDynValue(FILE);
243
        if ( f == null ) {
244
            return null;
245
        }
246
        return f.getPath();
247
    }
248

    
249
    public static File getFile(DynObject dynobj) {
250
        File f = (File) dynobj.getDynValue(FILE);
251
        return f;
252
    }
253

    
254
    public static String getRecordSeparator(DynObject dynobj) {
255
        String s = (String) dynobj.getDynValue(RECORDSEPARATOR);
256
        return StringEscapeUtils.unescapeJava(s);
257
    }
258

    
259
    public static String getGeometryColumn(DynObject dynobj) {
260
        String s = (String) dynobj.getDynValue(GEOMETRY_COLUMN);
261
        return s;
262
    }
263

    
264
    public static int getGeometryType(DynObject dynobj) {
265
        Integer gtype = (Integer) dynobj.getDynValue(GEOMETRY_TYPE);
266
        if( gtype == null ) {
267
            return Geometry.TYPES.UNKNOWN;
268
        }
269
        return gtype;
270
    }
271

    
272
    public static String getGeometryFormat(DynObject dynobj) {
273
        String gformat = (String) dynobj.getDynValue(GEOMETRY_FORMAT);
274
        if( StringUtils.isBlank(gformat) ) {
275
            return "WKT";
276
        }
277
        return gformat;
278
    }
279

    
280
    public static int getGeometrySubType(DynObject dynobj) {
281
        Integer gsubtype = (Integer) dynobj.getDynValue(GEOMETRY_SUBTYPE);
282
        if( gsubtype == null ) {
283
            return Geometry.SUBTYPES.UNKNOWN;
284
        }
285
        return gsubtype;
286
    }
287

    
288
    public static Locale getLocale(DynObject dynobj) {
289
        try {
290
            String s = (String) dynobj.getDynValue(LOCALE);
291
            if ( s.trim().length() == 0 ) {
292
                return null;
293
            }
294
            if ( "DEFAULT".equalsIgnoreCase(s.trim()) ) {
295
                return Locale.getDefault();
296
            }
297
            Locale locale;
298
            // locale = Locale.forLanguageTag(s); // Since java 1.7
299
            String[] ss = s.split("-");
300
            switch (ss.length) {
301
            case 1:
302
                locale = new Locale(ss[0]);
303
                break;
304
            case 2:
305
                locale = new Locale(ss[0], ss[1]);
306
                break;
307
            case 3:
308
            default:
309
                locale = new Locale(ss[0], ss[1], ss[2]);
310
                break;
311
            }
312
            return locale;
313
        } catch (Exception ex) {
314
            LOGGER.warn("Can't get locale from CSV parameters.", ex);
315
            return null;
316
        }
317
    }
318

    
319
    public static String getCommentStartMarker(DynObject dynobj) {
320
        String s = (String) dynobj.getDynValue(COMMENTSTARTMARKER);
321
        return StringEscapeUtils.unescapeJava(s);
322
    }
323
    
324
    public static String getPointColumnName(DynObject dynobj) {
325
        String s = (String) dynobj.getDynValue(POINT_COLUMN_NAME);
326
        return s;
327
    }
328

    
329
    public static String getQuoteCharacter(DynObject dynobj) {
330
        String s = (String) dynobj.getDynValue(QUOTECHAR);
331
        s = StringEscapeUtils.unescapeJava(s);
332
        if ( StringUtils.isBlank(s) ) {
333
            return null;
334
        }
335
        return s.substring(0, 1);
336
    }
337

    
338
    public static String getDelimiter(DynObject dynobj) {
339
        String s = (String) dynobj.getDynValue(DELIMITER);
340
        s = StringEscapeUtils.unescapeJava(s);
341
        if ( StringUtils.isBlank(s) ) {
342
            return null;
343
        }
344
        return s.substring(0, 1);
345
    }
346

    
347
    public static String getHeader(DynObject dynobj) {
348
        String s = (String) dynobj.getDynValue(HEADER);
349
        s = StringEscapeUtils.unescapeJava(s);
350
        if ( StringUtils.isBlank(s) ) {
351
            return null;
352
        }
353
        return s;
354
    }
355

    
356
    public static String[] getHeaders(DynObject dynobj) {
357
        String s = getHeader(dynobj);
358
        if ( StringUtils.isBlank(s) ) {
359
            return null;
360
        }
361
        String sep = getDelimiter(dynobj);
362
        if ( sep == null ) {
363
            sep = getDelimiter(s);
364
            if ( sep == null ) {
365
                // Chungo
366
                return null;
367
            }
368
        }
369
        String[] ss = s.split("[" + sep + "]");
370
        return ss;
371
    }
372

    
373
    public static String getDelimiter(String line) {
374
        if( StringUtils.isBlank(line) ) {
375
            return null;
376
        }
377
        String sep = null;
378
        // Cuidado con los ":", los he puesto al final a proposito
379
        // ya que podian estar en la cadena para separar el size
380
        // de cada tipo.
381
        String seps = ",;-|@#/+$%&!:";
382
        for ( int i = 0; i < seps.length(); i++ ) {
383
            sep = seps.substring(i, 1);
384
            if ( line.contains(seps.substring(i, 1)) ) {
385
                break;
386
            }
387
            sep = null;
388
        }
389
        return sep;
390
    }
391

    
392
    public static String getCharset(DynObject dynobj) {
393
        String s = (String) dynobj.getDynValue(CHARSET);
394
        return StringEscapeUtils.unescapeJava(s);
395
    }
396

    
397
    public static String[] getPointDimensionNames(DynObject dynobj) {
398
        String s = (String) dynobj.getDynValue("point");
399
        if ( StringUtils.isBlank(s) ) {
400
            return null;
401
        }
402
        return s.split(",");
403
    }
404

    
405
    public static boolean getSurroundingSpacesNeedQuotes(DynObject dynobj) {
406
        Boolean b = (Boolean) dynobj.getDynValue(SURROUNDINGSPACESNEEDQUOTES);
407
        return BooleanUtils.isTrue(b);
408
    }
409
    
410
    public static boolean getIncludeMetadataInHeader(DynObject dynobj) {
411
        Boolean b = (Boolean) dynobj.getDynValue(INCLUDE_METADATA_IN_HEADER);
412
        return BooleanUtils.isTrue(b);
413
    }
414

    
415
    public static boolean getAutomaticTypesDetection(DynObject dynobj) {
416
        Boolean b = (Boolean) dynobj.getDynValue(AUTOMATICTYPESDETECTION);
417
        return BooleanUtils.isTrue(b);
418
    }
419

    
420
    public static boolean getIgnoreErrors(DynObject dynobj) {
421
        Boolean b = (Boolean) dynobj.getDynValue(IGNOREERRORS);
422
        return BooleanUtils.isTrue(b);
423
    }
424

    
425
    public static boolean isFirstLineHeader(DynObject dynobj) {
426
        Boolean b = (Boolean) dynobj.getDynValue(FIRST_LINE_HEADER);
427
        return BooleanUtils.isTrue(b);
428
    }
429

    
430
//    static int[] getFieldTypes(DynObject dynobj) {
431
//        String s = (String) dynobj.getDynValue(FIELDTYPES);
432
//        if ( StringUtils.isBlank(s) ) {
433
//            return null;
434
//        }
435
//        String sep = getDelimiter(s);
436
//        if ( sep == null ) {
437
//            return null;
438
//        }
439
//        DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
440
//        String fieldTypeNames[] = s.split("[" + sep + "]");
441
//        int fieldTypes[] = new int[fieldTypeNames.length];
442
//        for ( int i = 0; i < fieldTypeNames.length; i++ ) {
443
//            s = fieldTypeNames[i].trim();
444
//            if ( s.contains(":") ) {
445
//                s = s.split(":")[0];
446
//            }
447
//            fieldTypes[i] = dataTypeManager.getType(s);
448
//        }
449
//        return fieldTypes;
450
//    }
451
//
452
//    static int[] getFieldSizes(DynObject dynobj) {
453
//        String s = (String) dynobj.getDynValue(FIELDTYPES);
454
//        if ( StringUtils.isBlank(s) ) {
455
//            return null;
456
//        }
457
//        String sep = getDelimiter(s);
458
//        if ( sep == null ) {
459
//            return null;
460
//        }
461
//        DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
462
//        String fieldTypeNames[] = s.split("[" + sep + "]");
463
//        int fieldSizes[] = new int[fieldTypeNames.length];
464
//        for ( int i = 0; i < fieldTypeNames.length; i++ ) {
465
//            String fieldtypeDef = fieldTypeNames[i].trim();
466
//            if ( fieldtypeDef.contains(":") ) {
467
//                try {
468
//                    String[] parts = fieldtypeDef.split(":");
469
//                    int fieldType = dataTypeManager.getType(parts[0]);
470
//                    if( fieldType == DataTypes.GEOMETRY ) {
471
//                        fieldSizes[i] = 1;
472
//                    } else {
473
//                        s = parts[1];
474
//                        fieldSizes[i] = Integer.parseInt(s);
475
//                    }
476
//                } catch (Exception ex) {
477
//                    logger.warn("Can't get size of field " + i + " (" + fieldtypeDef + ").", ex);
478
//                }
479
//            } else {
480
//                fieldSizes[i] = 0;
481
//            }
482
//        }
483
//        return fieldSizes;
484
//    }
485

    
486
    public static String getRawFieldTypes(DynObject dynobj) {
487
        String s = (String) dynobj.getDynValue(FIELDTYPES);
488
        if ( StringUtils.isBlank(s) ) {
489
            return null;
490
        }
491
        return s.trim();
492
    }
493

    
494
    public static int getSkipLines(DynObject dynobj) {
495
        Integer n = (Integer) dynobj.getDynValue("skipLines");
496
        if ( n == null ) {
497
            return 0;
498
        }
499
        return n;
500
    }
501

    
502
    public static int getLimit(DynObject dynobj) {
503
        Integer n = (Integer) dynobj.getDynValue(LIMIT);
504
        if ( n == null ) {
505
            return -1;
506
        }
507
        return n;
508
    }
509

    
510
    public static String getRawFieldsDefinition(DynObject dynobj) {
511
        String s = (String) dynobj.getDynValue("fieldsDefinition");
512
        if ( StringUtils.isBlank(s) ) {
513
            return null;
514
        }
515
        return s.trim();
516
    }
517

    
518
    public static class FieldDefinition {
519

    
520
        private final int start;
521
        private final int end;
522

    
523
        public FieldDefinition(String def) {
524
            def = def.trim();
525
            String[] ss = def.split(":");
526
            this.start = Integer.parseInt(ss[0]);
527
            if ( ss.length < 2 ) {
528
                this.end = -1;
529
            } else {
530
                this.end = Integer.parseInt(ss[1]);
531
            }
532
        }
533

    
534
        public int getStart() {
535
            return this.start;
536
        }
537

    
538
        public int getEnd() {
539
            return this.end;
540
        }
541

    
542
        public boolean getToEndOfLine() {
543
            return this.end == -1;
544
        }
545
    }
546

    
547
    public static FieldDefinition[] getFieldsDefinition(DynObject dynobj) {
548
        String definition = getRawFieldsDefinition(dynobj);
549
        if ( definition == null ) {
550
            return null;
551
        }
552
        int i=0;
553
        try {
554
            String[] defs = StringUtils.split(definition);
555
            FieldDefinition[] fieldsDefinition = new FieldDefinition[defs.length];
556
            for ( i = 0; i < defs.length; i++ ) {
557
                fieldsDefinition[i] = new FieldDefinition(defs[i]);
558
            }
559
            return fieldsDefinition;
560
        } catch (Exception ex) {
561
            throw  new IllegalArgumentException("Can't recognize the format field definition '"+definition+"' ("+i+").");
562
        }
563
    }
564
    
565
}