This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/main by this push:
     new f5ff1a4a207 CAUSEWAY-3883: converts PluralInvocationHandler to record 
(refactor)
f5ff1a4a207 is described below

commit f5ff1a4a2071cddfa62516096ecdac8f3341f463
Author: Andi Huber <[email protected]>
AuthorDate: Mon Jun 16 20:20:40 2025 +0200

    CAUSEWAY-3883: converts PluralInvocationHandler to record (refactor)
---
 .../runtimeservices/src/main/java/module-info.java |  2 +-
 .../handlers/DomainObjectInvocationHandler.java    | 23 +++++----
 .../wrapper/handlers/PluralInvocationHandler.java  | 55 ++++++++--------------
 .../wrapper/handlers/ProxyGenerator.java           | 14 +++---
 4 files changed, 40 insertions(+), 54 deletions(-)

diff --git a/core/runtimeservices/src/main/java/module-info.java 
b/core/runtimeservices/src/main/java/module-info.java
index f435d98c1ad..c3431651f2f 100644
--- a/core/runtimeservices/src/main/java/module-info.java
+++ b/core/runtimeservices/src/main/java/module-info.java
@@ -61,7 +61,7 @@
     requires jakarta.xml.bind;
     requires jakarta.inject;
     requires static lombok;
-    requires org.apache.causeway.applib;
+    requires transitive org.apache.causeway.applib;
     requires org.apache.causeway.commons;
     requires org.apache.causeway.core.config;
     requires org.apache.causeway.core.interaction;
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
index 6ca432e4feb..3330f3b1aec 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java
@@ -89,22 +89,22 @@ public final class DomainObjectInvocationHandler<T>
     /**
      * The <tt>title()</tt> method; may be <tt>null</tt>.
      */
-    protected Method titleMethod;
+    protected final Method titleMethod;
 
     /**
      * The <tt>__causeway_save()</tt> method from {@link 
WrappingObject#__causeway_save()}.
      */
-    protected Method __causeway_saveMethod;
+    protected final Method __causeway_saveMethod;
 
     /**
      * The <tt>__causeway_wrapped()</tt> method from {@link 
WrappingObject#__causeway_wrapped()}.
      */
-    protected Method __causeway_wrappedMethod;
+    protected final Method __causeway_wrappedMethod;
 
     /**
      * The <tt>__causeway_executionModes()</tt> method from {@link 
WrappingObject#__causeway_executionModes()}.
      */
-    protected Method __causeway_executionModes;
+    protected final Method __causeway_executionModes;
 
     private final EntityFacet entityFacet;
     private final ManagedObject mixeeAdapter;
@@ -123,15 +123,18 @@ public DomainObjectInvocationHandler(
                 syncControl);
         this.proxyGenerator = proxyGenerator;
 
+        var _titleMethod = (Method)null;
         try {
-            titleMethod = context().delegate().getClass().getMethod("title", 
_Constants.emptyClasses);
+            _titleMethod = context().delegate().getClass().getMethod("title", 
_Constants.emptyClasses);
         } catch (final NoSuchMethodException e) {
             // ignore
         }
