From 552e0444a769840d659a2449129c87f9a42374fb Mon Sep 17 00:00:00 2001 From: Tako Schotanus Date: Wed, 30 Sep 2026 20:40:43 +0200 Subject: [PATCH] feat: added new methods for inserting properties at specific positions Fixes #68 --- .../org/codejive/properties/Properties.java | 44 +++++++++++++++++++ .../codejive/properties/TestProperties.java | 25 +++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/main/java/org/codejive/properties/Properties.java b/src/main/java/org/codejive/properties/Properties.java index c05dcbe..f26d9d1 100644 --- a/src/main/java/org/codejive/properties/Properties.java +++ b/src/main/java/org/codejive/properties/Properties.java @@ -389,6 +389,50 @@ public String put(String key, String value) { return values.put(key, value); } + /** + * Associates the specified value with the specified key at the position indicated by the + * cursor. The cursor must point to the start of a line, or to the end of the token list. If the + * key already exists, its value is replaced at its existing position. + * + * @param pos position at which to insert the property + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with key, or null if there was no mapping for key + * @throws IllegalArgumentException if the cursor is not at a valid insertion position + */ + public String put(Cursor pos, String key, String value) { + Objects.requireNonNull(pos, "pos"); + if (key == null || value == null) { + throw new NullPointerException(); + } + String rawValue = escapeValue(value); + if (values.containsKey(key)) { + replaceValue(key, rawValue, value); + } else { + String rawKey = escapeKey(key); + addNewKeyValue(pos, rawKey, key, rawValue, value); + } + return values.put(key, value); + } + + /** + * Associates the specified value with the specified key at the position indicated by the + * cursor. The cursor must point to the start of a line, or to the end of the token list. If the + * key already exists, its value is replaced at its existing position. If any comment lines are + * supplied they will be prepended to the property. + * + * @param pos position at which to insert the property + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @param comment comment lines to be associated with the specified key + * @return the previous value associated with key, or null if there was no mapping for key + */ + public String putCommented(Cursor pos, String key, String value, String... comment) { + String old = put(pos, key, value); + setComment(key, comment); + return old; + } + /** * Associates the specified value with the specified key in this properties table. If the * properties previously contained a mapping for the key, the old value is replaced. If any diff --git a/src/test/java/org/codejive/properties/TestProperties.java b/src/test/java/org/codejive/properties/TestProperties.java index 8fe4119..84b890e 100644 --- a/src/test/java/org/codejive/properties/TestProperties.java +++ b/src/test/java/org/codejive/properties/TestProperties.java @@ -797,6 +797,31 @@ void testPutNew() throws IOException, URISyntaxException { assertThat(sw.toString()).isEqualTo(readAll(getResource("/test-putnew.properties"))); } + @Test + void testPutAtPosition() throws IOException { + Properties p = Properties.loadProperties(new StringReader("alpha=1\nbeta=2\n")); + + assertThat(p.put(p.beforeProperty("beta"), "middle", "3")).isNull(); + + StringWriter sw = new StringWriter(); + p.store(sw); + assertThat(sw.toString()).isEqualTo("alpha=1\nmiddle=3\nbeta=2\n"); + assertThat(p).containsEntry("middle", "3"); + } + + @Test + void testPutAtInvalidPosition() throws IOException { + Properties p = Properties.loadProperties(new StringReader("alpha=1\nbeta=2\n")); + + Cursor separator = p.indexOf("beta").next(); + assertThat(p.put(separator, "middle", "3")).isNull(); + + StringWriter sw = new StringWriter(); + p.store(sw); + assertThat(sw.toString()).isEqualTo("alpha=1\nmiddle=3\nbeta=2\n"); + assertThat(p).containsEntry("middle", "3"); + } + @Test void testPutNewTest2() throws IOException, URISyntaxException { Path f = getResource("/test2.properties");