Skip to content

Commit 074a0c2

Browse files
Merge pull request #564 from ie3-institute/ck/#434-csvColumnOrder
Write csv entries in correct order
2 parents 657d038 + 1e739b5 commit 074a0c2

File tree

3 files changed

+52
-15
lines changed

3 files changed

+52
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- Fix JavaDoc creation
2424
- Create JavaDoc with java 17 instead of java 8
2525
- Let JavDoc pass, if there are warnings **ATTENTION:** Should be removed, when JavaDoc is fixed! (cf. Issue [#494](https://github.com/ie3-institute/PowerSystemDataModel/issues/494))
26+
- `BufferedCsvWriter` writes columns in the order, that the headline elements are defined [#434](https://github.com/ie3-institute/PowerSystemDataModel/issues/393)
2627

2728
### Changed
2829
- BREAKING: PvInput Model parameter name height changed to elevationAngle [#393](https://github.com/ie3-institute/PowerSystemDataModel/issues/393) :warning:

src/main/java/edu/ie3/datamodel/io/csv/BufferedCsvWriter.java

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.util.Arrays;
1313
import java.util.Map;
1414
import java.util.Objects;
15+
import java.util.stream.Collectors;
16+
import java.util.stream.Stream;
1517

1618
/**
1719
* This class extends the {@link BufferedWriter} and adds information about the file shape of the
@@ -27,10 +29,11 @@ public class BufferedCsvWriter extends BufferedWriter {
2729
"Direct appending is prohibited. Use write instead.";
2830

2931
/**
30-
* Build a new CsvBufferedWriter
32+
* Build a new CsvBufferedWriter. The order of headline elements given in this constructor defines
33+
* the order of columns in file
3134
*
3235
* @param filePath String representation of the full path to the target file
33-
* @param headLineElements Elements of the csv head line
36+
* @param headLineElements Elements of the csv headline
3437
* @param csvSep csv separator char
3538
* @param append true to append to an existing file, false to overwrite an existing file (if any),
3639
* if no file exists, a new one will be created in both cases
@@ -47,7 +50,8 @@ public BufferedCsvWriter(
4750
/**
4851
* Build a new CsvBufferedWriter. This is a "convenience" Constructor. The absolute file path is
4952
* assembled by concatenation of {@code baseFolder} and {@code fileDefinition}'s file path
50-
* information.
53+
* information. The order of headline elements in {@code fileDefinition} defines the order of
54+
* columns in file
5155
*
5256
* @param baseFolder Base folder, from where the file hierarchy should start
5357
* @param fileDefinition The foreseen shape of the file
@@ -73,16 +77,15 @@ public BufferedCsvWriter(String baseFolder, CsvFileDefinition fileDefinition, bo
7377
*/
7478
public synchronized void write(Map<String, String> entityFieldData)
7579
throws IOException, SinkException {
76-
/* Check against eligible head line elements */
80+
/* Check against eligible headline elements */
7781
if (entityFieldData.size() != headLineElements.length
7882
|| !entityFieldData.keySet().containsAll(Arrays.asList(headLineElements)))
7983
throw new SinkException(
8084
"The provided data does not meet the pre-defined head line elements '"
8185
+ String.join(",", headLineElements)
8286
+ "'.");
8387

84-
String[] entries = entityFieldData.values().toArray(new String[0]);
85-
writeOneLine(entries);
88+
writeOneLine(Arrays.stream(headLineElements).map(entityFieldData::get));
8689
}
8790

8891
/**
@@ -101,15 +104,18 @@ public final synchronized void writeFileHeader() throws IOException {
101104
* @throws IOException If writing is not possible
102105
*/
103106
private void writeOneLine(String[] entries) throws IOException {
104-
for (int i = 0; i < entries.length; i++) {
105-
String attribute = entries[i];
106-
super.append(attribute);
107-
if (i + 1 < entries.length) {
108-
super.append(csvSep);
109-
} else {
110-
super.append("\n");
111-
}
112-
}
107+
writeOneLine(Arrays.stream(entries));
108+
}
109+
110+
/**
111+
* Write one line to the csv file
112+
*
113+
* @param entries Stream of entries to write
114+
* @throws IOException If writing is not possible
115+
*/
116+
private void writeOneLine(Stream<String> entries) throws IOException {
117+
super.append(entries.collect(Collectors.joining(csvSep)));
118+
super.append("\n");
113119
flush();
114120
}
115121

src/test/groovy/edu/ie3/datamodel/io/csv/BufferedCsvWriterTest.groovy

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package edu.ie3.datamodel.io.csv
77

8+
import edu.ie3.datamodel.exceptions.FileException
89
import edu.ie3.datamodel.exceptions.SinkException
910
import edu.ie3.util.io.FileIOUtils
1011
import org.apache.commons.io.FilenameUtils
@@ -78,4 +79,33 @@ class BufferedCsvWriterTest extends Specification {
7879
def e = thrown(SinkException)
7980
e.message == "The provided data does not meet the pre-defined head line elements 'a,b,c'."
8081
}
82+
83+
def "The buffered csv writer writes out content in the order specified by the headline elements"() {
84+
given:
85+
def targetFile = FilenameUtils.concat(tmpDirectory.toString(), "order_test.csv")
86+
def writer = new BufferedCsvWriter(targetFile, ["third_header", "second_header", "first_header"] as String[], ",", false)
87+
writer.writeFileHeader()
88+
def content = [
89+
"third_header": "third_value",
90+
"first_header": "first_value",
91+
"second_header": "second_value"
92+
]
93+
94+
when:
95+
writer.write(content)
96+
writer.close()
97+
/* Read in the content */
98+
def writtenContent = ""
99+
def headline = ""
100+
try(BufferedReader reader = new BufferedReader(new FileReader(targetFile))) {
101+
headline = reader.readLine()
102+
writtenContent = reader.readLine()
103+
} catch (Exception e) {
104+
throw new FileException("Unable to read content of test file '"+targetFile+"'.", e)
105+
}
106+
107+
then:
108+
headline == "third_header,second_header,first_header"
109+
writtenContent == "third_value,second_value,first_value"
110+
}
81111
}

0 commit comments

Comments
 (0)