This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 32e0c94662 TOML fix
32e0c94662 is described below
commit 32e0c9466260ec4866b783868ab6660d0a8efdfc
Author: James Bognar <[email protected]>
AuthorDate: Wed Mar 18 19:02:50 2026 -0400
TOML fix
---
.../java/org/apache/juneau/toml/TomlParser.java | 5 +++--
.../org/apache/juneau/toml/TomlParserSession.java | 21 +++++++++++----------
.../java/org/apache/juneau/toml/TomlSerializer.java | 1 +
.../apache/juneau/toml/TomlSerializerSession.java | 4 ++--
.../apache/juneau/a/rttests/RoundTripMaps_Test.java | 2 --
.../apache/juneau/parquet/ParquetParser_Test.java | 3 ---
6 files changed, 17 insertions(+), 19 deletions(-)
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParser.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParser.java
index 59d3cf703d..0d9b0b31f0 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParser.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParser.java
@@ -37,8 +37,9 @@ import org.apache.juneau.parser.*;
* <li><b>Null values</b> — TOML has no null type. Absent keys yield null
for object properties.
* The parser treats the configured <c>nullValue</c> string (e.g.
<c><NULL></c>) as Java null
* when it appears as a value.
- * <li><b>Non-string map keys</b> — TOML keys are always strings. Parsing
to
- * <c>Map<Integer,String></c> or similar requires key
conversion that may not round-trip.
+ * <li><b>Non-string map keys</b> — TOML keys are always strings.
Non-string key types
+ * (e.g. <c>Map<Integer,String></c>) are converted via
{@link org.apache.juneau.parser.ParserSession#convertAttrToType(Object, String,
org.apache.juneau.ClassMeta) convertAttrToType}.
+ * Null keys are serialized as the string <c>null</c> and
converted back to Java null during parsing.
* <li><b>Polymorphic types</b> — Parsing to interfaces or abstract
classes requires a
* {@link
org.apache.juneau.BeanContext.Builder#beanDictionary(Class[]) bean dictionary}
* when no <c>_type</c> discriminator is present in the document.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
index fe701faeda..f5cd29bc9c 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlParserSession.java
@@ -100,11 +100,7 @@ public class TomlParserSession extends ReaderParserSession
{
Object inner = root.get("_value");
return (T) convertValue(inner, type);
}
- T result = convertMapToType(root, type);
- // Fallback: convert LinkedHashMap to JsonMap when
target expects Map (JsonMap preferred for TOML)
- if (result instanceof Map m && !(result instanceof
JsonMap) && type.isMap())
- return (T) toJsonMap(m);
- return result;
+ return convertMapToType(root, type);
}
}
@@ -345,12 +341,17 @@ public class TomlParserSession extends
ReaderParserSession {
}
private <T> T convertMapToType(Map<String, Object> map, ClassMeta<T>
type) throws ParseException, ExecutableException {
- // When target is JsonMap, convert LinkedHashMap to JsonMap
(parser produces LinkedHashMap)
if (type.isMap()) {
- Class<?> inner = type.inner();
- if (JsonMap.class.isAssignableFrom(inner) || (inner !=
null && "org.apache.juneau.collections.JsonMap".equals(inner.getName())))
- return (T) toJsonMap(map);
- return (T) map;
+ var keyType = type.getKeyType();
+ var valueType = type.getValueType();
+ Map m = type.canCreateNewInstance(getOuter()) ? (Map)
type.newInstance(getOuter()) : newGenericMap(type);
+ for (var e : map.entrySet()) {
+ String keyStr = "null".equals(e.getKey()) ?
null : e.getKey();
+ Object key = convertAttrToType(m, keyStr,
keyType);
+ Object val = convertValue(e.getValue(),
valueType);
+ m.put(key, val);
+ }
+ return (T) m;
}
BeanMap<?> bm = toBeanMap(type.newInstance(getOuter()));
populateBeanMap(bm, map);
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializer.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializer.java
index 7fc4c3bcc1..a842cde232 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializer.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializer.java
@@ -89,6 +89,7 @@ import org.apache.juneau.serializer.*;
* Use <c>keepNullProperties()</c> to write the configured
<c>nullValue</c> string (e.g. <c><NULL></c>) instead.
* <li><b>Map keys</b> — TOML tables only support string keys. Maps with
non-string keys
* (e.g. <c>Map<Integer,String></c>) have keys converted via
<c>toString()</c>; ensure results are valid TOML keys.
+ * Null keys are serialized as the string <c>null</c>.
* <li><b>Polymorphic types</b> — <c>addBeanTypes()</c> and
<c>addRootType()</c> add <c>_type</c>
* discriminators for polymorphic parsing; use with care as TOML
structure differs from JSON.
* <li><b>Root-level collections</b> — TOML expects a root table. Root
arrays use array-of-tables
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
index 81e3783258..08ff2e4cd5 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/toml/TomlSerializerSession.java
@@ -129,7 +129,7 @@ public class TomlSerializerSession extends
WriterSerializerSession {
private void serializeMapAtRoot(TomlWriter w, Map<?,?> map,
ClassMeta<?> type) throws SerializeException {
Predicate<Object> checkNull = x -> isKeepNullProperties() ||
nn(x);
forEachEntry(map, e -> {
- String k = toString(e.getKey());
+ String k = e.getKey() == null ? "null" :
toString(e.getKey());
Object v = e.getValue();
if (!checkNull.test(v))
return;
@@ -323,7 +323,7 @@ public class TomlSerializerSession extends
WriterSerializerSession {
private void serializeMapAsTable(TomlWriter w, String path, Map<?,?>
map, ClassMeta<?> type) throws SerializeException {
Predicate<Object> checkNull = x -> isKeepNullProperties() ||
nn(x);
forEachEntry(map, e -> {
- String k = toString(e.getKey());
+ String k = e.getKey() == null ? "null" :
toString(e.getKey());
Object v = e.getValue();
if (!checkNull.test(v))
return;
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripMaps_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripMaps_Test.java
index a2f60703ea..4c6ae0b972 100755
---
a/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripMaps_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/a/rttests/RoundTripMaps_Test.java
@@ -178,8 +178,6 @@ class RoundTripMaps_Test extends TestBase {
tester(30, "Toml - default")
.serializer(TomlSerializer.create())
.parser(TomlParser.create())
- // TODO: Revisit when TomlParser supports HashMap and
maps with non-String keys
- .skipIf(o -> o instanceof HashMap || (o instanceof
Map<?,?> m && !m.isEmpty() && !(m.keySet().iterator().next() instanceof
String)))
.build(),
tester(31, "Csv - default")
.serializer(CsvSerializer.create().keepNullProperties())
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/parquet/ParquetParser_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/parquet/ParquetParser_Test.java
index 087b432bfc..48502f9e0e 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/parquet/ParquetParser_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/parquet/ParquetParser_Test.java
@@ -28,9 +28,6 @@ import org.junit.jupiter.api.*;
/**
* Tests for {@link ParquetParser}.
*/
-@SuppressWarnings({
- "unchecked" // Parser returns raw types; explicit casts required for
typed assertions
-})
class ParquetParser_Test extends TestBase {
@Test