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 / simplereaders / CSVReaderSuperCSV.java @ 47506

History | View | Annotate | Download (9.73 KB)

1
package org.gvsig.fmap.dal.store.csv.simplereaders;
2

    
3
import java.io.BufferedReader;
4
import java.io.File;
5
import java.io.IOException;
6
import java.io.Reader;
7
import java.util.List;
8
import java.util.function.Function;
9
import org.apache.commons.io.FilenameUtils;
10
import org.apache.commons.io.input.CloseShieldReader;
11
import org.apache.commons.lang3.StringUtils;
12
import org.apache.commons.text.StringEscapeUtils;
13
import org.gvsig.fmap.dal.store.csv.CSVStoreParameters;
14
import org.gvsig.fmap.dal.store.csv.virtualrows.RandomAccessFileIndex;
15
import org.gvsig.fmap.dal.store.csv.virtualrows.RandomAccessFileReader;
16
import static org.gvsig.fmap.dal.store.csv.virtualrows.RandomAccessFileReader.FILTER_NONE;
17
import org.gvsig.fmap.dal.store.csv.virtualrows.SuperCSVList;
18
import org.gvsig.tools.dynobject.DynObject;
19
import org.gvsig.tools.task.SimpleTaskStatus;
20
import org.gvsig.tools.util.GetItemWithSize64;
21
import org.slf4j.Logger;
22
import org.slf4j.LoggerFactory;
23
import org.supercsv.comment.CommentStartsWith;
24
import org.supercsv.io.CsvListReader;
25
import org.supercsv.prefs.CsvPreference;
26
import org.supercsv.quote.QuoteMode;
27

    
28
public class CSVReaderSuperCSV extends AbstractSimpleReader {
29

    
30
    //
31
    // http://supercsv.sourceforge.net/examples_reading.html
32
    // http://supercsv.sourceforge.net/apidocs/index.html
33
    //
34
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVReaderSuperCSV.class);
35

    
36
    private CsvListReader reader;
37
    private final CSVStoreParameters parameters;
38
    private List<String>  nextLine;
39
    private int columns;
40

    
41
    public CSVReaderSuperCSV(Reader in, CSVStoreParameters parameters) {
42
        this(parameters);
43
        this.reader = new CsvListReader(in, getCSVPreferences());
44
    }    
45
    
46
    public CSVReaderSuperCSV(CSVStoreParameters parameters) {
47
        this.reader = null;
48
        this.parameters = parameters;
49
        this.reader = null;
50
        this.nextLine = null;
51
        this.columns = 0;
52
    }
53

    
54
    public CSVStoreParameters getParameters() {
55
        return this.parameters;
56
    }
57

    
58
    @Override
59
    public String[] getHeader() throws IOException {
60
        return this.reader.getHeader(true);
61
    }
62
    
63
    @Override
64
    public int getColumnsCount() throws IOException {
65
        if( this.columns <= 0 ) {
66
            this.columns = reader.length();
67
            if( this.columns <= 0 ) {
68
                this.nextLine = this.reader.read();
69
                this.columns = reader.length();
70
            }
71
        }
72
        return this.columns;
73
    }
74

    
75
    @Override
76
    public GetItemWithSize64<List<String>>  getVirtualRows(SimpleTaskStatus status) {
77
        RandomAccessFileReader theReader = null;
78
        RandomAccessFileIndex theIndex = null;
79
        try {
80
            CSVStoreParameters params = getParameters();
81
            File data_file = CSVStoreParameters.getFile(params);
82
            if( data_file.length()< 10*1024*1024 ) {
83
                return null;
84
            }
85
            
86
            Function<BufferedReader, Integer> numberOfLinesInRecord = new Function<BufferedReader, Integer>() {
87
                @Override
88
                public Integer apply(BufferedReader breader) {
89
                    CloseShieldReader theReader = CloseShieldReader.wrap(breader);
90
                    CsvListReader parser = new CsvListReader(theReader, getCSVPreferences());
91
                    try {
92
                        List<String> values = parser.read();
93
                    } catch (IOException ex) {
94
                        return 1;
95
                    }
96
                    return parser.getLineNumber();
97
                }
98
            };
99

    
100
            String charset = CSVStoreParameters.getCharset(params);
101
            File index_file = getIndexFile(data_file);
102
            
103
            theReader = new RandomAccessFileReader(data_file, charset);
104
            theIndex = theReader.createOrOpenIndexOfLines(index_file, false, FILTER_NONE, status, numberOfLinesInRecord);
105
            
106
            SuperCSVList list = new SuperCSVList(
107
                    theReader, 
108
                    theIndex, 
109
                    CSVStoreParameters.isFirstLineHeader(getParameters())?1:0
110
            );
111
            
112
            list.setPreferences(this.getCSVPreferences());
113
            return list;
114
        } catch (IOException ex) {
115
            return null;
116
        } finally {
117
            // We do not close the index or the reader because we need it to remain open
118
//            IOUtils.closeQuietly(theReader);
119
//            IOUtils.closeQuietly(theIndex);
120
        }
121
    }
122
    
123
    @Override
124
    public List<String> read() throws IOException {
125
        List<String> line;
126
        if( this.nextLine != null ) {
127
            line = this.nextLine;
128
            this.nextLine = null;
129
        } else {
130
            line = this.reader.read();
131
        }
132
        if( line!=null ) {
133
            for (int i = 0; i < line.size(); i++) {
134
                String s = line.get(i);
135
                if( s!=null ) {
136
                    line.set(i, unescapeCRLF(s));
137
                }
138
            }
139
        }
140
        return line;
141
    }
142

    
143
    @Override
144
    public void close() throws IOException {
145
        this.reader.close();
146
    }
