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

commit 834c64eca58b1b4162b3337edf89d407dc868dd0
Author: James Bognar <[email protected]>
AuthorDate: Tue May 12 12:09:19 2026 -0400

    refactor: drop MarshallingSession from BeanMap constructor; use 
transitional setter (TODO-5 Step 4)
    
    Co-authored-by: Cursor <[email protected]>
---
 .../src/main/java/org/apache/juneau/BeanMap.java   | 31 +++++++++++++++++-----
 .../java/org/apache/juneau/BeanPropertyMeta.java   | 13 +++++++--
 .../java/org/apache/juneau/MarshallingSession.java |  8 ++++--
 .../apache/juneau/internal/DelegateBeanMap.java    |  3 ++-
 todo/TODO-5-bean-runtime-types-to-commons.md       |  8 +++---
 5 files changed, 49 insertions(+), 14 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
index 24519be464..f3efd25e1d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
@@ -95,24 +95,43 @@ public class BeanMap<T> extends AbstractMap<String,Object> 
implements Delegate<T
 
        /** The BeanMeta associated with the class of the object. */
        protected BeanMeta<T> meta;
-       private final MarshallingSession session;
+       private MarshallingSession session;
 
        private final String typePropertyName;
 
        /**
-        * Instance of this class are instantiated through the 
MarshallingContext class.
+        * Constructor.
+        *
+        * <p>
+        * Bean-modeling-only constructor. Does not carry a {@link 
MarshallingSession} reference.
+        * The marshalling layer wires the session in via {@link 
#setMarshallingSession(MarshallingSession)}
+        * immediately after construction.
         *
-        * @param session The bean session object that created this bean map.
         * @param bean The bean to wrap inside this map.
         * @param meta The metadata associated with the bean class.
         */
