]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/CsvWriter.java
Adapt CMS Web to new assembly approach.
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / CsvWriter.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.util;
17
18 import java.io.IOException;
19 import java.io.OutputStream;
20 import java.io.OutputStreamWriter;
21 import java.io.UnsupportedEncodingException;
22 import java.io.Writer;
23 import java.util.Iterator;
24 import java.util.List;
25
26 /** Write in CSV format. */
27 public class CsvWriter {
28 private final Writer out;
29
30 private char separator = ',';
31 private char quote = '\"';
32
33 /**
34 * Creates a CSV writer.
35 *
36 * @param out
37 * the stream to write to. Caller is responsible for closing it.
38 */
39 public CsvWriter(OutputStream out) {
40 this.out = new OutputStreamWriter(out);
41 }
42
43 /**
44 * Creates a CSV writer.
45 *
46 * @param out
47 * the stream to write to. Caller is responsible for closing it.
48 */
49 public CsvWriter(OutputStream out, String encoding) {
50 try {
51 this.out = new OutputStreamWriter(out, encoding);
52 } catch (UnsupportedEncodingException e) {
53 throw new UtilsException("Cannot initialize CSV writer", e);
54 }
55 }
56
57 /**
58 * Write a CSV line. Also used to write a header if needed (this is
59 * transparent for the CSV writer): simply call it first, before writing the
60 * lines.
61 */
62 public void writeLine(List<?> tokens) {
63 try {
64 Iterator<?> it = tokens.iterator();
65 while (it.hasNext()) {
66 writeToken(it.next().toString());
67 if (it.hasNext())
68 out.write(separator);
69 }
70 out.write('\n');
71 out.flush();
72 } catch (IOException e) {
73 throw new UtilsException("Could not write " + tokens, e);
74 }
75 }
76
77 /**
78 * Write a CSV line. Also used to write a header if needed (this is
79 * transparent for the CSV writer): simply call it first, before writing the
80 * lines.
81 */
82 public void writeLine(Object[] tokens) {
83 try {
84 for (int i = 0; i < tokens.length; i++) {
85 if (tokens[i] == null) {
86 // TODO configure how to deal with null
87 writeToken("");
88 } else {
89 writeToken(tokens[i].toString());
90 }
91 if (i != (tokens.length - 1))
92 out.write(separator);
93 }
94 out.write('\n');
95 out.flush();
96 } catch (IOException e) {
97 throw new UtilsException("Could not write " + tokens, e);
98 }
99 }
100
101 protected void writeToken(String token) throws IOException {
102 // +2 for possible quotes, another +2 assuming there would be an already
103 // quoted string where quotes needs to be duplicated
104 // another +2 for safety
105 // we don't want to increase buffer size while writing
106 StringBuffer buf = new StringBuffer(token.length() + 6);
107 char[] arr = token.toCharArray();
108 boolean shouldQuote = false;
109 for (char c : arr) {
110 if (!shouldQuote) {
111 if (c == separator)
112 shouldQuote = true;
113 if (c == '\n')
114 shouldQuote = true;
115 }
116
117 if (c == quote) {
118 shouldQuote = true;
119 // duplicate quote
120 buf.append(quote);
121 }
122
123 // generic case
124 buf.append(c);
125 }
126
127 if (shouldQuote == true)
128 out.write(quote);
129 out.write(buf.toString());
130 if (shouldQuote == true)
131 out.write(quote);
132 }
133
134 public void setSeparator(char separator) {
135 this.separator = separator;
136 }
137
138 public void setQuote(char quote) {
139 this.quote = quote;
140 }
141
142 }