]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/CsvWriter.java
Improve ACR, introduce migration from JCR.
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / CsvWriter.java
1 package org.argeo.util;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.io.OutputStreamWriter;
6 import java.io.UnsupportedEncodingException;
7 import java.io.Writer;
8 import java.nio.charset.Charset;
9 import java.util.Iterator;
10 import java.util.List;
11
12 /** Write in CSV format. */
13 public class CsvWriter {
14 private final Writer out;
15
16 private char separator = ',';
17 private char quote = '\"';
18
19 /**
20 * Creates a CSV writer.
21 *
22 * @param out the stream to write to. Caller is responsible for closing it.
23 *
24 * @deprecated Use {@link #CsvWriter(OutputStream, Charset)} instead.
25 *
26 */
27 @Deprecated
28 public CsvWriter(OutputStream out) {
29 this.out = new OutputStreamWriter(out);
30 }
31
32 /**
33 * Creates a CSV writer.
34 *
35 * @param out the stream to write to. Caller is responsible for closing it.
36 * @param encoding the encoding to use.
37 *
38 * @deprecated Use {@link #CsvWriter(OutputStream, Charset)} instead.
39 */
40 @Deprecated
41 public CsvWriter(OutputStream out, String encoding) {
42 try {
43 this.out = new OutputStreamWriter(out, encoding);
44 } catch (UnsupportedEncodingException e) {
45 throw new IllegalArgumentException(e);
46 }
47 }
48
49 /**
50 * Creates a CSV writer.
51 *
52 * @param out the stream to write to. Caller is responsible for closing it.
53 * @param charset the charset to use
54 */
55 public CsvWriter(OutputStream out, Charset charset) {
56 this.out = new OutputStreamWriter(out, charset);
57 }
58
59 /**
60 * Creates a CSV writer.
61 *
62 * @param out the stream to write to. Caller is responsible for closing it.
63 */
64 public CsvWriter(Writer writer) {
65 this.out = writer;
66 }
67
68 /**
69 * Write a CSV line. Also used to write a header if needed (this is transparent
70 * for the CSV writer): simply call it first, before writing the lines.
71 */
72 public void writeLine(List<?> tokens) {
73 try {
74 Iterator<?> it = tokens.iterator();
75 while (it.hasNext()) {
76 Object obj = it.next();
77 writeToken(obj != null ? obj.toString() : null);
78 if (it.hasNext())
79 out.write(separator);
80 }
81 out.write('\n');
82 out.flush();
83 } catch (IOException e) {
84 throw new RuntimeException("Could not write " + tokens, e);
85 }
86 }
87
88 /**
89 * Write a CSV line. Also used to write a header if needed (this is transparent
90 * for the CSV writer): simply call it first, before writing the lines.
91 */
92 public void writeLine(Object[] tokens) {
93 try {
94 for (int i = 0; i < tokens.length; i++) {
95 if (tokens[i] == null) {
96 writeToken(null);
97 } else {
98 writeToken(tokens[i].toString());
99 }
100 if (i != (tokens.length - 1))
101 out.write(separator);
102 }
103 out.write('\n');
104 out.flush();
105 } catch (IOException e) {
106 throw new RuntimeException("Could not write " + tokens, e);
107 }
108 }
109
110 protected void writeToken(String token) throws IOException {
111 if (token == null) {
112 // TODO configure how to deal with null
113 out.write("");
114 return;
115 }
116 // +2 for possible quotes, another +2 assuming there would be an already
117 // quoted string where quotes needs to be duplicated
118 // another +2 for safety
119 // we don't want to increase buffer size while writing
120 StringBuffer buf = new StringBuffer(token.length() + 6);
121 char[] arr = token.toCharArray();
122 boolean shouldQuote = false;
123 for (char c : arr) {
124 if (!shouldQuote) {
125 if (c == separator)
126 shouldQuote = true;
127 if (c == '\n')
128 shouldQuote = true;
129 }
130
131 if (c == quote) {
132 shouldQuote = true;
133 // duplicate quote
134 buf.append(quote);
135 }
136
137 // generic case
138 buf.append(c);
139 }
140
141 if (shouldQuote == true)
142 out.write(quote);
143 out.write(buf.toString());
144 if (shouldQuote == true)
145 out.write(quote);
146 }
147
148 public void setSeparator(char separator) {
149 this.separator = separator;
150 }
151
152 public void setQuote(char quote) {
153 this.quote = quote;
154 }
155
156 }