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

History | View | Annotate | Download (19.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
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
                // Do nothing, continue
122
            }
123
        }
124
        return this.featureType;
125
    }
126
    
127
    @Override
128
    protected DelegatedDynObject getDelegatedDynObject() {
129
        return parameters;
130
    }
131

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
337
    public static String getDelimiter(DynObject dynobj) {
338
        String s = (String) dynobj.getDynValue(DELIMITER);
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 getHeader(DynObject dynobj) {
347
        String s = (String) dynobj.getDynValue(HEADER);
348
        s = StringEscapeUtils.unescapeJava(s);
349
        if ( StringUtils.isBlank(s) ) {
350
            return null;
351
        }
352
        return s;
353
    }
354

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

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

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

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

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

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

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

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

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

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

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

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

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

    
517
    public static class FieldDefinition {
518

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

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

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

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

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

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