This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch docs
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/docs by this push:
new 0d726ed358 docs: document MarshalledMap/MarshalledList and
Json5Map/Json5List (TODO-34)
0d726ed358 is described below
commit 0d726ed358d6a24497a090c36ea2fe8d9813d58e
Author: James Bognar <[email protected]>
AuthorDate: Mon May 18 15:09:21 2026 -0400
docs: document MarshalledMap/MarshalledList and Json5Map/Json5List (TODO-34)
Co-authored-by: Cursor <[email protected]>
---
pages/release-notes/9.5.0.md | 124 +++++++++++++++++++++++--
pages/topics/01.02.Marshalling.md | 12 ++-
pages/topics/02.08.JsonMap.md | 32 +++++--
pages/topics/02.16.ParsingIntoGenericModels.md | 9 +-
pages/topics/23.01.V9.5-migration-guide.md | 21 ++++-
5 files changed, 172 insertions(+), 26 deletions(-)
diff --git a/pages/release-notes/9.5.0.md b/pages/release-notes/9.5.0.md
index e400e684a9..91a236e227 100644
--- a/pages/release-notes/9.5.0.md
+++ b/pages/release-notes/9.5.0.md
@@ -6,7 +6,7 @@ title: "Release 9.5.0"
**Date:** TBD
-Juneau 9.5.0 is a minor release with native TOML and YAML support, BSON
(Binary JSON) support for MongoDB-interoperable binary serialization, CBOR
(Concise Binary Object Representation) per RFC 8949 for IoT and constrained
environments, full CSV serializer/parser support, JCS (JSON Canonicalization
Scheme) per RFC 8785 for deterministic hashing and signing, RDF/THRIFT and
RDF/PROTO binary format support, native serialization support for
lazy-evaluated sequence types, large-dataset stream [...]
+Juneau 9.5.0 is a minor release with native TOML and YAML support, BSON
(Binary JSON) support for MongoDB-interoperable binary serialization, CBOR
(Concise Binary Object Representation) per RFC 8949 for IoT and constrained
environments, full CSV serializer/parser support, JCS (JSON Canonicalization
Scheme) per RFC 8785 for deterministic hashing and signing, RDF/THRIFT and
RDF/PROTO binary format support, native serialization support for
lazy-evaluated sequence types, large-dataset stream [...]
### juneau-marshall
@@ -55,6 +55,107 @@ Juneau 9.5.0 is a minor release with native TOML and YAML
support, BSON (Binary
public class Pet { ... }
```
+#### Neutral `MarshalledMap` / `MarshalledList` collections + `Json5Map` /
`Json5List` (TODO-34)
+
+A major refactor of the generic-model collection hierarchy. `JsonMap` /
`JsonList` are no longer the
+single one-size-fits-all generic-model types: they are now
strict-JSON-flavored subclasses of a new
+neutral, marshaller-agnostic base, with JSON5-flavored siblings in
`org.apache.juneau.json5`.
+
+**Behavioral break.** `JsonMap.toString()` and `JsonList.toString()` now
return strict
+[RFC 8259](https://www.rfc-editor.org/rfc/rfc8259) JSON (was JSON5), and their
`(CharSequence)` /
+`(Reader)` constructors and `ofJson(...)` factories now default to
`JsonParser.DEFAULT` (was
+`Json5Parser.DEFAULT`). See the [v9.5 Migration
Guide](/docs/topics/V9.5-migration-guide) for the
+full breakdown and the recommended fix paths.
+
+##### New neutral base in `org.apache.juneau.collections`
+
+- **`MarshalledMap`** (extends `LinkedHashMap<String,Object>`) and
**`MarshalledList`** (extends
+ `LinkedList<Object>`) — neutral base classes with no language coupling.
Their default `toString()`
+ is the inherited `LinkedHashMap` / `LinkedList` form.
+- Carry the full marshaller-agnostic surface: typed accessors (`getInt`,
`getLong`, `getBoolean`,
+ `getString`, `getStringArray`, `getWithDefault`, `findKeyIgnoreCase`,
`find`, etc.), fluent setters
+ (`append`, `appendIf`, `appendIfAbsent`, `appendReverse`, etc.), bean
integration (`cast`,
+ `setBeanSession`, `getMarshallingSession`), `ObjectRest`-driven path
navigation (`getAt`, `putAt`,
+ `postAt`, `deleteAt`), copy-with-filter helpers (`include`, `exclude`,
`keepAll`, `removeAll`),
+ inner-map plumbing (`inner`), nested-collection accessors (`getMap`,
`getList`), and the standard
+ `EMPTY_MAP` / `EMPTY_LIST` / `unmodifiable()` / `modifiable()` family.
+
+##### `JsonMap` / `JsonList` retargeted to strict JSON (breaking)
+
+- `toString()` now returns `Json.of(this)` — strict RFC 8259 JSON (was
`Json5.of(this)`).
+- `(CharSequence)` / `(Reader)` constructors and `ofJson(...)` static
factories now default to
+ `JsonParser.DEFAULT` (was `Json5Parser.DEFAULT`). Bare-constructor calls
that feed JSON5 input
+ (unquoted keys, single-quoted strings) into `new JsonMap(...)` will now
throw `ParseException`.
+- The JSON-specific helpers `toJson()` / `toJson5()` / `toJsonl()` / `toJcs()`
/ `toHjson()` /
+ `toReadableJson5()` stay on `JsonMap` / `JsonList`. **`toJson()` is now the
synonym for
+ `toString()`**, not `toJson5()`.
+
+##### New `Json5Map` / `Json5List` in `org.apache.juneau.json5`
+
+- `Json5Map` (extends `MarshalledMap`) and `Json5List` (extends
`MarshalledList`) carry the JSON5
+ flavor that `JsonMap` / `JsonList` used to carry: `toString()` returns
`Json5.of(this)`,
+ `(CharSequence)` / `(Reader)` constructors default to `Json5Parser.DEFAULT`,
`ofJson5(...)` static
+ factories, JSON5-flavored `putJson5(...)`.
+- These are the drop-in replacement for callers that today rely on
`JsonMap.toString()` producing
+ JSON5 or on `new JsonMap("{unquoted:'json5'}")` parsing JSON5.
+
+##### Parser sessions now produce flavored maps / lists (breaking)
+
+`MarshallingSession` now exposes two `protected` factory hooks —
`newGenericMap()` and
+`newGenericList()` — that control the runtime type of maps / lists created
during parsing into an
+unbound `Object` / `Map<String,Object>` / `Collection<Object>` target. The
base session returns the
+neutral `MarshalledMap` / `MarshalledList`; per-language parser sessions
override to return their
+flavored type:
+
+| Parser | `parse(text, Object.class)` runtime type |
+|---|---|
+| `JsonParser.DEFAULT` | `JsonMap` / `JsonList` (unchanged) |
+| `Json5Parser.DEFAULT` | `Json5Map` / `Json5List` (**new** — used to be
`JsonMap` / `JsonList`) |
+| Any other parser (`XmlParser`, `YamlParser`, `UonParser`,
`UrlEncodingParser`, `MsgPackParser`, `CborParser`, `BsonParser`, `HtmlParser`,
`HoconParser`, `JsonlParser`, `MarkdownParser`, `HjsonParser`, `CsvParser`,
`RdfXmlParser`, etc.) | `MarshalledMap` / `MarshalledList` (**new** — used to
be `JsonMap` / `JsonList`) |
+
+Code that casts the result to `JsonMap` / `JsonList` (or uses `instanceof
JsonMap` / `instanceof
+JsonList`) will throw `ClassCastException` against any non-`JsonParser`
parser. Recommended fixes:
+
+1. **Cast to the matching flavored type** (`Json5Map` / `Json5List`), or
+2. **Cast to the neutral base** (`MarshalledMap` / `MarshalledList`) when
flavor doesn't matter
+ at the call site, or
+3. **Pass an explicit target class** to force the old runtime type:
+ `parser.parse(text, JsonMap.class)`. The hook is only consulted for
`Object` / `Map<String,Object>` /
+ `Collection<Object>` targets; explicit targets always win.
+
+Nested maps / lists inside a parsed structure are also produced through the
hook, so the flavor
+propagates uniformly through the parsed tree.
+
+##### `ResolvingJsonMap` renamed to `ResolvingMarshalledMap`
+
+The SVL-resolving map (which moved into `org.apache.juneau.collections` as
part of TODO-14)
+has been **renamed** to `ResolvingMarshalledMap` and re-parented from
`JsonMap` to the new neutral
+`MarshalledMap` base. SVL resolution is language-agnostic, so the strict-JSON
parent was no longer
+the right shape. Hard rename, no deprecation shim. See the SVL "Package Moves"
table further down
+in this file and the [v9.5 Migration Guide](/docs/topics/V9.5-migration-guide)
for the import update.
+
+##### Migration
+
+The behavioral break around `JsonMap.toString()` / `JsonList.toString()`, the
bare-constructor
+default parser change, and the parser-produced runtime-type change are all
called out in detail in
+the v9.5 migration guide. The short version:
+
+| Old behavior | New behavior | Recommended migration |
+|---|---|---|
+| `JsonMap.toString()` → JSON5 | strict JSON | Use `Json5Map` (or
`Json5.of(map)`) for JSON5 output. |
+| `new JsonMap("{unquoted:'json5'}")` parses JSON5 | parses strict JSON
(throws) | Use `new Json5Map(...)` / `Json5Map.ofJson5(...)`. |
+| `Json5Parser.DEFAULT.parse(s, Object.class)` → `JsonMap` | → `Json5Map` |
Cast to `Json5Map`, or to neutral `MarshalledMap`, or pass `parser.parse(s,
JsonMap.class)`. |
+| Other parsers' `parse(s, Object.class)` → `JsonMap` | → `MarshalledMap` |
Same fix options. |
+| `import org.apache.juneau.collections.ResolvingJsonMap;` | `import
org.apache.juneau.collections.ResolvingMarshalledMap;` | Hard rename; update
imports and any `new ResolvingJsonMap(...)` constructor calls. |
+
+##### Future work (Phase D — not delivered in 9.5)
+
+Per-language flavored `XMap` / `XList` pairs for the remaining marshallers
(`XmlMap` / `XmlList`,
+`YamlMap` / `YamlList`, `UonMap` / `UonList`, `HoconMap` / `HoconList`,
`BsonMap` / `BsonList`,
+`MsgPackMap` / `MsgPackList`, `CborMap` / `CborList`, etc.) are planned as a
follow-on. Until they
+land, parser sessions other than `JsonParserSession` / `Json5ParserSession`
produce the neutral
+`MarshalledMap` / `MarshalledList`.
+
### juneau-commons
### juneau-config
@@ -1212,12 +1313,17 @@ Both marshaller classes were updated to expose the full
static API:
The serialization helper methods on `JsonMap` and `JsonList` have been renamed
from the `asX()` convention
to the `toX()` convention and extended with additional JSON-flavor methods.
+Note: in the same release `JsonMap.toString()` / `JsonList.toString()` were
retargeted from JSON5 to
+strict JSON as part of TODO-34 (see the "Neutral `MarshalledMap` /
`MarshalledList`" section above).
+That means `toJson()` (not `toJson5()`) is now the synonym for `toString()`,
and the rows below have
+been updated to reflect the new mapping.
+
##### `JsonMap`
| New Method | Description |
|---|---|
-| `toJson()` | Serializes to standard JSON (double-quoted keys/strings). |
-| `toJson5()` | Serializes to JSON5 — unquoted keys, single-quoted strings.
Synonym for `toString()`. |
+| `toJson()` | Serializes to strict RFC 8259 JSON (double-quoted
keys/strings). Synonym for `toString()`. |
+| `toJson5()` | Serializes to JSON5 — unquoted keys, single-quoted strings. |
| `toJsonl()` | Serializes to JSON Lines. |
| `toJcs()` | Serializes to Canonical JSON (RFC 8785). |
| `toHjson()` | Serializes to HJSON. |
@@ -1228,8 +1334,8 @@ to the `toX()` convention and extended with additional
JSON-flavor methods.
| New Method | Description |
|---|---|
-| `toJson()` | Serializes to standard JSON. |
-| `toJson5()` | Serializes to JSON5. Synonym for `toString()`. |
+| `toJson()` | Serializes to strict RFC 8259 JSON. Synonym for `toString()`. |
+| `toJson5()` | Serializes to JSON5. |
| `toJsonl()` | Serializes to JSON Lines. |
| `toJcs()` | Serializes to Canonical JSON (RFC 8785). |
| `toHjson()` | Serializes to HJSON. |
@@ -1241,8 +1347,8 @@ The following `asX()` methods have been removed in favor
of their `toX()` equiva
| Removed | Replacement |
|---|---|
-| `asJson()` | `toJson5()` or `toString()` |
-| `asString()` | `toJson5()` |
+| `asJson()` | `toJson()` or `toString()` (now both strict JSON) |
+| `asString()` | `toString()` — but note `toString()` is now strict JSON.
Callers that genuinely want the old JSON5 form should switch to
`Json5Map.toString()` / `Json5List.toString()` (or call `toJson5()` on
`JsonMap` / `JsonList`). |
| `asReadableString()` *(JsonMap only)* | `toReadableJson5()` |
| `asString(WriterSerializer)` | `toString(WriterSerializer)` |
@@ -1462,9 +1568,9 @@ The Simple Variable Language (SVL) engine —
`VarResolver`, `VarResolverSession
|-----|-----|
| `org.apache.juneau.svl.*` | `org.apache.juneau.commons.svl.*` |
| `org.apache.juneau.svl.vars.*` | `org.apache.juneau.commons.svl.vars.*` |
-| `org.apache.juneau.svl.ResolvingJsonMap` |
`org.apache.juneau.collections.ResolvingJsonMap` |
+| `org.apache.juneau.svl.ResolvingJsonMap` |
`org.apache.juneau.collections.ResolvingMarshalledMap` |
-Source code referencing the old packages must update its import statements.
`ResolvingJsonMap` stays in `juneau-marshall` (it still depends on `JsonMap`)
but moves into the existing `org.apache.juneau.collections` package.
+Source code referencing the old packages must update its import statements.
The map has also been renamed to `ResolvingMarshalledMap` and re-parented from
`JsonMap` to the new neutral `MarshalledMap` base (see the TODO-34 entry near
the top of this file) — its SVL-resolution behavior is language-agnostic. Hard
rename; no deprecation shim, so callers must update both the import and any
`new ResolvingJsonMap(...)` constructor calls.
##### `Args` and `ManifestFile` Redesigned and Moved (breaking)
diff --git a/pages/topics/01.02.Marshalling.md
b/pages/topics/01.02.Marshalling.md
index 1c34b375ee..b37af924df 100644
--- a/pages/topics/01.02.Marshalling.md
+++ b/pages/topics/01.02.Marshalling.md
@@ -406,14 +406,16 @@ to generate DOMs in any of the supported languages.
```java
// Create JSON strings from scratch using fluent-style code.
-String myMap = JsonMap.create().append("foo","bar").asJson();
-String myList = JsonList.of("foo", 123, null, jsonObject).asJson();
+String myMap = Json5Map.create().append("foo","bar").toJson5();
+String myList = Json5List.of("foo", 123, null, jsonObject).toJson5();
-// Parse directly from JSON into generic DOMs.
-Map myMap = JsonMap.ofJson("{foo:'bar'}");
-List myList = JsonList.ofJson("['foo',123,null]");
+// Parse directly from JSON5 into generic DOMs.
+Map myMap = Json5Map.ofJson5("{foo:'bar'}");
+List myList = Json5List.ofJson5("['foo',123,null]");
```
+Both pairs sit on top of a new neutral <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledMap.html"
target="_blank">MarshalledMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledList.html"
target="_blank">MarshalledList</a> base introduced in v9.5; <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> carry the strict [...]
+
These classes provide lots of convenience methods including:
- Methods for direct marshalling to/from any of the other supported languages.
diff --git a/pages/topics/02.08.JsonMap.md b/pages/topics/02.08.JsonMap.md
index ec21ba17e6..aaeca5ecb8 100644
--- a/pages/topics/02.08.JsonMap.md
+++ b/pages/topics/02.08.JsonMap.md
@@ -10,13 +10,19 @@ consisting of beans).
If you want to quickly generate JSON/XML/HTML from generic maps/collections,
or parse JSON/XML/HTML into generic
maps/collections, these classes work well.
-These classes extend directly from the following JCF classes:
+:::tip
+In v9.5, `JsonMap` / `JsonList` were re-parented onto a new neutral base — <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledMap.html"
target="_blank">MarshalledMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledList.html"
target="_blank">MarshalledList</a> — which carries all the marshaller-agnostic
surface (typed accessors, fluent setters, `getAt`/`putAt` path navigation, bean
integration, etc.) with no language coupling. `JsonMap` / `JsonList` are no
[...]
+:::
+
+These classes extend the following JCF / Juneau classes:
<tree>
<node-0><java-class><a
href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedHashMap.html"
target="_blank">java.util.LinkedHashMap</a></java-class></node-0>
-<node-1><java-class><a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">org.apache.juneau.collections.JsonMap</a></java-class></node-1>
+<node-1><java-class><a
href="/site/apidocs/org/apache/juneau/collections/MarshalledMap.html"
target="_blank">org.apache.juneau.collections.MarshalledMap</a></java-class></node-1>
+<node-2><java-class><a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">org.apache.juneau.collections.JsonMap</a></java-class></node-2>
<node-0><java-class><a
href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/LinkedList.html"
target="_blank">java.util.LinkedList</a></java-class></node-0>
-<node-1><java-class><a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">org.apache.juneau.collections.JsonList</a></java-class></node-1>
+<node-1><java-class><a
href="/site/apidocs/org/apache/juneau/collections/MarshalledList.html"
target="_blank">org.apache.juneau.collections.MarshalledList</a></java-class></node-1>
+<node-2><java-class><a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">org.apache.juneau.collections.JsonList</a></java-class></node-2>
</tree>
The <a href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> and <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> classes are very similar to the `JSONObject` and
`JSONArray` classes found in other libraries.
@@ -27,7 +33,7 @@ These object can be serialized in one of three ways:
- Using the provided <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html#writeTo(java.io.Writer)"
target="_blank">JsonMap.writeTo(java.io.Writer)</a> or <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html#writeTo(java.io.Writer)"
target="_blank">JsonList.writeTo(java.io.Writer)</a> methods.
- Passing them to one of the <a
href="/site/apidocs/org/apache/juneau/serializer/Serializer.html"
target="_blank">Serializer</a> serialize methods.
-- Simply calling the <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html#asJson()"
target="_blank">JsonMap.asJson()</a>/<a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html#toString()"
target="_blank">JsonMap.toString()</a> or <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html#asString()"
target="_blank">JsonList.asString()</a>/<a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html#toString()"
target="_blank">JsonList.toString()</a> [...]
+- Simply calling the <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html#toString()"
target="_blank">JsonMap.toString()</a> or <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html#toString()"
target="_blank">JsonList.toString()</a> methods which will serialize it as
strict RFC 8259 JSON. (Use <a
href="/site/apidocs/org/apache/juneau/json5/Json5Map.html"
target="_blank">Json5Map</a> / <a
href="/site/apidocs/org/apache/juneau/json5/Json5List.html" target="_blank [...]
Any valid JSON can be parsed into an unstructured model consisting of generic
<a href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> and <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> objects.
(Any valid XML can also be parsed into an unstructured model)
@@ -47,9 +53,12 @@ json = Json.of(map);
// Or convert it to XML.
String xml = Xml.of(map);
-// Or just use toString() or asJson().
-json = map.toString();
-json = map.asJson();
+// toString() / toJson() return strict RFC 8259 JSON.
+String strict = map.toString(); // {"a":{"name":"John Smith","age":21}, ...}
+String strict2 = map.toJson(); // synonym for toString().
+
+// toJson5() returns the historical unquoted-key / single-quoted-string form.
+String json5 = map.toJson5(); // {a:{name:'John Smith',age:21}, ...}
```
The <a href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> and <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> classes have many convenience features:
@@ -82,6 +91,11 @@ map.inner(anotherMap);
```
:::note
-As a general rule, if you do not specify a target type during parsing, or if
the target type cannot be determined
-through reflection, the parsers automatically generate <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> and <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> objects.
+As a general rule, if you do not specify a target type during parsing, or if
the target type cannot be determined through reflection, the parser generates a
flavored map/list whose runtime type matches the parser:
+
+- <a href="/site/apidocs/org/apache/juneau/json/JsonParser.html"
target="_blank">JsonParser</a> produces <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a>.
+- <a href="/site/apidocs/org/apache/juneau/json5/Json5Parser.html"
target="_blank">Json5Parser</a> produces <a
href="/site/apidocs/org/apache/juneau/json5/Json5Map.html"
target="_blank">Json5Map</a> / <a
href="/site/apidocs/org/apache/juneau/json5/Json5List.html"
target="_blank">Json5List</a>.
+- All other parsers (`XmlParser`, `YamlParser`, `UonParser`, `HoconParser`,
`MsgPackParser`, `CborParser`, `BsonParser`, `HtmlParser`, `JsonlParser`,
`HjsonParser`, `MarkdownParser`, `CsvParser`, RDF parsers, etc.) currently
produce the neutral <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledMap.html"
target="_blank">MarshalledMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledList.html"
target="_blank">MarshalledList</a>.
+
+Callers that need a specific runtime type — for example to keep an explicit
`(JsonMap)` cast working — should pass an explicit target class to the parser,
e.g. `parser.parse(text, JsonMap.class)`. The flavor hook is only consulted for
unbound `Object` / `Map<String,Object>` / `Collection<Object>` targets;
explicit target classes always win.
:::
diff --git a/pages/topics/02.16.ParsingIntoGenericModels.md
b/pages/topics/02.16.ParsingIntoGenericModels.md
index e954f89c10..4dbfff4cdb 100644
--- a/pages/topics/02.16.ParsingIntoGenericModels.md
+++ b/pages/topics/02.16.ParsingIntoGenericModels.md
@@ -12,8 +12,13 @@ The same is true when parsing `collections`.
You can use any `Collection<T>` (e.g. `HashSet<String>`, `LinkedList<MyBean>`)
or array (e.g. `Object[]`, `String[]`, `String[][]`) but using <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> is recommended.
-When the map or list type is not specified, or is the abstract
`Map<String,Object>`, `Collection<Object>`, or `List<Object>` types, the parser
will use
-<a href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> and <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a> by default.
+When the map or list type is not specified, or is the abstract
`Map<String,Object>`, `Collection<Object>`, or `List<Object>` types, the
runtime type the parser creates depends on the parser's flavor:
+
+- <a href="/site/apidocs/org/apache/juneau/json/JsonParser.html"
target="_blank">JsonParser</a> produces <a
href="/site/apidocs/org/apache/juneau/collections/JsonMap.html"
target="_blank">JsonMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/JsonList.html"
target="_blank">JsonList</a>.
+- <a href="/site/apidocs/org/apache/juneau/json5/Json5Parser.html"
target="_blank">Json5Parser</a> produces <a
href="/site/apidocs/org/apache/juneau/json5/Json5Map.html"
target="_blank">Json5Map</a> / <a
href="/site/apidocs/org/apache/juneau/json5/Json5List.html"
target="_blank">Json5List</a>.
+- All other parsers (`XmlParser`, `YamlParser`, `UonParser`, `HoconParser`,
`MsgPackParser`, `CborParser`, `BsonParser`, `HtmlParser`, `JsonlParser`,
`HjsonParser`, `MarkdownParser`, `CsvParser`, RDF parsers, etc.) currently
produce the neutral <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledMap.html"
target="_blank">MarshalledMap</a> / <a
href="/site/apidocs/org/apache/juneau/collections/MarshalledList.html"
target="_blank">MarshalledList</a>.
+
+All three pairs extend the same neutral `MarshalledMap` / `MarshalledList`
base, so the generic-model API shown in the examples below (`getString(...)`,
`getInt(...)`, `getMap(...)`, `getList(...)`, `cast(MyBean.class)`, etc.) works
identically whether the parser handed you a `JsonMap`, a `Json5Map`, or a
`MarshalledMap`. Typing variables as `MarshalledMap` / `MarshalledList` (or as
`Map<String,Object>` / `List<Object>`) keeps callers parser-flavor-agnostic. If
you specifically want the [...]
For example, given the following JSON:
diff --git a/pages/topics/23.01.V9.5-migration-guide.md
b/pages/topics/23.01.V9.5-migration-guide.md
index 5e57bb04d8..81f7add687 100644
--- a/pages/topics/23.01.V9.5-migration-guide.md
+++ b/pages/topics/23.01.V9.5-migration-guide.md
@@ -36,7 +36,7 @@ teams jumping from 9.1 (or earlier) directly to 9.5 have a
single reference.
|-----|-----|-------|
| `org.apache.juneau.svl.*` | `org.apache.juneau.commons.svl.*` | Update
imports for `VarResolver`, `VarResolverSession`, `Var`, and related SVL types. |
| `org.apache.juneau.svl.vars.*` | `org.apache.juneau.commons.svl.vars.*` |
Update imports for `ArgsVar`, `ManifestFileVar`, `SystemPropertiesVar`, etc. |
-| `org.apache.juneau.svl.ResolvingJsonMap` |
`org.apache.juneau.collections.ResolvingJsonMap` | `ResolvingJsonMap` remains
in `juneau-marshall` and now lives in the collections package. |
+| `org.apache.juneau.svl.ResolvingJsonMap` |
`org.apache.juneau.collections.ResolvingMarshalledMap` |
`ResolvingMarshalledMap` (renamed from `ResolvingJsonMap` in TODO-34) remains
in `juneau-marshall` and now lives in the collections package. See the TODO-34
section below for the rename details. |
| `org.apache.juneau.collections.Args` | <a
href="/site/apidocs/org/apache/juneau/commons/runtime/Args.html"
target="_blank">`org.apache.juneau.commons.runtime.Args`</a> | Legacy
`JsonMap`-based type removed. New type is immutable and `Optional`-based. |
| `org.apache.juneau.utils.ManifestFile` | <a
href="/site/apidocs/org/apache/juneau/commons/runtime/ManifestFile.html"
target="_blank">`org.apache.juneau.commons.runtime.ManifestFile`</a> | Legacy
`JsonMap`-based type removed. New type is immutable and `Optional`-based. |
| `Args#getArg(int)` / `getArg(String)` / `getArgs(String)` / `hasArg(String)`
/ `size()` | `Args#get(int)` / `get(String)` / `getAll(String)` / `has(String)`
/ `argCount()+optionCount()` | `get(...)` now returns `Optional<String>`. |
@@ -46,6 +46,25 @@ teams jumping from 9.1 (or earlier) directly to 9.5 have a
single reference.
| `SettingSource` / `SettingStore` / `FunctionalSource` / `FunctionalStore` |
`PropertySource` / `PropertyStore` / `FunctionalPropertySource` /
`FunctionalPropertyStore` | SPI rename for settings/property source
composition. The old types have been removed (no compatibility shims); existing
`Settings` facade remains, migrate custom source/store implementations to the
renamed interfaces. |
| Source-specific SVL lookups (`$S`, `$E`, `$A`, `$MF`, `$C`) as the only
option for property discovery | New unified resolver `$P{key[,default]}` | `$P`
walks the configured `Settings` source hierarchy. Keep source-specific vars
when strict source targeting is required. |
+## MarshalledMap / MarshalledList + Json5Map / Json5List (TODO-34)
+
+The generic-model collection hierarchy has been refactored. `JsonMap` /
`JsonList` are no longer the
+one-size-fits-all generic-model types: they are now strict-JSON-flavored
subclasses of a new
+neutral, marshaller-agnostic base (`MarshalledMap` / `MarshalledList`), with
JSON5-flavored siblings
+(`Json5Map` / `Json5List`) carrying the historical JSON5 behavior. Parser
sessions now produce
+flavored maps / lists based on the parser's language, which changes the
runtime type returned by
+`parser.parse(text, Object.class)` for every parser other than `JsonParser`.
+
+| Old | New | Notes |
+|-----|-----|-------|
+| `JsonMap#toString()` returned JSON5 (via `Json5.of(this)`). | Returns strict
RFC 8259 JSON (via `Json.of(this)`). | Callers that want JSON5 output should
switch to `Json5Map` (or call `Json5.of(map)` explicitly). On `JsonMap` itself,
`toJson5()` still returns JSON5 — only `toString()` changed. |
+| `JsonList#toString()` returned JSON5. | Returns strict JSON. | Same advice —
switch to `Json5List`, or call `Json5.of(list)` / `list.toJson5()`. |
+| `new JsonMap(CharSequence)` / `new JsonMap(Reader)` /
`JsonMap.ofJson(CharSequence)` defaulted to `Json5Parser.DEFAULT`. | Default to
`JsonParser.DEFAULT`. | Callers feeding JSON5-with-unquoted-keys text into the
bare constructor will now throw `ParseException`. Either: (1) switch to `new
Json5Map(CharSequence)` / `Json5Map.ofJson5(...)`, or (2) pass an explicit
`Json5Parser.DEFAULT` to `MarshalledMap.ofText(text, Json5Parser.DEFAULT)`. |
+| `new JsonList(CharSequence)` / `new JsonList(Reader)` /
`JsonList.ofJson(CharSequence)` defaulted to `Json5Parser.DEFAULT`. | Default
to `JsonParser.DEFAULT`. | Same change, same advice — switch to `Json5List` /
`Json5List.ofJson5(...)`, or pass an explicit `Json5Parser.DEFAULT` to
`MarshalledList.ofText(...)`. |
+| `Json5Parser.DEFAULT.parse(s, Object.class)` returned a `JsonMap` (and
nested objects were `JsonMap` / `JsonList`). | Returns a `Json5Map` (and nested
objects are `Json5Map` / `Json5List`). | Same change applies to `parse(s,
Map.class)` / `parse(s, Collection.class)` targets, and to nested maps / lists
inside the parsed tree. Code that casts the result to `JsonMap` will throw
`ClassCastException`. Fix options: (1) cast to `Json5Map` / `Json5List`
instead, (2) cast to the neutral `Marsh [...]
+| Every parser other than `JsonParser` / `Json5Parser` (`XmlParser`,
`YamlParser`, `UonParser`, `UrlEncodingParser`, `HoconParser`, `MsgPackParser`,
`CborParser`, `BsonParser`, `HtmlParser`, `JsonlParser`, `HjsonParser`,
`MarkdownParser`, `CsvParser`, `RdfXmlParser`, etc.) returned `JsonMap` /
`JsonList` from `parse(s, Object.class)`. | Returns the neutral `MarshalledMap`
/ `MarshalledList`. | Same fix options as the `Json5Parser` row above.
Per-language flavored `XMap` / `XList` (e.g. ` [...]
+| `org.apache.juneau.collections.ResolvingJsonMap` |
`org.apache.juneau.collections.ResolvingMarshalledMap` | Renamed AND
re-parented from `JsonMap` to the new neutral `MarshalledMap` base — SVL
resolution is language-agnostic. Hard rename, no deprecation shim. Update the
import and any `new ResolvingJsonMap(...)` constructor calls. |
+
## Bean→Marshalled Renames
### Annotation Renames