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

ahuber pushed a commit to branch 3752-appfeat.filter.spi-a
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/3752-appfeat.filter.spi-a by 
this push:
     new 320e0a0dcb0 CAUSEWAY-3752: more work on invalid vis. contexts
320e0a0dcb0 is described below

commit 320e0a0dcb04013451611bd0e2e6854f3b84bb5b
Author: andi-huber <[email protected]>
AuthorDate: Sun Dec 7 05:32:38 2025 +0100

    CAUSEWAY-3752: more work on invalid vis. contexts
    
    - flattens ObjectValidPropertiesFacetImpl
---
 .../ObjectValidPropertiesFacet.java                |   2 +-
 .../ObjectValidPropertiesFacetAbstract.java        |  46 --------
 .../impl/ObjectValidPropertiesFacetImpl.java       |  76 +++++++------
 .../interactions/vis/ParamVisibilityContext.java   |   2 +-
 .../core/metamodel/spec/ObjectSpecification.java   |  44 ++++----
 .../spec/impl/ObjectSpecificationDefault.java      | 118 +++++++++------------
 .../handlers/DomainObjectInvocationHandler.java    |   3 +-
 7 files changed, 117 insertions(+), 174 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacet.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacet.java
index 8172dcbc059..04d8543e743 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacet.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacet.java
@@ -35,6 +35,6 @@ public interface ObjectValidPropertiesFacet extends Facet, 
ValidatingInteraction
      *
      * <p>If the object is actually valid, should return <tt>null</tt>.
      */
-    public String invalidReason(ObjectValidityContext context);
+    String invalidReason(ObjectValidityContext context);
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacetAbstract.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacetAbstract.java
deleted file mode 100644
index e586b25d253..00000000000
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacetAbstract.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.core.metamodel.facets.object.objectvalidprops;
-
-import org.apache.causeway.core.metamodel.facetapi.Facet;
-import org.apache.causeway.core.metamodel.facetapi.FacetAbstract;
-import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import 
org.apache.causeway.core.metamodel.interactions.val.ObjectValidityContext;
-import org.apache.causeway.core.metamodel.interactions.val.ValidityContext;
-
-public abstract class ObjectValidPropertiesFacetAbstract extends FacetAbstract 
implements ObjectValidPropertiesFacet {
-
-    private static final Class<? extends Facet> type() {
-        return ObjectValidPropertiesFacet.class;
-    }
-
-    public ObjectValidPropertiesFacetAbstract(final FacetHolder holder) {
-        super(type(), holder);
-    }
-
-    @Override
-    public String invalidates(final ValidityContext ic) {
-        if (!(ic instanceof ObjectValidityContext)) {
-            return null;
-        }
-        final ObjectValidityContext validityContext = (ObjectValidityContext) 
ic;
-        return invalidReason(validityContext);
-    }
-
-}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
index c970a26df94..06a82a704f4 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java
@@ -19,50 +19,64 @@
 package org.apache.causeway.core.metamodel.facets.object.objectvalidprops.impl;
 
 import org.apache.causeway.applib.annotation.Where;
+import org.apache.causeway.core.metamodel.facetapi.Facet;
 import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import 
org.apache.causeway.core.metamodel.facets.object.objectvalidprops.ObjectValidPropertiesFacetAbstract;
+import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
+import 
org.apache.causeway.core.metamodel.facets.object.objectvalidprops.ObjectValidPropertiesFacet;
 import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint;
 import 
org.apache.causeway.core.metamodel.interactions.val.ObjectValidityContext;
+import org.apache.causeway.core.metamodel.interactions.val.ValidityContext;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.spec.feature.MixedIn;
 
