Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix JavaDoc creation
- Create JavaDoc with java 17 instead of java 8
- 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))
- `BufferedCsvWriter` writes columns in the order, that the headline elements are defined [#434](https://github.com/ie3-institute/PowerSystemDataModel/issues/393)

### Changed
- BREAKING: PvInput Model parameter name height changed to elevationAngle [#393](https://github.com/ie3-institute/PowerSystemDataModel/issues/393) :warning:
Expand Down
36 changes: 21 additions & 15 deletions src/main/java/edu/ie3/datamodel/io/csv/BufferedCsvWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

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

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

String[] entries = entityFieldData.values().toArray(new String[0]);
writeOneLine(entries);
writeOneLine(Arrays.stream(headLineElements).map(entityFieldData::get));
}

/**
Expand All @@ -101,15 +104,18 @@ public final synchronized void writeFileHeader() throws IOException {
* @throws IOException If writing is not possible
*/
private void writeOneLine(String[] entries) throws IOException {
for (int i = 0; i < entries.length; i++) {
String attribute = entries[i];
super.append(attribute);
if (i + 1 < entries.length) {
super.append(csvSep);
} else {
super.append("\n");
}
}
writeOneLine(Arrays.stream(entries));
}

/**
* Write one line to the csv file
*
* @param entries Stream of entries to write
* @throws IOException If writing is not possible
*/
private void writeOneLine(Stream<String> entries) throws IOException {
super.append(entries.collect(Collectors.joining(csvSep)));
super.append("\n");
flush();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package edu.ie3.datamodel.io.csv

import edu.ie3.datamodel.exceptions.FileException
import edu.ie3.datamodel.exceptions.SinkException
import edu.ie3.util.io.FileIOUtils
import org.apache.commons.io.FilenameUtils
Expand Down Expand Up @@ -78,4 +79,33 @@ class BufferedCsvWriterTest extends Specification {
def e = thrown(SinkException)
e.message == "The provided data does not meet the pre-defined head line elements 'a,b,c'."
}

def "The buffered csv writer writes out content in the order specified by the headline elements"() {
given:
def targetFile = FilenameUtils.concat(tmpDirectory.toString(), "order_test.csv")
def writer = new BufferedCsvWriter(targetFile, ["third_header", "second_header", "first_header"] as String[], ",", false)
writer.writeFileHeader()
def content = [
"third_header": "third_value",
"first_header": "first_value",
"second_header": "second_value"
]

when:
writer.write(content)
writer.close()
/* Read in the content */
def writtenContent = ""
def headline = ""
try(BufferedReader reader = new BufferedReader(new FileReader(targetFile))) {
headline = reader.readLine()
writtenContent = reader.readLine()
} catch (Exception e) {
throw new FileException("Unable to read content of test file '"+targetFile+"'.", e)
}

then:
headline == "third_header,second_header,first_header"
writtenContent == "third_value,second_value,first_value"
}
}