Skip to content

Commit d4f0111

Browse files
committed
Update CSVEncoder.
1 parent 6750d2b commit d4f0111

2 files changed

Lines changed: 71 additions & 27 deletions

File tree

kilo-client/src/main/java/org/httprpc/kilo/io/CSVEncoder.java

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Date;
2424
import java.util.HashMap;
2525
import java.util.Map;
26+
import java.util.MissingResourceException;
2627
import java.util.ResourceBundle;
2728
import java.util.function.Function;
2829

@@ -32,7 +33,7 @@
3233
* Encodes CSV content.
3334
*/
3435
public class CSVEncoder extends Encoder<Iterable<?>> {
35-
private Collection<String> keys;
36+
private Collection<?> keys;
3637

3738
private Map<Class<?>, Function<Object, String>> formatters = new HashMap<>();
3839

@@ -46,7 +47,7 @@ public class CSVEncoder extends Encoder<Iterable<?>> {
4647
* @param keys
4748
* The column keys.
4849
*/
49-
public CSVEncoder(Collection<String> keys) {
50+
public CSVEncoder(Collection<?> keys) {
5051
if (keys == null) {
5152
throw new IllegalArgumentException();
5253
}
@@ -120,18 +121,21 @@ private void encode(Iterable<?> rows, Writer writer) throws IOException {
120121

121122
for (var key : keys) {
122123
if (key == null) {
123-
throw new IllegalStateException();
124+
throw new IllegalStateException("Missing key.");
124125
}
125126

126127
if (i > 0) {
127128
writer.write(DELIMITER);
128129
}
129130

130-
String heading;
131-
if (resourceBundle == null) {
132-
heading = key;
133-
} else {
134-
heading = resourceBundle.getObject(key).toString();
131+
var heading = key;
132+
133+
if (resourceBundle != null) {
134+
try {
135+
heading = resourceBundle.getObject(key.toString());
136+
} catch (MissingResourceException exception) {
137+
// No-op
138+
}
135139
}
136140

137141
encode(heading, writer);
@@ -151,31 +155,35 @@ private void encode(Iterable<?> rows, Writer writer) throws IOException {
151155
writer.write(DELIMITER);
152156
}
153157

154-
var value = map.get(key);
158+
encode(map.get(key), writer);
159+
160+
i++;
161+
}
155162

156-
if (value != null) {
157-
if (value instanceof Date date) {
158-
value = date.toInstant();
159-
}
163+
writer.write("\r\n");
164+
}
165+
}
160166

161-
var formatter = formatters.get(value.getClass());
167+
private void encode(Object value, Writer writer) throws IOException {
168+
if (value == null) {
169+
return;
170+
}
162171

163-
if (formatter != null) {
164-
value = formatter.apply(value);
165-
}
172+
if (value instanceof Date date) {
173+
value = date.toInstant();
174+
}
166175

167-
switch (value) {
168-
case CharSequence text -> encode(text, writer);
169-
case Number number -> encode(number, writer);
170-
case Boolean flag -> encode(flag, writer);
171-
default -> encode(value.toString(), writer);
172-
}
173-
}
176+
var formatter = formatters.get(value.getClass());
174177

175-
i++;
176-
}
178+
if (formatter != null) {
179+
value = formatter.apply(value);
180+
}
177181

178-
writer.write("\r\n");
182+
switch (value) {
183+
case CharSequence text -> encode(text, writer);
184+
case Number number -> encode(number, writer);
185+
case Boolean flag -> encode(flag, writer);
186+
default -> encode(value.toString(), writer);
179187
}
180188
}
181189

kilo-client/src/test/java/org/httprpc/kilo/io/CSVEncoderTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.IOException;
2020
import java.io.StringWriter;
2121
import java.time.Instant;
22+
import java.time.LocalDate;
2223
import java.time.LocalDateTime;
2324
import java.time.format.DateTimeFormatter;
2425
import java.time.format.FormatStyle;
@@ -131,6 +132,41 @@ public void testRecords() throws IOException {
131132
assertEquals(expected, writer.toString());
132133
}
133134

135+
@Test
136+
public void testKeys() throws IOException {
137+
var date = LocalDate.now();
138+
139+
var keys = listOf("a", date);
140+
141+
var csvEncoder = new CSVEncoder(keys);
142+
143+
var dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
144+
145+
csvEncoder.format(LocalDate.class, dateFormatter::format);
146+
csvEncoder.setResourceBundle(ResourceBundle.getBundle(getClass().getPackageName() + ".csv"));
147+
148+
var rows = listOf(
149+
mapOf(
150+
entry("a", true),
151+
entry(date, 123)
152+
),
153+
mapOf(
154+
entry("a", false),
155+
entry(date, 456)
156+
)
157+
);
158+
159+
var writer = new StringWriter();
160+
161+
csvEncoder.write(rows, writer);
162+
163+
var expected = "\"a\",\"" + dateFormatter.format(date) + "\"\r\n"
164+
+ "true,123\r\n"
165+
+ "false,456\r\n";
166+
167+
assertEquals(expected, writer.toString());
168+
}
169+
134170
@Test
135171
public void testFormat() throws IOException {
136172
var date = new Date();

0 commit comments

Comments
 (0)