147

    
148
    @Override
149
    public List<String> skip(int lines) throws IOException {
150
        if( lines <= 0 ) {
151
            return null;
152
        }
153
        if( this.nextLine != null ) {
154
            this.nextLine = null;
155
            lines--;
156
        }
157
        List<String> row = null;
158
        for ( int i = 0; i < lines; i++ ) {
159
            row = reader.read();
160
        }
161
        return row;
162
    }
163

    
164
    public final CsvPreference getCSVPreferences() {
165
        try {
166
            String s;
167
            char quoteChar;
168
            int delimiterChar;
169
            String endOfLineSymbols;
170

    
171
            DynObject params = this.getParameters();
172

    
173
            CsvPreference.Builder builder;
174

    
175
            CsvPreference defaultPreference = CSVStoreParameters
176
                    .getPredefinedCSVPreferences(params);
177
            if ( defaultPreference == null ) {
178
                defaultPreference = CsvPreference.STANDARD_PREFERENCE;
179
            }
180

    
181
            endOfLineSymbols = CSVStoreParameters.getRecordSeparator(params);
182
            if ( StringUtils.isBlank(endOfLineSymbols) ) {
183
                endOfLineSymbols = defaultPreference.getEndOfLineSymbols();
184
            }
185
            s = CSVStoreParameters.getQuoteCharacter(params);
186
            if ( StringUtils.isBlank(s) ) {
187
                quoteChar = (char) defaultPreference.getQuoteChar();
188
            } else {
189
                quoteChar = s.charAt(0);
190
            }
191
            s = CSVStoreParameters.getDelimiter(params);
192
            if ( StringUtils.isBlank(s) ) {
193
                delimiterChar = defaultPreference.getDelimiterChar();
194
            } else {
195
                delimiterChar = s.charAt(0);
196
            }
197

    
198
            builder = new CsvPreference.Builder(quoteChar, delimiterChar,
199
                    endOfLineSymbols);
200

    
201
            s = CSVStoreParameters.getCommentStartMarker(params);
202
            if ( !StringUtils.isBlank(s) ) {
203
                CommentStartsWith cs = new CommentStartsWith(s);
204
                builder.skipComments(cs);
205
            }
206

    
207
            builder.surroundingSpacesNeedQuotes(CSVStoreParameters
208
                    .getSurroundingSpacesNeedQuotes(params));
209
            QuoteMode quoteMode = CSVStoreParameters.getQuoteMode(params);
210
            if ( quoteMode != null ) {
211
                builder.useQuoteMode(quoteMode);
212
            }
213
            return builder.build();
214
        } catch (Exception e) {
215
            LOGGER.warn("Can't make preferences for CSV '" + getFullFileName()
216
                    + "'.", e);
217
            return null;
218
        }
219
    }
220
    
221
    private String getFullFileName() {
222
        // Usar solo para mostrar mensajes en el logger.
223
        String s;
224
        try {
225
            s = getParameters().getFile().getAbsolutePath();
226
        } catch (Exception e2) {
227
            s = "(unknow)";
228
        }
229
        return s;        
230
    }
231

    
232
    @Override
233
    public int getLine() {
234
        if( this.reader==null ) {
235
            return 0;
236
        }
237
        return this.reader.getLineNumber();
238
    }
239

    
240
    @Override
241
    public List<String> nextRowValues() {
242
        try {
243
            return this.read();
244
        } catch (IOException ex) {
245
            throw new RuntimeException(ex);
246
        }
247
    }
248

    
249
    public static String escapeCRLF(String s) {
250
        if( s==null ) {
251
            return s;
252
        }
253
        String s1 = s;
254
        s1 = StringUtils.replace(s1, "\\", "\\\\");
255
        s1 = StringUtils.replace(s1, "\n", "\\n");
256
        s1 = StringUtils.replace(s1, "\r", "\\r");
257
        return s1;
258
    }
259
    
260
    public static String unescapeCRLF(String s) {
261
        if( s==null || s.indexOf('\\')==-1 ) {
262
            return s;
263
        }
264
        String s1 = s;
265
        s1 = s.replaceAll("(?:^\\\\n)|(?:([^\\\\])\\\\n)","$1\n");
266
        s1 = s1.replaceAll("(?:^\\\\r)|(?:([^\\\\])\\\\n)","$1\r");
267
        s1 = StringUtils.replace(s1, "\\\\", "\\");
268
        return s1;
269
    }
270
    
271
    
272
    public static void main(String[] args) {
273
        String s0 = "\\n{\\n   \"ANGULO\":\"0.000\",\\n    \"\tEXTO\":\"RAVAL ROIG\\\\r\\\\n - \\\\r\\\\nVIRGEN DEL SOCORRO\",\\n    \"LINK_POLIGONO\":\"HVCSGISCODE_ENT_11230100000000001\",\\n    \"GEOMETRY\":\"00000000014125fe9b57b4a23441503411cb1c432d\"\\n}";
274
        System.out.println("#"+s0+"#");
275
        String s1 = s0.replaceAll("(?:^\\\\n)|(?:([^\\\\])\\\\n)","$1\n");
276
        System.out.println("#"+s1+"#");
277
        String s2 = s1.replaceAll("([^\\\\])\\\\r","$1{r}");
278
        System.out.println("#"+s2+"#");
279
        String s3 = StringEscapeUtils.unescapeCsv(s0);
280
        System.out.println("#"+s3+"#");
281
    }
282
    
283
    
284
    public static File getIndexFile(File data_file) {
285
        if (data_file == null){
286
            return null;
287
        }
288
        File index_file = new File(FilenameUtils.removeExtension(data_file.getAbsolutePath()) + ".idx");
289
        return index_file;
290
    }
291

    
292
}