-       protected BeanMap(MarshallingSession session, T bean, BeanMeta<T> meta) 
{
-               this.session = session;
+       protected BeanMap(T bean, BeanMeta<T> meta) {
                this.bean = bean;
                this.meta = meta;
                if (ne(meta.getConstructorArgs()))
                        propertyCache = new TreeMap<>();
-               this.typePropertyName = 
session.getBeanTypePropertyName(meta.getClassMeta());
+               this.typePropertyName = meta.getTypePropertyName();
+       }
+
+       /**
+        * Wires this bean map to a {@link MarshallingSession}.
+        *
+        * <p>
+        * Transitional API used by the marshalling layer (e.g. {@link 
MarshallingSession#toBeanMap(Object)})
+        * to wire a session into a {@link BeanMap} immediately after 
construction. Required for any
+        * marshalling-side operation that depends on session-aware behavior 
(type conversion, child
+        * collection construction, etc.). Will be removed when {@link BeanMap} 
is fully decoupled from
+        * the marshalling layer (TODO-5 Step 5+).
+        *
+        * @param value The marshalling session that produced this bean map.
+        */
+       protected void setMarshallingSession(MarshallingSession value) {
+               this.session = value;
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index 8bec99efa8..1c896d48e6 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -1297,7 +1297,7 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                if (o == null)
                        return null;
                if (cm.isBean())
-                       return new BeanMap(session, o, new 
BeanMetaFiltered(cm.getBeanMeta(), properties));
+                       return newBeanMap(session, o, new 
BeanMetaFiltered(cm.getBeanMeta(), properties));
                if (cm.isMap()) {
                        var propsArray = properties == null ? null : 
properties.toArray(new String[0]);
                        return new FilteredKeyMap(cm, (Map)o, propsArray);
@@ -1309,11 +1309,20 @@ public class BeanPropertyMeta implements 
Comparable<BeanPropertyMeta> {
                        }
                        var bm = bc.getBeanMeta(o.getClass());
                        if (nn(bm))
-                               return new BeanMap(session, o, new 
BeanMetaFiltered(cm.getBeanMeta(), properties));
+                               return newBeanMap(session, o, new 
BeanMetaFiltered(cm.getBeanMeta(), properties));
                }
                return o;
        }
 
+       @SuppressWarnings({
+               "unchecked"  // Type erasure requires unchecked cast for 
filtered bean map construction
+       })
+       private static BeanMap newBeanMap(MarshallingSession session, Object o, 
BeanMetaFiltered meta) {
+               var bm = new BeanMap(o, meta);
+               bm.setMarshallingSession(session);
+               return bm;
+       }
+
        @SuppressWarnings({
                "java:S3776" // Cognitive complexity acceptable for inner 
property getter with delegate/swap handling
        })
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingSession.java
index 75cd894bea..15fe991f6d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MarshallingSession.java
@@ -1029,7 +1029,9 @@ public class MarshallingSession extends ContextSession 
implements ConverterSessi
                T bean = null;
                if (e(m.getConstructorArgs()))
                        bean = newBean(outer, c);
-               return new BeanMap<>(this, bean, m);
+               var bm = new BeanMap<>(bean, m);
+               bm.setMarshallingSession(this);
+               return bm;
        }
 
        /**
@@ -1126,7 +1128,9 @@ public class MarshallingSession extends ContextSession 
implements ConverterSessi
                BeanMeta m = cm.getBeanMeta();
                if (m == null)
                        throw bex(c, "Class is not a bean.  Reason=''{0}''", 
cm.getNotABeanReason());
-               return new BeanMap<>(this, o, m);
+               var bm = new BeanMap<>(o, m);
+               bm.setMarshallingSession(this);
+               return bm;
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
index 77e8b33cf8..4f2e776ff1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java
@@ -64,7 +64,8 @@ public class DelegateBeanMap<T> extends BeanMap<T> {
                "unchecked" // Type erasure requires cast for BeanMap creation
        })
        public DelegateBeanMap(T bean, MarshallingSession session) {
-               super(session, bean, 
session.getBeanMeta((Class<T>)bean.getClass()));
+               super(bean, session.getBeanMeta((Class<T>)bean.getClass()));
+               setMarshallingSession(session);
        }
 
        /**
diff --git a/todo/TODO-5-bean-runtime-types-to-commons.md 
b/todo/TODO-5-bean-runtime-types-to-commons.md
index 6cf99c7b34..f42ce844f0 100644
--- a/todo/TODO-5-bean-runtime-types-to-commons.md
+++ b/todo/TODO-5-bean-runtime-types-to-commons.md
@@ -4,14 +4,16 @@ This is the remaining work from **Phase 5 of the bean-layer 
split**. Phase 5a (t
 
 ---
 
-## Status (as of Phase 5c checkpoint)
+## Status (as of Phase 5d checkpoint)
+
+**Step 4 complete.** `BeanMap` no longer takes a `MarshallingSession` in its 
constructor. Picked **Option (c)** (transitional setter) per the plan — 
minimum-disturbance and no behavioral change. The `private final 
MarshallingSession session` field became `private MarshallingSession session` 
(no longer final, defaults to null), the constructor signature dropped to 
`BeanMap(T bean, BeanMeta<T> meta)`, and a new `protected void 
setMarshallingSession(MarshallingSession value)` is called by t [...]
 
 **Step 3 complete.** `BeanPropertyMeta.get`/`set` no longer call 
`ObjectSwap.swap`/`unswap` directly. The class now carries two install-time 
`BiFunction<MarshallingSession,Object,Object>` callbacks 
(`readTransform`/`writeTransform`) that default to identity. `BeanMeta` 
installs swap-aware closures via a new private helper 
`installSwapAwareTransforms(BeanPropertyMeta.Builder)` immediately after 
`Builder.validate()` succeeds (only when `Builder.swap != null` or 
`Builder.rawTypeMeta.hasChil [...]
 
 - [x] **Step 1** — `BeanConfigContext` POJO + builder in `commons.bean`. 
Carries: visibility settings, all `beans*Require*` toggles, 
`findFluentSetters`, `unsortedProperties`, `useInterfaceProxies`, 
`useJavaBeanIntrospector`, `ignoreMissingSetters`, `ignoreTransientFields`, 
`ignoreUnknownBeanProperties`, `propertyNamer`, `beanTypePropertyName`, 
`notBeanPackageNames` / `notBeanPackagePrefixes` / `notBeanClasses`, 
`BeanStore`, `AnnotationProvider`, optional `Predicate<ClassInfo>` override  
[...]
 - [x] **Step 2** — Replaced `ClassMeta` with `ClassInfo` for pure-reflection 
access inside `BeanMeta`. Added a `classInfo` field (a re-typed view of the 
same instance as `classMeta`, since `ClassMeta extends ClassInfoTyped extends 
ClassInfo`) and routed all reflection calls (`inner()`, `isMemberClass()`, 
`isNotStatic()`, `isAnonymousClass()`, `isRecord()`, `isInterface()`, 
`getRecordComponents()`, `getName()`, `getParentsAndInterfaces()`, 
`getPublicConstructors()`, `getDeclaredConstructo [...]
 - [x] **Step 3** — Removed swap-aware `get`/`set` from `BeanPropertyMeta`. 
Picked option (a) (pluggable callbacks). Added 
`BiFunction<MarshallingSession,Object,Object>` `readTransform` / 
`writeTransform` fields with identity defaults; exposed corresponding 
`Builder.readTransform(...)` / `Builder.writeTransform(...)` setters. The 
bean-modeling `get`/`set` paths inside `BeanPropertyMeta` no longer call 
`ObjectSwap.swap` / `ObjectSwap.unswap` directly — instead they invoke the 
installed tra [...]
-- [ ] **Step 4** — Remove `MarshallingSession` back-pointer from `BeanMap`. 
After Step 3, `BeanMap.get/put` are raw property reads/writes; 
`MarshallingSession.toBeanMap` wraps a `BeanMap` for serialization and applies 
swaps externally.
+- [x] **Step 4** — Removed `MarshallingSession` from the `BeanMap` constructor 
signature (Option c — transitional setter). `BeanMap` now exposes 
`setMarshallingSession(MarshallingSession)` that the marshalling layer wires in 
immediately after construction. The `session` field defaults to null on direct 
construction; only `BeanMap.getBean()` (for read-only beans with constructor 
args), `BeanPropertyMeta.add`/`set`, and child-properties-filter operations 
need it set, and they all go throug [...]
 - [ ] **Step 5** — Remove `BeanRegistry` field from `BeanPropertyMeta`. Lift 
dictionary metadata into a marshalling-side companion (`MarshalledPropertyMeta` 
or a side-map keyed by `BeanPropertyMeta`).
 - [ ] **Step 6** — `BeanMeta` becomes constructible by both `ClassMeta` and 
direct `commons.bean` callers via `BeanMeta.of(MyClass.class, 
BeanConfigContext.DEFAULT)`. `ClassMeta` becomes a *consumer* of `BeanMeta` 
rather than its creator.
 - [ ] **Step 7** — Re-check whether `ExtendedBeanMeta` and per-format 
extensions (`XmlBeanMeta`, `RdfBeanMeta`, `HtmlBeanMeta`) need to follow 
`BeanMeta` to `commons.bean`. Default expectation: they stay in 
`juneau-marshall`.
@@ -19,7 +21,7 @@ This is the remaining work from **Phase 5 of the bean-layer 
split**. Phase 5a (t
 - [ ] **Step 9** — Reference sweep: 80–120 unique files (mostly inside 
`juneau-marshall`). Update imports, Javadoc `{@link …}` references, 
package-info docs.
 - [ ] **Step 10** — Update `juneau-docs` release notes / migration guide 
(`docs/pages/release-notes/9.5.0.md`, `## Package Moves` section) with the 
bean-runtime relocations.
 
-The "incomplete-but-documented over broken-build" rule from Phase 5a still 
applies. When picking up the next slice of this work, **Step 4 is the 
recommended next checkpoint** — Step 3 made `BeanPropertyMeta.get`/`set` raw 
(modulo installed callback), so the next blocker is the `MarshallingSession` 
back-pointer carried by `BeanMap` and the parallel swap-application sites 
currently inside `BeanMap` (none today on the read path — `BeanMap.get` just 
delegates to `BeanPropertyMeta.get` — but  [...]
+The "incomplete-but-documented over broken-build" rule from Phase 5a still 
applies. When picking up the next slice of this work, **Step 5 is the 
recommended next checkpoint** — Step 4 dropped the constructor coupling but the 
`BeanMap.session` field is still read by `BeanPropertyMeta.add` / 
`BeanPropertyMeta.set` / `applyChildPropertiesFilter` (for `convertToType` / 
`JsonList(session)` / `JsonMap(session)` construction) and a transitional 
`BeanMap.getMarshallingSession()` accessor still s [...]
 
 ---
 

Reply via email to