1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.io;
33
34 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
35 import java.io.File;
36 import java.io.IOException;
37 import java.io.Reader;
38 import java.io.StringReader;
39 import java.io.UncheckedIOException;
40 import java.nio.charset.Charset;
41 import java.util.List;
42 import java.util.Map;
43 import javax.annotation.CheckReturnValue;
44 import javax.annotation.ParametersAreNonnullByDefault;
45 import org.spf4j.base.CharSequences;
46 import org.spf4j.io.csv.CharSeparatedValues;
47 import org.spf4j.io.csv.CsvParseException;
48 import org.spf4j.io.csv.CsvReader;
49
50
51
52
53
54
55
56
57
58 @ParametersAreNonnullByDefault
59 @SuppressFBWarnings("NP_LOAD_OF_KNOWN_NULL_VALUE")
60 public final class Csv {
61
62 public static final CharSeparatedValues CSV = new CharSeparatedValues(',');
63
64 private static final char[] TO_ESCAPE = new char[]{',', '\n', '\r', '"'};
65
66 private Csv() {
67 }
68
69 public interface CsvHandler<T> extends org.spf4j.io.csv.CsvHandler<T> {
70 }
71
72 public interface CsvRowHandler<T> extends org.spf4j.io.csv.CsvRowHandler<T> {
73 }
74
75 public interface CsvMapHandler<T> extends org.spf4j.io.csv.CsvMapHandler<T> {
76 }
77
78 public static String[] readSystemProperty(final String propertyName, final String... defaults) {
79 String propertyVal = System.getProperty(propertyName);
80 if (propertyVal == null) {
81 return defaults;
82 } else {
83 List<String> row;
84 try {
85 row = readRow(propertyVal);
86 } catch (CsvParseException ex) {
87 throw new RuntimeException("Unable to parser property " + propertyName + " = " + propertyVal, ex);
88 }
89 return row.toArray(new String[row.size()]);
90 }
91 }
92
93 public static void writeCsvRow(final Appendable writer, final Object... elems) throws IOException {
94 CSV.writeCsvRow(writer, elems);
95 }
96
97 public static void writeCsvRow2(final Appendable writer, final Object obj, final Object... elems)
98 throws IOException {
99 CSV.writeCsvRow2(writer, obj, elems);
100 }
101
102 public static void writeCsvRow(final Appendable writer, final long... elems) throws IOException {
103 CSV.writeCsvRow(writer, elems);
104 }
105
106 public static void writeCsvRowNoEOL(final long[] elems, final Appendable writer) throws IOException {
107 CSV.writeCsvRowNoEOL(elems, writer);
108 }
109
110 public static void writeCsvRow(final Appendable writer, final Iterable<?> elems) throws IOException {
111 CSV.writeCsvRow(writer, elems);
112 }
113
114 public static void writeCsvRowNoEOL(final Iterable<?> elems, final Appendable writer) throws IOException {
115 CSV.writeCsvRowNoEOL(elems, writer);
116 }
117
118 public static <T> T read(final File file, final Charset charset,
119 final CsvMapHandler<T> handler) throws IOException, CsvParseException {
120 return CSV.read(file, charset, handler);
121 }
122
123 public static <T> T read(final File file, final Charset charset,
124 final CsvHandler<T> handler) throws IOException, CsvParseException {
125 return CSV.read(file, charset, handler);
126 }
127
128 public static List<Map<String, String>> read(final Reader preader) throws IOException, CsvParseException {
129 return CSV.read(preader);
130 }
131
132 public static <T> T read(final Reader preader,
133 final CsvMapHandler<T> handler) throws IOException, CsvParseException {
134 return CSV.read(preader, handler);
135 }
136
137 public static List<String> readRow(final String row) throws CsvParseException {
138 try {
139 return readRow(new StringReader(row));
140 } catch (IOException ex) {
141 throw new UncheckedIOException(ex);
142 }
143 }
144
145 public static List<String> readRow(final Reader reader) throws IOException, CsvParseException {
146 return CSV.readRow(reader);
147 }
148
149 public static <T> T readRow(final Reader reader, final CsvRowHandler<T> handler)
150 throws IOException, CsvParseException {
151 return CSV.readRow(reader, handler);
152 }
153
154 public static <T> T read(final Reader preader,
155 final CsvHandler<T> handler) throws IOException, CsvParseException {
156 return CSV.read(preader, handler);
157 }
158
159
160
161
162
163
164
165
166
167
168 public static <T> T readNoBom(final PushbackReader reader, final CsvHandler<T> handler)
169 throws IOException, CsvParseException {
170 return CSV.readNoBom(reader, handler);
171 }
172
173
174
175
176
177
178
179
180 public static Iterable<Iterable<String>> asIterable(final Reader preader) {
181 return CSV.asIterable(preader);
182 }
183
184 public static CsvReader reader(final Reader preader) throws IOException {
185 return CSV.reader(preader);
186 }
187
188 public static CsvReader readerNoBOM(final PushbackReader reader) {
189 return CSV.readerNoBOM(reader);
190 }
191
192 public static void writeCsvElement(final CharSequence elem, final Appendable writer) throws IOException {
193 if (CharSequences.containsAnyChar(elem, TO_ESCAPE)) {
194 writeQuotedCsvElement(elem, writer);
195 } else {
196 writer.append(elem);
197 }
198 }
199
200 public static void writeQuotedCsvElement(final CharSequence elem, final Appendable writer) throws IOException {
201 int length = elem.length();
202 writer.append('"');
203 for (int i = 0; i < length; i++) {
204 char c = elem.charAt(i);
205 if (c == '"') {
206 writer.append("\"\"");
207 } else {
208 writer.append(c);
209 }
210 }
211 writer.append('"');
212 }
213
214 public static CharSequence toCsvElement(final CharSequence elem) {
215 if (CharSequences.containsAnyChar(elem, TO_ESCAPE)) {
216 StringBuilder sw = new StringBuilder(elem.length() + 2);
217 try {
218 writeQuotedCsvElement(elem, sw);
219 } catch (IOException ex) {
220 throw new UncheckedIOException(ex);
221 }
222 return sw.toString();
223 } else {
224 return elem;
225 }
226 }
227
228
229
230
231
232
233
234
235
236 @CheckReturnValue
237 public static int readCsvElement(final Reader reader, final StringBuilder addElemTo) throws IOException {
238 int c = reader.read();
239 if (c < 0) {
240 return c;
241 }
242 if (c == '"') {
243 c = reader.read();
244 while (c >= 0) {
245 if (c == '"') {
246 int c2 = reader.read();
247 if (c2 >= 0) {
248 if (c2 == '"') {
249 addElemTo.append((char) c);
250 } else {
251 return c2;
252 }
253 } else {
254 return c2;
255 }
256 } else {
257 addElemTo.append((char) c);
258 }
259 c = reader.read();
260 }
261 } else {
262 while (c != ',' && c != '\n' && c != '\r' && c >= 0) {
263 addElemTo.append((char) c);
264 c = reader.read();
265 }
266 }
267 return c;
268 }
269
270 }