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
21 changes: 21 additions & 0 deletions src/main/java/org/codejive/properties/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -513,16 +513,37 @@ private Cursor addNewKeyValue(
pos = afterLastProperty();
}

boolean afterFinalComment = isAfterFinalComment(pos);

// Add a newline whitespace token if necessary
pos = prepareNewLine(pos);

if (afterFinalComment) {
// Keep a trailing comment free rather than attaching it to the new key.
pos.addEol(eolType);
}

// Add tokens for key, separator and value
pos.add(new PropertiesParser.Token(PropertiesParser.Type.KEY, rawKey, key));
pos.add(new PropertiesParser.Token(PropertiesParser.Type.SEPARATOR, "="));
pos.add(new PropertiesParser.Token(PropertiesParser.Type.VALUE, rawValue, value));
return pos;
}

// Returns true only at the end of the token list when the last token is a comment,
// optionally followed by one EOL. An existing blank line after the comment returns false.
// Uses a copy so the insertion cursor is not moved.
private boolean isAfterFinalComment(Cursor pos) {
if (!pos.atEnd()) {
return false;
}
Cursor previous = pos.copy().prev();
if (previous.isEol()) {
previous.prev();
}
return previous.isType(PropertiesParser.Type.COMMENT);
}

// Prepare the list for adding a new line at the given position. It will make sure the cursor
// is at a valid insertion point and that any required EOLs are added.
private Cursor prepareNewLine(Cursor pos) {
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/org/codejive/properties/TestProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,24 @@ void testPutFirstLineHeaderOnlyCrLf() throws IOException {
expectStoreText(p, "put=putVal\r\n # header\r\n");
}

@Test
void testPutLastLine() throws IOException {
final String given = "key=val\n" + "# trailer comment";
final String expected = "key=val\n" + "# trailer comment\n" + "\n" + "put=putVal";
Properties p = Properties.loadProperties(new StringReader(given));
p.put(p.last().next(), "put", "putVal");
expectStoreText(p, expected);
assertThat(p.getComment("put")).isEmpty();
}

@Test
void testPutLastLineWithFinalEol() throws IOException {
Properties p = Properties.loadProperties(new StringReader("key=val\r\n # trailer\r\n"));
p.put(p.last().next(), "put", "putVal");
expectStoreText(p, "key=val\r\n # trailer\r\n\r\nput=putVal\r\n");
assertThat(p.getComment("put")).isEmpty();
}

private void expectStoreText(Properties props, String expectedText) throws IOException {
StringWriter sw = new StringWriter();
props.store(sw);
Expand Down
Loading