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 b672ab9663b CAUSEWAY-3859: Java record refactoring (part 21)
b672ab9663b is described below

commit b672ab9663bfcdd202593e84cb884863622ae4b8
Author: Andi Huber <[email protected]>
AuthorDate: Wed Feb 19 14:56:31 2025 +0100

    CAUSEWAY-3859: Java record refactoring (part 21)
    
    - validate ActionInteractionHead creation
    - more unused code removal
---
 .../core/metamodel/execution/ActionExecutor.java   |  4 +-
 .../core/metamodel/execution/PropertyModifier.java | 14 ++--
 .../core/metamodel/facets/DomainEventHelper.java   |  6 +-
 .../actions/action/invocation/IdentifierUtil.java  |  2 +-
 .../facets/object/value/CompositeValueUpdater.java |  2 +-
 .../ActionParameterChoicesFacetFromAction.java     |  2 +-
 ...ActionParameterChoicesFacetFromElementType.java |  2 +-
 .../ActionParameterChoicesFacetViaMethod.java      |  2 +-
 .../interactions/ActionArgValidityContext.java     |  2 +-
 .../interactions/ActionValidityContext.java        |  2 +-
 .../metamodel/interactions/InteractionContext.java |  2 +-
 .../metamodel/interactions/InteractionHead.java    | 55 +++++++------
 .../managed/ActionInteractionHead.java             | 90 +++++++---------------
 .../managed/ParameterNegotiationModel.java         |  2 +-
 .../authorization/AuthorizationFacetAbstract.java  |  4 +-
 ...arameterChoicesFacetFromParentedCollection.java |  2 +-
 .../core/metamodel/spec/feature/ObjectAction.java  |  2 +-
 .../metamodel/spec/impl/ObjectActionDefault.java   |  6 +-
 .../metamodel/spec/impl/ObjectActionMixedIn.java   |  4 +-
 .../metamodel/spec/impl/ObjectMemberAbstract.java  |  4 +-
 .../spec/impl/OneToOneAssociationDefault.java      |  2 +-
 .../command/CommandDtoFactoryDefault.java          |  2 +-
 .../executor/MemberExecutorServiceDefault.java     |  9 +--
 .../interaction/InteractionDtoFactoryDefault.java  |  4 +-
 .../facets/TenantedAuthorizationFacetDefault.java  |  2 +-
 25 files changed, 100 insertions(+), 128 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/ActionExecutor.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/ActionExecutor.java
