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>&lt;NULL&gt;</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&lt;Integer,String&gt;</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&lt;Integer,String&gt;</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>&lt;NULL&gt;</c>) instead.
  *     <li><b>Map keys</b> — TOML tables only support string keys. Maps with 
non-string keys
  *             (e.g. <c>Map&lt;Integer,String&gt;</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

Reply via email to