-public class ObjectValidPropertiesFacetImpl
-extends ObjectValidPropertiesFacetAbstract {
+public record ObjectValidPropertiesFacetImpl(
+               FacetHolder facetHolder)
+implements ObjectValidPropertiesFacet {
 
-    // REVIEW: should provide this rendering context, rather than hardcoding.
-    // the net effect currently is that class members annotated with
-    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will 
indeed
-    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly)
-    // for any other value for Where
-    private final Where where = Where.ANYWHERE;
+    @Override public Class<? extends Facet> facetType() { return 
ObjectValidPropertiesFacet.class; }
+    @Override public Precedence precedence() { return Precedence.DEFAULT; }
 
-    public ObjectValidPropertiesFacetImpl(final FacetHolder holder) {
-        super(holder);
+    @Override
+    public String toString() {
+        return FacetUtil.toString(this);
     }
 
     @Override
-    public String invalidReason(
-            final ObjectValidityContext context) {
-        final StringBuilder buf = new StringBuilder();
-        final ManagedObject adapter = context.target();
+    public String invalidates(final ValidityContext ic) {
+        return (ic instanceof final ObjectValidityContext validityContext)
+               ? invalidReason(validityContext)
+                       : null;
+    }
 
-        var visibilityConstraint = VisibilityConstraint.invalid(where);
+    @Override
+    public String invalidReason(final ObjectValidityContext context) {
+        final ManagedObject mo = context.target();
+        var sb = new StringBuilder();
 
-        adapter.objSpec().streamProperties(MixedIn.EXCLUDED)
-        .filter(property->property.isVisible(adapter, context.initiatedBy(), 
visibilityConstraint).isVetoed()) // ignore hidden properties
-        .filter(property->property.isUsable(adapter, context.initiatedBy(), 
visibilityConstraint).isVetoed())  // ignore disabled properties
-        .forEach(property->{
-            final ManagedObject value = property.get(adapter, 
context.initiatedBy());
-            if (property.isAssociationValid(adapter, value, 
context.initiatedBy()).isVetoed()) {
-                if (buf.length() > 0) {
-                    buf.append(", ");
-                }
-                buf.append(property.getFriendlyName(context::target));
-            }
-        });
-        if (buf.length() > 0)
-                       return "Invalid properties: " + buf.toString();
-        return null;
+        mo.objSpec().streamProperties(MixedIn.EXCLUDED)
+               .filter(property->property.isVisible(mo, context.initiatedBy(), 
VISIBILITY_CONSTRAINT).isVetoed()) // ignore hidden properties
+               .filter(property->property.isUsable(mo, context.initiatedBy(), 
VISIBILITY_CONSTRAINT).isVetoed())  // ignore disabled properties
+               .forEach(property->{
+                   final ManagedObject value = property.get(mo, 
context.initiatedBy());
+                   if (property.isAssociationValid(mo, value, 
context.initiatedBy()).isVetoed()) {
+                       if (sb.length() > 0) {
+                           sb.append(", ");
+                       }
+                       sb.append(property.getFriendlyName(context::target));
+                   }
+               });
+        return (sb.length() > 0)
+                       ? "Invalid properties: " + sb.toString()
+               : null;
     }
 
+    // REVIEW: should provide the rendering context, rather than hardcoding.
+    // The net effect currently is that class members annotated with
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will 
indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly)
+    // for any other value for Where.
+    // However, ultimately we do check, whether the object is valid prior to 
persisting,
+    // I think, this should not be constraint by WhatViewer or Where.
+    private final static VisibilityConstraint VISIBILITY_CONSTRAINT = 
VisibilityConstraint.noViewer(Where.ANYWHERE);
+
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ParamVisibilityContext.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ParamVisibilityContext.java
index 31ebcf36410..f2da555eea0 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ParamVisibilityContext.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ParamVisibilityContext.java
@@ -60,7 +60,7 @@ public ParamVisibilityContext(
             final RenderPolicy renderPolicy) {
 
        // assumption: param visibility is never directly constraint by 
WhatViewer or Where;
-       // instead those constraints apply only to their 'owning' actions
+       // instead those constraints apply only to their 'owning' action
        // in other words, if an action is visible honoring WhatViewer or 
Where, then no further
        // visibility vetos for params are considered based on WhatViewer or 
Where.
         this(InteractionContextType.ACTION_PARAMETER_VISIBLE,
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecification.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecification.java
index 5ef09db0245..9eaa0d7df9a 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecification.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecification.java
@@ -26,6 +26,7 @@
 import java.util.Optional;
 import java.util.stream.Stream;
 
+import org.jspecify.annotations.NonNull;
 import org.jspecify.annotations.Nullable;
 
 import org.apache.causeway.applib.annotation.DomainObject;
@@ -78,7 +79,6 @@
 import 
org.apache.causeway.core.metamodel.spec.feature.ObjectAssociationContainer;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectMember;
 
-import org.jspecify.annotations.NonNull;
 import lombok.experimental.UtilityClass;
 
 /**
@@ -301,24 +301,24 @@ ObjectTitleContext createTitleInteractionContext(
 
     // internal API
     ObjectValidityContext createValidityInteractionContext(
-            final ManagedObject targetAdapter,
-            final InteractionInitiatedBy interactionInitiatedBy);
+            ManagedObject targetAdapter,
+            InteractionInitiatedBy interactionInitiatedBy);
 
     /**
      * Determines whether the specified object is in a valid state (for 
example,
      * so can be persisted); represented as a {@link Consent}.
      */
     Consent isValid(
-            final ManagedObject targetAdapter,
-            final InteractionInitiatedBy interactionInitiatedBy);
+            ManagedObject targetAdapter,
+            InteractionInitiatedBy interactionInitiatedBy);
 
     /**
      * Determines whether the specified object is in a valid state (for 
example,
      * so can be persisted); represented as a {@link InteractionResult}.
      */
     InteractionResult isValidResult(
-            final ManagedObject targetAdapter,
-            final InteractionInitiatedBy interactionInitiatedBy);
+            ManagedObject targetAdapter,
+            InteractionInitiatedBy interactionInitiatedBy);
 
     // -- FACETS
 
@@ -515,14 +515,12 @@ default boolean isEntityOrViewModelOrAbstract() {
      */
     default Object instantiatePojo() {
         final Class<?> correspondingClass = getCorrespondingClass();
-        if (correspondingClass.isArray()) {
-            return Array.newInstance(correspondingClass.getComponentType(), 0);
-        }
+        if (correspondingClass.isArray())
+                       return 
Array.newInstance(correspondingClass.getComponentType(), 0);
 
         final Class<?> cls = correspondingClass;
-        if (Modifier.isAbstract(cls.getModifiers())) {
-            throw new UnrecoverableException("Cannot create an instance of an 
abstract class: " + cls);
-        }
+        if (Modifier.isAbstract(cls.getModifiers()))
+                       throw new UnrecoverableException("Cannot create an 
instance of an abstract class: " + cls);
 
         final Object newInstance;
         try {
@@ -590,9 +588,8 @@ default public void assertPojoCompatible(final @Nullable 
Object pojo) {
     default public boolean isAssignableFrom(final Class<?> actualType) {
         var expectedType = getCorrespondingClass();
         if(expectedType.isAssignableFrom(actualType)
-                || ClassExtensions.equalsWhenBoxing(expectedType, actualType)) 
{
-            return true;
-        }
+                || ClassExtensions.equalsWhenBoxing(expectedType, actualType))
+                       return true;
         return false;
     }
 
@@ -603,9 +600,8 @@ default public boolean isPojoCompatible(final Object pojo) {
         var actualType = pojo.getClass();
 
         if(expectedType.isAssignableFrom(actualType)
-                || ClassExtensions.equalsWhenBoxing(expectedType, actualType)) 
{
-            return true;
-        }
+                || ClassExtensions.equalsWhenBoxing(expectedType, actualType))
+                       return true;
 
         var elementSpec = getElementSpecification()
                 .orElse(this);
@@ -646,12 +642,10 @@ public static ObjectSpecification commonSuperType(
 
         var cls_a = a.getCorrespondingClass();
         var cls_b = b.getCorrespondingClass();
-        if(cls_a.isAssignableFrom(cls_b)) {
-            return a;
-        }
-        if(cls_b.isAssignableFrom(cls_a)) {
-            return b;
-        }
+        if(cls_a.isAssignableFrom(cls_b))
+                       return a;
+        if(cls_b.isAssignableFrom(cls_a))
+                       return b;
         // assuming the algorithm is correct: if non of the above is true,
         // we must be able to walk up the tree on both branches
         _Assert.assertNotNull(a.superclass());
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
index 51319832e4f..f6ecd455d5e 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
@@ -165,7 +165,7 @@ public ObjectSpecificationDefault(
 
         // naturally supports attribute inheritance from the type's hierarchy
         this.introspectionPolicy = 
this.lookupFacet(IntrospectionPolicyFacet.class)
-                
.map(introspectionPolicyFacet->introspectionPolicyFacet.getIntrospectionPolicy())
+                .map(IntrospectionPolicyFacet::getIntrospectionPolicy)
                 
.orElseGet(()->mmc.getConfiguration().core().metaModel().introspector().policy());
 
         this.facetedMethodsBuilder =
@@ -273,13 +273,12 @@ private Stream<ObjectAssociation> createAssociations() {
     }
 
     private ObjectAssociation createAssociation(final FacetedMethod 
facetMethod) {
-        if (facetMethod.featureType().isCollection()) {
-            return OneToManyAssociationDefault.forMethod(facetMethod);
-        } else if (facetMethod.featureType().isProperty()) {
-            return OneToOneAssociationDefault.forMethod(facetMethod);
-        } else {
-            return null;
-        }
+        if (facetMethod.featureType().isCollection())
+                       return 
OneToManyAssociationDefault.forMethod(facetMethod);
+               else if (facetMethod.featureType().isProperty())
+                       return 
OneToOneAssociationDefault.forMethod(facetMethod);
+               else
+                       return null;
     }
 
     private Stream<ObjectAction> createActions() {
@@ -302,9 +301,8 @@ private ObjectAction createAction(final FacetedMethod 
facetedMethod) {
             return this.isMixin()
                     ? ObjectActionDefault.forMixinMain(facetedMethod)
                     : ObjectActionDefault.forMethod(facetedMethod);
-        } else {
-            return null;
-        }
+        } else
+                       return null;
     }
 
     // -- getObjectAction
@@ -375,7 +373,7 @@ private void catalogueActions(final 
BiConsumer<ResolvedMethod, ObjectMember> onM
 
     private final _Lazy<Optional<ObjectSpecification>> elementSpecification =
             _Lazy.threadSafe(()->lookupFacet(TypeOfFacet.class)
-                    .map(typeOfFacet -> typeOfFacet.elementSpec()));
+                    .map(TypeOfFacet::elementSpec));
 
     @Override
     public Optional<ObjectSpecification> getElementSpecification() {
@@ -555,7 +553,7 @@ public final String getFullIdentifier() {
     }
 
     @Override
-    public void introspect(IntrospectionRequest request) {
+    public void introspect(final IntrospectionRequest request) {
         switch (request) {
             case REGISTER -> 
introspectUpTo(IntrospectionState.NOT_INTROSPECTED,
                 ()->"introspect(%s)".formatted(request));
@@ -592,7 +590,7 @@ enum IntrospectionState {
     /**
      * @param introspectionContextProvider keeps track of the causal chain of 
introspection requests
      */
-    private void introspectUpTo(final IntrospectionState upTo, 
Supplier<String> introspectionContextProvider) {
+    private void introspectUpTo(final IntrospectionState upTo, final 
Supplier<String> introspectionContextProvider) {
         if(!isLessThan(upTo)) return; // optimization
 
         if(log.isDebugEnabled()) {
@@ -645,9 +643,8 @@ private boolean isLessThan(final IntrospectionState upTo) {
     }
 
     protected void loadSpecOfSuperclass(final Class<?> superclass) {
-        if (superclass == null) {
-            return;
-        }
+        if (superclass == null)
+                       return;
         superclassSpec = specLoaderInternal().loadSpecification(superclass);
         if (superclassSpec != null) {
             if (log.isDebugEnabled()) {
@@ -803,7 +800,7 @@ public Can<LogicalType> getAliases() {
     // -- ICON
 
     @Override
-    public Optional<ObjectSupport.IconResource> getIcon(final ManagedObject 
domainObject, ObjectSupport.IconSize iconSize) {
+    public Optional<ObjectSupport.IconResource> getIcon(final ManagedObject 
domainObject, final ObjectSupport.IconSize iconSize) {
         if(ManagedObjects.isSpecified(domainObject)) {
             _Assert.assertEquals(domainObject.objSpec(), this);
         }
@@ -849,7 +846,7 @@ public boolean isOfTypeResolvePrimitive(final 
ObjectSpecification other) {
     @Override
     public String getSingularName() {
         return lookupFacet(ObjectNamedFacet.class)
-            .flatMap(textFacet->textFacet.translated())
+            .flatMap(ObjectNamedFacet::translated)
             // unexpected code reach, however keep for JUnit testing
             .orElseGet(()->String.format(
                     "(%s has neither title- nor object-named-facet)",
@@ -920,12 +917,10 @@ private static class NotANoopFacetFilter<Q extends Facet> 
implements Predicate<Q
 
         @Override
         public boolean test(final Q facet) {
-            if(facet==null) {
-                return false;
-            }
-            if(!facet.precedence().isFallback()) {
-                return true;
-            }
+            if(facet==null)
+                               return false;
+            if(!facet.precedence().isFallback())
+                               return true;
             if(noopFacet == null) {
                 noopFacet = facet;
             }
@@ -957,9 +952,8 @@ public Can<ObjectSpecification> interfaces() {
 
     @Override
     public Can<ObjectSpecification> subclasses(final Depth depth) {
-        if (depth == Depth.DIRECT) {
-            return directSubclasses.snapshot();
-        }
+        if (depth == Depth.DIRECT)
+                       return directSubclasses.snapshot();
 
         // depth == Depth.TRANSITIVE)
         if (transitiveSubclasses == null) {
@@ -1061,9 +1055,8 @@ public Stream<ObjectAction> streamDeclaredActions(
      * Creates all mixed in properties and collections for this spec.
      */
     private Stream<ObjectAssociation> createMixedInAssociations() {
-        if (isInjectable() || isValue()) {
-            return Stream.empty();
-        }
+        if (isInjectable() || isValue())
+                       return Stream.empty();
         return getCausewayBeanTypeRegistry().streamMixinTypes()
                 .flatMap(this::createMixedInAssociation);
     }
@@ -1072,17 +1065,14 @@ private Stream<ObjectAssociation> 
createMixedInAssociation(final Class<?> mixinT
         var mixinSpec = specLoaderInternal().loadSpecification(mixinType,
                 IntrospectionRequest.FULL);
         if (mixinSpec == null
-                || mixinSpec == this) {
-            return Stream.empty();
-        }
+                || mixinSpec == this)
+                       return Stream.empty();
         var mixinFacet = mixinSpec.mixinFacet().orElse(null);
-        if(mixinFacet == null) {
-            // this shouldn't happen; to be covered by meta-model validation 
later
+        if(mixinFacet == null)
+                       // this shouldn't happen; to be covered by meta-model 
validation later
             return Stream.empty();
-        }
-        if(!mixinFacet.isMixinFor(getCorrespondingClass())) {
-            return Stream.empty();
-        }
+        if(!mixinFacet.isMixinFor(getCorrespondingClass()))
+                       return Stream.empty();
         var mixinMethodName = mixinFacet.getMainMethodName();
 
         return mixinSpec.streamActions(ActionScope.ANY, MixedIn.EXCLUDED)
@@ -1106,22 +1096,18 @@ private Stream<ObjectActionMixedIn> 
createMixedInAction(final Class<?> mixinType
         var mixinSpec = specLoaderInternal().loadSpecification(mixinType,
                 IntrospectionRequest.FULL);
         if (mixinSpec == null
-                || mixinSpec == this) {
-            return Stream.empty();
-        }
+                || mixinSpec == this)
+                       return Stream.empty();
         var mixinFacet = mixinSpec.mixinFacet().orElse(null);
-        if(mixinFacet == null) {
-            // this shouldn't happen; to be covered by meta-model validation 
later
-            return Stream.empty();
-        }
-        if(!mixinFacet.isMixinFor(getCorrespondingClass())) {
+        if(mixinFacet == null)
+                       // this shouldn't happen; to be covered by meta-model 
validation later
             return Stream.empty();
-        }
+        if(!mixinFacet.isMixinFor(getCorrespondingClass()))
+                       return Stream.empty();
         // don't mixin Object_ mixins to domain services
         if(getBeanSort().isManagedBeanContributing()
-                && mixinFacet.isMixinFor(java.lang.Object.class)) {
-            return Stream.empty();
-        }
+                && mixinFacet.isMixinFor(java.lang.Object.class))
+                       return Stream.empty();
 
         var mixinMethodName = mixinFacet.getMainMethodName();
 
@@ -1152,7 +1138,6 @@ private boolean 
whenIsValueThenIsAlsoConstructorMixin(final ObjectAction act) {
     public Consent isValid(
             final ManagedObject targetAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
-
         return isValidResult(targetAdapter, 
interactionInitiatedBy).createConsent();
     }
 
@@ -1160,9 +1145,7 @@ public Consent isValid(
     public InteractionResult isValidResult(
             final ManagedObject targetAdapter,
             final InteractionInitiatedBy interactionInitiatedBy) {
-        var validityContext =
-                createValidityInteractionContext(
-                        targetAdapter, interactionInitiatedBy);
+        var validityContext = createValidityInteractionContext(targetAdapter, 
interactionInitiatedBy);
         return InteractionUtils.isValidResult(this, validityContext);
     }
 
@@ -1172,7 +1155,8 @@ public InteractionResult isValidResult(
      */
     @Override
     public ObjectValidityContext createValidityInteractionContext(
-            final ManagedObject targetAdapter, final InteractionInitiatedBy 
interactionInitiatedBy) {
+            final ManagedObject targetAdapter,
+            final InteractionInitiatedBy interactionInitiatedBy) {
         return new ObjectValidityContext(targetAdapter, 
getFeatureIdentifier(), interactionInitiatedBy);
     }
 
@@ -1205,14 +1189,12 @@ private void createMixedInActionsAndResort() {
                 || getBeanSort().isManagedBeanContributing()
                 // in support of composite value-type constructor mixins
                 || getBeanSort().isValue();
-        if(!include) {
-            return;
-        }
+        if(!include)
+                       return;
         var mixedInActions = createMixedInActions()
                 .collect(Collectors.toList());
-        if(mixedInActions.isEmpty()) {
-           return; // nothing to do (this spec has no mixed-in actions, 
regular actions have already been added)
-        }
+        if(mixedInActions.isEmpty())
+                       return; // nothing to do (this spec has no mixed-in 
actions, regular actions have already been added)
 
         var regularActions = _Lists.newArrayList(objectActions); // defensive 
copy
 
@@ -1228,14 +1210,12 @@ private void createMixedInActionsAndResort() {
      * one-shot: must be no-op, if already created
      */
     private void createMixedInAssociationsAndResort() {
-        if(!isEntityOrViewModelOrAbstract()) {
-            return;
-        }
+        if(!isEntityOrViewModelOrAbstract())
+                       return;
         var mixedInAssociations = createMixedInAssociations()
                 .collect(Collectors.toList());
-        if(mixedInAssociations.isEmpty()) {
-           return; // nothing to do (this spec has no mixed-in associations, 
regular associations have already been added)
-        }
+        if(mixedInAssociations.isEmpty())
+                       return; // nothing to do (this spec has no mixed-in 
associations, regular associations have already been added)
 
         var regularAssociations = _Lists.newArrayList(associations); // 
defensive copy
 
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 493aeeb256f..fad1f3d6ee8 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
@@ -236,8 +236,9 @@ private Object handleSaveMethod(
             final ObjectSpecification targetNoSpec) {
 
         runValidationTask(wrapperInvocation, ()->{
+               var iConstraint = iConstraint(wrapperInvocation);
             var interactionResult =
-                    targetNoSpec.isValidResult(targetAdapter, 
iConstraint(wrapperInvocation).initiatedBy());
+                    targetNoSpec.isValidResult(targetAdapter, 
iConstraint.initiatedBy());
             notifyListenersAndVetoIfRequired(interactionResult);
         });
 

Reply via email to