index 650fa2948bb..6b0cbe4f505 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/ActionExecutor.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/ActionExecutor.java
@@ -134,7 +134,7 @@ public Object execute(final ActionInvocation 
currentExecution) {
         // but ... no point in attempting this if no bookmark is yet available.
         // this logic is for symmetry with PropertyModifier, which has a 
scenario where this might occur.
         //
-        var ownerAdapter = head.getOwner();
+        var ownerAdapter = head.owner();
         Optional<Bookmark> ownerBookmarkIfAny = 
ManagedObjects.bookmark(ownerAdapter);
         var ownerHasBookmark = ownerBookmarkIfAny.isPresent();
         if (ownerHasBookmark) {
@@ -213,7 +213,7 @@ private Object invokeMethodElseFromCache(
 
         final Object[] executionParameters = 
MmUnwrapUtils.multipleAsArray(arguments);
         final Object targetPojo = Objects.requireNonNull(
-                MmUnwrapUtils.single(head.getTarget()),
+                MmUnwrapUtils.single(head.target()),
                 ()->"Could not extract pojo, that this invocation is targeted 
at.");
 
         final ActionSemanticsFacet semanticsFacet = 
getFacetHolder().getFacet(ActionSemanticsFacet.class);
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/PropertyModifier.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/PropertyModifier.java
index 34a2443bdc3..600ffebcb5f 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/PropertyModifier.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/PropertyModifier.java
@@ -148,7 +148,7 @@ public Object execute(final PropertyEdit currentExecution) {
         // One way this might occur is if using excel module to populate an 
entity representing each line of the spreadsheet;
         // but the entity will be transient at the point.  But there's 
probably very little value in creating DTOs in such a scenario.
         //
-        var ownerAdapter = head.getOwner();
+        var ownerAdapter = head.owner();
         var ownerHasBookmark = 
ManagedObjects.bookmark(ownerAdapter).isPresent();
 
         if (ownerHasBookmark) {
@@ -160,11 +160,11 @@ public Object execute(final PropertyEdit 
currentExecution) {
         if(!isPostable()) {
             // don't emit domain events
             executeClearOrSetWithoutEvents(newValue);
-            return head.getTarget().getPojo();
+            return head.target().getPojo();
         }
 
         // ... post the executing event
-        var oldValuePojo = 
getterFacet.getAssociationValueAsPojo(head.getTarget(), interactionInitiatedBy);
+        var oldValuePojo = 
getterFacet.getAssociationValueAsPojo(head.target(), interactionInitiatedBy);
         var newValuePojo = MmUnwrapUtils.single(newValue);
 
         var propertyDomainEvent =
@@ -190,7 +190,7 @@ public Object execute(final PropertyEdit currentExecution) {
         executeClearOrSetWithoutEvents(newValueAfterEventPolling);
 
         // reading the actual value from the target object, playing it safe...
-        var actualNewValue = 
getterFacet.getAssociationValueAsPojo(head.getTarget(), interactionInitiatedBy);
+        var actualNewValue = 
getterFacet.getAssociationValueAsPojo(head.target(), interactionInitiatedBy);
         if (!Objects.equals(oldValuePojo, actualNewValue)) {
 
             // ... post the executed event
@@ -204,7 +204,7 @@ public Object execute(final PropertyEdit currentExecution) {
 
         // with action invocations, we inject services in the returned pojo at 
this point.
         // for property sets, though, there's no need, as we're just returning 
the targetPojo itself
-        return head.getTarget().getPojo();
+        return head.target().getPojo();
 
         //
         // REVIEW: the corresponding action has a whole bunch of error 
handling here.
@@ -221,10 +221,10 @@ public Object execute(final PropertyEdit 
currentExecution) {
     public void executeClearOrSetWithoutEvents(final @NonNull ManagedObject 
newValue) {
         if(ManagedObjects.isNullOrUnspecifiedOrEmpty(newValue)) {
             clearFacet.clearProperty(
-                    owningProperty, head.getTarget(), interactionInitiatedBy);
+                    owningProperty, head.target(), interactionInitiatedBy);
         } else {
             setterFacet.setProperty(
-                    owningProperty, head.getTarget(), newValue, 
interactionInitiatedBy);
+                    owningProperty, head.target(), newValue, 
interactionInitiatedBy);
         }
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
index 8c7cc4da446..95b8991c7f3 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/DomainEventHelper.java
@@ -116,7 +116,7 @@ public void postEventForAction(
                 event = existingEvent;
             } else {
                 // all other phases, create a new event
-                final S source = 
uncheckedCast(MmUnwrapUtils.single(head.getTarget()));
+                final S source = 
uncheckedCast(MmUnwrapUtils.single(head.target()));
                 final Object[] arguments = 
MmUnwrapUtils.multipleAsArray(argumentAdapters);
                 final Identifier identifier = 
facetHolder.getFeatureIdentifier();
                 event = newActionDomainEvent(eventType, identifier, source, 
arguments);
@@ -249,7 +249,7 @@ public <S, T> PropertyDomainEvent<S, T> 
postEventForProperty(
             } else {
                 // all other phases, create a new event
 
-                final S source = 
uncheckedCast(MmUnwrapUtils.single(head.getTarget()));
+                final S source = 
uncheckedCast(MmUnwrapUtils.single(head.target()));
                 final Identifier identifier = 
facetHolder.getFeatureIdentifier();
 
                 event = newPropertyDomainEvent(eventType, identifier, source, 
oldValue, newValue);
@@ -340,7 +340,7 @@ public <S, T> CollectionDomainEvent<S, T> 
postEventForCollection(
         try {
             final CollectionDomainEvent<S, T> event;
 
-            final S source = 
uncheckedCast(MmUnwrapUtils.single(head.getTarget()));
+            final S source = 
uncheckedCast(MmUnwrapUtils.single(head.target()));
             final Identifier identifier = facetHolder.getFeatureIdentifier();
             event = newCollectionDomainEvent(eventType, phase, identifier, 
source);
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/IdentifierUtil.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/IdentifierUtil.java
index bb5db3d3487..07804d782b9 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/IdentifierUtil.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/IdentifierUtil.java
@@ -108,7 +108,7 @@ public String logicalMemberIdentifierFor(
                 if (interactionHead instanceof ActionInteractionHead) {
                     ObjectAction objectActionOnMixee =
                             ((ActionInteractionHead) 
interactionHead).getMetaModel();
-                    ObjectSpecification specificationOfMixee = 
interactionHead.getOwner().getSpecification();
+                    ObjectSpecification specificationOfMixee = 
interactionHead.owner().getSpecification();
                     return logicalMemberIdentifierFor(specificationOfMixee, 
objectActionOnMixee);
                 }
             }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/value/CompositeValueUpdater.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/value/CompositeValueUpdater.java
index 0705248f1a1..455bb347aee 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/value/CompositeValueUpdater.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/value/CompositeValueUpdater.java
@@ -116,7 +116,7 @@ private ManagedObject simpleExecute(
 
         var method = methodFacade.asMethodForIntrospection();
         final Object[] executionParameters = 
MmUnwrapUtils.multipleAsArray(parameters);
-        final Object targetPojo = MmUnwrapUtils.single(head.getTarget());
+        final Object targetPojo = MmUnwrapUtils.single(head.target());
         var resultPojo = CanonicalInvoker
                 .invokeWithConvertedArgs(method.method(), targetPojo,
                         methodFacade.getArguments(executionParameters, 
ParameterConverters.DEFAULT));
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromAction.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromAction.java
index bab20c558b0..1ce6b64e7f2 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromAction.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromAction.java
@@ -71,7 +71,7 @@ public Can<ManagedObject> getChoices(
             final Can<ManagedObject> pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        var collectionAsObject = choicesFromCollection.get(head.getOwner(), 
interactionInitiatedBy);
+        var collectionAsObject = choicesFromCollection.get(head.owner(), 
interactionInitiatedBy);
         return 
CollectionFacet.streamAdapters(collectionAsObject).collect(Can.toCan());
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromElementType.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromElementType.java
index db5f153b47b..e72603a4a3e 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromElementType.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/ActionParameterChoicesFacetFromElementType.java
@@ -58,7 +58,7 @@ public Can<ManagedObject> getChoices(
             final ActionInteractionHead head,
             final Can<ManagedObject> pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        return choicesFacet.getChoices(head.getTarget(), 
interactionInitiatedBy);
+        return choicesFacet.getChoices(head.target(), interactionInitiatedBy);
     }
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
index c761c821e13..b66cf424592 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
@@ -73,7 +73,7 @@ public Can<ManagedObject> getChoices(
             final InteractionInitiatedBy interactionInitiatedBy) {
 
         var method = methods.getFirstElseFail();
-        final Object collectionOrArray = 
MmInvokeUtils.invokeAutofit(patConstructor, method, head.getTarget(), 
pendingArgs);
+        final Object collectionOrArray = 
MmInvokeUtils.invokeAutofit(patConstructor, method, head.target(), pendingArgs);
         if (collectionOrArray == null) {
             return Can.empty();
         }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionArgValidityContext.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionArgValidityContext.java
index 41a34d6d8f7..ec53ddc460a 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionArgValidityContext.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionArgValidityContext.java
@@ -53,7 +53,7 @@ public ActionArgValidityContext(
         super(InteractionContextType.ACTION_PROPOSED_ARGUMENT,
                 head,
                 id,
-                
()->objectAction.getParameters().getElseFail(position).getFriendlyName(()->head.getTarget()),
+                
()->objectAction.getParameters().getElseFail(position).getFriendlyName(head::target),
                 interactionInitiatedBy);
         this.objectAction = objectAction;
         this.args = args;
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionValidityContext.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionValidityContext.java
index 860ef3ebdd2..c0e7a6d8231 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionValidityContext.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ActionValidityContext.java
@@ -50,7 +50,7 @@ public ActionValidityContext(
         super(InteractionContextType.ACTION_INVOKE,
                 head,
                 id,
-                ()->objectAction.getFriendlyName(()->head.getTarget()),
+                ()->objectAction.getFriendlyName(head::target),
                 interactionInitiatedBy);
         this.objectAction = objectAction;
         this.args = args;
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionContext.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionContext.java
index 2ee1014c49d..ef8954fe3aa 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionContext.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionContext.java
@@ -117,7 +117,7 @@ protected InteractionContext(
      * The target object that this interaction is associated with.
      */
     public ManagedObject getTarget() {
-        return head.getTarget();
+        return head.target();
     }
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionHead.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionHead.java
index e0b73f220d2..87ebcc2b45f 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionHead.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionHead.java
@@ -21,15 +21,12 @@
 import java.util.Objects;
 import java.util.Optional;
 
+import org.jspecify.annotations.NonNull;
+
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.object.ManagedObjects;
 
-import lombok.AccessLevel;
-import lombok.Getter;
-import org.jspecify.annotations.NonNull;
-import lombok.RequiredArgsConstructor;
-
 /**
  * Model that holds the objects involved with the interaction.
  * That is a tuple of {regular-object, (same) regular-object}
@@ -37,54 +34,64 @@
  * is represented.
  * @since 2.0
  */
-@Getter
-@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
-public class InteractionHead {
+public interface InteractionHead {
     /**
      * The owning object of an interaction.
      */
-    @NonNull private final ManagedObject owner;
+    ManagedObject owner();
 
     /**
      * Typically equal to {@code owner}, except for mixins,
      * where {@code target} is the mixin instance.
      */
-    @NonNull private final ManagedObject target;
+    ManagedObject target();
 
     /** Regular case, when owner equals target. (no mixin) */
     public static InteractionHead regular(final ManagedObject owner) {
-        return InteractionHead.of(owner, owner);
+        return new InteractionHeadRecord(owner, owner);
     }
 
     /** Mixin case, when target is a mixin for the owner. */
     public static InteractionHead mixin(final @NonNull ManagedObject owner, 
final @NonNull ManagedObject target) {
-        return InteractionHead.of(owner, target);
+        return new InteractionHeadRecord(owner, target);
     }
 
     /**
      * as used by the domain event subsystem
      * @return optionally the owner (mixee), based on whether the target is a 
mixin
      */
-    public Optional<ManagedObject> getMixee() {
-        return Objects.equals(getOwner(), getTarget())
+    default Optional<ManagedObject> getMixee() {
+        return Objects.equals(owner(), target())
                 ? Optional.empty()
-                : Optional.of(getOwner());
+                : Optional.of(owner());
     }
 
     // -- HELPER
-
-    /** factory with consistency checks */
-    private static InteractionHead of(final @NonNull ManagedObject owner, 
final @NonNull ManagedObject target) {
-        if(ManagedObjects.isSpecified(owner)
+    
+    /**
+     * Immutable implementation of {@link InteractionHead} with consistency 
checks. 
+     */
+    record InteractionHeadRecord(
+        ManagedObject owner,
+        ManagedObject target) implements InteractionHead {
+       
+        // canonical constructor with consistency checks
+        public InteractionHeadRecord(
+            ManagedObject owner,
+            ManagedObject target) {
+            if(ManagedObjects.isSpecified(owner)
                 && owner.getSpecification().getBeanSort().isMixin()) {
-            throw _Exceptions.unrecoverable("unexpected: owner is a mixin %s", 
owner);
-        }
-        if(ManagedObjects.isSpecified(target)
+                throw _Exceptions.unrecoverable("unexpected: owner is a mixin 
%s", owner);
+            }
+            if(ManagedObjects.isSpecified(target)
                 && target.getSpecification().getBeanSort().isMixin()
                 && target.getPojo()==null) {
-            throw _Exceptions.unrecoverable("target not spec. %s", target);
+                throw _Exceptions.unrecoverable("target not spec. %s", target);
+            }
+            this.owner = owner;
+            this.target = target;
         }
-        return new InteractionHead(owner, target);
+        
     }
 
 }
\ No newline at end of file
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteractionHead.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteractionHead.java
index e7eb6154d1c..7a7f85ca2a7 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteractionHead.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteractionHead.java
@@ -18,35 +18,27 @@
  */
 package org.apache.causeway.core.metamodel.interactions.managed;
 
-import java.util.List;
-
-import org.jspecify.annotations.Nullable;
+import org.jspecify.annotations.NonNull;
 
 import org.apache.causeway.commons.collections.Can;
-import org.apache.causeway.commons.internal.assertions._Assert;
-import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.core.metamodel.interactions.InteractionHead;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 
-import lombok.Getter;
-import org.jspecify.annotations.NonNull;
 import lombok.extern.log4j.Log4j2;
 
 @Log4j2
-public class ActionInteractionHead
-extends InteractionHead
-implements HasMetaModel<ObjectAction> {
-
-    @Getter(onMethod = @__(@Override))
-    @NonNull private final ObjectAction metaModel;
-    @Getter private final MultiselectChoices multiselectChoices;
+public record ActionInteractionHead(
+    @NonNull InteractionHeadRecord interactionHeadRecord,
+    @NonNull ObjectAction objectAction,
+    @NonNull MultiselectChoices multiselectChoices)
+implements InteractionHead, HasMetaModel<ObjectAction> {
 
     public static ActionInteractionHead of(
             final @NonNull ObjectAction objectAction,
             final @NonNull ManagedObject owner,
             final @NonNull ManagedObject target) {
-        return new ActionInteractionHead(objectAction, owner, target, 
Can::empty);
+        return new ActionInteractionHead(new InteractionHeadRecord(owner, 
target), objectAction, Can::empty);
     }
 
     public static ActionInteractionHead of(
@@ -54,53 +46,12 @@ public static ActionInteractionHead of(
             final @NonNull ManagedObject owner,
             final @NonNull ManagedObject target,
             final @NonNull MultiselectChoices multiselectChoices) {
-        return new ActionInteractionHead(objectAction, owner, target, 
multiselectChoices);
-    }
-
-    protected ActionInteractionHead(
-            final @NonNull ObjectAction objectAction,
-            final @NonNull ManagedObject owner,
-            final @NonNull ManagedObject target,
-            final @NonNull MultiselectChoices multiselectChoices) {
-        super(owner, target);
-        this.metaModel = objectAction;
-        this.multiselectChoices = multiselectChoices;
-    }
-
-    /**
-     * Immutable tuple of ManagedObjects, each representing {@code null} and 
each holding
-     * the corresponding parameter's {@code ObjectSpecification}.
-     * <p>
-     * The size of the tuple corresponds to the number of parameters.
-     */
-    public Can<ManagedObject> getEmptyParameterValues() {
-        return getMetaModel().getParameters().stream()
-            .map(objectActionParameter->
-                ManagedObject.empty(objectActionParameter.getElementType()))
-            .collect(Can.toCan());
-    }
-
-    /**
-     * Immutable tuple of ManagedObjects, wrapping the passed in argument 
pojos.
-     * Nulls are allowed as arguments, but the list size must match the 
expected parameter count.
-     * <p>
-     * The size of the tuple corresponds to the number of parameters.
-     * @param pojoArgList - argument pojos
-     */
-    public Can<ManagedObject> getPopulatedParameterValues(final @Nullable 
List<Object> pojoArgList) {
-        var params = getMetaModel().getParameters();
-
-        _Assert.assertEquals(params.size(), _NullSafe.size(pojoArgList));
-
-        if(params.isEmpty()) return Can.empty();
-        
-        return params.zipMap(pojoArgList, (objectActionParameter, argPojo)->
-            ManagedObject.adaptParameter(objectActionParameter, argPojo));
-    }
-
-    public ParameterNegotiationModel emptyModel(final ManagedAction 
managedAction) {
-        return ParameterNegotiationModel.of(managedAction, 
getEmptyParameterValues());
+        return new ActionInteractionHead(new InteractionHeadRecord(owner, 
target), objectAction, multiselectChoices);
     }
+    
+    @Override public ObjectAction getMetaModel() { return objectAction(); }
+    @Override public ManagedObject owner() { return 
interactionHeadRecord.owner(); }
+    @Override public ManagedObject target() { return 
interactionHeadRecord.target(); }
 
     /**
      * See step 1 'Fill in defaults' in
@@ -111,7 +62,7 @@ public ParameterNegotiationModel emptyModel(final 
ManagedAction managedAction) {
     public ParameterNegotiationModel defaults(final ManagedAction 
managedAction) {
 
         // init with empty values
-        var pendingParamModel = ParameterNegotiationModel.of(managedAction, 
getEmptyParameterValues());
+        var pendingParamModel = ParameterNegotiationModel.of(managedAction, 
emptyParameterValues());
 
         // fill in the parameter defaults with a single sweep through all 
default providing methods in order, 
         // updating the pendingParamModel at each iteration
@@ -121,6 +72,21 @@ public ParameterNegotiationModel defaults(final 
ManagedAction managedAction) {
         }
         
         return pendingParamModel;
+    }    
+    
+    // -- HELPER
+
+    /**
+     * Immutable tuple of ManagedObjects, each representing {@code null} and 
each holding
+     * the corresponding parameter's {@code ObjectSpecification}.
+     * <p>
+     * The size of the tuple corresponds to the number of parameters.
+     */
+    private Can<ManagedObject> emptyParameterValues() {
+        return getMetaModel().getParameters().stream()
+            .map(objectActionParameter->
+                ManagedObject.empty(objectActionParameter.getElementType()))
+            .collect(Can.toCan());
     }
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java
index 7a0eedb5fbe..5d1f3e81dcd 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java
@@ -114,7 +114,7 @@ public int getParamCount() {
     }
 
     @NonNull public ManagedObject getActionTarget() {
-        return getHead().getTarget();
+        return getHead().target();
     }
 
     @NonNull public Observable<String> getObservableActionValidation() {
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java
index 7bd10c766db..02807de2b4b 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java
@@ -50,7 +50,7 @@ public AuthorizationFacetAbstract(
     @Override
     public String hides(final VisibilityContext ic) {
 
-        if(ic.getHead().getOwner().getSpecification().isValue()) {
+        if(ic.getHead().owner().getSpecification().isValue()) {
             return null; // never hide value-types
         }
 
@@ -71,7 +71,7 @@ public String hides(final VisibilityContext ic) {
     @Override
     public Optional<VetoReason> disables(final UsabilityContext ic) {
 
-        if(ic.getHead().getOwner().getSpecification().isValue()) {
+        if(ic.getHead().owner().getSpecification().isValue()) {
             return Optional.empty(); // never disable value-types
         }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
index 14522984cc7..cbbeceb59f1 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
@@ -49,7 +49,7 @@ public Can<ManagedObject> getChoices(
             final Can<ManagedObject> pendingArgs,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        var collectionAsObject = coll.get(head.getOwner(), 
interactionInitiatedBy);
+        var collectionAsObject = coll.get(head.owner(), 
interactionInitiatedBy);
         return 
CollectionFacet.streamAdapters(collectionAsObject).collect(Can.toCan());
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
index 107cc59e69c..865dcbd5aca 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
@@ -416,7 +416,7 @@ public static String friendlyNameFor(
                         
.map(mixedInMember->mixedInMember.getFriendlyName(mixeeAdapter.asSupplier()))
                         .orElseThrow(_Exceptions::unexpectedCodeReach);
             }
-            return action.getFriendlyName(head::getOwner);
+            return action.getFriendlyName(head::owner);
         }
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionDefault.java
index a56430c035f..14e449f920c 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionDefault.java
@@ -403,7 +403,7 @@ public ManagedObject executeWithRuleChecking(
             final InteractionInitiatedBy interactionInitiatedBy,
             final Where where) {
 
-        var target = head.getOwner();
+        var target = head.owner();
 
         // see it?
         final Consent visibility = isVisible(target, interactionInitiatedBy, 
where);
@@ -439,7 +439,7 @@ public ManagedObject execute(
         _Assert.assertEquals(this.getParameterCount(), argumentAdapters.size(),
                 "action's parameter count and provided argument count must 
match");
 
-        final ManagedObject owner = head.getOwner();
+        final ManagedObject owner = head.owner();
 
         if(!interactionInitiatedBy.isPassThrough()) {
             setupCommand(head, argumentAdapters);
@@ -531,7 +531,7 @@ public void setupCommand(
             final InteractionHead head,
             final Can<ManagedObject> argumentAdapters) {
 
-        if(head.getOwner().getSpecification().isValue()) {
+        if(head.owner().getSpecification().isValue()) {
             return; // do not record value type mixin actions
         }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionMixedIn.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionMixedIn.java
index 9cc6f3c27a0..7acb87a40a4 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionMixedIn.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionMixedIn.java
@@ -156,9 +156,9 @@ public ManagedObject execute(
             final Can<ManagedObject> argumentAdapters,
             final InteractionInitiatedBy interactionInitiatedBy) {
 
-        final ManagedObject owner = head.getOwner();
+        final ManagedObject owner = head.owner();
         final ManagedObject target = mixinAdapterFor(mixinSpec, owner);
-        _Assert.assertEquals(target.getSpecification(), 
head.getTarget().getSpecification(),
+        _Assert.assertEquals(target.getSpecification(), 
head.target().getSpecification(),
                 "head has the wrong target (should be a mixed-in adapter, but 
is the mixee adapter)");
 
         if(!interactionInitiatedBy.isPassThrough()) {
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectMemberAbstract.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectMemberAbstract.java
index 57bc1aac13f..e6dba6945c9 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectMemberAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectMemberAbstract.java
@@ -121,7 +121,7 @@ public final String getFriendlyName(final 
Supplier<ManagedObject> domainObjectPr
         return namedFacet
             .getSpecialization()
             .fold(  textFacet->textFacet.translated(),
-                    
textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).getTarget()));
+                    
textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).target()));
     }
 
     @Override
@@ -140,7 +140,7 @@ public final Optional<String> getDescription(final 
Supplier<ManagedObject> domai
         .map(MemberDescribedFacet::getSpecialization)
         .map(specialization->specialization
                 .fold(textFacet->textFacet.translated(),
-                      
textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).getTarget())));
+                      
textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).target())));
     }
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationDefault.java
index 2da9edffbc1..2b4e996437c 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationDefault.java
@@ -117,7 +117,7 @@ private ValidityContext createValidateInteractionContext(
                 head,
                 getFeatureIdentifier(),
                 proposedValue,
-                ()->getFriendlyName(head::getTarget),
+                ()->getFriendlyName(head::target),
                 interactionInitiatedBy);
     }
 
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandDtoFactoryDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandDtoFactoryDefault.java
index 143b0472ab5..2b7038483a0 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandDtoFactoryDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandDtoFactoryDefault.java
@@ -173,7 +173,7 @@ private CommandDto asCommandDto(final UUID interactionId, 
final InteractionHead
         dto.setTimestamp(clockService.getClock().nowAsXmlGregorianCalendar());
 
         // transient/detached entities have no bookmark, fail early
-        var bookmark = ManagedObjects.bookmarkElseFail(targetHead.getOwner());
+        var bookmark = ManagedObjects.bookmarkElseFail(targetHead.owner());
         final OidsDto targetOids = CommandDtoUtils.targetsFor(dto);
         targetOids.getOid().add(bookmark.toOidDto());
 
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index c644bb0c5bd..3c634596139 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -161,7 +161,7 @@ private ManagedObject invokeActionInternally(
         var actionId = owningAction.getFeatureIdentifier();
         log.debug("about to invoke action {}", actionId);
 
-        var targetAdapter = head.getTarget();
+        var targetAdapter = head.target();
         var targetPojo = MmUnwrapUtils.single(targetAdapter);
 
         var argumentPojos = argumentAdapters.stream()
@@ -239,7 +239,7 @@ private ManagedObject setOrClearPropertyInternally(
 
         final InteractionHead head = propertyModifier.getHead();
 
-        var domainObject = head.getTarget();
+        var domainObject = head.target();
 
         if(propertyModifier.getInteractionInitiatedBy().isPassThrough()) {
             /* directly access property setter to prevent triggering of domain 
events
@@ -262,7 +262,7 @@ private ManagedObject setOrClearPropertyInternally(
 
         var propertyId = owningProperty.getFeatureIdentifier();
 
-        var targetManagedObject = head.getTarget();
+        var targetManagedObject = head.target();
         var target = MmUnwrapUtils.single(targetManagedObject);
         var argValuePojo = 
MmUnwrapUtils.single(propertyModifier.getNewValue());
 
@@ -292,7 +292,6 @@ private ManagedObject setOrClearPropertyInternally(
         var result = getObjectManager().adapt(targetPojo);
         _Xray.exitInvocation(xrayHandle);
         return result;
-
     }
 
     // -- HELPER
@@ -304,7 +303,7 @@ private Object invokeMethodPassThrough(
             final Can<ManagedObject> arguments) {
 
         final Object[] executionParameters = 
MmUnwrapUtils.multipleAsArray(arguments);
-        final Object targetPojo = MmUnwrapUtils.single(head.getTarget());
+        final Object targetPojo = MmUnwrapUtils.single(head.target());
         return CanonicalInvoker.invoke(methodFacade, targetPojo, 
executionParameters);
     }
 
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
index e66e48a75f9..095a7ad640b 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/interaction/InteractionDtoFactoryDefault.java
@@ -87,7 +87,7 @@ public ActionInvocationDto asActionInvocationDto(
         var interaction = 
interactionProviderProvider.get().currentInteractionElseFail();
         final int nextEventSequence = ((InteractionInternal) 
interaction).getThenIncrementExecutionSequence();
 
-        var owner = head.getOwner();
+        var owner = head.owner();
 
         // transient/detached entities have no bookmark, fail early
         var targetBookmark = ManagedObjects.bookmarkElseFail(owner);
@@ -128,7 +128,7 @@ public PropertyEditDto asPropertyEditDto(
             final InteractionHead interactionHead,
             final ManagedObject newValueAdapterIfAny) {
 
-        ManagedObject targetAdapter = interactionHead.getOwner();
+        ManagedObject targetAdapter = interactionHead.owner();
 
         final Interaction interaction = 
interactionProviderProvider.get().currentInteractionElseFail();
         final int nextEventSequence = ((InteractionInternal) 
interaction).getThenIncrementExecutionSequence();
diff --git 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacetDefault.java
 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacetDefault.java
index 22e32825f77..9e84d1040a1 100644
--- 
a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacetDefault.java
+++ 
b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacetDefault.java
@@ -81,7 +81,7 @@ private Optional<String> evaluate(final EvaluationDispatcher 
evaluationDispatche
             return Optional.empty();
         }
 
-        var domainObject = head.getOwner().getPojo();
+        var domainObject = head.owner().getPojo();
         var userName = userService.currentUserNameElseNobody();
 
         var applicationUser = findApplicationUser(userName);


Reply via email to