+        this.titleMethod = _titleMethod;
+        
         try {
-            __causeway_saveMethod = 
WrappingObject.class.getMethod("__causeway_save", _Constants.emptyClasses);
-            __causeway_wrappedMethod = 
WrappingObject.class.getMethod("__causeway_wrapped", _Constants.emptyClasses);
-            __causeway_executionModes = 
WrappingObject.class.getMethod("__causeway_executionModes", 
_Constants.emptyClasses);
+            this.__causeway_saveMethod = 
WrappingObject.class.getMethod("__causeway_save", _Constants.emptyClasses);
+            this.__causeway_wrappedMethod = 
WrappingObject.class.getMethod("__causeway_wrapped", _Constants.emptyClasses);
+            this.__causeway_executionModes = 
WrappingObject.class.getMethod("__causeway_executionModes", 
_Constants.emptyClasses);
 
         } catch (final NoSuchMethodException nsme) {
             throw new IllegalStateException(
@@ -435,7 +438,7 @@ private Collection<?> lookupWrappingObject(
             throw new IllegalStateException("Unable to create proxy for 
collection; "
                     + "proxyContextHandler not provided");
         }
-        return proxyGenerator.collectionProxy(collectionToLookup, this, otma);
+        return proxyGenerator.collectionProxy(collectionToLookup, 
context().syncControl(), otma);
     }
 
     private Map<?, ?> lookupWrappingObject(
@@ -448,7 +451,7 @@ private Collection<?> lookupWrappingObject(
             throw new IllegalStateException("Unable to create proxy for 
collection; "
                     + "proxyContextHandler not provided");
         }
-        return proxyGenerator.mapProxy(mapToLookup, this, otma);
+        return proxyGenerator.mapProxy(mapToLookup, context().syncControl(), 
otma);
     }
 
     private Object handleActionMethod(
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/PluralInvocationHandler.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/PluralInvocationHandler.java
index 17fd445fef6..d49152c35d8 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/PluralInvocationHandler.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/PluralInvocationHandler.java
@@ -22,29 +22,30 @@
 import java.util.Collection;
 import java.util.Map;
 
+import org.apache.causeway.applib.services.wrapper.control.SyncControl;
 import 
org.apache.causeway.applib.services.wrapper.events.CollectionMethodEvent;
 import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.semantics.CollectionSemantics;
 import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.causeway.core.runtime.wrap.WrapperInvocationHandler;
 
-import lombok.Getter;
-import lombok.experimental.Accessors;
-
 /**
- * Base class in support of non-scalar types to be proxied up.
+ * InvocationHandler in support of non-scalar types to be proxied up.
  *
  * @param <T> Domain Object type
  * @param <P> non-scalar type (eg. {@link Collection} or {@link Map}) to be 
proxied
  */
-final class PluralInvocationHandler<T, P>
-implements WrapperInvocationHandler {
+record PluralInvocationHandler<T, P>(
+        WrapperInvocationHandler.Context context,
+        OneToManyAssociation oneToManyAssociation,
+        CollectionSemantics collectionSemantics
+        ) implements WrapperInvocationHandler {
 
     // -- FACTORIES
     
    static <T, C extends Collection<?>> PluralInvocationHandler<T, C> 
forCollection(
            final C collectionToBeProxied,
-           final DomainObjectInvocationHandler<T> handler,
+           final SyncControl syncControl,
            final OneToManyAssociation otma) {
        
        
_Assert.assertTrue(Collection.class.isAssignableFrom(collectionToBeProxied.getClass()),
@@ -52,14 +53,14 @@ static <T, C extends Collection<?>> 
PluralInvocationHandler<T, C> forCollection(
                        PluralInvocationHandler.class.getName() + 
".forCollection(..)",
                        collectionToBeProxied.getClass()));
        
-       return new PluralInvocationHandler<>(collectionToBeProxied, handler, 
otma,
+       return new PluralInvocationHandler<>(collectionToBeProxied, 
syncControl, otma,
                 CollectionSemantics
                     .valueOfElseFail(collectionToBeProxied.getClass()));
     }
     
    static <T, M extends Map<?,?>> PluralInvocationHandler<T, M> forMap(
            final M mapToBeProxied,
-           final DomainObjectInvocationHandler<T> handler,
+           final SyncControl syncControl,
            final OneToManyAssociation otma) {
 
        
_Assert.assertTrue(Map.class.isAssignableFrom(mapToBeProxied.getClass()),
@@ -67,37 +68,21 @@ static <T, M extends Map<?,?>> PluralInvocationHandler<T, 
M> forMap(
                        PluralInvocationHandler.class.getName() + ".forMap(..)",
                        mapToBeProxied.getClass()));
        
-       return new PluralInvocationHandler<>(mapToBeProxied, handler, otma,
+       return new PluralInvocationHandler<>(mapToBeProxied, syncControl, otma,
                CollectionSemantics.MAP);
    }
    
-    // -- CONSTRUCTION
-    
-    @Getter(onMethod_ = {@Override}) @Accessors(fluent=true) 
-    private final WrapperInvocationHandler.Context context;
-    
-    private final OneToManyAssociation oneToManyAssociation;
-    private final CollectionSemantics collectionSemantics;
+    // -- NON CANONICAL CONSTRUCTOR
     
-    protected PluralInvocationHandler(
+    private PluralInvocationHandler(
             final P collectionOrMapToBeProxied,
-            final DomainObjectInvocationHandler<T> handler,
+            final SyncControl syncControl,
             final OneToManyAssociation otma,
             final CollectionSemantics collectionSemantics) {
-
-        this.context = 
WrapperInvocationHandler.Context.of(otma.getMetaModelContext(), 
-                collectionOrMapToBeProxied, handler.context().syncControl());
-
-        this.oneToManyAssociation = otma;
-        this.collectionSemantics = collectionSemantics;
-    }
-
-    public OneToManyAssociation getCollection() {
-        return oneToManyAssociation;
-    }
-
-    public T getDomainObject() {
-        return (T) context().delegate();
+        
+        this(WrapperInvocationHandler.Context.of(otma.getMetaModelContext(), 
+                        collectionOrMapToBeProxied, syncControl), 
+                otma, collectionSemantics);
     }
 
     @Override
@@ -112,8 +97,8 @@ public Object invoke(final Object collectionObject, final 
Method method, final O
             var event =
                     new CollectionMethodEvent(
                             context().delegate(),
-                            getCollection().getFeatureIdentifier(),
-                            getDomainObject(),
+                            oneToManyAssociation().getFeatureIdentifier(),
+                            context().delegate(),
                             method.getName(),
                             args,
                             returnValueObj);
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/ProxyGenerator.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/ProxyGenerator.java
index dda662c6503..a9942fb76ef 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/ProxyGenerator.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/ProxyGenerator.java
@@ -75,11 +75,11 @@ public <T> T mixinProxy(
      */
     public <T, E> Collection<E> collectionProxy(
             final Collection<E> collectionToBeProxied,
-            final DomainObjectInvocationHandler<T> handler,
+            final SyncControl syncControl,
             final OneToManyAssociation otma) {
     
         var collectionInvocationHandler = PluralInvocationHandler
-            .forCollection(collectionToBeProxied, handler, otma);
+            .forCollection(collectionToBeProxied, syncControl, otma);
     
         var proxyBase = CollectionSemantics
             .valueOfElseFail(collectionToBeProxied.getClass())
@@ -93,16 +93,14 @@ public <T, E> Collection<E> collectionProxy(
      * handler.
      */
     public <T, P, Q> Map<P, Q> mapProxy(
-            final Map<P, Q> collectionToBeProxied,
-            final DomainObjectInvocationHandler<T> handler,
+            final Map<P, Q> mapToBeProxied,
+            final SyncControl syncControl,
             final OneToManyAssociation otma) {
     
-        var mapInvocationHandler = PluralInvocationHandler
-            .forMap(collectionToBeProxied, handler, otma);
-    
         var proxyBase = Map.class;
     
-        return instantiateProxy(_Casts.uncheckedCast(proxyBase), 
mapInvocationHandler);
+        return instantiateProxy(_Casts.uncheckedCast(proxyBase), 
PluralInvocationHandler
+            .forMap(mapToBeProxied, syncControl, otma));
     }
     
     // -- HELPER

Reply via email to