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

History | View | Annotate | Download (20.1 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, null);
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 boolean isBlankOrDefaultLocale(DynObject dynobj) {
289
        String s = (String) dynobj.getDynValue(LOCALE);
290
        if (StringUtils.isBlank(s)) {
291
            return true;
292
        }
293
        return StringUtils.equalsIgnoreCase("DEFAULT",s.trim());
294
    }
295

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

    
327
    public static String getCommentStartMarker(DynObject dynobj) {
328
        String s = (String) dynobj.getDynValue(COMMENTSTARTMARKER);
329
        return StringEscapeUtils.unescapeJava(s);
330
    }
331
    
332
    public static String getPointColumnName(DynObject dynobj) {
333
        String s = (String) dynobj.getDynValue(POINT_COLUMN_NAME);
334
        return s;
335
    }
336

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

    
346
    public static String getDelimiter(DynObject dynobj) {
347
        String s = (String) dynobj.getDynValue(DELIMITER);
348
        s = StringEscapeUtils.unescapeJava(s);
349
        if ( StringUtils.isBlank(s) ) {
350
            return null;
351
        }
352
        return s.substring(0, 1);
353
    }
354

    
355
    public static String getHeader(DynObject dynobj) {
356
        String s = (String) dynobj.getDynValue(HEADER);
357
        s = StringEscapeUtils.unescapeJava(s);
358
        if ( StringUtils.isBlank(s) ) {
359
            return null;
360
        }
361
        return s;
362
    }
363

    
364
    public static String[] getHeaders(DynObject dynobj) {
365
        String s = getHeader(dynobj);
366
        if ( StringUtils.isBlank(s) ) {
367
            return null;
368
        }
369
        String sep = getDelimiter(dynobj);
370
        if ( sep == null ) {
371
            sep = getDelimiter(s);
372
            if ( sep == null ) {
373
                // Chungo
374
                return null;
375
            }
376
        }
377
        String[] ss = s.split("[" + sep + "]");
378
        return ss;
379
    }
380

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

    
400
    public static String getCharset(DynObject dynobj) {
401
        String s = (String) dynobj.getDynValue(CHARSET);
402
        return StringEscapeUtils.unescapeJava(s);
403
    }
404

    
405
    public static String[] getPointDimensionNames(DynObject dynobj) {
406
        String s = (String) dynobj.getDynValue("point");
407
        if ( StringUtils.isBlank(s) ) {
408
            return null;
409
        }
410
        return s.split(",");
411
    }
412

    
413
    public static boolean getSurroundingSpacesNeedQuotes(DynObject dynobj) {
414
        Boolean b = (Boolean) dynobj.getDynValue(SURROUNDINGSPACESNEEDQUOTES);
415
        return BooleanUtils.isTrue(b);
416
    }
417
    
418
    public static boolean getIncludeMetadataInHeader(DynObject dynobj) {
419
        Boolean b = (Boolean) dynobj.getDynValue(INCLUDE_METADATA_IN_HEADER);
420
        return BooleanUtils.isTrue(b);
421
    }
422

    
423
    public static boolean getAutomaticTypesDetection(DynObject dynobj) {
424
        Boolean b = (Boolean) dynobj.getDynValue(AUTOMATICTYPESDETECTION);
425
        return BooleanUtils.isTrue(b);
426
    }
427

    
428
    public static boolean getIgnoreErrors(DynObject dynobj) {
429
        Boolean b = (Boolean) dynobj.getDynValue(IGNOREERRORS);
430
        return BooleanUtils.isTrue(b);
431
    }
432

    
433
    public static boolean isFirstLineHeader(DynObject dynobj) {
434
        Boolean b = (Boolean) dynobj.getDynValue(FIRST_LINE_HEADER);
435
        return BooleanUtils.isTrue(b);
436
    }
437

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

    
494
    public static String getRawFieldTypes(DynObject dynobj) {
495
        String s = (String) dynobj.getDynValue(FIELDTYPES);
496
        if ( StringUtils.isBlank(s) ) {
497
            return null;
498
        }
499
        return s.trim();
500
    }
501

    
502
    public static int getSkipLines(DynObject dynobj) {
503
        Integer n = (Integer) dynobj.getDynValue("skipLines");
504
        if ( n == null ) {
505
            return 0;
506
        }
507
        return n;
508
    }
509

    
510
    public static int getLimit(DynObject dynobj) {
511
        Integer n = (Integer) dynobj.getDynValue(LIMIT);
512
        if ( n == null ) {
513
            return -1;
514
        }
515
        return n;
516
    }
517

    
518
    public static String getRawFieldsDefinition(DynObject dynobj) {
519
        String s = (String) dynobj.getDynValue("fieldsDefinition");
520
        if ( StringUtils.isBlank(s) ) {
521
            return null;
522
        }
523
        return s.trim();
524
    }
525

    
526
    public static class FieldDefinition {
527

    
528
        private final int start;
529
        private final int end;
530

    
531
        public FieldDefinition(String def) {
532
            def = def.trim();
533
            String[] ss = def.split(":");
534
            this.start = Integer.parseInt(ss[0]);
535
            if ( ss.length < 2 ) {
536
                this.end = -1;
537
            } else {
538
                this.end = Integer.parseInt(ss[1]);
539
            }
540
        }
541

    
542
        public int getStart() {
543
            return this.start;
544
        }
545

    
546
        public int getEnd() {
547
            return this.end;
548
        }
549

    
550
        public boolean getToEndOfLine() {
551
            return this.end == -1;
552
        }
553
    }
554

    
555
    public static FieldDefinition[] getFieldsDefinition(DynObject dynobj) {
556
        String definition = getRawFieldsDefinition(dynobj);
557
        if ( definition == null ) {
558
            return null;
559
        }
560
        int i=0;
561
        try {
562
            String[] defs = StringUtils.split(definition);
563
            FieldDefinition[] fieldsDefinition = new FieldDefinition[defs.length];
564
            for ( i = 0; i < defs.length; i++ ) {
565
                fieldsDefinition[i] = new FieldDefinition(defs[i]);
566
            }
567
            return fieldsDefinition;
568
        } catch (Exception ex) {
569
            throw  new IllegalArgumentException("Can't recognize the format field definition '"+definition+"' ("+i+").");
570
        }
571
    }
572
    
573
}