From db9e465ae9a6d6a34f5d57fd07d4b66dcc7c0ab0 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:03:19 +0100 Subject: [PATCH 01/25] CAUSEWAY-3752: flattens HiddenObjectFacetViaMethod --- .../facets/all/hide/HiddenFacet.java | 22 -------- .../members/hidden/HiddenFacetAbstract.java | 3 +- .../object/hidden/HiddenInstanceFacet.java | 3 +- .../object/hidden/HiddenObjectFacet.java | 3 +- .../hidden/HiddenObjectFacetAbstract.java | 47 ---------------- .../facets/object/hidden/HiddenTypeFacet.java | 4 +- .../HiddenTypeFacetFromAuthorization.java | 11 +--- .../method/HiddenObjectFacetViaMethod.java | 56 +++++++++---------- 8 files changed, 37 insertions(+), 112 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacetAbstract.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java index ce145305973..f73cd0c2d96 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java @@ -30,28 +30,6 @@ public interface HiddenFacet extends WhereValueFacet, HidingInteractionAdvisor { - public enum Semantics { - - /** regular semantics */ - HIDDEN, - - /** inverted semantics */ - SHOWN; - - public boolean isHidden() { - return this == HIDDEN; - } - - public boolean isShown() { - return this == SHOWN; - } - } - - // default semantics unless inverted - default Semantics getSemantics() { - return Semantics.HIDDEN; - } - // -- PREDICATES static boolean isAlwaysHidden(final @NonNull FacetHolder facetHolder) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java index c3a0fc53ece..64cd86ebedc 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java @@ -55,7 +55,7 @@ private HiddenFacetAbstract(final HiddenFacetAbstract toplevelFacet) { } @Override - public String hides(final VisibilityContext ic) { + public final String hides(final VisibilityContext ic) { return hiddenReason(ic.target(), ic.where()); } @@ -68,7 +68,6 @@ public String hides(final VisibilityContext ic) { @Override public final void visitAttributes(final BiConsumer visitor) { super.visitAttributes(visitor); - visitor.accept("semantics", getSemantics()); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java index 2243cb6948c..d6deefe0265 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; @@ -38,6 +37,6 @@ * @apiNote An unification attempt on HiddenTypeFacet and HiddenObjectFacet into a single, * failed, because both facets must co-exist, where each has veto power (not one overruling the other). */ -public interface HiddenInstanceFacet extends Facet, HidingInteractionAdvisor { +public interface HiddenInstanceFacet extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java index 217a021e1b7..a8a72f838fb 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java @@ -18,11 +18,12 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; -public interface HiddenObjectFacet extends HiddenInstanceFacet { +public interface HiddenObjectFacet extends Facet, HiddenInstanceFacet { /** * Copy this facet to another {@link FacetHolder}. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacetAbstract.java deleted file mode 100644 index cd83642e1a2..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacetAbstract.java +++ /dev/null @@ -1,47 +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.hidden; - -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.vis.VisibilityContext; -import org.apache.causeway.core.metamodel.object.ManagedObject; - -public abstract class HiddenObjectFacetAbstract -extends FacetAbstract -implements HiddenObjectFacet { - - private static final Class type() { - return HiddenObjectFacet.class; - } - - public HiddenObjectFacetAbstract(final FacetHolder holder) { - super(type(), holder); - } - - @Override - public String hides(final VisibilityContext ic) { - final ManagedObject toValidate = ic.target(); - return toValidate != null ? hiddenReason(toValidate) : null; - } - - protected abstract String hiddenReason(ManagedObject toHide); - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java index f05d8e798ed..96d7334cd12 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java @@ -18,6 +18,8 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; -public interface HiddenTypeFacet extends HiddenInstanceFacet { +import org.apache.causeway.core.metamodel.facetapi.Facet; + +public interface HiddenTypeFacet extends Facet, HiddenInstanceFacet { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java index 3245f2a36f5..2a091645fea 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java @@ -29,15 +29,8 @@ public record HiddenTypeFacetFromAuthorization( FacetHolder facetHolder ) implements HiddenTypeFacet { - @Override - public Class facetType() { - return HiddenTypeFacet.class; - } - - @Override - public Precedence precedence() { - return Precedence.HIGH; // facet has final say, don't override; - } + @Override public Class facetType() { return HiddenTypeFacet.class; } + @Override public Precedence precedence() { return Precedence.HIGH; } @Override public String hides(final VisibilityContext vc) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java index 0b3b36ebb7e..37d774d5cc6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java @@ -24,35 +24,33 @@ import org.jspecify.annotations.Nullable; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.HasImperativeAspect; import org.apache.causeway.core.metamodel.facets.ImperativeAspect; import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacetAbstract; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; -import lombok.Getter; -import org.jspecify.annotations.NonNull; +public record HiddenObjectFacetViaMethod( + ImperativeAspect imperativeAspect, + FacetHolder facetHolder + ) implements HiddenObjectFacet, HasImperativeAspect { -public class HiddenObjectFacetViaMethod -extends HiddenObjectFacetAbstract -implements HasImperativeAspect { - - @Getter(onMethod_ = {@Override}) private final @NonNull ImperativeAspect imperativeAspect; - - public static Optional create( - final @Nullable ResolvedMethod methodIfAny, - final FacetHolder holder) { - - return Optional.ofNullable(methodIfAny) - .map(method->ImperativeAspect.singleRegularMethod(method, Intent.CHECK_IF_HIDDEN)) - .map(imperativeAspect->new HiddenObjectFacetViaMethod(imperativeAspect, holder)); - } - - private HiddenObjectFacetViaMethod(final ImperativeAspect imperativeAspect, final FacetHolder holder) { - super(holder); - this.imperativeAspect = imperativeAspect; + public static Optional create( + final @Nullable ResolvedMethod methodIfAny, + final FacetHolder holder) { + + return Optional.ofNullable(methodIfAny) + .map(method->ImperativeAspect.singleRegularMethod(method, Intent.CHECK_IF_HIDDEN)) + .map(imperativeAspect->new HiddenObjectFacetViaMethod(imperativeAspect, holder)); + } + + @Override public Class facetType() { return HiddenObjectFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT;} + + public ImperativeAspect getImperativeAspect() { + return imperativeAspect; } @Override @@ -61,12 +59,6 @@ public String hides(final VisibilityContext ic) { return toValidate != null ? hiddenReason(toValidate) : null; } - @Override - public String hiddenReason(final ManagedObject target) { - final boolean isHidden = imperativeAspect.eval(target, false); - return isHidden ? "Hidden" : null; - } - @Override public HiddenObjectFacetViaMethod copyTo(final FacetHolder holder) { return new HiddenObjectFacetViaMethod(imperativeAspect, holder); @@ -74,7 +66,15 @@ public HiddenObjectFacetViaMethod copyTo(final FacetHolder holder) { @Override public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); + HiddenObjectFacet.super.visitAttributes(visitor); imperativeAspect.visitAttributes(visitor); } + + // -- HELPER + + private String hiddenReason(final ManagedObject target) { + final boolean isHidden = imperativeAspect.eval(target, false); + return isHidden ? "Hidden" : null; + } + } From 2e229403374353769e9a9df1b16bb49a5670e629 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:15:48 +0100 Subject: [PATCH 02/25] CAUSEWAY-3752: adds filter (SPI) --- .../appfeat/ApplicationFeatureFilter.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java b/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java new file mode 100644 index 00000000000..434584a4e83 --- /dev/null +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java @@ -0,0 +1,43 @@ +/* + * 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.applib.services.appfeat; + +/** + * The various viewer implementations will individually honor any filters registered with Spring, + * based on a matching qualifier ('graphql', 'restful', etc.). + * + *

All filters that match a qualifier are consulted until any one rejects the {@link ApplicationFeature}. + * + *

In no filters match a qualifier, all {@link ApplicationFeature} are accepted. + * + * @since 4.0 {@index} + */ +@FunctionalInterface +public interface ApplicationFeatureFilter { + + public final static String GRAPHQL_VIEWER = "graphql"; + public final static String RESTFUL_VIEWER = "restful"; + public final static String WICKET_VIEWER = "wicket"; + + /** + * Whether to include given {@link ApplicationFeature}. + */ + boolean filter(ApplicationFeature feature); + +} From 8517f20c28e4f30214c50338b59db8fd938db247 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:16:16 +0100 Subject: [PATCH 03/25] CAUSEWAY-3752: flattens PrototypeFacetForActionAnnotation --- .../PrototypeFacetForActionAnnotation.java | 36 ++++++++---- .../prototype/PrototypeFacetAbstract.java | 57 ------------------- .../PrototypeFacetAnnotationFactoryTest.java | 3 +- .../prototype/PrototypeFacetAbstractTest.java | 4 +- 4 files changed, 30 insertions(+), 70 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstract.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java index ff3f1ef9dd6..ca232656ea0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java @@ -19,16 +19,21 @@ package org.apache.causeway.core.metamodel.facets.actions.action.prototype; import java.util.Optional; +import java.util.function.BiConsumer; import java.util.function.Supplier; import org.apache.causeway.applib.annotation.Action; import org.apache.causeway.applib.annotation.RestrictTo; import org.apache.causeway.core.config.environment.DeploymentType; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacetAbstract; +import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; +import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -public class PrototypeFacetForActionAnnotation -extends PrototypeFacetAbstract { +public record PrototypeFacetForActionAnnotation( + DeploymentType deploymentType, + FacetHolder facetHolder + ) implements PrototypeFacet { public static Optional create( final Optional actionsIfAny, @@ -36,14 +41,25 @@ public static Optional create( final Supplier lazyDeploymentType) { return actionsIfAny - .map(Action::restrictTo) - .filter(restrictTo -> restrictTo == RestrictTo.PROTOTYPING) - .map(restrictTo -> new PrototypeFacetForActionAnnotation(holder, lazyDeploymentType.get())); - + .map(Action::restrictTo) + .filter(restrictTo -> restrictTo == RestrictTo.PROTOTYPING) + .map(restrictTo -> new PrototypeFacetForActionAnnotation(lazyDeploymentType.get(), holder)); } - private PrototypeFacetForActionAnnotation(final FacetHolder holder, final DeploymentType deploymentType) { - super(holder, deploymentType); - } + @Override public Class facetType() { return PrototypeFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override + public String hides(VisibilityContext ic) { + return deploymentType.isProduction() + ? "Prototyping action not visible in production mode" + : null; + } + + @Override + public void visitAttributes(final BiConsumer visitor) { + PrototypeFacet.super.visitAttributes(visitor); + visitor.accept("deploymentType", deploymentType.name()); + } + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstract.java deleted file mode 100644 index 102fd5c4b03..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstract.java +++ /dev/null @@ -1,57 +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.actions.prototype; - -import java.util.function.BiConsumer; - -import org.apache.causeway.core.config.environment.DeploymentType; -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.vis.VisibilityContext; - -public abstract class PrototypeFacetAbstract -extends FacetAbstract -implements PrototypeFacet { - - private final DeploymentType deploymentType; - - private static final Class type() { - return PrototypeFacet.class; - } - - public PrototypeFacetAbstract(final FacetHolder holder, final DeploymentType deploymentType) { - super(type(), holder); - this.deploymentType = deploymentType; - } - - @Override - public String hides( - final VisibilityContext ic) { - return deploymentType.isProduction() - ? "Prototyping action not visible in production mode" - : null; - } - - @Override - public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); - visitor.accept("deploymentType", deploymentType.name()); - } -} diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java index 63213d0d216..801c09362ee 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java @@ -31,7 +31,6 @@ import org.apache.causeway.core.metamodel.facets.FacetFactory.ProcessMethodContext; import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract; import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacetAbstract; class PrototypeFacetAnnotationFactoryTest extends FacetFactoryTestAbstract { @@ -66,7 +65,7 @@ public void someAction() {} //then final Facet facet = facetedMethod.getFacet(PrototypeFacet.class); assertNotNull(facet); - assertTrue(facet instanceof PrototypeFacetAbstract); + assertTrue(facet instanceof PrototypeFacet); assertNoMethodsRemoved(); }); } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java index 6ad5905f6f7..7b9297e2c69 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java @@ -25,6 +25,7 @@ import org.apache.causeway.core.config.environment.DeploymentType; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.facets.actions.action.prototype.PrototypeFacetForActionAnnotation; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; class PrototypeFacetAbstractTest { @@ -40,7 +41,8 @@ public void allCombinations() throws Exception { protected void givenWhenThen(final DeploymentType deploymentType, final String expected) { // given - final PrototypeFacetAbstract facet = new PrototypeFacetAbstract(mockFacetHolder, deploymentType){}; + var facet = new PrototypeFacetForActionAnnotation( + deploymentType, mockFacetHolder); // when final String reason = facet.hides(mockVisibilityContext); From b1cba84d8f1174b1d517cd4f6788d10a72b0ccbd Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:24:14 +0100 Subject: [PATCH 04/25] CAUSEWAY-3752: converts to record TenantedAuthorizationFacetDefault --- .../TenantedAuthorizationFacetDefault.java | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) 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 d1fba456caf..f0ec0530d44 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 @@ -27,8 +27,8 @@ import org.apache.causeway.applib.services.user.UserService; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; 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.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; @@ -36,32 +36,17 @@ import org.apache.causeway.extensions.secman.applib.user.dom.ApplicationUser; import org.apache.causeway.extensions.secman.applib.user.dom.ApplicationUserRepository; -public class TenantedAuthorizationFacetDefault -extends FacetAbstract -implements TenantedAuthorizationFacet { - - private static Class type() { - return TenantedAuthorizationFacet.class; - } - - private final List evaluators; - private final ApplicationUserRepository applicationUserRepository; - private final UserService userService; - private final Provider queryResultsCacheProvider; - - public TenantedAuthorizationFacetDefault( - final List evaluators, - final ApplicationUserRepository applicationUserRepository, - final Provider queryResultsCacheProvider, - final UserService userService, - final FacetHolder holder) { - super(type(), holder); - this.evaluators = evaluators; - this.applicationUserRepository = applicationUserRepository; - this.queryResultsCacheProvider = queryResultsCacheProvider; - this.userService = userService; - } - +public record TenantedAuthorizationFacetDefault( + List evaluators, + ApplicationUserRepository applicationUserRepository, + Provider queryResultsCacheProvider, + UserService userService, + FacetHolder facetHolder + ) implements TenantedAuthorizationFacet { + + @Override public Class facetType() { return TenantedAuthorizationFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override public String hides(final VisibilityContext ic) { return evaluate(ApplicationTenancyEvaluator::hides, ic.head()) @@ -119,5 +104,10 @@ protected ApplicationUser findApplicationUser(final String userName) { protected ApplicationUser findApplicationUserNoCache(final String userName) { return applicationUserRepository.findByUsername(userName).orElse(null); } + + @Override + public String toString() { + return FacetUtil.toString(this); + } } From 76d23a89211cbb3bba8fdab8379ca999cc0fb9e7 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:34:08 +0100 Subject: [PATCH 05/25] CAUSEWAY-3752: flattens HideForContextFacet(s) --- .../method/HideForContextFacetAbstract.java | 39 ------------------- .../method/HideForContextFacetNone.java | 21 +++++++--- .../method/HideForContextFacetViaMethod.java | 33 +++++++++------- 3 files changed, 33 insertions(+), 60 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetAbstract.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetAbstract.java deleted file mode 100644 index 29d25e5a352..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetAbstract.java +++ /dev/null @@ -1,39 +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.members.hidden.method; - -import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facetapi.FacetAbstract; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; - -public abstract class HideForContextFacetAbstract extends FacetAbstract implements HideForContextFacet { - - private static final Class type() { - return HideForContextFacet.class; - } - - public HideForContextFacetAbstract(final FacetHolder holder) { - super(type(), holder); - } - - public HideForContextFacetAbstract(final FacetHolder holder, final Facet.Precedence precedence) { - super(type(), holder, precedence); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java index b151fe944c6..b9678a672ce 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java @@ -18,15 +18,19 @@ */ package org.apache.causeway.core.metamodel.facets.members.hidden.method; +import org.apache.causeway.commons.collections.Can; +import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.facets.ImperativeFacet; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -public class HideForContextFacetNone -extends HideForContextFacetAbstract { - - public HideForContextFacetNone(final FacetHolder holder) { - super(holder, Precedence.FALLBACK); - } +public record HideForContextFacetNone(FacetHolder facetHolder) +implements HideForContextFacet, ImperativeFacet { + + @Override public Class facetType() { return HideForContextFacet.class; } + @Override public Precedence precedence() { return Precedence.FALLBACK; } + @Override public Intent getIntent() { return Intent.CHECK_IF_HIDDEN;} /** * Always returns null. @@ -36,4 +40,9 @@ public String hides(final VisibilityContext ic) { return null; } + @Override + public Can getMethods() { + return Can.empty(); + } + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java index 89b26eae214..0cd8243d854 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java @@ -23,29 +23,27 @@ import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmInvokeUtils; -import lombok.Getter; -import org.jspecify.annotations.NonNull; +public record HideForContextFacetViaMethod( + Can methods, + FacetHolder facetHolder + ) implements HideForContextFacet, ImperativeFacet { + + @Override public Class facetType() { return HideForContextFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override public Intent getIntent() { return Intent.CHECK_IF_HIDDEN;} -public class HideForContextFacetViaMethod -extends HideForContextFacetAbstract -implements ImperativeFacet { - - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + public Can getMethods() { return methods(); } public HideForContextFacetViaMethod(final ResolvedMethod method, final FacetHolder holder) { - super(holder); - this.methods = ImperativeFacet.singleRegularMethod(method); - } - - @Override - public Intent getIntent() { - return Intent.CHECK_IF_HIDDEN; + this(ImperativeFacet.singleRegularMethod(method), holder); } @Override @@ -60,8 +58,13 @@ public String hides(final VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); + HideForContextFacet.super.visitAttributes(visitor); ImperativeFacet.visitAttributes(this, visitor); } + + @Override + public String toString() { + return FacetUtil.toString(this); + } } From 7e1a221934ac9c433c23be8157752862919fd88a Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:45:37 +0100 Subject: [PATCH 06/25] CAUSEWAY-3752: flattens AuthorizationFacetImpl --- .../AuthorizationFacetAbstract.java | 92 ------------------- .../authorization/AuthorizationFacetImpl.java | 60 +++++++++++- .../AuthorizationPostProcessor.java | 2 +- 3 files changed, 58 insertions(+), 96 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java 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 deleted file mode 100644 index 3754ad7cf3c..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetAbstract.java +++ /dev/null @@ -1,92 +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.postprocessors.allbutparam.authorization; - -import java.util.Optional; - -import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; -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.use.UsabilityContext; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -import org.apache.causeway.core.security.authorization.manager.AuthorizationManager; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public abstract class AuthorizationFacetAbstract -extends FacetAbstract -implements AuthorizationFacet { - - private static final Class type() { - return AuthorizationFacet.class; - } - - private final AuthorizationManager authorizationManager; - - public AuthorizationFacetAbstract( - final FacetHolder holder) { - super(type(), holder); - this.authorizationManager = getAuthorizationManager(); - } - - @Override - public String hides(final VisibilityContext ic) { - - if(ic.head().owner().objSpec().isValue()) { - return null; // never hide value-types - } - - var hides = authorizationManager - .isVisible( - getInteractionService().currentInteractionContextElseFail(), - ic.identifier()) - ? null - : "Not authorized to view"; - - if(hides!=null && log.isDebugEnabled()) { - log.debug("hides[{}] -> {}", ic.identifier(), hides); - } - - return hides; - } - - @Override - public Optional disables(final UsabilityContext ic) { - - if(ic.head().owner().objSpec().isValue()) { - return Optional.empty(); // never disable value-types - } - - var disables = authorizationManager - .isUsable( - getInteractionService().currentInteractionContextElseFail(), - ic.identifier()) - ? null - : AuthorizationFacet.formatNotAuthorizedToEdit(ic.identifier(), getMetaModelContext()); - - if(disables!=null && log.isDebugEnabled()) { - log.debug("disables[{}] -> {}", ic.identifier(), disables); - } - - return Optional.ofNullable(disables).map(VetoReason::unauthorized); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetImpl.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetImpl.java index fc82c0c9ba6..a79efd196b6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetImpl.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacetImpl.java @@ -18,12 +18,66 @@ */ package org.apache.causeway.core.metamodel.postprocessors.allbutparam.authorization; +import java.util.Optional; + +import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; +import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; +import org.apache.causeway.core.security.authorization.manager.AuthorizationManager; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public record AuthorizationFacetImpl( + AuthorizationManager authorizationManager, + FacetHolder facetHolder + ) implements AuthorizationFacet { + + @Override public Class facetType() { return AuthorizationFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + + @Override + public String hides(final VisibilityContext ic) { + + if(ic.head().owner().objSpec().isValue()) { + return null; // never hide value-types + } + + var hides = authorizationManager + .isVisible( + facetHolder.getInteractionService().currentInteractionContextElseFail(), + ic.identifier()) + ? null + : "Not authorized to view"; + + if(hides!=null && log.isDebugEnabled()) { + log.debug("hides[{}] -> {}", ic.identifier(), hides); + } + + return hides; + } + + @Override + public Optional disables(final UsabilityContext ic) { + + if(ic.head().owner().objSpec().isValue()) { + return Optional.empty(); // never disable value-types + } + + var disables = authorizationManager + .isUsable( + facetHolder.getInteractionService().currentInteractionContextElseFail(), + ic.identifier()) + ? null + : AuthorizationFacet.formatNotAuthorizedToEdit(ic.identifier(), facetHolder.getMetaModelContext()); -public class AuthorizationFacetImpl extends AuthorizationFacetAbstract { + if(disables!=null && log.isDebugEnabled()) { + log.debug("disables[{}] -> {}", ic.identifier(), disables); + } - public AuthorizationFacetImpl(final FacetHolder holder) { - super(holder); + return Optional.ofNullable(disables).map(VetoReason::unauthorized); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationPostProcessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationPostProcessor.java index 389dcb4495b..355b1904c8d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationPostProcessor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationPostProcessor.java @@ -57,7 +57,7 @@ public void postProcessCollection(final ObjectSpecification objectSpecification, } private static void addFacet(final FacetHolder facetHolder) { - facetHolder.addFacet(new AuthorizationFacetImpl(facetHolder)); + facetHolder.addFacet(new AuthorizationFacetImpl(facetHolder.getAuthorizationManager(), facetHolder)); } } From 81d05578135c7d50cf8880a58ef9ed16fd26ee87 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 11:56:21 +0100 Subject: [PATCH 07/25] CAUSEWAY-3752: flattens ActionParameterHiddenFacetViaMethod --- .../ActionParameterHiddenFacetAbstract.java | 51 ------------------- .../ActionParameterHiddenFacetViaMethod.java | 43 ++++++++++------ 2 files changed, 27 insertions(+), 67 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacetAbstract.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacetAbstract.java deleted file mode 100644 index 3f4c1677373..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacetAbstract.java +++ /dev/null @@ -1,51 +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.param.hide; - -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.vis.ParamVisibilityContext; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; - -public abstract class ActionParameterHiddenFacetAbstract -extends FacetAbstract -implements ActionParameterHiddenFacet { - - private static final Class type() { - return ActionParameterHiddenFacet.class; - } - - public ActionParameterHiddenFacetAbstract(final FacetHolder holder) { - super(type(), holder); - } - - @Override - public String hides(final VisibilityContext context) { - if (!(context instanceof ParamVisibilityContext)) { - return null; - } - var actionArgVisibilityContext = (ParamVisibilityContext) context; - return isHidden( - actionArgVisibilityContext.target(), - actionArgVisibilityContext.args()) - ? "Hidden" - : null; - } -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java index 1b042af9ba6..504a5fdf23d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -28,33 +30,42 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; -import org.apache.causeway.core.metamodel.facets.param.hide.ActionParameterHiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.param.hide.ActionParameterHiddenFacet; +import org.apache.causeway.core.metamodel.interactions.vis.ParamVisibilityContext; +import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmInvokeUtils; -import lombok.Getter; -import org.jspecify.annotations.NonNull; - -public class ActionParameterHiddenFacetViaMethod -extends ActionParameterHiddenFacetAbstract -implements ImperativeFacet { +public record ActionParameterHiddenFacetViaMethod( + Can methods, + Optional patConstructor, + FacetHolder facetHolder + ) implements ActionParameterHiddenFacet, ImperativeFacet { + + @Override public Class facetType() { return ActionParameterHiddenFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override public Intent getIntent() { return Intent.CHECK_IF_VALID;} - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; - private final @NonNull Optional patConstructor; + public Can getMethods() { return methods(); } public ActionParameterHiddenFacetViaMethod( final ResolvedMethod method, final Optional patConstructor, final FacetHolder holder) { - - super(holder); - this.methods = ImperativeFacet.singleMethod(method, patConstructor); - this.patConstructor = patConstructor; + this(ImperativeFacet.singleMethod(method, patConstructor), patConstructor, holder); } @Override - public Intent getIntent() { - return Intent.CHECK_IF_VALID; + public String hides(final VisibilityContext context) { + if (!(context instanceof ParamVisibilityContext)) { + return null; + } + var actionArgVisibilityContext = (ParamVisibilityContext) context; + return isHidden( + actionArgVisibilityContext.target(), + actionArgVisibilityContext.args()) + ? "Hidden" + : null; } @Override @@ -85,7 +96,7 @@ public boolean semanticEquals(final @NonNull Facet otherFacet) { @Override public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); + ActionParameterHiddenFacet.super.visitAttributes(visitor); ImperativeFacet.visitAttributes(this, visitor); } From e0450b95bb9a12c8d59b790f8fabaf64738979dc Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 12:14:25 +0100 Subject: [PATCH 08/25] CAUSEWAY-3752: removes superfluous interfaces --- .../core/metamodel/facetapi/FacetUtil.java | 18 +++++--- .../facetapi/FacetWithAttributes.java | 17 -------- .../object/hidden/HiddenInstanceFacet.java | 42 ------------------- .../object/hidden/HiddenObjectFacet.java | 3 +- .../facets/object/hidden/HiddenTypeFacet.java | 3 +- .../DisablingInteractionAdvisor.java | 3 +- .../HidingInteractionAdvisor.java | 21 ++++++++-- .../ValidatingInteractionAdvisor.java | 3 +- 8 files changed, 36 insertions(+), 74 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetUtil.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetUtil.java index fd6af2ddcef..02823c588e0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetUtil.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetUtil.java @@ -34,9 +34,9 @@ import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.commons.internal.collections._Lists; import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.DisablingOrEnabling; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.HidingOrShowing; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.Validating; +import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; +import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; +import org.apache.causeway.core.metamodel.interactions.ValidatingInteractionAdvisor; import org.apache.causeway.core.metamodel.util.snapshot.XmlSchema; import lombok.experimental.UtilityClass; @@ -245,9 +245,17 @@ public static void visitAttributes(Facet facet, BiConsumer visit } private String interactionAdvisors(Facet facet, final String delimiter) { - return Stream.of(Validating.class, HidingOrShowing.class, DisablingOrEnabling.class) + return Stream.of( + ValidatingInteractionAdvisor.class, + HidingInteractionAdvisor.class, + DisablingInteractionAdvisor.class) .filter(marker->marker.isAssignableFrom(facet.getClass())) - .map(Class::getSimpleName) + .map(cls->switch(cls.getSimpleName().substring(0, 1)) { + case "V" -> "Validating"; + case "H" -> "HidingOrShowing"; + case "D" -> "DisablingOrEnabling"; + default -> "?"; + }) .collect(Collectors.joining(delimiter)); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetWithAttributes.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetWithAttributes.java index 8b407ca2349..de713a767f6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetWithAttributes.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facetapi/FacetWithAttributes.java @@ -31,22 +31,5 @@ public interface FacetWithAttributes { default void visitAttributes(final BiConsumer visitor) { FacetUtil.visitAttributes((Facet)this, visitor); } - - /** - * Marker interface used within {@link FacetUtil#visitAttributes()}. - */ - public static interface HidingOrShowing { - } - - /** - * Marker interface used within {@link FacetUtil#visitAttributes()}. - */ - public static interface DisablingOrEnabling { - } - /** - * Marker interface used within {@link FacetUtil#visitAttributes()}. - */ - public static interface Validating { - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java deleted file mode 100644 index d6deefe0265..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java +++ /dev/null @@ -1,42 +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.hidden; - -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; -import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; - -/** - * Mechanism for determining whether an object should be hidden. - * - *

Even though all the properties of an object may themselves be visible, there - * could be reasons to hide the object. - * - *

In the standard Apache Causeway Programming Model, typically corresponds to the - * hidden method. - * - * @see HiddenFacet - * @see HiddenObjectFacet - * @see HiddenTypeFacet - * - * @apiNote An unification attempt on HiddenTypeFacet and HiddenObjectFacet into a single, - * failed, because both facets must co-exist, where each has veto power (not one overruling the other). - */ -public interface HiddenInstanceFacet extends HidingInteractionAdvisor { - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java index a8a72f838fb..ea89a1cb040 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java @@ -20,10 +20,11 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; -public interface HiddenObjectFacet extends Facet, HiddenInstanceFacet { +public interface HiddenObjectFacet extends Facet, HidingInteractionAdvisor { /** * Copy this facet to another {@link FacetHolder}. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java index 96d7334cd12..2906447d45c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java @@ -19,7 +19,8 @@ package org.apache.causeway.core.metamodel.facets.object.hidden; import org.apache.causeway.core.metamodel.facetapi.Facet; +import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; -public interface HiddenTypeFacet extends Facet, HiddenInstanceFacet { +public interface HiddenTypeFacet extends Facet, HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java index c7f2440c20c..583ed963cd0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java @@ -21,7 +21,6 @@ import java.util.Optional; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.DisablingOrEnabling; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; /** @@ -32,7 +31,7 @@ * @see HidingInteractionAdvisor */ public interface DisablingInteractionAdvisor -extends InteractionAdvisorFacet, DisablingOrEnabling { +extends InteractionAdvisorFacet { /** * Whether the rule represented by this facet disables the member to which diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java index 37ec3e6e4ed..890c7944578 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java @@ -18,18 +18,31 @@ */ package org.apache.causeway.core.metamodel.interactions; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.HidingOrShowing; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; /** - * Mix-in interface for facets that can advise as to whether a member should be - * hidden. + * Mechanism for determining whether an object or member should be hidden. * + *

Even though all the properties of an object may themselves be visible, there + * could be reasons to hide the object. + * + *

In the standard Apache Causeway Programming Model, typically corresponds to the + * hidden method. + * + * @see HiddenFacet + * @see HiddenObjectFacet + * @see HiddenTypeFacet * @see DisablingInteractionAdvisor * @see ValidatingInteractionAdvisor + * + * @apiNote An unification attempt on HiddenTypeFacet and HiddenObjectFacet into a single, + * failed, because both facets must co-exist, where each has veto power (not one overruling the other). */ public interface HidingInteractionAdvisor -extends InteractionAdvisorFacet, HidingOrShowing { +extends InteractionAdvisorFacet { /** * Whether the rule represented by this facet hides the member to which it diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java index 469505eeab3..082cdf71459 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions; import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.Validating; import org.apache.causeway.core.metamodel.interactions.val.ValidityContext; /** @@ -33,7 +32,7 @@ * @see DisablingInteractionAdvisor * @see HidingInteractionAdvisor */ -public interface ValidatingInteractionAdvisor extends InteractionAdvisorFacet, Validating { +public interface ValidatingInteractionAdvisor extends InteractionAdvisorFacet { /** * Whether the validation represented by this facet passes or fails. From 33008640790b8d61e6c05a4a0d0ecaf9459f8e33 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 12:40:49 +0100 Subject: [PATCH 09/25] CAUSEWAY-3752: more hierarchy cleanup --- .../apache/causeway/commons/io/JaxbUtils.java | 1 - .../causeway/commons/net/DataUriTest.java | 2 - .../metamodel/consent/InteractionAdvisor.java | 39 ----------------- .../actions/prototype/PrototypeFacet.java | 3 +- .../method/DisableForContextFacet.java | 3 +- .../hidden/method/HideForContextFacet.java | 3 +- .../members/navigation/NavigationFacet.java | 3 +- .../object/disabled/DisabledObjectFacet.java | 3 +- .../object/hidden/HiddenObjectFacet.java | 3 +- .../facets/object/hidden/HiddenTypeFacet.java | 3 +- .../disable/ActionParameterDisabledFacet.java | 3 +- .../hide/ActionParameterHiddenFacet.java | 3 +- .../DisablingInteractionAdvisor.java | 4 +- .../HidingInteractionAdvisor.java | 4 +- .../interactions/InteractionAdvisorFacet.java | 43 ------------------- .../ValidatingInteractionAdvisor.java | 4 +- .../authorization/AuthorizationFacet.java | 6 +-- .../consent/InteractionResultTest.java | 37 +++++++++++++--- .../facets/TenantedAuthorizationFacet.java | 3 +- .../attributes/temporal/DateTimeConfig.java | 1 - 20 files changed, 53 insertions(+), 118 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionAdvisorFacet.java diff --git a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java index f8726d3f1d0..ce6c8310f48 100644 --- a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java +++ b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java @@ -24,7 +24,6 @@ import java.io.StringReader; import java.io.StringWriter; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; diff --git a/commons/src/test/java/org/apache/causeway/commons/net/DataUriTest.java b/commons/src/test/java/org/apache/causeway/commons/net/DataUriTest.java index 3fd6f9b17ef..4bfba4e4eec 100644 --- a/commons/src/test/java/org/apache/causeway/commons/net/DataUriTest.java +++ b/commons/src/test/java/org/apache/causeway/commons/net/DataUriTest.java @@ -27,8 +27,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.apache.causeway.commons.net.DataUri; - import lombok.RequiredArgsConstructor; class DataUriTest { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionAdvisor.java index 875c2634771..f5ddfdf5826 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/InteractionAdvisor.java @@ -18,13 +18,7 @@ */ package org.apache.causeway.core.metamodel.consent; -import java.util.function.BiConsumer; - import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.interactions.InteractionAdvisorFacet; - -import org.jspecify.annotations.NonNull; /** * Marker interface for implementations (specifically, {@link Facet}s) that can @@ -34,37 +28,4 @@ */ public interface InteractionAdvisor { - /** - * For testing purposes only. - */ - public static InteractionAdvisor forTesting() { - return new InteractionAdvisorFacet() { - - @Override - public boolean semanticEquals(final @NonNull Facet other) { - return this == other; - } - - @Override - public void visitAttributes(final BiConsumer visitor) { - } - - @Override - public Class facetType() { - return null; - } - - @Override - public FacetHolder facetHolder() { - return null; - } - - @Override - public Precedence precedence() { - return Facet.Precedence.FALLBACK; - } - - }; - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java index cab8fd3ba3a..d0c4abd67cd 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java @@ -18,12 +18,11 @@ */ package org.apache.causeway.core.metamodel.facets.actions.prototype; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; /** * Indicates that the action should only be available in prototype mode. */ -public interface PrototypeFacet extends Facet, HidingInteractionAdvisor { +public interface PrototypeFacet extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacet.java index b05a26680f2..f7b56322e12 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.members.disabled.method; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -30,6 +29,6 @@ * In the standard Apache Causeway Programming Model, corresponds to invoking the * disableXxx support method for the member. */ -public interface DisableForContextFacet extends Facet, DisablingInteractionAdvisor { +public interface DisableForContextFacet extends DisablingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java index 84b495b703e..f4bc5f8ccf9 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.members.hidden.method; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -30,6 +29,6 @@ * In the standard Apache Causeway Programming Model, corresponds to invoking the * hideXxx support method for the member. */ -public interface HideForContextFacet extends Facet, HidingInteractionAdvisor { +public interface HideForContextFacet extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java index 10fc0cc1643..79cb05fa316 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.members.navigation; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; @@ -26,5 +25,5 @@ * Hides object members that would allow navigation to a domain type that is * {@link HiddenTypeFacet hidden} (typically due to security permissions). */ -public interface NavigationFacet extends Facet, HidingInteractionAdvisor { +public interface NavigationFacet extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/DisabledObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/DisabledObjectFacet.java index 395670db73e..370001f3058 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/DisabledObjectFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/DisabledObjectFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.object.disabled; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.object.immutable.ImmutableFacet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; @@ -39,7 +38,7 @@ * @see ImmutableFacet */ public interface DisabledObjectFacet -extends Facet, DisablingInteractionAdvisor { +extends DisablingInteractionAdvisor { /** * Clone this facet onto another {@link FacetHolder}. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java index ea89a1cb040..ab9595c5984 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java @@ -18,13 +18,12 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; -public interface HiddenObjectFacet extends Facet, HidingInteractionAdvisor { +public interface HiddenObjectFacet extends HidingInteractionAdvisor { /** * Copy this facet to another {@link FacetHolder}. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java index 2906447d45c..160ec79b1dd 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java @@ -18,9 +18,8 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; -public interface HiddenTypeFacet extends Facet, HidingInteractionAdvisor { +public interface HiddenTypeFacet extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/ActionParameterDisabledFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/ActionParameterDisabledFacet.java index 9e17a7b44ee..84d71e16308 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/ActionParameterDisabledFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/ActionParameterDisabledFacet.java @@ -22,7 +22,6 @@ import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -33,7 +32,7 @@ * In the standard Apache Causeway Programming Model, corresponds to invoking the * disableNXxx support method for an action. */ -public interface ActionParameterDisabledFacet extends Facet, DisablingInteractionAdvisor { +public interface ActionParameterDisabledFacet extends DisablingInteractionAdvisor { /** * Reason why the parameter is disabled, or Optional.empts() if okay. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java index 9def2099734..cb0ded7b205 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.facets.param.hide; import org.apache.causeway.commons.collections.Can; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -32,7 +31,7 @@ * hideNXxx support method for an action. */ public interface ActionParameterHiddenFacet -extends Facet, HidingInteractionAdvisor { +extends HidingInteractionAdvisor { /** * Whether the parameter is hidden. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java index 583ed963cd0..2620328e176 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java @@ -21,6 +21,8 @@ import java.util.Optional; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; +import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; /** @@ -31,7 +33,7 @@ * @see HidingInteractionAdvisor */ public interface DisablingInteractionAdvisor -extends InteractionAdvisorFacet { +extends InteractionAdvisor, Facet { /** * Whether the rule represented by this facet disables the member to which diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java index 890c7944578..27acff9c1b6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java @@ -18,6 +18,8 @@ */ package org.apache.causeway.core.metamodel.interactions; +import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; @@ -42,7 +44,7 @@ * failed, because both facets must co-exist, where each has veto power (not one overruling the other). */ public interface HidingInteractionAdvisor -extends InteractionAdvisorFacet { +extends InteractionAdvisor, Facet { /** * Whether the rule represented by this facet hides the member to which it diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionAdvisorFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionAdvisorFacet.java deleted file mode 100644 index 8d51bc3d318..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionAdvisorFacet.java +++ /dev/null @@ -1,43 +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.interactions; - -import org.apache.causeway.core.metamodel.consent.Allow; -import org.apache.causeway.core.metamodel.consent.Consent; -import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; -import org.apache.causeway.core.metamodel.consent.Veto; -import org.apache.causeway.core.metamodel.facetapi.Facet; - -/** - * Used by {@link Consent} (specifically the main implementations {@link Allow} - * and {@link Veto}), with the idea being that the only things that can create - * {@link Consent} objects are {@link Facet}s. - * - *

- * TODO: note, this is a work-in-progress, because the DnD viewer in particular - * creates its own {@link Allow}s and {@link Veto}s. The constructors that it - * uses have been deprecated to flag that the DnD logic should move into - * {@link Facet}s that implement this interface. - * - * @author Dan Haywood - * - */ -public interface InteractionAdvisorFacet extends InteractionAdvisor, Facet { - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java index 082cdf71459..33c569418c3 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java @@ -18,6 +18,7 @@ */ package org.apache.causeway.core.metamodel.interactions; +import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.val.ValidityContext; @@ -32,7 +33,8 @@ * @see DisablingInteractionAdvisor * @see HidingInteractionAdvisor */ -public interface ValidatingInteractionAdvisor extends InteractionAdvisorFacet { +public interface ValidatingInteractionAdvisor +extends InteractionAdvisor, Facet { /** * Whether the validation represented by this facet passes or fails. diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java index b847f3f8671..beb035cb80d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java @@ -18,12 +18,12 @@ */ package org.apache.causeway.core.metamodel.postprocessors.allbutparam.authorization; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants; import org.apache.causeway.core.metamodel.context.MetaModelContext; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; import org.apache.causeway.core.metamodel.interactions.vis.ActionVisibilityContext; @@ -34,14 +34,12 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation; import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; -import org.jspecify.annotations.NonNull; - /** * Optionally hide or disable an object, property, collection or action * depending on the authorization. */ public interface AuthorizationFacet -extends Facet, HidingInteractionAdvisor, DisablingInteractionAdvisor { +extends HidingInteractionAdvisor, DisablingInteractionAdvisor { public static boolean hidesProperty( final @NonNull OneToOneAssociation property, diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/consent/InteractionResultTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/consent/InteractionResultTest.java index 7c10916fd76..ba40bce73d3 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/consent/InteractionResultTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/consent/InteractionResultTest.java @@ -18,6 +18,9 @@ */ package org.apache.causeway.core.metamodel.consent; +import java.util.function.BiConsumer; + +import org.jspecify.annotations.NonNull; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -28,11 +31,35 @@ import org.apache.causeway.applib.services.wrapper.events.InteractionEvent; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; +import org.apache.causeway.core.metamodel.facetapi.Facet; class InteractionResultTest { private InteractionResult.Builder builder = InteractionResult.builder(Mockito.mock(InteractionEvent.class)); + private static interface InteractionAdvisorFacet + extends InteractionAdvisor, Facet { + } + + public static InteractionAdvisor interactionAdvisor() { + return new InteractionAdvisorFacet() { + @Override public boolean semanticEquals(final @NonNull Facet other) { + return this == other; + } + @Override public void visitAttributes(final BiConsumer visitor) { + } + @Override public Class facetType() { + return null; + } + @Override public org.apache.causeway.core.metamodel.facetapi.FacetHolder facetHolder() { + return null; + } + @Override public Precedence precedence() { + return Facet.Precedence.FALLBACK; + } + }; + } + @Test void shouldHaveNullReasonWhenJustInstantiated() { var result = builder.build(); @@ -48,22 +75,22 @@ void shouldBeEmptyWhenJustInstantiated() { @Test void shouldHaveNonNullReasonWhenAdvisedWithNonNull() { - advise(vetoReason("foo"), InteractionAdvisor.forTesting()); + advise(vetoReason("foo"), interactionAdvisor()); var result = builder.build(); assertEquals("foo", extractReason(result)); } @Test void shouldConcatenateAdviseWhenAdvisedWithNonNull() { - advise(vetoReason("foo"), InteractionAdvisor.forTesting()); - advise(vetoReason("bar"), InteractionAdvisor.forTesting()); + advise(vetoReason("foo"), interactionAdvisor()); + advise(vetoReason("bar"), interactionAdvisor()); var result = builder.build(); assertEquals("foo; bar", extractReason(result)); } @Test void shouldNotBeEmptyWhenAdvisedWithNonNull() { - advise(vetoReason("foo"), InteractionAdvisor.forTesting()); + advise(vetoReason("foo"), interactionAdvisor()); var result = builder.build(); assertTrue(result.isVetoing()); assertFalse(result.isAllowing()); @@ -71,7 +98,7 @@ void shouldNotBeEmptyWhenAdvisedWithNonNull() { @Test void shouldThrowWhenAdvisedWithNull() { - assertThrowsExactly(NullPointerException.class, ()->advise(null, InteractionAdvisor.forTesting())); + assertThrowsExactly(NullPointerException.class, ()->advise(null, interactionAdvisor())); assertThrowsExactly(NullPointerException.class, ()->advise(vetoReason("foo"), null)); } diff --git a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacet.java b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacet.java index 4a58b04e15c..9cfc85ffd2c 100644 --- a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacet.java +++ b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/facets/TenantedAuthorizationFacet.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.extensions.secman.integration.facets; -import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; @@ -27,7 +26,7 @@ * depending on the tenancy. */ public interface TenantedAuthorizationFacet -extends Facet, HidingInteractionAdvisor, DisablingInteractionAdvisor { +extends HidingInteractionAdvisor, DisablingInteractionAdvisor { @Override public default boolean isObjectTypeSpecific() { diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/temporal/DateTimeConfig.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/temporal/DateTimeConfig.java index afc7d3ede74..0ae95a9708d 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/temporal/DateTimeConfig.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/attributes/temporal/DateTimeConfig.java @@ -18,7 +18,6 @@ */ package org.apache.causeway.viewer.wicket.ui.components.attributes.temporal; -import java.io.IOException; import java.util.Locale; import java.util.Map; From eb035462ccb4bd67dffa5884befcddbf35ce2664 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 12:45:22 +0100 Subject: [PATCH 10/25] CAUSEWAY-3752: converts to record NavigationFacetFromHiddenType --- .../NavigationFacetFromHiddenType.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java index cd6874af027..4453d8a3671 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java @@ -24,7 +24,6 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.commons.internal.assertions._Assert; 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.facets.members.navigation.NavigationFacet; import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; @@ -32,26 +31,21 @@ import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; -public class NavigationFacetFromHiddenType -extends FacetAbstract -implements - NavigationFacet { +public record NavigationFacetFromHiddenType( + ObjectSpecification navigatedType, + FacetHolder facetHolder + ) implements NavigationFacet { - private final ObjectSpecification navigatedType; + public static Optional create(final ObjectSpecification navigatedType, final FacetHolder holder) { + return navigatedType.isValue() + ? Optional.empty() // don't create for value types (optimization, not strictly required) + : Optional.of(new NavigationFacetFromHiddenType(navigatedType, holder)); + } - private static final Class type() { - return NavigationFacet.class; - } - - public static Optional create(final ObjectSpecification navigatedType, final FacetHolder holder) { - return navigatedType.isValue() - ? Optional.empty() // don't create for value types (optimization, not strictly required) - : Optional.of(new NavigationFacetFromHiddenType(navigatedType, holder)); - } + @Override public Class facetType() { return NavigationFacet.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } - private NavigationFacetFromHiddenType(final ObjectSpecification navigatedType, final FacetHolder holder) { - super(type(), holder); - this.navigatedType = navigatedType; + public NavigationFacetFromHiddenType { _Assert.assertTrue(navigatedType.isSingular(), ()->String.format( "framework bug: elementType must not match any supported plural (collection) types, " + "nevertheless got %s", navigatedType)); @@ -77,7 +71,7 @@ public String hides(final VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); + NavigationFacet.super.visitAttributes(visitor); visitor.accept("navigatedType", navigatedType.logicalTypeName()); visitor.accept("navigatedTypeFqcn", navigatedType.getCorrespondingClass().getName()); } From 184abce19fdd04e4074e43bcf3feb4c8dd1925aa Mon Sep 17 00:00:00 2001 From: andi-huber Date: Thu, 27 Nov 2025 13:48:36 +0100 Subject: [PATCH 11/25] CAUSEWAY-3752: aligning facet names for hiding advisors --- .../metamodel/execution/ActionExecutor.java | 2 +- .../metamodel/facets/HasImperativeAspect.java | 10 +- .../metamodel/facets/ImperativeFacet.java | 14 +- .../action/ActionAnnotationFacetFactory.java | 6 +- .../ActionInvocationFacetAbstract.java | 9 +- ...ForDeploymentTypeViaActionAnnotation.java} | 17 +- .../HiddenFacetForActionLayoutAnnotation.java | 4 +- .../layout/HiddenFacetForActionLayoutXml.java | 8 +- ...java => HiddenFacetForDeploymentType.java} | 2 +- ...tionParameterValidationFacetViaMethod.java | 9 +- .../ActionValidationFacetViaMethod.java | 9 +- ...enFacet.java => HiddenFacetForLayout.java} | 6 +- .../HasImperativeTextFacetAbstract.java | 9 +- .../CollectionAccessorFacetViaAccessor.java | 9 +- ...denFacetForCollectionLayoutAnnotation.java | 4 +- .../HiddenFacetForCollectionLayoutXml.java | 8 +- .../DisableForContextFacetViaMethod.java | 9 +- ...java => HiddenFacetForLayoutAbstract.java} | 16 +- ...ddenFacetFromLayoutPropertiesAbstract.java | 52 - ...xtFacet.java => HiddenFacetForMember.java} | 7 +- ...ava => HiddenFacetForMemberViaMethod.java} | 12 +- ...HiddenFacetForMemberViaMethodFactory.java} | 6 +- .../method/HideForContextFacetNone.java | 48 - ...cet.java => HiddenFacetForNavigation.java} | 6 +- .../callbacks/CallbackFacetAbstract.java | 5 +- .../CssClassFacetViaCssClassMethod.java | 6 +- .../method/DisabledObjectFacetViaMethod.java | 5 +- ...=> HiddenFacetForNoMembersAuthorized.java} | 5 +- ...iddenFacetForNoMembersAuthorizedImpl.java} | 6 +- ...ctFacet.java => HiddenFacetForObject.java} | 4 +- ...ddenTypeFacetFromAuthorizationFactory.java | 4 +- ...ava => HiddenFacetForObjectViaMethod.java} | 22 +- .../icon/method/IconFacetViaIconMethod.java | 1 - .../method/IconFacetViaIconNameMethod.java | 1 - .../layout/LayoutPrefixFacetViaMethod.java | 5 - .../support/ObjectSupportFacetFactory.java | 10 +- .../object/title/TitleFacetAbstract.java | 4 +- .../TitleFacetViaTitleAnnotation.java | 11 +- .../methods/TitleFacetFromToStringMethod.java | 6 +- .../methods/TitleFacetViaTitleMethod.java | 5 +- ...onParameterAutoCompleteFacetViaMethod.java | 9 +- .../ActionParameterChoicesFacetViaMethod.java | 9 +- ...ActionParameterDefaultsFacetViaMethod.java | 9 +- ...ActionParameterDisabledFacetViaMethod.java | 9 +- ...ava => HiddenFacetForActionParameter.java} | 2 +- ...nParameterHiddenFacetViaMethodFactory.java | 6 +- ...ddenFacetForActionParameterViaMethod.java} | 22 +- ...tionParameterValidationFacetViaMethod.java | 9 +- .../PropertyAccessorFacetViaAccessor.java | 9 +- .../PropertyAutoCompleteFacetMethod.java | 9 +- .../method/PropertyChoicesFacetViaMethod.java | 9 +- .../method/PropertyDefaultFacetViaMethod.java | 9 +- ...iddenFacetForPropertyLayoutAnnotation.java | 4 +- .../HiddenFacetForPropertyLayoutXml.java | 8 +- .../PropertyClearFacetViaClearMethod.java | 9 +- .../PropertyClearFacetViaSetterMethod.java | 9 +- ...rtyInitializationFacetViaSetterMethod.java | 9 +- .../PropertySetterFacetViaSetterMethod.java | 9 +- .../PropertyValidateFacetViaMethod.java | 9 +- .../HidingInteractionAdvisor.java | 12 +- .../metamodel/layout/LayoutFacetUtil.java | 4 +- .../authorization/AuthorizationFacet.java | 2 +- ...ddenFacetForNavigationFromHiddenType.java} | 20 +- ...ationFacetFromHiddenTypePostProcessor.java | 8 +- .../ApplicationFeatureRepositoryDefault.java | 4 +- .../metamodel/DomainMemberDefault.java | 6 +- .../metamodel/spec/ObjectSpecification.java | 4 +- .../metamodel/spec/feature/ObjectAction.java | 8 +- .../spec/feature/ObjectAssociation.java | 10 +- .../metamodel/spec/feature/ObjectMember.java | 6 +- .../spec/impl/ObjectActionDefault.java | 4 +- .../spec/impl/ObjectMemberAbstract.java | 4 +- .../spec/impl/ObjectSpecificationDefault.java | 8 +- .../spec/impl/ProgrammingModelDefault.java | 4 +- ...notationEnforcesMetamodelContribution.java | 2 +- .../metamodel/spec/impl/_SpecPredicates.java | 6 +- .../causeway/core/metamodel/util/Facets.java | 6 +- .../facets/FacetFactoryTestAbstract.java | 2 +- ...AnnotationFacetFactoryTest_RestrictTo.java | 8 +- .../PrototypeFacetAnnotationFactoryTest.java | 6 +- ...ctionLayoutAnnotationFacetFactoryTest.java | 4 +- .../prototype/PrototypeFacetAbstractTest.java | 4 +- ...CollectionLayoutAnnotationFactoryTest.java | 4 +- .../CallbackFacetFactoryTestAbstract.java | 2 +- .../ObjectHiddenMethodFacetFactoryTest.java | 2 +- ...ObjectSupportFacetFactoryTestAbstract.java | 2 +- .../PropertyMethodsFacetFactoryTest.java | 30 +- .../PropertyLayoutAnnotationFactoryTest.java | 4 +- ...ssociationPredicatesTest_visibleWhere.java | 8 +- ...tAssociationAbstractTest_alwaysHidden.java | 21 +- ...sViewer_IntegTest.dump_facets.approved.xml | 32 +- ...nDomain_IntegTest.dump_facets.approved.xml | 32 +- ...sViewer_IntegTest.dump_facets.approved.xml | 28 +- ...pDomain_IntegTest.dump_facets.approved.xml | 28 +- ...etaModelRegressionTest.verify.approved.xml | 1162 ++++++++--------- 95 files changed, 1003 insertions(+), 1044 deletions(-) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/{PrototypeFacetForActionAnnotation.java => HiddenFacetForDeploymentTypeViaActionAnnotation.java} (79%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/{PrototypeFacet.java => HiddenFacetForDeploymentType.java} (92%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/{HiddenFacet.java => HiddenFacetForLayout.java} (91%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/{HiddenFacetAbstract.java => HiddenFacetForLayoutAbstract.java} (86%) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetFromLayoutPropertiesAbstract.java rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/{HideForContextFacet.java => HiddenFacetForMember.java} (82%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/{HideForContextFacetViaMethod.java => HiddenFacetForMemberViaMethod.java} (88%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/{HideForContextFacetViaMethodFactory.java => HiddenFacetForMemberViaMethodFactory.java} (91%) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/{NavigationFacet.java => HiddenFacetForNavigation.java} (84%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/{HiddenTypeFacet.java => HiddenFacetForNoMembersAuthorized.java} (82%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/{HiddenTypeFacetFromAuthorization.java => HiddenFacetForNoMembersAuthorizedImpl.java} (95%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/{HiddenObjectFacet.java => HiddenFacetForObject.java} (91%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/{HiddenObjectFacetViaMethod.java => HiddenFacetForObjectViaMethod.java} (81%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/{ActionParameterHiddenFacet.java => HiddenFacetForActionParameter.java} (97%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/{ActionParameterHiddenFacetViaMethod.java => HiddenFacetForActionParameterViaMethod.java} (83%) rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/{NavigationFacetFromHiddenType.java => HiddenFacetForNavigationFromHiddenType.java} (81%) 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 6c21e2243af..c8363fc6bbf 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 @@ -81,7 +81,7 @@ public static ActionExecutor forAction( throw _Exceptions.illegalArgument("arguments must be specified for action %s", owningAction); }}); - var method = actionInvocationFacetAbstract.getMethods().getFirstElseFail(); + var method = actionInvocationFacetAbstract.methods().getFirstElseFail(); return new ActionExecutor( owningAction.getMetaModelContext(), facetHolder, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/HasImperativeAspect.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/HasImperativeAspect.java index e7c034df9a6..0862b038959 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/HasImperativeAspect.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/HasImperativeAspect.java @@ -24,16 +24,16 @@ public interface HasImperativeAspect extends ImperativeFacet { - ImperativeAspect getImperativeAspect(); + ImperativeAspect imperativeAspect(); @Override - default Can getMethods() { - return getImperativeAspect().methods(); + default Can methods() { + return imperativeAspect().methods(); } @Override - default Intent getIntent() { - return getImperativeAspect().intent(); + default Intent intent() { + return imperativeAspect().intent(); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ImperativeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ImperativeFacet.java index fbcbfaef4a1..3ee47dafb4d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ImperativeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ImperativeFacet.java @@ -56,7 +56,7 @@ public interface ImperativeFacet extends Facet { /** * The {@link Method}s invoked by this {@link Facet}. */ - public Can getMethods(); + Can methods(); public static enum Intent { CHECK_IF_HIDDEN, @@ -79,17 +79,17 @@ public static enum Intent { /** * The intent of this method, so that the {@link WrapperFactory} knows whether to delegate on or to reject. */ - public Intent getIntent(); + Intent intent(); public static void visitAttributes(final ImperativeFacet imperativeFacet, final BiConsumer visitor) { - var methods = imperativeFacet.getMethods(); + var methods = imperativeFacet.methods(); visitor.accept("methods", methods.stream() .map(MethodFacade::toString) .collect(Collectors.joining(", "))); methods.forEach(method-> visitor.accept( - "intent." + method.getName(), imperativeFacet.getIntent())); + "intent." + method.getName(), imperativeFacet.intent())); } // -- UTILITIES @@ -103,11 +103,11 @@ public static Intent getIntent(final ObjectMember member, final ResolvedMethod m case 0: break; case 1: - return imperativeFacets.get(0).getIntent(); + return imperativeFacets.get(0).intent(); default: Intent intentToReturn = null; for (ImperativeFacet imperativeFacet : imperativeFacets) { - Intent intent = imperativeFacet.getIntent(); + Intent intent = imperativeFacet.intent(); if(intentToReturn == null) { intentToReturn = intent; } else if(intentToReturn != intent) { @@ -143,7 +143,7 @@ public static Can singleRegularMethod(final @NonNull ResolvedMetho // -- HELPER private boolean containsMethod(final ResolvedMethod method) { - return getMethods().stream() + return methods().stream() .map(MethodFacade::asMethodForIntrospection) .anyMatch(method::equals); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java index 14d86e5e7d9..2b43c9ae2f4 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java @@ -35,7 +35,7 @@ import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionDomainEventFacet; import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForAction; import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForMixedInPropertyOrCollection; -import org.apache.causeway.core.metamodel.facets.actions.action.prototype.PrototypeFacetForActionAnnotation; +import org.apache.causeway.core.metamodel.facets.actions.action.prototype.HiddenFacetForDeploymentTypeViaActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.action.typeof.TypeOfFacetForActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.fileaccept.FileAcceptFacetForActionAnnotation; import org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacet; @@ -145,10 +145,10 @@ void processRestrictTo(final ProcessMethodContext processMethodContext, final Op // search for @Action(restrictTo=...) addFacetIfPresent( - PrototypeFacetForActionAnnotation + HiddenFacetForDeploymentTypeViaActionAnnotation .create( actionIfAny, facetedMethod, - ()->super.getSystemEnvironment().deploymentType())); + super.getSystemEnvironment().deploymentType())); } void processSemantics(final ProcessMethodContext processMethodContext, final Optional actionIfAny) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetAbstract.java index ebe4a5d6930..00a5f69b9d3 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetAbstract.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.events.domain.ActionDomainEvent; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -32,7 +34,7 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public abstract class ActionInvocationFacetAbstract extends DomainEventFacetAbstract> @@ -46,7 +48,8 @@ private static final Class type() { // -- CONSTRUCTION - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; @Getter(onMethod_ = {@Override}) private final ObjectSpecification declaringType; @Getter(onMethod_ = {@Override}) private final ObjectSpecification returnType; @@ -67,7 +70,7 @@ protected ActionInvocationFacetAbstract( } @Override - public final Intent getIntent() { + public final Intent intent() { return Intent.EXECUTE; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/HiddenFacetForDeploymentTypeViaActionAnnotation.java similarity index 79% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/HiddenFacetForDeploymentTypeViaActionAnnotation.java index ca232656ea0..45a3edca345 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/PrototypeFacetForActionAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/prototype/HiddenFacetForDeploymentTypeViaActionAnnotation.java @@ -20,33 +20,32 @@ import java.util.Optional; import java.util.function.BiConsumer; -import java.util.function.Supplier; import org.apache.causeway.applib.annotation.Action; import org.apache.causeway.applib.annotation.RestrictTo; import org.apache.causeway.core.config.environment.DeploymentType; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; +import org.apache.causeway.core.metamodel.facets.actions.prototype.HiddenFacetForDeploymentType; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -public record PrototypeFacetForActionAnnotation( +public record HiddenFacetForDeploymentTypeViaActionAnnotation( DeploymentType deploymentType, FacetHolder facetHolder - ) implements PrototypeFacet { + ) implements HiddenFacetForDeploymentType { - public static Optional create( + public static Optional create( final Optional actionsIfAny, final FacetHolder holder, - final Supplier lazyDeploymentType) { + final DeploymentType deploymentType) { return actionsIfAny .map(Action::restrictTo) .filter(restrictTo -> restrictTo == RestrictTo.PROTOTYPING) - .map(restrictTo -> new PrototypeFacetForActionAnnotation(lazyDeploymentType.get(), holder)); + .map(restrictTo -> new HiddenFacetForDeploymentTypeViaActionAnnotation(deploymentType, holder)); } - @Override public Class facetType() { return PrototypeFacet.class; } + @Override public Class facetType() { return HiddenFacetForDeploymentType.class; } @Override public Precedence precedence() { return Precedence.DEFAULT; } @Override @@ -58,7 +57,7 @@ public String hides(VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - PrototypeFacet.super.visitAttributes(visitor); + HiddenFacetForDeploymentType.super.visitAttributes(visitor); visitor.accept("deploymentType", deploymentType.name()); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutAnnotation.java index 4d1a7ccd099..51b78fde56e 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutAnnotation.java @@ -23,10 +23,10 @@ import org.apache.causeway.applib.annotation.ActionLayout; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; -public class HiddenFacetForActionLayoutAnnotation extends HiddenFacetAbstract { +public class HiddenFacetForActionLayoutAnnotation extends HiddenFacetForLayoutAbstract { public static Optional create( final Optional actionLayoutIfAny, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutXml.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutXml.java index 39ab3bf49e5..69746f843d6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutXml.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/layout/HiddenFacetForActionLayoutXml.java @@ -23,14 +23,14 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.ActionLayoutData; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; public class HiddenFacetForActionLayoutXml -extends HiddenFacetAbstract { +extends HiddenFacetForLayoutAbstract { - public static Optional create( + public static Optional create( final ActionLayoutData actionLayout, final FacetHolder holder, final Precedence precedence) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/HiddenFacetForDeploymentType.java similarity index 92% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/HiddenFacetForDeploymentType.java index d0c4abd67cd..27c0b77a281 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/prototype/HiddenFacetForDeploymentType.java @@ -23,6 +23,6 @@ /** * Indicates that the action should only be available in prototype mode. */ -public interface PrototypeFacet extends HidingInteractionAdvisor { +public interface HiddenFacetForDeploymentType extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java index d19a8e813e7..9f6fdc96fcd 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionParameterValidationFacetViaMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.applib.services.i18n.TranslationService; @@ -33,13 +35,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterValidationFacetViaMethod extends ActionParameterValidationFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationService translationService; private final TranslationContext translationContext; @@ -55,7 +58,7 @@ public ActionParameterValidationFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_VALID; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java index d9a669f40ca..b5cf3c70b41 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; @@ -34,13 +36,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionValidationFacetViaMethod extends ActionValidationFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationContext translationContext; private final Optional patConstructor; @@ -56,7 +59,7 @@ public ActionValidationFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_VALID; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForLayout.java similarity index 91% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForLayout.java index f73cd0c2d96..e6afa5f0713 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForLayout.java @@ -25,15 +25,15 @@ import org.jspecify.annotations.NonNull; /** - * Hide a property, collection or action. + * Optionally hides a property, collection or action via layout. */ -public interface HiddenFacet +public interface HiddenFacetForLayout extends WhereValueFacet, HidingInteractionAdvisor { // -- PREDICATES static boolean isAlwaysHidden(final @NonNull FacetHolder facetHolder) { - return WhereValueFacet.isAlways(facetHolder, HiddenFacet.class); + return WhereValueFacet.isAlways(facetHolder, HiddenFacetForLayout.class); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/i8n/imperative/HasImperativeTextFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/i8n/imperative/HasImperativeTextFacetAbstract.java index 37c14e97f8e..d21e35d9258 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/i8n/imperative/HasImperativeTextFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/i8n/imperative/HasImperativeTextFacetAbstract.java @@ -21,6 +21,8 @@ import java.util.Objects; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.functional.Try; @@ -34,7 +36,7 @@ import org.apache.causeway.core.metamodel.object.ManagedObjects; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class HasImperativeTextFacetAbstract extends FacetAbstract @@ -44,7 +46,8 @@ public class HasImperativeTextFacetAbstract protected final TranslationContext translationContext; - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; protected HasImperativeTextFacetAbstract( final Class facetType, @@ -64,7 +67,7 @@ public final Try text(final ManagedObject object) { } @Override - public final Intent getIntent() { + public final Intent intent() { return Intent.UI_HINT; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/accessor/CollectionAccessorFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/accessor/CollectionAccessorFacetViaAccessor.java index d636ae92fed..4a5abe7520f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/accessor/CollectionAccessorFacetViaAccessor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/accessor/CollectionAccessorFacetViaAccessor.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -34,13 +36,14 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class CollectionAccessorFacetViaAccessor extends PropertyOrCollectionAccessorFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public CollectionAccessorFacetViaAccessor( final ObjectSpecification declaringType, @@ -51,7 +54,7 @@ public CollectionAccessorFacetViaAccessor( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.ACCESSOR; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutAnnotation.java index 1a42c66f40e..16bb823aa6b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutAnnotation.java @@ -24,11 +24,11 @@ import org.apache.causeway.applib.annotation.CollectionLayout; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; public class HiddenFacetForCollectionLayoutAnnotation -extends HiddenFacetAbstract { +extends HiddenFacetForLayoutAbstract { public static Optional create( final Optional collectionLayoutIfAny, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutXml.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutXml.java index c7262bbbcd3..eec0cf04234 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutXml.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/layout/HiddenFacetForCollectionLayoutXml.java @@ -23,14 +23,14 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.CollectionLayoutData; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; public class HiddenFacetForCollectionLayoutXml -extends HiddenFacetAbstract { +extends HiddenFacetForLayoutAbstract { - public static Optional create( + public static Optional create( final CollectionLayoutData collectionLayout, final FacetHolder holder, final Precedence precedence) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java index 60ad25c09fc..dfb3ffba37f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; @@ -34,13 +36,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class DisableForContextFacetViaMethod extends DisableForContextFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationContext translationContext; public DisableForContextFacetViaMethod( @@ -52,7 +55,7 @@ public DisableForContextFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_DISABLED; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetForLayoutAbstract.java similarity index 86% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetForLayoutAbstract.java index 64cd86ebedc..1cd770ba76f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetForLayoutAbstract.java @@ -24,25 +24,25 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.WhereValueFacetAbstract; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; -public abstract class HiddenFacetAbstract +public abstract class HiddenFacetForLayoutAbstract extends WhereValueFacetAbstract -implements HiddenFacet { +implements HiddenFacetForLayout { - public static final Class type() { - return HiddenFacet.class; + public static final Class type() { + return HiddenFacetForLayout.class; } - public HiddenFacetAbstract( + public HiddenFacetForLayoutAbstract( final Where where, final FacetHolder holder) { super(type(), holder, where); } - public HiddenFacetAbstract( + public HiddenFacetForLayoutAbstract( final Where where, final FacetHolder holder, final Facet.Precedence precedence) { @@ -50,7 +50,7 @@ public HiddenFacetAbstract( } // to instantiate contributed facets - private HiddenFacetAbstract(final HiddenFacetAbstract toplevelFacet) { + private HiddenFacetForLayoutAbstract(final HiddenFacetForLayoutAbstract toplevelFacet) { super(type(), toplevelFacet.facetHolder(), toplevelFacet.where()); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetFromLayoutPropertiesAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetFromLayoutPropertiesAbstract.java deleted file mode 100644 index 96a622b0b76..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/HiddenFacetFromLayoutPropertiesAbstract.java +++ /dev/null @@ -1,52 +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.members.hidden; - -import java.util.Properties; - -import org.apache.causeway.applib.annotation.Where; -import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.object.ManagedObject; - -public abstract class HiddenFacetFromLayoutPropertiesAbstract extends HiddenFacetAbstract { - - protected static Where hidden(final Properties properties) { - if(properties == null) { - return null; - } - final String hidden = _Strings.emptyToNull(properties.getProperty("hidden")); - if(hidden == null) { - return null; - } - return Where.valueOf(hidden); - } - - protected HiddenFacetFromLayoutPropertiesAbstract(final Where where, final FacetHolder holder) { - super(where, holder); - } - - @Override - public String hiddenReason(final ManagedObject targetAdapter, final Where whereContext) { - if(!where().includes(whereContext)) { - return null; - } - return "Hidden on " + where().getFriendlyName(); - } -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMember.java similarity index 82% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMember.java index f4bc5f8ccf9..b147146ac52 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMember.java @@ -22,13 +22,12 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; /** - * Hide a property, collection or action based on the state of the target + * Optionally hides a property, collection or action based on the state of the target * {@link ManagedObject object}. * - *

- * In the standard Apache Causeway Programming Model, corresponds to invoking the + *

In the standard Apache Causeway Programming Model, corresponds to invoking the * hideXxx support method for the member. */ -public interface HideForContextFacet extends HidingInteractionAdvisor { +public interface HiddenFacetForMember extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethod.java similarity index 88% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethod.java index 0cd8243d854..957c85ce6c0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethod.java @@ -31,18 +31,18 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmInvokeUtils; -public record HideForContextFacetViaMethod( +public record HiddenFacetForMemberViaMethod( Can methods, FacetHolder facetHolder - ) implements HideForContextFacet, ImperativeFacet { + ) implements HiddenFacetForMember, ImperativeFacet { - @Override public Class facetType() { return HideForContextFacet.class; } + @Override public Class facetType() { return HiddenFacetForMember.class; } @Override public Precedence precedence() { return Precedence.DEFAULT; } - @Override public Intent getIntent() { return Intent.CHECK_IF_HIDDEN;} + @Override public Intent intent() { return Intent.CHECK_IF_HIDDEN;} public Can getMethods() { return methods(); } - public HideForContextFacetViaMethod(final ResolvedMethod method, final FacetHolder holder) { + public HiddenFacetForMemberViaMethod(final ResolvedMethod method, final FacetHolder holder) { this(ImperativeFacet.singleRegularMethod(method), holder); } @@ -58,7 +58,7 @@ public String hides(final VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - HideForContextFacet.super.visitAttributes(visitor); + HiddenFacetForMember.super.visitAttributes(visitor); ImperativeFacet.visitAttributes(this, visitor); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethodFactory.java similarity index 91% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethodFactory.java index d857fb2f997..dbd5e4fd0e3 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HiddenFacetForMemberViaMethodFactory.java @@ -26,11 +26,11 @@ import org.apache.causeway.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract; import org.apache.causeway.core.metamodel.methods.MethodFinder; -public class HideForContextFacetViaMethodFactory +public class HiddenFacetForMemberViaMethodFactory extends MemberSupportFacetFactoryAbstract { @Inject - public HideForContextFacetViaMethodFactory(final MetaModelContext mmc) { + public HiddenFacetForMemberViaMethodFactory(final MetaModelContext mmc) { super(mmc, FeatureType.MEMBERS, MemberSupportPrefix.HIDE); } @@ -44,7 +44,7 @@ protected void search( .peek(processMethodContext::removeMethod) .forEach(hideMethod->{ addFacet( - new HideForContextFacetViaMethod( + new HiddenFacetForMemberViaMethod( hideMethod, processMethodContext.getFacetHolder())); }); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java deleted file mode 100644 index b9678a672ce..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java +++ /dev/null @@ -1,48 +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.members.hidden.method; - -import org.apache.causeway.commons.collections.Can; -import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; -import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.ImperativeFacet; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; - -public record HideForContextFacetNone(FacetHolder facetHolder) -implements HideForContextFacet, ImperativeFacet { - - @Override public Class facetType() { return HideForContextFacet.class; } - @Override public Precedence precedence() { return Precedence.FALLBACK; } - @Override public Intent getIntent() { return Intent.CHECK_IF_HIDDEN;} - - /** - * Always returns null. - */ - @Override - public String hides(final VisibilityContext ic) { - return null; - } - - @Override - public Can getMethods() { - return Can.empty(); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/HiddenFacetForNavigation.java similarity index 84% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/HiddenFacetForNavigation.java index 79cb05fa316..9c8c6349c10 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/NavigationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/HiddenFacetForNavigation.java @@ -18,12 +18,12 @@ */ package org.apache.causeway.core.metamodel.facets.members.navigation; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForNoMembersAuthorized; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; /** * Hides object members that would allow navigation to a domain type that is - * {@link HiddenTypeFacet hidden} (typically due to security permissions). + * {@link HiddenFacetForNoMembersAuthorized hidden} (typically due to security permissions). */ -public interface NavigationFacet extends HidingInteractionAdvisor { +public interface HiddenFacetForNavigation extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacetAbstract.java index 762cf7ebcc6..4dcb5f79dd4 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/callbacks/CallbackFacetAbstract.java @@ -28,6 +28,7 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; +import lombok.experimental.Accessors; /** * Adapter superclass for {@link Facet}s for {@link CallbackFacet}. @@ -36,7 +37,7 @@ public abstract class CallbackFacetAbstract extends FacetAbstract implements CallbackFacet { - @Getter(onMethod_ = {@Override}) + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) private final Can methods; private final Can asRegularMethods; @@ -50,7 +51,7 @@ protected CallbackFacetAbstract( } @Override - public final Intent getIntent() { + public final Intent intent() { return Intent.LIFECYCLE; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/cssclass/method/CssClassFacetViaCssClassMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/cssclass/method/CssClassFacetViaCssClassMethod.java index f3ecec740a0..5648f5f4986 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/cssclass/method/CssClassFacetViaCssClassMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/cssclass/method/CssClassFacetViaCssClassMethod.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -32,13 +33,14 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class CssClassFacetViaCssClassMethod extends CssClassFacetAbstract implements HasImperativeAspect { - @Getter(onMethod_ = {@Override}) private final @NonNull ImperativeAspect imperativeAspect; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull ImperativeAspect imperativeAspect; public static Optional create( final @Nullable ResolvedMethod methodIfAny, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java index 41af51e99c6..b21da7680e8 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/disabled/method/DisabledObjectFacetViaMethod.java @@ -35,13 +35,16 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; import lombok.Getter; +import lombok.experimental.Accessors; + import org.jspecify.annotations.NonNull; public class DisabledObjectFacetViaMethod extends DisabledObjectFacetAbstract implements HasImperativeAspect { - @Getter(onMethod_ = {@Override}) private final @NonNull ImperativeAspect imperativeAspect; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull ImperativeAspect imperativeAspect; private final TranslationContext translationContext; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorized.java similarity index 82% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorized.java index 160ec79b1dd..961ff1781d2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorized.java @@ -20,6 +20,9 @@ import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; -public interface HiddenTypeFacet extends HidingInteractionAdvisor { +/** + * Optionally hides an object, based on whether non of its properties, collections and actions is visible. + */ +public interface HiddenFacetForNoMembersAuthorized extends HidingInteractionAdvisor { } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedImpl.java similarity index 95% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedImpl.java index 2a091645fea..85dfea926de 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorization.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedImpl.java @@ -25,11 +25,11 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.MixedIn; -public record HiddenTypeFacetFromAuthorization( +public record HiddenFacetForNoMembersAuthorizedImpl( FacetHolder facetHolder - ) implements HiddenTypeFacet { + ) implements HiddenFacetForNoMembersAuthorized { - @Override public Class facetType() { return HiddenTypeFacet.class; } + @Override public Class facetType() { return HiddenFacetForNoMembersAuthorized.class; } @Override public Precedence precedence() { return Precedence.HIGH; } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForObject.java similarity index 91% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForObject.java index ab9595c5984..e55b14915ee 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenObjectFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForObject.java @@ -23,7 +23,7 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; -public interface HiddenObjectFacet extends HidingInteractionAdvisor { +public interface HiddenFacetForObject extends HidingInteractionAdvisor { /** * Copy this facet to another {@link FacetHolder}. @@ -32,6 +32,6 @@ public interface HiddenObjectFacet extends HidingInteractionAdvisor { * {@link ObjectSpecification}, and then copied down onto each of the spec's * {@link ObjectMember}s. */ - public HiddenObjectFacet copyTo(FacetHolder holder); + public HiddenFacetForObject copyTo(FacetHolder holder); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java index e501f314430..ee80164d010 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java @@ -28,7 +28,7 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; /** - * Installs the {@link HiddenTypeFacetFromAuthorization} on the + * Installs the {@link HiddenFacetForNoMembersAuthorizedImpl} on the * {@link ObjectSpecification}. */ public class HiddenTypeFacetFromAuthorizationFactory @@ -42,7 +42,7 @@ public HiddenTypeFacetFromAuthorizationFactory(final MetaModelContext mmc) { @Override public void process(final ProcessClassContext processClassContext) { final FacetHolder facetHolder = processClassContext.getFacetHolder(); - FacetUtil.addFacet(new HiddenTypeFacetFromAuthorization(facetHolder)); + FacetUtil.addFacet(new HiddenFacetForNoMembersAuthorizedImpl(facetHolder)); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenFacetForObjectViaMethod.java similarity index 81% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenFacetForObjectViaMethod.java index 37d774d5cc6..a75a2dbd070 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenObjectFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenFacetForObjectViaMethod.java @@ -28,30 +28,26 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.HasImperativeAspect; import org.apache.causeway.core.metamodel.facets.ImperativeAspect; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForObject; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; -public record HiddenObjectFacetViaMethod( +public record HiddenFacetForObjectViaMethod( ImperativeAspect imperativeAspect, FacetHolder facetHolder - ) implements HiddenObjectFacet, HasImperativeAspect { + ) implements HiddenFacetForObject, HasImperativeAspect { - public static Optional create( + public static Optional create( final @Nullable ResolvedMethod methodIfAny, final FacetHolder holder) { return Optional.ofNullable(methodIfAny) .map(method->ImperativeAspect.singleRegularMethod(method, Intent.CHECK_IF_HIDDEN)) - .map(imperativeAspect->new HiddenObjectFacetViaMethod(imperativeAspect, holder)); + .map(imperativeAspect->new HiddenFacetForObjectViaMethod(imperativeAspect, holder)); } - @Override public Class facetType() { return HiddenObjectFacet.class; } + @Override public Class facetType() { return HiddenFacetForObject.class; } @Override public Precedence precedence() { return Precedence.DEFAULT;} - - public ImperativeAspect getImperativeAspect() { - return imperativeAspect; - } @Override public String hides(final VisibilityContext ic) { @@ -60,13 +56,13 @@ public String hides(final VisibilityContext ic) { } @Override - public HiddenObjectFacetViaMethod copyTo(final FacetHolder holder) { - return new HiddenObjectFacetViaMethod(imperativeAspect, holder); + public HiddenFacetForObjectViaMethod copyTo(final FacetHolder holder) { + return new HiddenFacetForObjectViaMethod(imperativeAspect, holder); } @Override public void visitAttributes(final BiConsumer visitor) { - HiddenObjectFacet.super.visitAttributes(visitor); + HiddenFacetForObject.super.visitAttributes(visitor); imperativeAspect.visitAttributes(visitor); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconMethod.java index 3cb2fde883c..d1abdbfc5b2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconMethod.java @@ -50,7 +50,6 @@ public static Optional create( @Override public Class facetType() { return IconFacet.class; } @Override public Precedence precedence() { return Precedence.DEFAULT; } - @Override public ImperativeAspect getImperativeAspect() { return imperativeAspect; } @Override public Optional icon(ManagedObject domainObject, IconSize iconSize) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconNameMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconNameMethod.java index 68bd46e1eba..0b00b1f5afb 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconNameMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/icon/method/IconFacetViaIconNameMethod.java @@ -51,7 +51,6 @@ public static Optional create( @Override public Class facetType() { return IconFacet.class; } @Override public Precedence precedence() { return Precedence.LOW; } - @Override public ImperativeAspect getImperativeAspect() { return imperativeAspect; } @Override public Optional icon(ManagedObject domainObject, IconSize iconSize) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/layout/LayoutPrefixFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/layout/LayoutPrefixFacetViaMethod.java index b218b0fe685..6fcb0f11eb6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/layout/LayoutPrefixFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/layout/LayoutPrefixFacetViaMethod.java @@ -68,11 +68,6 @@ public String layoutPrefix(final ManagedObject managedObject) { } } - @Override - public ImperativeAspect getImperativeAspect() { - return imperativeAspect(); - } - @Override public void visitAttributes(final BiConsumer visitor) { LayoutPrefixFacet.super.visitAttributes(visitor); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java index 30485697243..a19a1bf1adb 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java @@ -37,8 +37,8 @@ import org.apache.causeway.core.metamodel.facets.object.cssclass.method.CssClassFacetViaCssClassMethod; import org.apache.causeway.core.metamodel.facets.object.disabled.DisabledObjectFacet; import org.apache.causeway.core.metamodel.facets.object.disabled.method.DisabledObjectFacetViaMethod; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; -import org.apache.causeway.core.metamodel.facets.object.hidden.method.HiddenObjectFacetViaMethod; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForObject; +import org.apache.causeway.core.metamodel.facets.object.hidden.method.HiddenFacetForObjectViaMethod; import org.apache.causeway.core.metamodel.facets.object.icon.method.IconFacetViaIconMethod; import org.apache.causeway.core.metamodel.facets.object.icon.method.IconFacetViaIconNameMethod; import org.apache.causeway.core.metamodel.facets.object.layout.LayoutPrefixFacetViaMethod; @@ -51,7 +51,7 @@ /** * Installs {@link DisabledObjectFacetViaMethod} - * and {@link HiddenObjectFacetViaMethod} on the + * and {@link HiddenFacetForObjectViaMethod} on the * {@link ObjectSpecification}, and copies this facet onto each * {@link ObjectMember}. *

@@ -81,7 +81,7 @@ public final void process(final ProcessClassContext processClassContext) { // priming 'toString()' into Precedence.INFERRED rank inferTitleFromToString(processClassContext); - processObjectSupport(processClassContext, ObjectSupportMethod.HIDDEN, NO_ARG, HiddenObjectFacetViaMethod::create); + processObjectSupport(processClassContext, ObjectSupportMethod.HIDDEN, NO_ARG, HiddenFacetForObjectViaMethod::create); processObjectSupport(processClassContext, ObjectSupportMethod.DISABLED, NO_ARG, DisabledObjectFacetViaMethod::create); processObjectSupport(processClassContext, ObjectSupportMethod.TITLE, NO_ARG, TitleFacetViaTitleMethod::create); processObjectSupport(processClassContext, ObjectSupportMethod.LAYOUT, NO_ARG, LayoutPrefixFacetViaMethod::create); @@ -101,7 +101,7 @@ public void process(final ProcessMethodContext processMethodContext) { .map(disabledObjectFacet->disabledObjectFacet.clone(member)) .ifPresent(FacetUtil::addFacet); - owningSpec.lookupFacet(HiddenObjectFacet.class) + owningSpec.lookupFacet(HiddenFacetForObject.class) .map(hiddenObjectFacet->hiddenObjectFacet.copyTo(member)) .ifPresent(FacetUtil::addFacet); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/TitleFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/TitleFacetAbstract.java index 9a410be7f9b..db3689f0f2f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/TitleFacetAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/TitleFacetAbstract.java @@ -62,8 +62,8 @@ public boolean semanticEquals(final @NonNull Facet other) { && otherFacet instanceof ImperativeFacet) { return ((ImperativeFacet)this) - .getMethods() - .equals(((ImperativeFacet)otherFacet).getMethods()); + .methods() + .equals(((ImperativeFacet)otherFacet).methods()); } return false; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java index 39e9a0041d0..f3eb799aaba 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/annotation/TitleFacetViaTitleAnnotation.java @@ -25,6 +25,8 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.annotation.Title; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._Strings; @@ -35,8 +37,8 @@ import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; import org.apache.causeway.commons.internal.reflection._Reflect.InterfacePolicy; import org.apache.causeway.commons.internal.reflection._Reflect.TypeHierarchyPolicy; -import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.ObjectSupportMethod; import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.MessageTemplate; +import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.ObjectSupportMethod; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.Evaluators; import org.apache.causeway.core.metamodel.facets.Evaluators.MethodEvaluator; @@ -49,8 +51,8 @@ import lombok.AccessLevel; import lombok.Getter; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; +import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -85,7 +87,8 @@ public static Optional create( } @Getter private final Can components; - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; protected TitleFacetViaTitleAnnotation(final Can components, final FacetHolder holder) { super(holder); @@ -109,7 +112,7 @@ protected TitleFacetViaTitleAnnotation(final Can components, fin } @Override - public Intent getIntent() { + public Intent intent() { return Intent.UI_HINT; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetFromToStringMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetFromToStringMethod.java index 14a08e92da2..347a7256716 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetFromToStringMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetFromToStringMethod.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -33,13 +34,14 @@ import org.apache.causeway.core.metamodel.facets.object.title.TitleRenderRequest; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class TitleFacetFromToStringMethod extends TitleFacetAbstract implements HasImperativeAspect { - @Getter(onMethod_ = {@Override}) private final @NonNull ImperativeAspect imperativeAspect; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull ImperativeAspect imperativeAspect; public static Optional create( final @Nullable ResolvedMethod methodIfAny, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java index 68e8a809598..706ea5731bf 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/title/methods/TitleFacetViaTitleMethod.java @@ -36,6 +36,8 @@ import org.apache.causeway.core.metamodel.object.ManagedObjects; import lombok.Getter; +import lombok.experimental.Accessors; + import org.jspecify.annotations.NonNull; import lombok.extern.slf4j.Slf4j; @@ -44,7 +46,8 @@ public class TitleFacetViaTitleMethod extends TitleFacetAbstract implements HasImperativeAspect { - @Getter(onMethod_ = {@Override}) private final @NonNull ImperativeAspect imperativeAspect; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull ImperativeAspect imperativeAspect; private final TranslationContext translationContext; public static Optional create( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java index c322b857d3e..45e154fac3e 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -38,13 +40,14 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterAutoCompleteFacetViaMethod extends ActionParameterAutoCompleteFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final ResolvedType paramSupportReturnType; private final int minLength; private final Optional patConstructor; @@ -63,7 +66,7 @@ public ActionParameterAutoCompleteFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHOICES_OR_AUTOCOMPLETE; } 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 b66cf424592..4dcdcd7715a 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 @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -38,13 +40,14 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterChoicesFacetViaMethod extends ActionParameterChoicesFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final ResolvedType paramSupportReturnType; private final Optional patConstructor; @@ -61,7 +64,7 @@ public ActionParameterChoicesFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHOICES_OR_AUTOCOMPLETE; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java index 349f16a3c1e..6ff0c4f338c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor; @@ -34,13 +36,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterDefaultsFacetViaMethod extends ActionParameterDefaultsFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final int paramNum; private final Optional patConstructor; @@ -63,7 +66,7 @@ public ActionParameterDefaultsFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.DEFAULTS; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java index 1557b86eeed..c2cb958daf1 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/disable/method/ActionParameterDisabledFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; @@ -35,13 +37,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterDisabledFacetViaMethod extends ActionParameterDisabledFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationContext translationContext; private final Optional patConstructor; @@ -57,7 +60,7 @@ public ActionParameterDisabledFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_VALID; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/HiddenFacetForActionParameter.java similarity index 97% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/HiddenFacetForActionParameter.java index cb0ded7b205..2481d0cf4e9 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/ActionParameterHiddenFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/HiddenFacetForActionParameter.java @@ -30,7 +30,7 @@ * In the standard Apache Causeway Programming Model, corresponds to invoking the * hideNXxx support method for an action. */ -public interface ActionParameterHiddenFacet +public interface HiddenFacetForActionParameter extends HidingInteractionAdvisor { /** diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethodFactory.java index 2ea4457fba4..3dd97ac4ea7 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethodFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethodFactory.java @@ -24,11 +24,11 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facets.FacetedMethodParameter; import org.apache.causeway.core.metamodel.facets.ParameterSupport.ParamSupportingMethodSearchResult; -import org.apache.causeway.core.metamodel.facets.param.hide.ActionParameterHiddenFacet; +import org.apache.causeway.core.metamodel.facets.param.hide.HiddenFacetForActionParameter; import org.apache.causeway.core.metamodel.facets.param.support.ActionParameterSupportFacetFactoryAbstract; /** - * Sets up {@link ActionParameterHiddenFacet}. + * Sets up {@link HiddenFacetForActionParameter}. */ public class ActionParameterHiddenFacetViaMethodFactory extends ActionParameterSupportFacetFactoryAbstract { @@ -45,7 +45,7 @@ protected void onSearchResult( var hideMethod = searchResult.supportingMethod(); var patConstructor = searchResult.patConstructor(); addFacet( - new ActionParameterHiddenFacetViaMethod( + new HiddenFacetForActionParameterViaMethod( hideMethod, patConstructor, paramAsHolder)); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/HiddenFacetForActionParameterViaMethod.java similarity index 83% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/HiddenFacetForActionParameterViaMethod.java index 504a5fdf23d..5a0413760d7 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/ActionParameterHiddenFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/method/HiddenFacetForActionParameterViaMethod.java @@ -30,25 +30,23 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; -import org.apache.causeway.core.metamodel.facets.param.hide.ActionParameterHiddenFacet; +import org.apache.causeway.core.metamodel.facets.param.hide.HiddenFacetForActionParameter; import org.apache.causeway.core.metamodel.interactions.vis.ParamVisibilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmInvokeUtils; -public record ActionParameterHiddenFacetViaMethod( +public record HiddenFacetForActionParameterViaMethod( Can methods, Optional patConstructor, FacetHolder facetHolder - ) implements ActionParameterHiddenFacet, ImperativeFacet { + ) implements HiddenFacetForActionParameter, ImperativeFacet { - @Override public Class facetType() { return ActionParameterHiddenFacet.class; } + @Override public Class facetType() { return HiddenFacetForActionParameter.class; } @Override public Precedence precedence() { return Precedence.DEFAULT; } - @Override public Intent getIntent() { return Intent.CHECK_IF_VALID;} + @Override public Intent intent() { return Intent.CHECK_IF_VALID;} - public Can getMethods() { return methods(); } - - public ActionParameterHiddenFacetViaMethod( + public HiddenFacetForActionParameterViaMethod( final ResolvedMethod method, final Optional patConstructor, final FacetHolder holder) { @@ -85,18 +83,18 @@ public boolean isHidden( @Override public boolean semanticEquals(final @NonNull Facet otherFacet) { - if(! (otherFacet instanceof ActionParameterHiddenFacetViaMethod)) { + if(! (otherFacet instanceof HiddenFacetForActionParameterViaMethod)) { return false; } - var other = (ActionParameterHiddenFacetViaMethod)otherFacet; + var other = (HiddenFacetForActionParameterViaMethod)otherFacet; return this.patConstructor.equals(other.patConstructor) - && this.getMethods().equals(other.getMethods()); + && this.methods().equals(other.methods()); } @Override public void visitAttributes(final BiConsumer visitor) { - ActionParameterHiddenFacet.super.visitAttributes(visitor); + HiddenFacetForActionParameter.super.visitAttributes(visitor); ImperativeFacet.visitAttributes(this, visitor); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java index 40c70a6787a..1db3be69c8c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/validate/method/ActionParameterValidationFacetViaMethod.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; @@ -34,13 +36,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class ActionParameterValidationFacetViaMethod extends ActionParameterValidationFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationContext translationContext; private final Optional patConstructor; @@ -56,7 +59,7 @@ public ActionParameterValidationFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_VALID; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java index 10913b41585..dbf5b053d8a 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -33,13 +35,14 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyAccessorFacetViaAccessor extends PropertyOrCollectionAccessorFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertyAccessorFacetViaAccessor( final ObjectSpecification declaringType, @@ -51,7 +54,7 @@ public PropertyAccessorFacetViaAccessor( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.ACCESSOR; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java index b5f98633ffe..52b0392efe0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -33,13 +35,14 @@ import org.apache.causeway.core.metamodel.object.MmVisibilityUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyAutoCompleteFacetMethod extends PropertyAutoCompleteFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final Class choicesClass; private final int minLength; @@ -54,7 +57,7 @@ public PropertyAutoCompleteFacetMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHOICES_OR_AUTOCOMPLETE; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethod.java index 830d1d907f2..e5855bef4b2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -33,13 +35,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyChoicesFacetViaMethod extends PropertyChoicesFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final Class choicesClass; public PropertyChoicesFacetViaMethod( @@ -52,7 +55,7 @@ public PropertyChoicesFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHOICES_OR_AUTOCOMPLETE; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethod.java index f1eb5b3c6aa..3e6a21e2664 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.exceptions.unrecoverable.UnknownTypeException; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; @@ -31,13 +33,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyDefaultFacetViaMethod extends PropertyDefaultFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertyDefaultFacetViaMethod( final ResolvedMethod method, @@ -47,7 +50,7 @@ public PropertyDefaultFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.DEFAULTS; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutAnnotation.java index fa313b9c518..8e40de8f247 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutAnnotation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutAnnotation.java @@ -23,11 +23,11 @@ import org.apache.causeway.applib.annotation.PropertyLayout; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; public class HiddenFacetForPropertyLayoutAnnotation -extends HiddenFacetAbstract { +extends HiddenFacetForLayoutAbstract { public static Optional create( final Optional propertyLayoutIfAny, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutXml.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutXml.java index 2e3ded06dd0..d2fba54f62b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutXml.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/HiddenFacetForPropertyLayoutXml.java @@ -23,14 +23,14 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.PropertyLayoutData; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.object.ManagedObject; public class HiddenFacetForPropertyLayoutXml -extends HiddenFacetAbstract { +extends HiddenFacetForLayoutAbstract { - public static Optional create( + public static Optional create( final PropertyLayoutData propertyLayout, final FacetHolder holder, final Precedence precedence) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java index e8395fe1f2a..bb2b49ff5c4 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaClearMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -31,13 +33,14 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyClearFacetViaClearMethod extends PropertyClearFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertyClearFacetViaClearMethod(final ResolvedMethod method, final FacetHolder holder) { super(holder); @@ -45,7 +48,7 @@ public PropertyClearFacetViaClearMethod(final ResolvedMethod method, final Facet } @Override - public Intent getIntent() { + public Intent intent() { return Intent.MODIFY_PROPERTY_SUPPORTING; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java index 68897a2e357..d4ed62aa867 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/clear/PropertyClearFacetViaSetterMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -31,13 +33,14 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyClearFacetViaSetterMethod extends PropertyClearFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertyClearFacetViaSetterMethod(final ResolvedMethod method, final FacetHolder holder) { super(holder); @@ -45,7 +48,7 @@ public PropertyClearFacetViaSetterMethod(final ResolvedMethod method, final Face } @Override - public Intent getIntent() { + public Intent intent() { return Intent.MODIFY_PROPERTY; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java index 42a06b25c9a..67d5bf40663 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/init/PropertyInitializationFacetViaSetterMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -29,13 +31,14 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyInitializationFacetViaSetterMethod extends PropertyInitializationFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertyInitializationFacetViaSetterMethod(final ResolvedMethod method, final FacetHolder holder) { super(holder); @@ -43,7 +46,7 @@ public PropertyInitializationFacetViaSetterMethod(final ResolvedMethod method, f } @Override - public Intent getIntent() { + public Intent intent() { // LIMITATION: we cannot distinguish between setXxx being called for a modify or for an initialization // so we just assume its a setter. return Intent.MODIFY_PROPERTY; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java index 73642bdd23b..d718108cdd5 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/update/modify/PropertySetterFacetViaSetterMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod; import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade; @@ -31,13 +33,14 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertySetterFacetViaSetterMethod extends PropertySetterFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; public PropertySetterFacetViaSetterMethod(final ResolvedMethod method, final FacetHolder holder) { super(holder); @@ -45,7 +48,7 @@ public PropertySetterFacetViaSetterMethod(final ResolvedMethod method, final Fac } @Override - public Intent getIntent() { + public Intent intent() { return Intent.MODIFY_PROPERTY; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java index 6d45cd1d404..e0f7c6d55fa 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethod.java @@ -20,6 +20,8 @@ import java.util.function.BiConsumer; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.commons.collections.Can; @@ -32,11 +34,12 @@ import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import lombok.Getter; -import org.jspecify.annotations.NonNull; +import lombok.experimental.Accessors; public class PropertyValidateFacetViaMethod extends PropertyValidateFacetAbstract implements ImperativeFacet { - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; + @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) + private final @NonNull Can methods; private final TranslationContext translationContext; public PropertyValidateFacetViaMethod( @@ -48,7 +51,7 @@ public PropertyValidateFacetViaMethod( } @Override - public Intent getIntent() { + public Intent intent() { return Intent.CHECK_IF_VALID; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java index 27acff9c1b6..1d676d2b80d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/HidingInteractionAdvisor.java @@ -20,9 +20,9 @@ import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenObjectFacet; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForObject; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForNoMembersAuthorized; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; /** @@ -34,9 +34,9 @@ *

In the standard Apache Causeway Programming Model, typically corresponds to the * hidden method. * - * @see HiddenFacet - * @see HiddenObjectFacet - * @see HiddenTypeFacet + * @see HiddenFacetForLayout + * @see HiddenFacetForObject + * @see HiddenFacetForNoMembersAuthorized * @see DisablingInteractionAdvisor * @see ValidatingInteractionAdvisor * diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/LayoutFacetUtil.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/LayoutFacetUtil.java index 42d581c4f87..41c6cec24a2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/LayoutFacetUtil.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/LayoutFacetUtil.java @@ -44,7 +44,7 @@ import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacet; import org.apache.causeway.core.metamodel.facets.all.described.MemberDescribedFacet; import org.apache.causeway.core.metamodel.facets.all.described.ObjectDescribedFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.facets.all.named.ObjectNamedFacet; import org.apache.causeway.core.metamodel.facets.collections.collection.defaultview.DefaultViewFacet; @@ -299,7 +299,7 @@ private void setHiddenIfAny( final HasHidden hasHidden, final FacetHolder facetHolder) { - var hiddenFacet = facetHolder.getFacet(HiddenFacet.class); + var hiddenFacet = facetHolder.getFacet(HiddenFacetForLayout.class); if (isNonFallback(hiddenFacet)) { final Where where = hiddenFacet.where(); if(where != null) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java index beb035cb80d..b66df8ab8be 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java @@ -35,7 +35,7 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; /** - * Optionally hide or disable an object, property, collection or action + * Optionally hides or disables an object, property, collection or action * depending on the authorization. */ public interface AuthorizationFacet diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java similarity index 81% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java index 4453d8a3671..127578a7af8 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenType.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java @@ -25,27 +25,27 @@ import org.apache.causeway.commons.internal.assertions._Assert; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.members.navigation.NavigationFacet; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; +import org.apache.causeway.core.metamodel.facets.members.navigation.HiddenFacetForNavigation; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForNoMembersAuthorized; import org.apache.causeway.core.metamodel.interactions.vis.ObjectVisibilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; -public record NavigationFacetFromHiddenType( +public record HiddenFacetForNavigationFromHiddenType( ObjectSpecification navigatedType, FacetHolder facetHolder - ) implements NavigationFacet { + ) implements HiddenFacetForNavigation { - public static Optional create(final ObjectSpecification navigatedType, final FacetHolder holder) { + public static Optional create(final ObjectSpecification navigatedType, final FacetHolder holder) { return navigatedType.isValue() ? Optional.empty() // don't create for value types (optimization, not strictly required) - : Optional.of(new NavigationFacetFromHiddenType(navigatedType, holder)); + : Optional.of(new HiddenFacetForNavigationFromHiddenType(navigatedType, holder)); } - @Override public Class facetType() { return NavigationFacet.class; } + @Override public Class facetType() { return HiddenFacetForNavigation.class; } @Override public Precedence precedence() { return Precedence.DEFAULT; } - public NavigationFacetFromHiddenType { + public HiddenFacetForNavigationFromHiddenType { _Assert.assertTrue(navigatedType.isSingular(), ()->String.format( "framework bug: elementType must not match any supported plural (collection) types, " + "nevertheless got %s", navigatedType)); @@ -53,7 +53,7 @@ public static Optional create(final ObjectSpecification navigat @Override public String hides(final VisibilityContext ic) { - var facet = navigatedType.getFacet(HiddenTypeFacet.class); + var facet = navigatedType.getFacet(HiddenFacetForNoMembersAuthorized.class); if(facet == null) { // not expected to happen; this facet should only be installed for object members // that navigate to a class that has the HiddenTypeFacet @@ -71,7 +71,7 @@ public String hides(final VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - NavigationFacet.super.visitAttributes(visitor); + HiddenFacetForNavigation.super.visitAttributes(visitor); visitor.accept("navigatedType", navigatedType.logicalTypeName()); visitor.accept("navigatedTypeFqcn", navigatedType.getCorrespondingClass().getName()); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenTypePostProcessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenTypePostProcessor.java index 66bcc7ed094..e961f316e88 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenTypePostProcessor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/NavigationFacetFromHiddenTypePostProcessor.java @@ -23,7 +23,7 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacet; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForNoMembersAuthorized; import org.apache.causeway.core.metamodel.postprocessors.MetaModelPostProcessorAbstract; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -32,7 +32,7 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; /** - * Installs the {@link NavigationFacetFromHiddenType} on all of the + * Installs the {@link HiddenFacetForNavigationFromHiddenType} on all of the * {@link ObjectMember}s of the {@link ObjectSpecification}. */ public class NavigationFacetFromHiddenTypePostProcessor extends MetaModelPostProcessorAbstract { @@ -60,8 +60,8 @@ public void postProcessCollection(final ObjectSpecification objectSpecification, // -- HELPER private static void addFacetIfRequired(final FacetHolder facetHolder, final ObjectSpecification navigatedType) { - if(navigatedType.containsNonFallbackFacet(HiddenTypeFacet.class)) { - FacetUtil.addFacetIfPresent(NavigationFacetFromHiddenType.create(navigatedType, facetHolder)); + if(navigatedType.containsNonFallbackFacet(HiddenFacetForNoMembersAuthorized.class)) { + FacetUtil.addFacetIfPresent(HiddenFacetForNavigationFromHiddenType.create(navigatedType, facetHolder)); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java index d286c6f943a..06423d74062 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java @@ -51,7 +51,7 @@ import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.SingleIntValueFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.objectvalue.maxlen.MaxLengthFacet; import org.apache.causeway.core.metamodel.facets.objectvalue.typicallen.TypicalLengthFacet; import org.apache.causeway.core.metamodel.facets.properties.update.modify.PropertySetterFacet; @@ -359,7 +359,7 @@ protected boolean exclude(final ObjectSpecification spec) { } protected boolean isHidden(final ObjectSpecification spec) { - return HiddenFacet.isAlwaysHidden(spec); + return HiddenFacetForLayout.isAlwaysHidden(spec); } protected boolean isBuiltIn(final ObjectSpecification spec) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java index 1042dfc5284..e69ab7abc55 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java @@ -37,7 +37,7 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; import org.apache.causeway.core.metamodel.facets.actions.validate.ActionValidationFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.members.disabled.DisabledFacet; import org.apache.causeway.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet; import org.apache.causeway.core.metamodel.facets.param.choices.ActionParameterChoicesFacet; @@ -164,7 +164,7 @@ public String getMixin() { @XmlElement @Override public String getHidden() { - return interpret(HiddenFacet.class); + return interpret(HiddenFacetForLayout.class); } @XmlElement @Override @@ -271,7 +271,7 @@ private static String interpretFacet(final Facet facet) { } if (facet instanceof ImperativeFacet) { ImperativeFacet imperativeFacet = (ImperativeFacet) facet; - return imperativeFacet.getMethods().getFirstElseFail().getName(); + return imperativeFacet.methods().getFirstElseFail().getName(); } final String name = facet.getClass().getSimpleName(); if (ignore(name)) { 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 d2ecdd8ca1a..5ef09db0245 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 @@ -50,7 +50,7 @@ import org.apache.causeway.core.metamodel.facetapi.HasFacetHolder; import org.apache.causeway.core.metamodel.facets.all.described.ObjectDescribedFacet; import org.apache.causeway.core.metamodel.facets.all.help.HelpFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.i8n.noun.HasNoun; import org.apache.causeway.core.metamodel.facets.all.i8n.staatic.HasStaticText; import org.apache.causeway.core.metamodel.facets.all.named.ObjectNamedFacet; @@ -391,7 +391,7 @@ default boolean isValueOrIsParented() { boolean isImmutable(); /** - * Whether has the {@link HiddenFacet} + * Whether has the {@link HiddenFacetForLayout} */ boolean isHidden(); 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 993c9537233..7c9dd3de031 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 @@ -43,7 +43,7 @@ import org.apache.causeway.core.metamodel.facets.WhereValueFacet; import org.apache.causeway.core.metamodel.facets.actions.action.choicesfrom.ChoicesFromFacet; import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.members.iconfa.FaFacet; import org.apache.causeway.core.metamodel.facets.members.iconfa.FaLayersProvider; import org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet; @@ -480,10 +480,10 @@ public static Predicate choicesFromAndHavingCollectionParameterFor } /** - * Returns true if no {@link HiddenFacet} is found that vetoes visibility. + * Returns true if no {@link HiddenFacetForLayout} is found that vetoes visibility. *

* However, whereHidden={@link Where#ALL_TABLES} is used as default - * when no {@link HiddenFacet} is found. + * when no {@link HiddenFacetForLayout} is found. * * @see ObjectAssociation.Predicates#visibleAccordingToHiddenFacet(Where) * @@ -491,7 +491,7 @@ public static Predicate choicesFromAndHavingCollectionParameterFor * however the current approach is more heap friendly */ public static Predicate visibleAccordingToHiddenFacet(final Where whereContext) { - return (final ObjectAction act) -> act.lookupFacet(HiddenFacet.class) + return (final ObjectAction act) -> act.lookupFacet(HiddenFacetForLayout.class) .map(WhereValueFacet.class::cast) .map(WhereValueFacet::where) // whereHidden=ALL_TABLES is the default when not specified otherwise diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java index 55204ee56d3..e6562079b7c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java @@ -29,7 +29,7 @@ import org.apache.causeway.commons.internal.functions._Predicates; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.WhereValueFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.util.Facets; @@ -139,7 +139,7 @@ private Predicates(){} public static Predicate staticallyVisible(final Where where) { return assoc -> { var b = assoc.streamFacets() - .filter(facet -> facet instanceof HiddenFacet) + .filter(facet -> facet instanceof HiddenFacetForLayout) .map(facet -> (WhereValueFacet) facet) .anyMatch(wawF -> wawF.where().includes(where)); return !b; @@ -147,10 +147,10 @@ public static Predicate staticallyVisible(final Where where) } /** - * Returns true if no {@link HiddenFacet} is found that vetoes visibility. + * Returns true if no {@link HiddenFacetForLayout} is found that vetoes visibility. *

* However, if it's a 1-to-Many, whereHidden={@link Where#ALL_TABLES} is used as default - * when no {@link HiddenFacet} is found. + * when no {@link HiddenFacetForLayout} is found. * * @see ObjectAction.Predicates#visibleAccordingToHiddenFacet(Where) * @@ -158,7 +158,7 @@ public static Predicate staticallyVisible(final Where where) * however the current approach is more heap friendly */ public static Predicate visibleAccordingToHiddenFacet(final Where whereContext) { - return (final ObjectAssociation assoc) -> assoc.lookupFacet(HiddenFacet.class) + return (final ObjectAssociation assoc) -> assoc.lookupFacet(HiddenFacetForLayout.class) .map(WhereValueFacet.class::cast) .map(WhereValueFacet::where) // in case it's a 1-to-Many, whereHidden=ALL_TABLES is the default when not specified otherwise diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java index d463c5c656d..f72c4bc4f59 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java @@ -35,7 +35,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.collections.sortedby.SortedByFacet; import org.apache.causeway.core.metamodel.facets.object.paged.PagedFacet; import org.apache.causeway.core.metamodel.facets.object.tabledec.TableDecoratorFacet; @@ -80,8 +80,8 @@ public interface ObjectMember extends ObjectFeature { * When the member is always hidden. * *

- * Determined as per the {@link HiddenFacet} being present and - * {@link HiddenFacet#where()} returning {@link Where#ANYWHERE}. + * Determined as per the {@link HiddenFacetForLayout} being present and + * {@link HiddenFacetForLayout#where()} returning {@link Where#ANYWHERE}. */ boolean isAlwaysHidden(); 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 e8bc2ace6cb..408c5ac95b7 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 @@ -48,7 +48,7 @@ import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionInvocationFacet; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; +import org.apache.causeway.core.metamodel.facets.actions.prototype.HiddenFacetForDeploymentType; import org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacet; import org.apache.causeway.core.metamodel.facets.param.choices.ActionParameterChoicesFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; @@ -202,7 +202,7 @@ public ActionScope getScope() { } private static ActionScope getScope(final FacetHolder facetHolder) { - return facetHolder.containsFacet(PrototypeFacet.class) + return facetHolder.containsFacet(HiddenFacetForDeploymentType.class) ? ActionScope.PROTOTYPE : ActionScope.PRODUCTION; } 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 cd53c40cb7c..c293cc0bfde 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 @@ -42,7 +42,7 @@ import org.apache.causeway.core.metamodel.facets.HasFacetedMethod; import org.apache.causeway.core.metamodel.facets.all.described.MemberDescribedFacet; import org.apache.causeway.core.metamodel.facets.all.help.HelpFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.i8n.staatic.HasStaticText; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.interactions.DisablingInteractionAdvisor; @@ -201,7 +201,7 @@ protected abstract VisibilityContext createVisibleInteractionContext( @Override public boolean isAlwaysHidden() { - return HiddenFacet.isAlwaysHidden(getFacetHolder()); + return HiddenFacetForLayout.isAlwaysHidden(getFacetHolder()); } /** 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 381916f1a51..51319832e4f 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 @@ -75,7 +75,7 @@ import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.facets.all.described.ObjectDescribedFacet; import org.apache.causeway.core.metamodel.facets.all.help.HelpFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacetForStaticMemberName; import org.apache.causeway.core.metamodel.facets.all.named.ObjectNamedFacet; @@ -352,7 +352,7 @@ private void cataloguePropertiesAndCollections(final BiConsumer field.streamFacets(ImperativeFacet.class) - .map(ImperativeFacet::getMethods) + .map(ImperativeFacet::methods) .flatMap(Can::stream) .map(MethodFacade::asMethodElseFail) // expected regular .peek(method->_Reflect.guardAgainstSynthetic(method.method())) // expected non-synthetic @@ -363,7 +363,7 @@ private void catalogueActions(final BiConsumer onM streamDeclaredActions(MixedIn.INCLUDED) .forEach(userAction-> userAction.streamFacets(ImperativeFacet.class) - .map(ImperativeFacet::getMethods) + .map(ImperativeFacet::methods) .flatMap(Can::stream) .map(MethodFacade::asMethodForIntrospection) .peek(method->_Reflect.guardAgainstSynthetic(method.method())) // expected non-synthetic @@ -1184,7 +1184,7 @@ public boolean isImmutable() { @Override public boolean isHidden() { - return containsFacet(HiddenFacet.class); + return containsFacet(HiddenFacetForLayout.class); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java index 5ce2f3c7c2f..df9536a1f9b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java @@ -36,7 +36,7 @@ import org.apache.causeway.core.metamodel.facets.members.cssclass.annotprop.CssClassFacetOnActionFromConfiguredRegexFactory; import org.apache.causeway.core.metamodel.facets.members.described.method.DescribedAsFacetForMemberViaMethodFactory; import org.apache.causeway.core.metamodel.facets.members.disabled.method.DisableForContextFacetViaMethodFactory; -import org.apache.causeway.core.metamodel.facets.members.hidden.method.HideForContextFacetViaMethodFactory; +import org.apache.causeway.core.metamodel.facets.members.hidden.method.HiddenFacetForMemberViaMethodFactory; import org.apache.causeway.core.metamodel.facets.members.named.method.NamedFacetForMemberViaMethodFactory; import org.apache.causeway.core.metamodel.facets.object.ViewModelSemanticCheckingFacetFactory; import org.apache.causeway.core.metamodel.facets.object.bookmarkpolicy.bookmarkable.BookmarkPolicyFacetFallbackFactory; @@ -181,7 +181,7 @@ private void addFacetFactories() { addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new NamedFacetForMemberViaMethodFactory(mmc)); addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new DescribedAsFacetForMemberViaMethodFactory(mmc)); addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new DisableForContextFacetViaMethodFactory(mmc)); - addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new HideForContextFacetViaMethodFactory(mmc)); + addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new HiddenFacetForMemberViaMethodFactory(mmc)); addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new CallbackFacetFactory(mmc)); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ValidatorDomainIncludeAnnotationEnforcesMetamodelContribution.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ValidatorDomainIncludeAnnotationEnforcesMetamodelContribution.java index 555f5a27a92..663322b1120 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ValidatorDomainIncludeAnnotationEnforcesMetamodelContribution.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ValidatorDomainIncludeAnnotationEnforcesMetamodelContribution.java @@ -105,7 +105,7 @@ public void validateObjectEnter(final ObjectSpecification spec) { .flatMap(Optional::stream) .filter(ImperativeFacet.class::isInstance) .map(ImperativeFacet.class::cast) - .map(ImperativeFacet::getMethods) + .map(ImperativeFacet::methods) .flatMap(Can::stream) .map(MethodFacade::asMethodForIntrospection) .forEach(supportMethods::add); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/_SpecPredicates.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/_SpecPredicates.java index df1d5fea4d9..b6de9c0e158 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/_SpecPredicates.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/_SpecPredicates.java @@ -19,7 +19,7 @@ package org.apache.causeway.core.metamodel.spec.impl; import org.apache.causeway.core.metamodel.facets.actions.contributing.ContributingFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.jspecify.annotations.NonNull; @@ -42,7 +42,7 @@ static boolean isGetterCandidate(final @NonNull ObjectAction action) { // -- HIGHER LEVEL - MIXINS static boolean isMixedInAction(final @NonNull ObjectAction mixinAction) { - if(HiddenFacet.isAlwaysHidden(mixinAction)) { + if(HiddenFacetForLayout.isAlwaysHidden(mixinAction)) { return false; } if(ContributingFacet.isActionContributionVetoed(mixinAction)) { @@ -58,7 +58,7 @@ static boolean isMixedInAssociation(final @NonNull ObjectAction mixinAction) { if(!mixinAction.getSemantics().isSafeInNature()) { return false; } - if(HiddenFacet.isAlwaysHidden(mixinAction)) { + if(HiddenFacetForLayout.isAlwaysHidden(mixinAction)) { return false; } if(ContributingFacet.isAssociationContributionVetoed(mixinAction)) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java index c779e530803..25790ca52d6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java @@ -50,7 +50,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; import org.apache.causeway.core.metamodel.facets.collections.collection.defaultview.DefaultViewFacet; import org.apache.causeway.core.metamodel.facets.members.cssclass.CssClassFacet; @@ -212,8 +212,8 @@ public boolean hasSafeSemantics(final FacetHolder holder) { } public Optional hiddenWhere(final ObjectFeature feature) { - return feature.lookupFacet(HiddenFacet.class) - .map(HiddenFacet::where); + return feature.lookupFacet(HiddenFacetForLayout.class) + .map(HiddenFacetForLayout::where); } public Predicate hiddenWhereMatches(final Predicate matcher) { diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java index 6e284489ccb..c7b31cba497 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/FacetFactoryTestAbstract.java @@ -479,7 +479,7 @@ protected final void assertMethodWasRemoved(final Class type, final String me protected final void assertMethodEqualsFirstIn( final @NonNull ResolvedMethod method, final @NonNull ImperativeFacet imperativeFacet) { - _Utils.assertMethodEquals(method, imperativeFacet.getMethods().getFirstElseFail().asMethodElseFail()); + _Utils.assertMethodEquals(method, imperativeFacet.methods().getFirstElseFail().asMethodElseFail()); } } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java index 6233eab87e8..920a40de5de 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactoryTest_RestrictTo.java @@ -25,7 +25,7 @@ import org.apache.causeway.applib.annotation.Action; import org.apache.causeway.core.metamodel.facets.FacetFactory.ProcessMethodContext; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; +import org.apache.causeway.core.metamodel.facets.actions.prototype.HiddenFacetForDeploymentType; class ActionAnnotationFacetFactoryTest_RestrictTo extends ActionAnnotationFacetFactoryTest { @@ -49,7 +49,7 @@ public void someAction() {} // when processRestrictTo(facetFactory, processMethodContext); // then - final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class); + final HiddenFacetForDeploymentType facet = facetedMethod.getFacet(HiddenFacetForDeploymentType.class); assertNotNull(facet); }); } @@ -67,7 +67,7 @@ public void someAction() {} // when processRestrictTo(facetFactory, processMethodContext); // then - final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class); + final HiddenFacetForDeploymentType facet = facetedMethod.getFacet(HiddenFacetForDeploymentType.class); assertNull(facet); }); } @@ -85,7 +85,7 @@ public void someAction() {} // when processRestrictTo(facetFactory, processMethodContext); // then - final PrototypeFacet facet = facetedMethod.getFacet(PrototypeFacet.class); + final HiddenFacetForDeploymentType facet = facetedMethod.getFacet(HiddenFacetForDeploymentType.class); assertNull(facet); }); } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java index 801c09362ee..58be1f2173c 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/action/PrototypeFacetAnnotationFactoryTest.java @@ -30,7 +30,7 @@ import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.FacetFactory.ProcessMethodContext; import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract; -import org.apache.causeway.core.metamodel.facets.actions.prototype.PrototypeFacet; +import org.apache.causeway.core.metamodel.facets.actions.prototype.HiddenFacetForDeploymentType; class PrototypeFacetAnnotationFactoryTest extends FacetFactoryTestAbstract { @@ -63,9 +63,9 @@ public void someAction() {} //when processRestrictTo(facetFactory, processMethodContext); //then - final Facet facet = facetedMethod.getFacet(PrototypeFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForDeploymentType.class); assertNotNull(facet); - assertTrue(facet instanceof PrototypeFacet); + assertTrue(facet instanceof HiddenFacetForDeploymentType); assertNoMethodsRemoved(); }); } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/layout/ActionLayoutAnnotationFacetFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/layout/ActionLayoutAnnotationFacetFactoryTest.java index e01bf5a4696..6f7417bc5a9 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/layout/ActionLayoutAnnotationFacetFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/layout/ActionLayoutAnnotationFacetFactoryTest.java @@ -35,7 +35,7 @@ import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract; import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacet; import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacetFallback; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.members.iconfa.FaFacet; class ActionLayoutAnnotationFacetFactoryTest @@ -78,7 +78,7 @@ class Customer { actionScenario(Customer.class, "foz", (processMethodContext, facetHolder, facetedMethod)->{ facetFactory.process(processMethodContext); - final Facet facet = facetedMethod.getFacet(HiddenFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForLayout.class); assertNotNull(facet); assertTrue(facet instanceof HiddenFacetForActionLayoutAnnotation); var actionLayoutFacetAnnotation = (HiddenFacetForActionLayoutAnnotation) facet; diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java index 7b9297e2c69..1320d9170b9 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/actions/prototype/PrototypeFacetAbstractTest.java @@ -25,7 +25,7 @@ import org.apache.causeway.core.config.environment.DeploymentType; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.facets.actions.action.prototype.PrototypeFacetForActionAnnotation; +import org.apache.causeway.core.metamodel.facets.actions.action.prototype.HiddenFacetForDeploymentTypeViaActionAnnotation; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; class PrototypeFacetAbstractTest { @@ -41,7 +41,7 @@ public void allCombinations() throws Exception { protected void givenWhenThen(final DeploymentType deploymentType, final String expected) { // given - var facet = new PrototypeFacetForActionAnnotation( + var facet = new HiddenFacetForDeploymentTypeViaActionAnnotation( deploymentType, mockFacetHolder); // when diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/collections/layout/annotation/CollectionLayoutAnnotationFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/collections/layout/annotation/CollectionLayoutAnnotationFactoryTest.java index 3cf86cc2d00..2516dc01410 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/collections/layout/annotation/CollectionLayoutAnnotationFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/collections/layout/annotation/CollectionLayoutAnnotationFactoryTest.java @@ -36,7 +36,7 @@ import org.apache.causeway.commons.internal.collections._Sets; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.i8n.staatic.HasStaticText; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.facets.collections.layout.CollectionLayoutFacetFactory; @@ -75,7 +75,7 @@ class Customer { // when facetFactory.process(processMethodContext); // then - final Facet facet = facetedMethod.getFacet(HiddenFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForLayout.class); assertNotNull(facet); assertTrue(facet instanceof HiddenFacetForCollectionLayoutAnnotation); final HiddenFacetForCollectionLayoutAnnotation collLayoutFacetAnnotation = (HiddenFacetForCollectionLayoutAnnotation) facet; diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/callback/CallbackFacetFactoryTestAbstract.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/callback/CallbackFacetFactoryTestAbstract.java index 105265ac066..1ff2c9a48f1 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/callback/CallbackFacetFactoryTestAbstract.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/callback/CallbackFacetFactoryTestAbstract.java @@ -81,7 +81,7 @@ protected void assertPicksUp( callbackMethods.forEach(method->{ assertMethodWasRemoved(method); - assertTrue(imperativeFacet.getMethods() + assertTrue(imperativeFacet.methods() .map(MethodFacade::asMethodElseFail).contains(method)); }); }); diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/hidden/ObjectHiddenMethodFacetFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/hidden/ObjectHiddenMethodFacetFactoryTest.java index 6d81e95afd6..5079303d2d3 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/hidden/ObjectHiddenMethodFacetFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/hidden/ObjectHiddenMethodFacetFactoryTest.java @@ -34,7 +34,7 @@ public boolean hidden() { return true; } } - assertPicksUp(1, facetFactory, Customer.class, ObjectSupportMethod.HIDDEN, HiddenObjectFacet.class); + assertPicksUp(1, facetFactory, Customer.class, ObjectSupportMethod.HIDDEN, HiddenFacetForObject.class); } } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactoryTestAbstract.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactoryTestAbstract.java index 086a9e17bf6..7706b3fb8a5 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactoryTestAbstract.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/object/support/ObjectSupportFacetFactoryTestAbstract.java @@ -77,7 +77,7 @@ protected void assertPicksUp( supportMethods.forEach(method->{ assertMethodWasRemoved(method); - assertTrue(imperativeFacet.getMethods() + assertTrue(imperativeFacet.methods() .map(MethodFacade::asMethodElseFail).contains(method)); }); diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/PropertyMethodsFacetFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/PropertyMethodsFacetFactoryTest.java index 90821cfaa9d..6c4b292a7ea 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/PropertyMethodsFacetFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/PropertyMethodsFacetFactoryTest.java @@ -30,9 +30,9 @@ import org.apache.causeway.core.metamodel.facets.members.disabled.method.DisableForContextFacet; import org.apache.causeway.core.metamodel.facets.members.disabled.method.DisableForContextFacetViaMethod; import org.apache.causeway.core.metamodel.facets.members.disabled.method.DisableForContextFacetViaMethodFactory; -import org.apache.causeway.core.metamodel.facets.members.hidden.method.HideForContextFacet; -import org.apache.causeway.core.metamodel.facets.members.hidden.method.HideForContextFacetViaMethod; -import org.apache.causeway.core.metamodel.facets.members.hidden.method.HideForContextFacetViaMethodFactory; +import org.apache.causeway.core.metamodel.facets.members.hidden.method.HiddenFacetForMember; +import org.apache.causeway.core.metamodel.facets.members.hidden.method.HiddenFacetForMemberViaMethod; +import org.apache.causeway.core.metamodel.facets.members.hidden.method.HiddenFacetForMemberViaMethodFactory; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.causeway.core.metamodel.facets.propcoll.memserexcl.SnapshotExcludeFacet; import org.apache.causeway.core.metamodel.facets.properties.accessor.PropertyAccessorFacetViaAccessor; @@ -312,7 +312,7 @@ class Customer { @Test void hiddenFacetFoundAndMethodRemoved() { - var facetFactory = new HideForContextFacetViaMethodFactory(getMetaModelContext()); + var facetFactory = new HiddenFacetForMemberViaMethodFactory(getMetaModelContext()); @SuppressWarnings("unused") class Customer { public String getFirstName() { return null; } @@ -325,10 +325,10 @@ class Customer { // when facetFactory.process(processMethodContext); // then - final Facet facet = facetedMethod.getFacet(HideForContextFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForMember.class); assertNotNull(facet); - assertTrue(facet instanceof HideForContextFacetViaMethod); - var hideForContextFacet = (HideForContextFacetViaMethod) facet; + assertTrue(facet instanceof HiddenFacetForMemberViaMethod); + var hideForContextFacet = (HiddenFacetForMemberViaMethod) facet; assertMethodEqualsFirstIn(propertyHideMethod, hideForContextFacet); assertMethodWasRemoved(propertyHideMethod); }); @@ -336,7 +336,7 @@ class Customer { @Test void hiddenFacetWithNoArgFoundAndMethodRemoved() { - var facetFactory = new HideForContextFacetViaMethodFactory(getMetaModelContext()); + var facetFactory = new HiddenFacetForMemberViaMethodFactory(getMetaModelContext()); @SuppressWarnings("unused") class Customer { public String getFirstName() { return null; } @@ -349,10 +349,10 @@ class Customer { // when facetFactory.process(processMethodContext); // then - final Facet facet = facetedMethod.getFacet(HideForContextFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForMember.class); assertNotNull(facet); - assertTrue(facet instanceof HideForContextFacetViaMethod); - var hideForContextFacet = (HideForContextFacetViaMethod) facet; + assertTrue(facet instanceof HiddenFacetForMemberViaMethod); + var hideForContextFacet = (HiddenFacetForMemberViaMethod) facet; assertMethodEqualsFirstIn(propertyHideMethod, hideForContextFacet); assertMethodWasRemoved(propertyHideMethod); }); @@ -386,7 +386,7 @@ class CustomerEx extends Customer { @Test void propertyFoundOnSuperclassButHelperMethodFoundOnSubclass() { var facetFactory = new PropertyAccessorFacetViaAccessorFactory(getMetaModelContext()); - var facetFactoryForHide = new HideForContextFacetViaMethodFactory(getMetaModelContext()); + var facetFactoryForHide = new HiddenFacetForMemberViaMethodFactory(getMetaModelContext()); var facetFactoryForDisable = new DisableForContextFacetViaMethodFactory(getMetaModelContext()); @SuppressWarnings("unused") class Customer { @@ -409,10 +409,10 @@ class CustomerEx extends Customer { facetFactoryForHide.process(processMethodContext); facetFactoryForDisable.process(processMethodContext); - final Facet facet = facetedMethod.getFacet(HideForContextFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForMember.class); assertNotNull(facet); - assertTrue(facet instanceof HideForContextFacetViaMethod); - var hideForContextFacet = (HideForContextFacetViaMethod) facet; + assertTrue(facet instanceof HiddenFacetForMemberViaMethod); + var hideForContextFacet = (HiddenFacetForMemberViaMethod) facet; assertMethodEqualsFirstIn(propertyHideMethod, hideForContextFacet); final Facet facet2 = facetedMethod.getFacet(DisableForContextFacet.class); diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/PropertyLayoutAnnotationFactoryTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/PropertyLayoutAnnotationFactoryTest.java index 4f9a48ee6a2..ff05baef77d 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/PropertyLayoutAnnotationFactoryTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/properties/propertylayout/PropertyLayoutAnnotationFactoryTest.java @@ -35,7 +35,7 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.FacetFactoryTestAbstract; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.facets.all.i8n.staatic.HasStaticText; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.facets.objectvalue.labelat.LabelAtFacet; @@ -79,7 +79,7 @@ class Customer { //when facetFactory.process(processMethodContext); //then - final Facet facet = facetedMethod.getFacet(HiddenFacet.class); + final Facet facet = facetedMethod.getFacet(HiddenFacetForLayout.class); assertNotNull(facet); assertTrue(facet instanceof HiddenFacetForPropertyLayoutAnnotation); var propLayoutFacetAnnotation = (HiddenFacetForPropertyLayoutAnnotation) facet; diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java index e33c1f8e2f2..2dddc95558c 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java @@ -35,17 +35,17 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.facets.WhereValueFacet; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForLayout; import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; class ObjectAssociationPredicatesTest_visibleWhere { private ObjectAssociation mockObjectAssociation; - private HiddenFacet mockHiddenFacet; + private HiddenFacetForLayout mockHiddenFacet; @BeforeEach public void setUp() throws Exception { - mockHiddenFacet = Mockito.mock(HiddenFacet.class); + mockHiddenFacet = Mockito.mock(HiddenFacetForLayout.class); mockObjectAssociation = Mockito.mock(ObjectAssociation.class); } @@ -83,7 +83,7 @@ public void visibleWhere( final Predicate predicate = association -> { final List facets = association.streamFacets() .filter(facet -> facet instanceof WhereValueFacet - && facet instanceof HiddenFacet) + && facet instanceof HiddenFacetForLayout) .collect(Collectors.toList()); for (Facet facet : facets) { final WhereValueFacet wawF = (WhereValueFacet) facet; diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java index d30bd6ef882..51d2d6b0893 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java @@ -35,10 +35,11 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.Facet; +import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.FacetedMethod; -import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetAbstract; +import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -157,7 +158,7 @@ public void whenNone() throws Exception { public void whenNoop() throws Exception { // given - addHiddenFacet(Where.EVERYWHERE, facetedMethod, true); + addHiddenFacet(Where.EVERYWHERE, facetedMethod, Precedence.FALLBACK); // when, then assertFalse(objectAssociation.isAlwaysHidden()); @@ -167,7 +168,7 @@ public void whenNoop() throws Exception { public void whenNotAlwaysEverywhere() throws Exception { // given - addHiddenFacet(Where.EVERYWHERE, facetedMethod, false); + addHiddenFacet(Where.EVERYWHERE, facetedMethod, Precedence.DEFAULT); // when, then assertThat(objectAssociation.isAlwaysHidden(), is(true)); @@ -177,7 +178,7 @@ public void whenNotAlwaysEverywhere() throws Exception { public void whenAlwaysNotEverywhere() throws Exception { // given - addHiddenFacet(Where.OBJECT_FORMS, facetedMethod, false); + addHiddenFacet(Where.OBJECT_FORMS, facetedMethod, Precedence.DEFAULT); // when, then assertFalse(objectAssociation.isAlwaysHidden()); @@ -187,7 +188,7 @@ public void whenAlwaysNotEverywhere() throws Exception { public void whenAlwaysEverywhere() throws Exception { // given - addHiddenFacet(Where.EVERYWHERE, facetedMethod, false); + addHiddenFacet(Where.EVERYWHERE, facetedMethod, Precedence.DEFAULT); // when, then assertTrue(objectAssociation.isAlwaysHidden()); @@ -197,7 +198,7 @@ public void whenAlwaysEverywhere() throws Exception { public void whenAlwaysAnywhere() throws Exception { // given - addHiddenFacet(Where.ANYWHERE, facetedMethod, false); + addHiddenFacet(Where.ANYWHERE, facetedMethod, Precedence.DEFAULT); // when, then assertTrue(objectAssociation.isAlwaysHidden()); @@ -206,14 +207,10 @@ public void whenAlwaysAnywhere() throws Exception { private static void addHiddenFacet( final Where where, final FacetedMethod holder, - final boolean noop) { - - var precedence = noop - ? Facet.Precedence.FALLBACK - : Facet.Precedence.DEFAULT; + final Precedence precedence) { FacetUtil.addFacet( - new HiddenFacetAbstract(where, holder, precedence) { + new HiddenFacetForLayoutAbstract(where, holder, precedence) { @Override protected String hiddenReason(final ManagedObject target, final Where whereContext) { return null; diff --git a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomainWithPdfJsViewer_IntegTest.dump_facets.approved.xml b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomainWithPdfJsViewer_IntegTest.dump_facets.approved.xml index 46d9df30b91..c78cf71aa25 100644 --- a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomainWithPdfJsViewer_IntegTest.dump_facets.approved.xml +++ b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomainWithPdfJsViewer_IntegTest.dump_facets.approved.xml @@ -59,8 +59,8 @@ - - + + @@ -257,9 +257,9 @@ - + - + @@ -414,9 +414,9 @@ - + - + @@ -675,9 +675,9 @@ - + - + @@ -839,9 +839,9 @@ - + - + @@ -950,9 +950,9 @@ - + - + @@ -1061,9 +1061,9 @@ - + - + @@ -1192,8 +1192,8 @@ - - + + diff --git a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomain_IntegTest.dump_facets.approved.xml b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomain_IntegTest.dump_facets.approved.xml index 029e8782a27..fbb05f8aee1 100644 --- a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomain_IntegTest.dump_facets.approved.xml +++ b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_MixinDomain_IntegTest.dump_facets.approved.xml @@ -59,8 +59,8 @@ - - + + @@ -250,9 +250,9 @@ - + - + @@ -407,9 +407,9 @@ - + - + @@ -668,9 +668,9 @@ - + - + @@ -832,9 +832,9 @@ - + - + @@ -943,9 +943,9 @@ - + - + @@ -1054,9 +1054,9 @@ - + - + @@ -1185,8 +1185,8 @@ - - + + diff --git a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomainWithPdfjsViewer_IntegTest.dump_facets.approved.xml b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomainWithPdfjsViewer_IntegTest.dump_facets.approved.xml index 46279cff1f0..11f5bb64cdd 100644 --- a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomainWithPdfjsViewer_IntegTest.dump_facets.approved.xml +++ b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomainWithPdfjsViewer_IntegTest.dump_facets.approved.xml @@ -59,8 +59,8 @@ - - + + @@ -246,9 +246,9 @@ - + - + @@ -403,9 +403,9 @@ - + - + @@ -664,9 +664,9 @@ - + - + @@ -828,9 +828,9 @@ - + - + @@ -939,9 +939,9 @@ - + - + @@ -1050,9 +1050,9 @@ - + - + diff --git a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomain_IntegTest.dump_facets.approved.xml b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomain_IntegTest.dump_facets.approved.xml index 8af28dc419b..27b3c68f9c0 100644 --- a/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomain_IntegTest.dump_facets.approved.xml +++ b/extensions/vw/pdfjs/metamodel/src/test/java/org/apache/causeway/extensions/pdfjs/metamodel/PdfjsViewer_PropDomain_IntegTest.dump_facets.approved.xml @@ -59,8 +59,8 @@ - - + + @@ -239,9 +239,9 @@ - + - + @@ -396,9 +396,9 @@ - + - + @@ -657,9 +657,9 @@ - + - + @@ -821,9 +821,9 @@ - + - + @@ -932,9 +932,9 @@ - + - + @@ -1043,9 +1043,9 @@ - + - + diff --git a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.verify.approved.xml b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.verify.approved.xml index d0fd56e899a..394650b4962 100644 --- a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.verify.approved.xml +++ b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/MetaModelRegressionTest.verify.approved.xml @@ -48,8 +48,8 @@ - - + + @@ -154,8 +154,8 @@ - - + + @@ -224,9 +224,9 @@ - + - + @@ -359,9 +359,9 @@ - + - + @@ -564,9 +564,9 @@ - + - + @@ -706,9 +706,9 @@ - + - + @@ -812,9 +812,9 @@ - + - + @@ -918,9 +918,9 @@ - + - + @@ -1051,8 +1051,8 @@ - - + + @@ -1123,9 +1123,9 @@ - + - + @@ -1258,9 +1258,9 @@ - + - + @@ -1463,9 +1463,9 @@ - + - + @@ -1605,9 +1605,9 @@ - + - + @@ -1711,9 +1711,9 @@ - + - + @@ -1817,9 +1817,9 @@ - + - + @@ -1935,8 +1935,8 @@ - - + + @@ -2072,8 +2072,8 @@ - - + + @@ -2144,9 +2144,9 @@ - + - + @@ -2279,9 +2279,9 @@ - + - + @@ -2484,9 +2484,9 @@ - + - + @@ -2638,8 +2638,8 @@ - - + + @@ -2749,9 +2749,9 @@ - + - + @@ -2855,9 +2855,9 @@ - + - + @@ -2961,9 +2961,9 @@ - + - + @@ -3079,8 +3079,8 @@ - - + + @@ -3170,8 +3170,8 @@ - - + + @@ -3238,9 +3238,9 @@ - + - + @@ -3373,9 +3373,9 @@ - + - + @@ -3578,9 +3578,9 @@ - + - + @@ -3720,9 +3720,9 @@ - + - + @@ -3826,9 +3826,9 @@ - + - + @@ -3932,9 +3932,9 @@ - + - + @@ -4065,8 +4065,8 @@ - - + + @@ -4128,8 +4128,8 @@ - - + + @@ -4197,9 +4197,9 @@ - + - + @@ -4332,9 +4332,9 @@ - + - + @@ -4537,9 +4537,9 @@ - + - + @@ -4679,9 +4679,9 @@ - + - + @@ -4785,9 +4785,9 @@ - + - + @@ -4891,9 +4891,9 @@ - + - + @@ -5129,8 +5129,8 @@ - - + + @@ -5344,8 +5344,8 @@ - - + + @@ -5469,9 +5469,9 @@ - + - + @@ -5604,9 +5604,9 @@ - + - + @@ -5809,9 +5809,9 @@ - + - + @@ -5951,9 +5951,9 @@ - + - + @@ -6057,9 +6057,9 @@ - + - + @@ -6163,9 +6163,9 @@ - + - + @@ -6407,8 +6407,8 @@ - - + + @@ -6628,8 +6628,8 @@ - - + + @@ -6879,9 +6879,9 @@ - + - + @@ -7014,9 +7014,9 @@ - + - + @@ -7219,9 +7219,9 @@ - + - + @@ -7361,9 +7361,9 @@ - + - + @@ -7467,9 +7467,9 @@ - + - + @@ -7573,9 +7573,9 @@ - + - + @@ -7706,8 +7706,8 @@ - - + + @@ -7769,8 +7769,8 @@ - - + + @@ -7828,8 +7828,8 @@ - - + + @@ -7887,8 +7887,8 @@ - - + + @@ -7946,8 +7946,8 @@ - - + + @@ -8005,8 +8005,8 @@ - - + + @@ -8064,8 +8064,8 @@ - - + + @@ -8123,8 +8123,8 @@ - - + + @@ -8182,8 +8182,8 @@ - - + + @@ -8241,8 +8241,8 @@ - - + + @@ -8300,8 +8300,8 @@ - - + + @@ -8481,9 +8481,9 @@ - + - + @@ -8616,9 +8616,9 @@ - + - + @@ -8821,9 +8821,9 @@ - + - + @@ -8963,9 +8963,9 @@ - + - + @@ -9069,9 +9069,9 @@ - + - + @@ -9175,9 +9175,9 @@ - + - + @@ -9314,8 +9314,8 @@ - - + + @@ -9575,9 +9575,9 @@ - + - + @@ -9710,9 +9710,9 @@ - + - + @@ -9915,9 +9915,9 @@ - + - + @@ -10057,9 +10057,9 @@ - + - + @@ -10163,9 +10163,9 @@ - + - + @@ -10269,9 +10269,9 @@ - + - + @@ -10490,8 +10490,8 @@ - - + + @@ -10653,9 +10653,9 @@ - + - + @@ -10788,9 +10788,9 @@ - + - + @@ -10993,9 +10993,9 @@ - + - + @@ -11135,9 +11135,9 @@ - + - + @@ -11241,9 +11241,9 @@ - + - + @@ -11347,9 +11347,9 @@ - + - + @@ -11590,8 +11590,8 @@ - - + + @@ -11753,9 +11753,9 @@ - + - + @@ -11888,9 +11888,9 @@ - + - + @@ -12093,9 +12093,9 @@ - + - + @@ -12235,9 +12235,9 @@ - + - + @@ -12341,9 +12341,9 @@ - + - + @@ -12447,9 +12447,9 @@ - + - + @@ -12690,8 +12690,8 @@ - - + + @@ -12878,9 +12878,9 @@ - + - + @@ -13013,9 +13013,9 @@ - + - + @@ -13218,9 +13218,9 @@ - + - + @@ -13360,9 +13360,9 @@ - + - + @@ -13466,9 +13466,9 @@ - + - + @@ -13572,9 +13572,9 @@ - + - + @@ -13711,8 +13711,8 @@ - - + + @@ -14075,9 +14075,9 @@ - + - + @@ -14210,9 +14210,9 @@ - + - + @@ -14415,9 +14415,9 @@ - + - + @@ -14557,9 +14557,9 @@ - + - + @@ -14663,9 +14663,9 @@ - + - + @@ -14769,9 +14769,9 @@ - + - + @@ -15078,8 +15078,8 @@ - - + + @@ -15423,9 +15423,9 @@ - + - + @@ -15558,9 +15558,9 @@ - + - + @@ -15763,9 +15763,9 @@ - + - + @@ -15905,9 +15905,9 @@ - + - + @@ -16011,9 +16011,9 @@ - + - + @@ -16117,9 +16117,9 @@ - + - + @@ -16543,8 +16543,8 @@ - - + + @@ -16691,9 +16691,9 @@ - + - + @@ -16826,9 +16826,9 @@ - + - + @@ -17031,9 +17031,9 @@ - + - + @@ -17173,9 +17173,9 @@ - + - + @@ -17279,9 +17279,9 @@ - + - + @@ -17385,9 +17385,9 @@ - + - + @@ -17518,8 +17518,8 @@ - - + + @@ -17670,9 +17670,9 @@ - + - + @@ -17805,9 +17805,9 @@ - + - + @@ -18010,9 +18010,9 @@ - + - + @@ -18152,9 +18152,9 @@ - + - + @@ -18258,9 +18258,9 @@ - + - + @@ -18364,9 +18364,9 @@ - + - + @@ -18497,8 +18497,8 @@ - - + + @@ -18649,9 +18649,9 @@ - + - + @@ -18784,9 +18784,9 @@ - + - + @@ -18989,9 +18989,9 @@ - + - + @@ -19131,9 +19131,9 @@ - + - + @@ -19237,9 +19237,9 @@ - + - + @@ -19343,9 +19343,9 @@ - + - + @@ -19476,8 +19476,8 @@ - - + + @@ -19534,8 +19534,8 @@ - - + + @@ -19825,8 +19825,8 @@ - - + + @@ -19969,8 +19969,8 @@ - - + + @@ -20246,8 +20246,8 @@ - - + + @@ -20381,8 +20381,8 @@ - - + + @@ -20585,8 +20585,8 @@ - - + + @@ -20692,8 +20692,8 @@ - - + + @@ -20709,8 +20709,8 @@ - - + + @@ -20919,8 +20919,8 @@ - - + + @@ -20937,8 +20937,8 @@ - - + + @@ -21147,8 +21147,8 @@ - - + + @@ -21165,8 +21165,8 @@ - - + + @@ -21389,8 +21389,8 @@ - - + + @@ -21407,8 +21407,8 @@ - - + + @@ -21635,8 +21635,8 @@ - - + + @@ -21729,8 +21729,8 @@ - - + + @@ -21934,9 +21934,9 @@ - + - + @@ -22069,9 +22069,9 @@ - + - + @@ -22274,9 +22274,9 @@ - + - + @@ -22491,9 +22491,9 @@ - + - + @@ -22627,8 +22627,8 @@ - - + + @@ -22726,8 +22726,8 @@ - - + + @@ -22875,8 +22875,8 @@ - - + + @@ -23050,9 +23050,9 @@ - + - + @@ -23156,9 +23156,9 @@ - + - + @@ -23289,8 +23289,8 @@ - - + + @@ -23352,8 +23352,8 @@ - - + + @@ -23507,8 +23507,8 @@ - - + + @@ -23581,9 +23581,9 @@ - + - + @@ -23716,9 +23716,9 @@ - + - + @@ -23921,9 +23921,9 @@ - + - + @@ -24063,9 +24063,9 @@ - + - + @@ -24169,9 +24169,9 @@ - + - + @@ -24300,8 +24300,8 @@ - - + + @@ -24385,8 +24385,8 @@ - - + + @@ -24448,8 +24448,8 @@ - - + + @@ -24507,9 +24507,9 @@ - + - + @@ -24640,8 +24640,8 @@ - - + + @@ -24703,8 +24703,8 @@ - - + + @@ -24858,8 +24858,8 @@ - - + + @@ -24932,9 +24932,9 @@ - + - + @@ -25067,9 +25067,9 @@ - + - + @@ -25272,9 +25272,9 @@ - + - + @@ -25414,9 +25414,9 @@ - + - + @@ -25520,9 +25520,9 @@ - + - + @@ -25655,8 +25655,8 @@ - - + + @@ -25740,8 +25740,8 @@ - - + + @@ -25803,8 +25803,8 @@ - - + + @@ -25862,9 +25862,9 @@ - + - + @@ -25995,8 +25995,8 @@ - - + + @@ -26058,8 +26058,8 @@ - - + + @@ -26213,8 +26213,8 @@ - - + + @@ -26287,9 +26287,9 @@ - + - + @@ -26422,9 +26422,9 @@ - + - + @@ -26627,9 +26627,9 @@ - + - + @@ -26769,9 +26769,9 @@ - + - + @@ -26875,9 +26875,9 @@ - + - + @@ -27010,8 +27010,8 @@ - - + + @@ -27095,8 +27095,8 @@ - - + + @@ -27158,8 +27158,8 @@ - - + + @@ -27217,9 +27217,9 @@ - + - + @@ -27338,8 +27338,8 @@ - - + + @@ -27448,8 +27448,8 @@ - - + + @@ -27465,8 +27465,8 @@ - - + + @@ -27663,8 +27663,8 @@ - - + + @@ -27766,8 +27766,8 @@ - - + + @@ -27779,8 +27779,8 @@ - - + + @@ -27977,8 +27977,8 @@ - - + + @@ -28080,8 +28080,8 @@ - - + + @@ -28093,8 +28093,8 @@ - - + + @@ -28305,8 +28305,8 @@ - - + + @@ -28408,8 +28408,8 @@ - - + + @@ -28421,8 +28421,8 @@ - - + + @@ -28633,8 +28633,8 @@ - - + + @@ -28735,8 +28735,8 @@ - - + + @@ -28820,8 +28820,8 @@ - - + + @@ -28920,8 +28920,8 @@ - - + + @@ -29140,8 +29140,8 @@ - - + + @@ -29269,8 +29269,8 @@ - - + + @@ -29362,8 +29362,8 @@ - - + + @@ -29491,8 +29491,8 @@ - - + + @@ -29584,8 +29584,8 @@ - - + + @@ -29785,8 +29785,8 @@ - - + + @@ -29892,8 +29892,8 @@ - - + + @@ -30016,8 +30016,8 @@ - - + + @@ -30123,8 +30123,8 @@ - - + + @@ -30247,8 +30247,8 @@ - - + + @@ -30455,8 +30455,8 @@ - - + + @@ -31223,9 +31223,9 @@ - + - + @@ -31358,9 +31358,9 @@ - + - + @@ -31563,9 +31563,9 @@ - + - + @@ -31705,9 +31705,9 @@ - + - + @@ -31943,9 +31943,9 @@ - + - + @@ -32049,9 +32049,9 @@ - + - + @@ -32170,8 +32170,8 @@ - - + + @@ -32348,8 +32348,8 @@ - - + + @@ -32526,8 +32526,8 @@ - - + + @@ -32704,8 +32704,8 @@ - - + + @@ -32882,8 +32882,8 @@ - - + + @@ -33060,8 +33060,8 @@ - - + + @@ -33238,8 +33238,8 @@ - - + + @@ -33416,8 +33416,8 @@ - - + + @@ -33606,8 +33606,8 @@ - - + + @@ -33765,8 +33765,8 @@ - - + + @@ -33834,8 +33834,8 @@ - - + + @@ -33903,8 +33903,8 @@ - - + + @@ -33955,9 +33955,9 @@ - + - + @@ -34090,9 +34090,9 @@ - + - + @@ -34295,9 +34295,9 @@ - + - + @@ -34437,9 +34437,9 @@ - + - + @@ -34543,9 +34543,9 @@ - + - + @@ -34649,9 +34649,9 @@ - + - + @@ -34782,8 +34782,8 @@ - - + + @@ -34854,9 +34854,9 @@ - + - + @@ -34989,9 +34989,9 @@ - + - + @@ -35194,9 +35194,9 @@ - + - + @@ -35411,9 +35411,9 @@ - + - + @@ -35517,9 +35517,9 @@ - + - + @@ -35623,9 +35623,9 @@ - + - + @@ -35756,8 +35756,8 @@ - - + + @@ -36001,9 +36001,9 @@ - + - + @@ -36136,9 +36136,9 @@ - + - + @@ -36341,9 +36341,9 @@ - + - + @@ -36483,9 +36483,9 @@ - + - + @@ -36589,9 +36589,9 @@ - + - + @@ -36695,9 +36695,9 @@ - + - + @@ -36828,8 +36828,8 @@ - - + + @@ -37241,9 +37241,9 @@ - + - + @@ -37376,9 +37376,9 @@ - + - + @@ -37581,9 +37581,9 @@ - + - + @@ -37723,9 +37723,9 @@ - + - + @@ -37829,9 +37829,9 @@ - + - + @@ -37935,9 +37935,9 @@ - + - + @@ -38056,8 +38056,8 @@ - - + + @@ -38248,18 +38248,18 @@ - - + + + + + + + - - - - - @@ -38335,8 +38335,8 @@ - - + + @@ -38454,8 +38454,8 @@ - - + + @@ -38523,9 +38523,9 @@ - + - + @@ -38658,9 +38658,9 @@ - + - + @@ -38863,9 +38863,9 @@ - + - + @@ -39005,9 +39005,9 @@ - + - + @@ -39145,8 +39145,8 @@ - - + + @@ -39207,9 +39207,9 @@ - + - + @@ -39313,9 +39313,9 @@ - + - + @@ -39446,8 +39446,8 @@ - - + + @@ -39681,9 +39681,9 @@ - + - + @@ -39816,9 +39816,9 @@ - + - + @@ -40021,9 +40021,9 @@ - + - + @@ -40163,9 +40163,9 @@ - + - + @@ -40351,9 +40351,9 @@ - + - + @@ -40457,9 +40457,9 @@ - + - + From e381b351f7cb3885c4904d6e5391120e1cd4a851 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Fri, 28 Nov 2025 08:26:50 +0100 Subject: [PATCH 12/25] CAUSEWAY-3752: HiddenFacetForFeatureFilter stub plus some refactoring --- .../all/hide/HiddenFacetForFeatureFilter.java | 30 ++++++++++ .../HiddenFacetForFeatureFilterFactory.java | 56 +++++++++++++++++++ .../hide/HiddenFacetForFeatureFilterImpl.java | 37 ++++++++++++ ...enFacetForNoMembersAuthorizedFactory.java} | 4 +- .../interactions/InteractionUtils.java | 30 ---------- .../metamodel/interactions/RenderPolicy.java | 18 +++++- .../vis/ObjectVisibilityContext.java | 3 +- .../spec/impl/ObjectActionDefault.java | 5 +- .../impl/OneToManyAssociationDefault.java | 6 +- .../spec/impl/OneToOneAssociationDefault.java | 5 +- .../spec/impl/ProgrammingModelDefault.java | 6 +- .../param/name/ParameterNameFacetTest.java | 2 +- 12 files changed, 157 insertions(+), 45 deletions(-) create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java rename core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/{HiddenTypeFacetFromAuthorizationFactory.java => HiddenFacetForNoMembersAuthorizedFactory.java} (92%) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java new file mode 100644 index 00000000000..97ec99873cc --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java @@ -0,0 +1,30 @@ +/* + * 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.all.hide; + +import org.apache.causeway.applib.services.appfeat.ApplicationFeatureFilter; +import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; + +/** + * Optionally hides a feature via {@link ApplicationFeatureFilter}. + */ +public interface HiddenFacetForFeatureFilter +extends HidingInteractionAdvisor { + +} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java new file mode 100644 index 00000000000..57c9e00d570 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java @@ -0,0 +1,56 @@ +/* + * 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.all.hide; + +import jakarta.inject.Inject; + +import org.apache.causeway.applib.services.appfeat.ApplicationFeatureFilter; +import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.facetapi.FacetUtil; +import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; +import org.apache.causeway.core.metamodel.spec.ObjectSpecification; + +/** + * Installs the {@link HiddenFacetForFeatureFilterImpl} on the + * {@link ObjectSpecification}. + */ +public class HiddenFacetForFeatureFilterFactory +extends FacetFactoryAbstract { + + @Inject + public HiddenFacetForFeatureFilterFactory(final MetaModelContext mmc) { + super(mmc, FeatureType.EVERYTHING_BUT_PARAMETERS); + mmc.getServiceRegistry().select(ApplicationFeatureFilter.class); + } + + @Override + public void process(final ProcessClassContext processClassContext) { + var facetHolder = processClassContext.getFacetHolder(); + //TODO WIP FacetUtil.addFacet(new HiddenFacetForFeatureFilterImpl(facetHolder)); + } + + @Override + public void process(ProcessMethodContext processMethodContext) { + var facetHolder = processMethodContext.getFacetHolder(); + //TODO WIP processMethodContext.getFeatureType().isProperty(); + //TODO WIP FacetUtil.addFacet(new HiddenFacetForFeatureFilterImpl(facetHolder)); + } + +} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java new file mode 100644 index 00000000000..aebbc38fb67 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java @@ -0,0 +1,37 @@ +/* + * 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.all.hide; + +import org.apache.causeway.core.metamodel.facetapi.Facet; +import org.apache.causeway.core.metamodel.facetapi.FacetHolder; +import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; + +public record HiddenFacetForFeatureFilterImpl( + FacetHolder facetHolder + ) implements HiddenFacetForFeatureFilter { + + @Override public Class facetType() { return HiddenFacetForFeatureFilter.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + + @Override + public String hides(final VisibilityContext vc) { + return null; + } + +} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedFactory.java similarity index 92% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedFactory.java index ee80164d010..d46d90caeba 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenTypeFacetFromAuthorizationFactory.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedFactory.java @@ -31,11 +31,11 @@ * Installs the {@link HiddenFacetForNoMembersAuthorizedImpl} on the * {@link ObjectSpecification}. */ -public class HiddenTypeFacetFromAuthorizationFactory +public class HiddenFacetForNoMembersAuthorizedFactory extends FacetFactoryAbstract { @Inject - public HiddenTypeFacetFromAuthorizationFactory(final MetaModelContext mmc) { + public HiddenFacetForNoMembersAuthorizedFactory(final MetaModelContext mmc) { super(mmc, FeatureType.OBJECTS_ONLY); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java index d88b2f462a9..5830881c3f7 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java @@ -25,8 +25,6 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.commons.internal.base._Strings; -import org.apache.causeway.core.config.CausewayConfiguration; -import org.apache.causeway.core.config.environment.DeploymentType; import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants; import org.apache.causeway.core.metamodel.consent.Consent; import org.apache.causeway.core.metamodel.consent.InteractionAdvisor; @@ -39,7 +37,6 @@ import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.ValidityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -import org.apache.causeway.core.metamodel.object.ManagedObject; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; @@ -139,12 +136,6 @@ public InteractionResultSet isValidResultSet( return resultSet.add(isValidResult(facetHolder, context)); } - public RenderPolicy renderPolicy(final ManagedObject ownerAdapter) { - return new RenderPolicy( - determineIfHiddenPolicyFrom(ownerAdapter), - determineIfDisabledPolicyFrom(ownerAdapter)); - } - // -- HELPER /** @@ -181,25 +172,4 @@ private static boolean isDomainEventAdvisor(final InteractionAdvisor advisor) { return advisor instanceof DomainEventFacetAbstract; } - private CausewayConfiguration.Prototyping.IfHiddenPolicy determineIfHiddenPolicyFrom(final ManagedObject ownerAdapter) { - DeploymentType deploymentType = ownerAdapter.getSystemEnvironment().deploymentType(); - switch (deploymentType) { - case PROTOTYPING: - return ownerAdapter.getConfiguration().prototyping().ifHiddenPolicy(); - case PRODUCTION: - default: - return CausewayConfiguration.Prototyping.IfHiddenPolicy.HIDE; - } - } - - private CausewayConfiguration.Prototyping.IfDisabledPolicy determineIfDisabledPolicyFrom(final ManagedObject ownerAdapter) { - DeploymentType deploymentType = ownerAdapter.getSystemEnvironment().deploymentType(); - switch (deploymentType) { - case PROTOTYPING: - return ownerAdapter.getConfiguration().prototyping().ifDisabledPolicy(); - case PRODUCTION: - default: - return CausewayConfiguration.Prototyping.IfDisabledPolicy.DISABLE; - } - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/RenderPolicy.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/RenderPolicy.java index ad171b9d1a2..f86ead9c360 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/RenderPolicy.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/RenderPolicy.java @@ -23,6 +23,7 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.core.config.CausewayConfiguration; +import org.apache.causeway.core.metamodel.context.MetaModelContext; /** *

Troubleshooting Visibility and Usability

@@ -66,7 +67,22 @@ public record RenderPolicy( */ CausewayConfiguration.Prototyping.@NonNull IfDisabledPolicy ifDisabledPolicy ) implements Serializable { - + + /** + * Counterpart to {@link #forActionParameters()}, that is objects and members, but not parameters. + */ + public static RenderPolicy forNonActionParam(MetaModelContext mmc) { + return new RenderPolicy( + switch (mmc.getSystemEnvironment().deploymentType()) { + case PROTOTYPING->mmc.getConfiguration().prototyping().ifHiddenPolicy(); + case PRODUCTION->CausewayConfiguration.Prototyping.IfHiddenPolicy.HIDE; + }, + switch (mmc.getSystemEnvironment().deploymentType()) { + case PROTOTYPING -> mmc.getConfiguration().prototyping().ifDisabledPolicy(); + case PRODUCTION -> CausewayConfiguration.Prototyping.IfDisabledPolicy.DISABLE; + }); + } + /** * Always HIDE and DISABLE. */ diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java index 4f542b7b043..44188f58c9b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java @@ -25,7 +25,6 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; -import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.ProposedHolder; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -58,7 +57,7 @@ public static ObjectVisibilityContext createForRegular( domainObject.objSpec().getFeatureIdentifier(), initiatedBy, where, - InteractionUtils.renderPolicy(domainObject)); + RenderPolicy.forNonActionParam(domainObject)); } // -- CONSTRUCTION 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 408c5ac95b7..124a32cf8fa 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 @@ -53,6 +53,7 @@ import org.apache.causeway.core.metamodel.facets.param.choices.ActionParameterChoicesFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.RenderPolicy; import org.apache.causeway.core.metamodel.interactions.use.ActionUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.ActionValidityContext; @@ -288,7 +289,7 @@ public VisibilityContext createVisibleInteractionContext( getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(target)); + RenderPolicy.forNonActionParam(target)); } // -- USABLE @@ -304,7 +305,7 @@ public UsabilityContext createUsableInteractionContext( getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(target)); + RenderPolicy.forNonActionParam(target)); } // -- VALIDATE diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java index 29f21d07c9f..1186be575cf 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java @@ -31,7 +31,7 @@ import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; -import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.RenderPolicy; import org.apache.causeway.core.metamodel.interactions.use.CollectionUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.CollectionVisibilityContext; @@ -83,7 +83,7 @@ public VisibilityContext createVisibleInteractionContext( return new CollectionVisibilityContext( headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + RenderPolicy.forNonActionParam(ownerAdapter)); } @Override @@ -93,7 +93,7 @@ public UsabilityContext createUsableInteractionContext( final Where where) { return new CollectionUsabilityContext( headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + RenderPolicy.forNonActionParam(ownerAdapter)); } // -- get, isEmpty, add, clear 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 ce7d544a473..0a131f6789f 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 @@ -44,6 +44,7 @@ import org.apache.causeway.core.metamodel.facets.properties.update.modify.PropertySetterFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.RenderPolicy; import org.apache.causeway.core.metamodel.interactions.use.PropertyUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.PropertyModifyContext; @@ -91,7 +92,7 @@ public VisibilityContext createVisibleInteractionContext( final Where where) { return new PropertyVisibilityContext( headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + RenderPolicy.forNonActionParam(ownerAdapter)); } @Override @@ -101,7 +102,7 @@ public UsabilityContext createUsableInteractionContext( final Where where) { return new PropertyUsabilityContext( headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + RenderPolicy.forNonActionParam(ownerAdapter)); } // -- VALIDITY diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java index df9536a1f9b..aaa51a6d2d0 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java @@ -25,6 +25,7 @@ import org.apache.causeway.core.metamodel.facets.actions.homepage.annotation.HomePageFacetAnnotationFactory; import org.apache.causeway.core.metamodel.facets.actions.layout.ActionLayoutFacetFactory; import org.apache.causeway.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethodFactory; +import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForFeatureFilterFactory; import org.apache.causeway.core.metamodel.facets.collections.accessor.CollectionAccessorFacetViaAccessorFactory; import org.apache.causeway.core.metamodel.facets.collections.collection.CollectionAnnotationFacetFactory; import org.apache.causeway.core.metamodel.facets.collections.javautilcollection.CollectionFacetFactory; @@ -47,7 +48,7 @@ import org.apache.causeway.core.metamodel.facets.object.domainservice.annotation.DomainServiceFacetAnnotationFactory; import org.apache.causeway.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacetFactory; import org.apache.causeway.core.metamodel.facets.object.grid.GridFacetFactory; -import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenTypeFacetFromAuthorizationFactory; +import org.apache.causeway.core.metamodel.facets.object.hidden.HiddenFacetForNoMembersAuthorizedFactory; import org.apache.causeway.core.metamodel.facets.object.ignore.annotation.RemoveAnnotatedMethodsFacetFactory; import org.apache.causeway.core.metamodel.facets.object.ignore.javalang.IteratorFilteringFacetFactory; import org.apache.causeway.core.metamodel.facets.object.ignore.javalang.RemoveMethodsFacetFactory; @@ -213,7 +214,7 @@ private void addFacetFactories() { // must come after DomainObjectAnnotationFacetFactory & MixinFacetFactory addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new ContributingFacetFromMixinFacetFactory(mmc)); - addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new HiddenTypeFacetFromAuthorizationFactory(mmc)); + addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new HiddenFacetForNoMembersAuthorizedFactory(mmc)); addFactory(FacetProcessingOrder.E1_MEMBER_MODELLING, new ValueSemanticsAnnotationFacetFactory(mmc)); @@ -242,6 +243,7 @@ private void addFacetFactories() { // should come near the end, after any facets that install PropertySetterFacet have run. addFactory(FacetProcessingOrder.Z1_FINALLY, new DisabledFacetOnPropertyInferredFactory(mmc)); + addFactory(FacetProcessingOrder.Z1_FINALLY, new HiddenFacetForFeatureFilterFactory(mmc)); addFactory(FacetProcessingOrder.Z1_FINALLY, new ViewModelSemanticCheckingFacetFactory(mmc)); } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java index d9295ddcd83..8131de3f39d 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java @@ -52,7 +52,7 @@ public void tearDown() throws Exception { @Test public void verifyProgrammingModelNumberOfFactories() { - assertEquals(61, programmingModel.streamFactories().count()); + assertEquals(62, programmingModel.streamFactories().count()); } @Test //verify we have the javac -parameter flag set when compiling this class From f351ca125390b83826d23e26c660b60724bf6ad7 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Wed, 3 Dec 2025 11:31:57 +0100 Subject: [PATCH 13/25] CAUSEWAY-3752: backtracking https://github.com/apache/causeway/pull/3264 to a point of sanity --- .../all/hide/HiddenFacetForFeatureFilter.java | 30 ---------- .../HiddenFacetForFeatureFilterFactory.java | 56 ------------------- .../hide/HiddenFacetForFeatureFilterImpl.java | 37 ------------ .../spec/impl/ProgrammingModelDefault.java | 2 - .../param/name/ParameterNameFacetTest.java | 2 +- 5 files changed, 1 insertion(+), 126 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java deleted file mode 100644 index 97ec99873cc..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilter.java +++ /dev/null @@ -1,30 +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.all.hide; - -import org.apache.causeway.applib.services.appfeat.ApplicationFeatureFilter; -import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; - -/** - * Optionally hides a feature via {@link ApplicationFeatureFilter}. - */ -public interface HiddenFacetForFeatureFilter -extends HidingInteractionAdvisor { - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java deleted file mode 100644 index 57c9e00d570..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java +++ /dev/null @@ -1,56 +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.all.hide; - -import jakarta.inject.Inject; - -import org.apache.causeway.applib.services.appfeat.ApplicationFeatureFilter; -import org.apache.causeway.core.metamodel.context.MetaModelContext; -import org.apache.causeway.core.metamodel.facetapi.FacetUtil; -import org.apache.causeway.core.metamodel.facetapi.FeatureType; -import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract; -import org.apache.causeway.core.metamodel.spec.ObjectSpecification; - -/** - * Installs the {@link HiddenFacetForFeatureFilterImpl} on the - * {@link ObjectSpecification}. - */ -public class HiddenFacetForFeatureFilterFactory -extends FacetFactoryAbstract { - - @Inject - public HiddenFacetForFeatureFilterFactory(final MetaModelContext mmc) { - super(mmc, FeatureType.EVERYTHING_BUT_PARAMETERS); - mmc.getServiceRegistry().select(ApplicationFeatureFilter.class); - } - - @Override - public void process(final ProcessClassContext processClassContext) { - var facetHolder = processClassContext.getFacetHolder(); - //TODO WIP FacetUtil.addFacet(new HiddenFacetForFeatureFilterImpl(facetHolder)); - } - - @Override - public void process(ProcessMethodContext processMethodContext) { - var facetHolder = processMethodContext.getFacetHolder(); - //TODO WIP processMethodContext.getFeatureType().isProperty(); - //TODO WIP FacetUtil.addFacet(new HiddenFacetForFeatureFilterImpl(facetHolder)); - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java deleted file mode 100644 index aebbc38fb67..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java +++ /dev/null @@ -1,37 +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.all.hide; - -import org.apache.causeway.core.metamodel.facetapi.Facet; -import org.apache.causeway.core.metamodel.facetapi.FacetHolder; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; - -public record HiddenFacetForFeatureFilterImpl( - FacetHolder facetHolder - ) implements HiddenFacetForFeatureFilter { - - @Override public Class facetType() { return HiddenFacetForFeatureFilter.class; } - @Override public Precedence precedence() { return Precedence.DEFAULT; } - - @Override - public String hides(final VisibilityContext vc) { - return null; - } - -} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java index aaa51a6d2d0..b5b9b83ad70 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java @@ -25,7 +25,6 @@ import org.apache.causeway.core.metamodel.facets.actions.homepage.annotation.HomePageFacetAnnotationFactory; import org.apache.causeway.core.metamodel.facets.actions.layout.ActionLayoutFacetFactory; import org.apache.causeway.core.metamodel.facets.actions.validate.method.ActionValidationFacetViaMethodFactory; -import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacetForFeatureFilterFactory; import org.apache.causeway.core.metamodel.facets.collections.accessor.CollectionAccessorFacetViaAccessorFactory; import org.apache.causeway.core.metamodel.facets.collections.collection.CollectionAnnotationFacetFactory; import org.apache.causeway.core.metamodel.facets.collections.javautilcollection.CollectionFacetFactory; @@ -243,7 +242,6 @@ private void addFacetFactories() { // should come near the end, after any facets that install PropertySetterFacet have run. addFactory(FacetProcessingOrder.Z1_FINALLY, new DisabledFacetOnPropertyInferredFactory(mmc)); - addFactory(FacetProcessingOrder.Z1_FINALLY, new HiddenFacetForFeatureFilterFactory(mmc)); addFactory(FacetProcessingOrder.Z1_FINALLY, new ViewModelSemanticCheckingFacetFactory(mmc)); } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java index 8131de3f39d..d9295ddcd83 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/facets/param/name/ParameterNameFacetTest.java @@ -52,7 +52,7 @@ public void tearDown() throws Exception { @Test public void verifyProgrammingModelNumberOfFactories() { - assertEquals(62, programmingModel.streamFactories().count()); + assertEquals(61, programmingModel.streamFactories().count()); } @Test //verify we have the javac -parameter flag set when compiling this class From 2135efc00de5dfe491928a569c956501e77cf8a5 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Wed, 3 Dec 2025 12:16:49 +0100 Subject: [PATCH 14/25] CAUSEWAY-3752: backporting some code from abandoned PR --- .../appfeat/ApplicationFeatureFilter.java | 12 +- .../services/wrapper/control/SyncControl.java | 64 +++--- .../internal/ioc/SpringContextHolder.java | 3 - .../src/main/java/module-info.java | 1 + .../core/ApplicationFeatureFilters.java | 85 +++++++ .../core/InteractionConstraint.java | 38 ++++ .../core/interaction/core/WhatViewer.java | 44 ++++ .../core/metamodel/consent/Consent.java | 8 +- .../DomainObjectInvocationHandler.java | 208 ++++++++---------- 9 files changed, 302 insertions(+), 161 deletions(-) create mode 100644 core/interaction/src/main/java/org/apache/causeway/core/interaction/core/ApplicationFeatureFilters.java create mode 100644 core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java create mode 100644 core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java b/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java index 434584a4e83..7a055cdd650 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java @@ -20,21 +20,19 @@ /** * The various viewer implementations will individually honor any filters registered with Spring, - * based on a matching qualifier ('graphql', 'restful', etc.). + * based on a matching qualifier ('Graphql', 'Restful', etc.). * *

All filters that match a qualifier are consulted until any one rejects the {@link ApplicationFeature}. - * - *

In no filters match a qualifier, all {@link ApplicationFeature} are accepted. + * + *

If no filters match a qualifier, any {@link ApplicationFeature} is accepted. + * + *

'NoViewer' is a reserved string internally used to mean 'no filtering', hence it should not be used to qualify a filter. * * @since 4.0 {@index} */ @FunctionalInterface public interface ApplicationFeatureFilter { - public final static String GRAPHQL_VIEWER = "graphql"; - public final static String RESTFUL_VIEWER = "restful"; - public final static String WICKET_VIEWER = "wicket"; - /** * Whether to include given {@link ApplicationFeature}. */ diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/control/SyncControl.java b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/control/SyncControl.java index cb2896057fa..bd21a063650 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/control/SyncControl.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/control/SyncControl.java @@ -20,8 +20,9 @@ import java.util.UUID; -import org.jspecify.annotations.Nullable; +import org.springframework.util.StringUtils; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.iactnlayer.InteractionContext; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.schema.cmd.v2.CommandDto; @@ -31,7 +32,7 @@ /** * Controls the way that a (synchronous) wrapper works. * - * @since 2.0 revised for 3.4 {@index} + * @since 2.0 revised for 3.4 and 4.0 {@index} */ public record SyncControl( /** @@ -50,7 +51,12 @@ public record SyncControl( * *

The default behaviour is to rethrow the exception. */ - ExceptionHandler exceptionHandler) { + ExceptionHandler exceptionHandler, + /** + * Simulated viewerId, honoring feature filtering. + */ + String viewerId, + Where where) { //TODO can this be further simplified, or is there already an API we can reuse? @@ -79,22 +85,22 @@ public void onCommand( } public static SyncControl defaults() { - return new SyncControl(false, false, null, null); + return new SyncControl(false, false, null, null, null, null); } - public SyncControl( - boolean isSkipRules, - boolean isSkipExecute, - @Nullable Can commandListeners, - @Nullable ExceptionHandler exceptionHandler) { - this.isSkipRules = isSkipRules; - this.isSkipExecute = isSkipExecute; - this.commandListeners = commandListeners!=null - ? commandListeners - : Can.empty(); - this.exceptionHandler = exceptionHandler!=null - ? exceptionHandler - : exception -> { throw exception; }; + public SyncControl { + commandListeners = commandListeners!=null + ? commandListeners + : Can.empty(); + exceptionHandler = exceptionHandler!=null + ? exceptionHandler + : exception -> { throw exception; }; + viewerId = StringUtils.hasText(viewerId) + ? viewerId + : "NoViewer"; + where = where!=null + ? where + : Where.ANYWHERE; } /** @@ -102,27 +108,27 @@ public SyncControl( * executing the underlying property or action */ public SyncControl withSkipRules() { - return new SyncControl(true, isSkipExecute, commandListeners, exceptionHandler); + return new SyncControl(true, isSkipExecute, commandListeners, exceptionHandler, viewerId, where); } public SyncControl withCheckRules() { - return new SyncControl(false, isSkipExecute, commandListeners, exceptionHandler); + return new SyncControl(false, isSkipExecute, commandListeners, exceptionHandler, viewerId, where); } /** * Explicitly set the action to be executed. */ public SyncControl withExecute() { - return new SyncControl(isSkipRules, false, commandListeners, exceptionHandler); + return new SyncControl(isSkipRules, false, commandListeners, exceptionHandler, viewerId, where); } /** * Explicitly set the action to not be executed, in other words a 'dry run'. */ public SyncControl withNoExecute() { - return new SyncControl(isSkipRules, true, commandListeners, exceptionHandler); + return new SyncControl(isSkipRules, true, commandListeners, exceptionHandler, viewerId, where); } - public SyncControl listen(@NonNull CommandListener commandListener) { - return new SyncControl(isSkipRules, isSkipExecute, commandListeners.add(commandListener), exceptionHandler); + public SyncControl listen(@NonNull final CommandListener commandListener) { + return new SyncControl(isSkipRules, isSkipExecute, commandListeners.add(commandListener), exceptionHandler, viewerId, where); } /** @@ -131,13 +137,21 @@ public SyncControl listen(@NonNull CommandListener commandListener) { *

The default behaviour is to rethrow the exception. */ public SyncControl withExceptionHandler(final @NonNull ExceptionHandler exceptionHandler) { - return new SyncControl(isSkipRules, isSkipExecute, commandListeners, exceptionHandler); + return new SyncControl(isSkipRules, isSkipExecute, commandListeners, exceptionHandler, viewerId, where); + } + + public SyncControl withViewerId(final String viewerId) { + return new SyncControl(isSkipRules, isSkipExecute, commandListeners, exceptionHandler, viewerId, where); + } + + public SyncControl withWhere(final Where where) { + return new SyncControl(isSkipRules, isSkipExecute, commandListeners, exceptionHandler, viewerId, where); } /** * @return whether this and other share the same execution mode, ignoring exceptionHandling */ - public boolean isEquivalent(SyncControl other) { + public boolean isEquivalent(final SyncControl other) { return this.isSkipExecute == other.isSkipExecute && this.isSkipRules == other.isSkipRules; } diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/ioc/SpringContextHolder.java b/commons/src/main/java/org/apache/causeway/commons/internal/ioc/SpringContextHolder.java index edae73de62a..d1c14fa31e3 100644 --- a/commons/src/main/java/org/apache/causeway/commons/internal/ioc/SpringContextHolder.java +++ b/commons/src/main/java/org/apache/causeway/commons/internal/ioc/SpringContextHolder.java @@ -105,7 +105,6 @@ public Optional get(final @NonNull Class requiredType) { * @see #select(Class, Annotation[]) * @see #getSingletonElseFail(Class) */ - @SuppressWarnings("javadoc") public Can select(final @NonNull Class requiredType) { var allMatchingBeans = springContext.getBeanProvider(requiredType) .orderedStream() @@ -128,7 +127,6 @@ public Can select(final @NonNull Class requiredType) { * * @see #select(Class) */ - @SuppressWarnings("javadoc") public Can select( final @NonNull Class requiredType, final @Nullable Annotation[] qualifiers) { @@ -165,7 +163,6 @@ public Can select( * @return IoC managed singleton * @throws NoSuchElementException - if the singleton is not resolvable */ - @SuppressWarnings("javadoc") public T getSingletonElseFail(final @NonNull Class type) { var candidates = select(type); if (candidates.getCardinality() == Cardinality.ZERO) { diff --git a/core/interaction/src/main/java/module-info.java b/core/interaction/src/main/java/module-info.java index 0f71704d9c1..ecf9de42631 100644 --- a/core/interaction/src/main/java/module-info.java +++ b/core/interaction/src/main/java/module-info.java @@ -18,6 +18,7 @@ */ module org.apache.causeway.core.interaction { exports org.apache.causeway.core.interaction; + exports org.apache.causeway.core.interaction.core; exports org.apache.causeway.core.interaction.scope; exports org.apache.causeway.core.interaction.session; diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/ApplicationFeatureFilters.java b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/ApplicationFeatureFilters.java new file mode 100644 index 00000000000..7bf7f815473 --- /dev/null +++ b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/ApplicationFeatureFilters.java @@ -0,0 +1,85 @@ +/* + * 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.interaction.core; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import org.jspecify.annotations.Nullable; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.util.StringUtils; + +import org.apache.causeway.applib.services.appfeat.ApplicationFeatureFilter; +import org.apache.causeway.commons.collections.Can; +import org.apache.causeway.commons.internal.base._NullSafe; +import org.apache.causeway.commons.internal.collections._Multimaps; + +record ApplicationFeatureFilters( + Can unqualifiedFilters, + Map> filtersByQualifier) { + + // -- FACTORIES + + static ApplicationFeatureFilters empty() { + return new ApplicationFeatureFilters(Can.empty(), Collections.emptyMap()); + } + + static ApplicationFeatureFilters collectFrom(final @Nullable ApplicationContext springContext) { + if(springContext==null) + //JUnit Support + return ApplicationFeatureFilters.empty(); + + var unqualifiedFilters = new ArrayList(); + var filtersByQualifier = _Multimaps.newListMultimap(); + + Stream.of(springContext.getBeanNamesForType(ApplicationFeatureFilter.class)) + .forEach(beanName->{ + var filterBean = springContext.getBean(beanName, ApplicationFeatureFilter.class); + @SuppressWarnings("deprecation") + Set qualifiers = AnnotationUtils.getRepeatableAnnotations(filterBean.getClass(), Qualifier.class); + if(!_NullSafe.isEmpty(qualifiers)) { + qualifiers.forEach(qualifier->{ + if(StringUtils.hasText(qualifier.value())) { + filtersByQualifier.putElement(qualifier.value(), filterBean); + } else { + unqualifiedFilters.add(filterBean); + } + }); + } else { + unqualifiedFilters.add(filterBean); + } + }); + + // Sanitize (no duplicates, when already in unqualified Can) and make immutable + var unqualifiedFiltersCanned = Can.ofCollection(unqualifiedFilters).distinct(); + var filtersByQualifierCanned = new HashMap>(); + filtersByQualifier.forEach((k, v)->filtersByQualifierCanned.put(k, Can.ofCollection(v).distinct().filter(it->!unqualifiedFiltersCanned.contains(it)))); + return new ApplicationFeatureFilters( + unqualifiedFiltersCanned, + Collections.unmodifiableMap(filtersByQualifierCanned)); + } + +} diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java new file mode 100644 index 00000000000..b84067ea71f --- /dev/null +++ b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java @@ -0,0 +1,38 @@ +/* + * 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.interaction.core; + +import org.apache.causeway.applib.annotation.Where; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; + +public record InteractionConstraint( + WhatViewer whatViewer, + InteractionInitiatedBy initiatedBy, + Where where + ) { + + public InteractionConstraint withWhere(final Where where) { + return new InteractionConstraint(whatViewer, initiatedBy, where); + } + + public InteractionConstraint withInitiatedBy(final InteractionInitiatedBy initiatedBy) { + return new InteractionConstraint(whatViewer, initiatedBy, where); + } + +} diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java new file mode 100644 index 00000000000..24b9b66771c --- /dev/null +++ b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java @@ -0,0 +1,44 @@ +/* + * 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.interaction.core; + +import org.apache.causeway.applib.services.command.CommandExecutorService; +import org.apache.causeway.applib.services.wrapper.WrapperFactory; + +/** + * Viewer identifier, used for viewer specific feature filtering. + */ +public record WhatViewer( + String viewerId) { + + /** + * Used by {@link WrapperFactory}, {@link CommandExecutorService} and Object title interaction. + */ + public static WhatViewer noViewer() { + return new WhatViewer("NoViewer"); + } + + /** + * @deprecated for refactoring only + */ + @Deprecated + public static WhatViewer invalid() { + return new WhatViewer("invalid"); + } +} diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java index fbb95181e90..4ffab01eca3 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java @@ -187,8 +187,8 @@ public static VetoReason delegatedTo(final @NonNull Class - * Will correspond to the {@link InteractionResult#getReason() reason} in + * + *

Will correspond to the {@link InteractionResult#getReason() reason} in * the contained {@link #getInteractionResult() InteractionResult} (if one * was specified). */ @@ -204,8 +204,7 @@ default Optional getReasonAsString() { /** * Description of the interaction that this consent represents. * - *

- * May be null. + *

May be null. */ String getDescription(); @@ -222,7 +221,6 @@ default Optional getReasonAsString() { * The {@link InteractionResult} that created this {@link Consent}. * * @return - may be null if created as a legacy {@link Consent}. - * */ public InteractionResult getInteractionResult(); 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 091d2dd3c20..a8b8fcd584e 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 @@ -26,7 +26,6 @@ import org.jspecify.annotations.Nullable; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.exceptions.recoverable.InteractionException; import org.apache.causeway.applib.id.LogicalType; import org.apache.causeway.applib.services.wrapper.DisabledException; @@ -46,6 +45,8 @@ import org.apache.causeway.commons.internal.collections._Arrays; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.commons.internal.reflection._GenericResolver; +import org.apache.causeway.core.interaction.core.InteractionConstraint; +import org.apache.causeway.core.interaction.core.WhatViewer; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.InteractionResult; import org.apache.causeway.core.metamodel.context.MetaModelContext; @@ -97,15 +98,14 @@ final class DomainObjectInvocationHandler } @Override - public Object invoke(WrapperInvocation wrapperInvocation) throws Throwable { + public Object invoke(final WrapperInvocation wrapperInvocation) throws Throwable { final Object target = wrapperInvocation.origin().pojo(); final Method method = wrapperInvocation.method(); if (classMetaData().isObjectMethod(method) - || isEnhancedEntityMethod(method)) { - return method.invoke(target, wrapperInvocation.args()); - } + || isEnhancedEntityMethod(method)) + return method.invoke(target, wrapperInvocation.args()); final ManagedObject targetAdapter = mmc().getObjectManager().adapt(target); @@ -113,77 +113,64 @@ public Object invoke(WrapperInvocation wrapperInvocation) throws Throwable { MmAssertionUtils.assertIsBookmarkSupported(targetAdapter); } - if (classMetaData.isTitleMethod(method) ) { - return handleTitleMethod(wrapperInvocation, targetAdapter); - } + if (classMetaData.isTitleMethod(method) ) + return handleTitleMethod(wrapperInvocation, targetAdapter); var resolvedMethod = _GenericResolver.resolveMethod(method, targetAdapter.objSpec().getCorrespondingClass()) .orElseThrow(); if(!wrapperInvocation.origin().isFallback()) { - if (classMetaData.isOriginMethod(method)) { - return wrapperInvocation.origin(); - } + if (classMetaData.isOriginMethod(method)) + return wrapperInvocation.origin(); // save method, through the proxy - if (classMetaData.isSaveMethod(method)) { - return handleSaveMethod(wrapperInvocation, targetAdapter, targetAdapter.objSpec()); - } + if (classMetaData.isSaveMethod(method)) + return handleSaveMethod(wrapperInvocation, targetAdapter, targetAdapter.objSpec()); } var objectMember = targetAdapter.objSpec().getMemberElseFail(resolvedMethod); var intent = ImperativeFacet.getIntent(objectMember, resolvedMethod); - if(intent == Intent.CHECK_IF_HIDDEN || intent == Intent.CHECK_IF_DISABLED) { - throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'", objectMember.getId()); - } + if(intent == Intent.CHECK_IF_HIDDEN || intent == Intent.CHECK_IF_DISABLED) + throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'", objectMember.getId()); - if (intent == Intent.DEFAULTS || intent == Intent.CHOICES_OR_AUTOCOMPLETE) { - return method.invoke(target, wrapperInvocation.args()); - } + if (intent == Intent.DEFAULTS || intent == Intent.CHOICES_OR_AUTOCOMPLETE) + return method.invoke(target, wrapperInvocation.args()); if (objectMember instanceof OneToOneAssociation prop) { - if (intent == Intent.CHECK_IF_VALID || intent == Intent.MODIFY_PROPERTY_SUPPORTING) { - throw _Exceptions.unsupportedOperation("Cannot invoke supporting method for '%s'; use only property accessor/mutator", objectMember.getId()); - } + if (intent == Intent.CHECK_IF_VALID || intent == Intent.MODIFY_PROPERTY_SUPPORTING) + throw _Exceptions.unsupportedOperation("Cannot invoke supporting method for '%s'; use only property accessor/mutator", objectMember.getId()); - if (intent == Intent.ACCESSOR) { - return handleGetterMethodOnProperty(wrapperInvocation, targetAdapter, prop); - } + if (intent == Intent.ACCESSOR) + return handleGetterMethodOnProperty(wrapperInvocation, targetAdapter, prop); - if (intent == Intent.MODIFY_PROPERTY || intent == Intent.INITIALIZATION) { - return handleSetterMethodOnProperty(wrapperInvocation, targetAdapter, prop); - } + if (intent == Intent.MODIFY_PROPERTY || intent == Intent.INITIALIZATION) + return handleSetterMethodOnProperty(wrapperInvocation, targetAdapter, prop); } if (objectMember instanceof OneToManyAssociation coll) { - if (intent == Intent.CHECK_IF_VALID) { - throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'; use only collection accessor/mutator", objectMember.getId()); - } + if (intent == Intent.CHECK_IF_VALID) + throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'; use only collection accessor/mutator", objectMember.getId()); - if (intent == Intent.ACCESSOR) { - return handleGetterMethodOnCollection(wrapperInvocation, targetAdapter, coll, objectMember.getId()); - } + if (intent == Intent.ACCESSOR) + return handleGetterMethodOnCollection(wrapperInvocation, targetAdapter, coll, objectMember.getId()); } if (objectMember instanceof ObjectAction objectAction) { - if (intent == Intent.CHECK_IF_VALID) { - throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'; use only the 'invoke' method", objectMember.getId()); - } + if (intent == Intent.CHECK_IF_VALID) + throw _Exceptions.unsupportedOperation("Cannot invoke supporting method '%s'; use only the 'invoke' method", objectMember.getId()); if(targetAdapter.objSpec().isMixin()) { final ManagedObject managedMixee = wrapperInvocation.origin().managedMixee(); - if (managedMixee == null) { - throw _Exceptions.illegalState("Missing the required managedMixee for action '%s'", objectAction.getId()); - } + if (managedMixee == null) + throw _Exceptions.illegalState("Missing the required managedMixee for action '%s'", objectAction.getId()); MmAssertionUtils.assertIsBookmarkSupported(managedMixee); final ObjectMember mixinMember = determineMixinMember(managedMixee, objectAction); if (mixinMember != null) { - if(mixinMember instanceof ObjectAction) { - return handleActionMethod(wrapperInvocation, managedMixee, (ObjectAction)mixinMember); - } + if(mixinMember instanceof ObjectAction) + return handleActionMethod(wrapperInvocation, managedMixee, (ObjectAction)mixinMember); if(mixinMember instanceof OneToOneAssociation) { _Assert.assertEquals(0, wrapperInvocation.args().length); return handleGetterMethodOnProperty(wrapperInvocation, managedMixee, (OneToOneAssociation)mixinMember); @@ -192,9 +179,8 @@ public Object invoke(WrapperInvocation wrapperInvocation) throws Throwable { _Assert.assertEquals(0, wrapperInvocation.args().length); return handleGetterMethodOnCollection(wrapperInvocation, managedMixee, (OneToManyAssociation)mixinMember, objectMember.getId()); } - } else { - throw _Exceptions.illegalState("Could not locate mixin member for action '%s' on spec '%s'", objectAction.getId(), targetAdapter.objSpec()); - } + } else + throw _Exceptions.illegalState("Could not locate mixin member for action '%s' on spec '%s'", objectAction.getId(), targetAdapter.objSpec()); } // this is just a regular non-mixin action. @@ -208,7 +194,8 @@ private static ObjectMember determineMixinMember( final ManagedObject domainObjectAdapter, final ObjectAction objectAction) { - if(domainObjectAdapter == null) return null; + if(domainObjectAdapter == null) + return null; var specification = domainObjectAdapter.objSpec(); var objectActions = specification.streamAnyActions(MixedIn.INCLUDED); @@ -225,12 +212,6 @@ private static ObjectMember determineMixinMember( // throw new RuntimeException("Unable to find the mixed-in action corresponding to " + objectAction.getIdentifier().toFullIdentityString()); } - private InteractionInitiatedBy getInteractionInitiatedBy(final WrapperInvocation wrapperInvocation) { - return wrapperInvocation.syncControl().isSkipRules() - ? InteractionInitiatedBy.FRAMEWORK - : InteractionInitiatedBy.USER; - } - private boolean isEnhancedEntityMethod(final Method method) { return targetSpec.entityFacet() .map(entityFacet->entityFacet.isProxyEnhancement(method)) @@ -256,18 +237,17 @@ private Object handleSaveMethod( runValidationTask(wrapperInvocation, ()->{ var interactionResult = - targetNoSpec.isValidResult(targetAdapter, getInteractionInitiatedBy(wrapperInvocation)); + targetNoSpec.isValidResult(targetAdapter, iConstraint(wrapperInvocation).initiatedBy()); notifyListenersAndVetoIfRequired(interactionResult); }); var spec = targetAdapter.objSpec(); - if(spec.isEntity()) { - return runExecutionTask(wrapperInvocation, ()->{ + if(spec.isEntity()) + return runExecutionTask(wrapperInvocation, ()->{ MmEntityUtils.persistInCurrentTransaction(targetAdapter); return null; }, ()->new ExceptionLogger("persist", targetAdapter)); - } return null; } @@ -284,8 +264,7 @@ private Object handleGetterMethodOnProperty( return runExecutionTask(wrapperInvocation, ()->{ - var interactionInitiatedBy = getInteractionInitiatedBy(wrapperInvocation); - var currentReferencedAdapter = property.get(targetAdapter, interactionInitiatedBy); + var currentReferencedAdapter = property.get(targetAdapter, iConstraint(wrapperInvocation).initiatedBy()); var currentReferencedObj = MmUnwrapUtils.single(currentReferencedAdapter); @@ -313,7 +292,7 @@ private Object handleSetterMethodOnProperty( runValidationTask(wrapperInvocation, ()->{ var interactionResult = property.isAssociationValid( - targetAdapter, argumentAdapter, getInteractionInitiatedBy(wrapperInvocation)) + targetAdapter, argumentAdapter, iConstraint(wrapperInvocation).initiatedBy()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); }); @@ -322,7 +301,7 @@ targetAdapter, argumentAdapter, getInteractionInitiatedBy(wrapperInvocation)) .forProperty(InteractionHead.regular(targetAdapter), property, argumentAdapter)); return runExecutionTask(wrapperInvocation, ()->{ - property.set(targetAdapter, argumentAdapter, getInteractionInitiatedBy(wrapperInvocation)); + property.set(targetAdapter, argumentAdapter, iConstraint(wrapperInvocation).initiatedBy()); return null; }, ()->new ExceptionLogger("setter " + property.getId(), targetAdapter)); } @@ -341,8 +320,7 @@ private Object handleGetterMethodOnCollection( return runExecutionTask(wrapperInvocation, ()->{ - var interactionInitiatedBy = getInteractionInitiatedBy(wrapperInvocation); - var currentReferencedAdapter = collection.get(targetAdapter, interactionInitiatedBy); + var currentReferencedAdapter = collection.get(targetAdapter, iConstraint(wrapperInvocation).initiatedBy()); var currentReferencedObj = MmUnwrapUtils.single(currentReferencedAdapter); @@ -369,20 +347,18 @@ private Object handleGetterMethodOnCollection( private Collection wrapCollection( final Collection collectionToLookup, final OneToManyAssociation otma) { - if(proxyGenerator == null) { - throw new IllegalStateException("Unable to create proxy for collection; " + if(proxyGenerator == null) + throw new IllegalStateException("Unable to create proxy for collection; " + "proxyContextHandler not provided"); - } return proxyGenerator.collectionProxy(collectionToLookup, otma); } private Map wrapMap( final Map mapToLookup, final OneToManyAssociation otma) { - if(proxyGenerator == null) { - throw new IllegalStateException("Unable to create proxy for collection; " + if(proxyGenerator == null) + throw new IllegalStateException("Unable to create proxy for collection; " + "proxyContextHandler not provided"); - } return proxyGenerator.mapProxy(mapToLookup, otma); } @@ -413,11 +389,7 @@ private Object handleActionMethod( .forAction(head, objectAction, argAdapters)); return runExecutionTask(wrapperInvocation, ()->{ - var interactionInitiatedBy = getInteractionInitiatedBy(wrapperInvocation); - - var returnedAdapter = objectAction.execute( - head, argAdapters, - interactionInitiatedBy); + var returnedAdapter = objectAction.execute(head, argAdapters, iConstraint(wrapperInvocation).initiatedBy()); return MmUnwrapUtils.single(returnedAdapter); }, ()->new ExceptionLogger("action " + objectAction.getId(), targetAdapter)); } @@ -428,33 +400,34 @@ private void checkValidity( final ObjectAction objectAction, final Can argAdapters) { - var interactionResult = objectAction - .isArgumentSetValid(head, argAdapters, getInteractionInitiatedBy(wrapperInvocation)) + var interactionResult = objectAction.isArgumentSetValid(head, argAdapters, iConstraint(wrapperInvocation).initiatedBy()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } private Object underlying(final Object arg) { - if (arg instanceof WrappingObject wrappingObject) { - return wrappingObject.__causeway_origin().pojo(); - } else { - return arg; - } + return (arg instanceof WrappingObject wrappingObject) + ? wrappingObject.__causeway_origin().pojo() + : arg; } - /** - * REVIEW: ideally should provide some way to allow to caller to indicate the 'where' context. Having - * a hard-coded value like this is an approximation. - */ - private final Where where = Where.ANYWHERE; + private static InteractionConstraint iConstraint(final WrapperInvocation wrapperInvocation) { + return new InteractionConstraint( + new WhatViewer(wrapperInvocation.syncControl().viewerId()), + wrapperInvocation.syncControl().isSkipRules() + ? InteractionInitiatedBy.FRAMEWORK + : InteractionInitiatedBy.USER, + wrapperInvocation.syncControl().where()); + } private void checkVisibility( final WrapperInvocation wrapperInvocation, final ManagedObject targetObjectAdapter, final ObjectMember objectMember) { - var visibleConsent = objectMember.isVisible(targetObjectAdapter, getInteractionInitiatedBy(wrapperInvocation), where); - var interactionResult = visibleConsent.getInteractionResult(); + var iConstraint = iConstraint(wrapperInvocation); + var interactionResult = objectMember.isVisible(targetObjectAdapter, iConstraint.initiatedBy(), iConstraint.where()) + .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -463,10 +436,10 @@ private void checkUsability( final ManagedObject targetObjectAdapter, final ObjectMember objectMember) { - var interactionResult = objectMember.isUsable( - targetObjectAdapter, - getInteractionInitiatedBy(wrapperInvocation), - where) + + var iConstraint = iConstraint(wrapperInvocation); + + var interactionResult = objectMember.isUsable(targetObjectAdapter, iConstraint.initiatedBy(), iConstraint.where()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -477,9 +450,8 @@ private void notifyListenersAndVetoIfRequired(final InteractionResult interactio var interactionEvent = interactionResult.interactionEvent(); mmc().getWrapperFactory().notifyListeners(interactionEvent); - if (interactionEvent.isVeto()) { - throw toException(interactionEvent); - } + if (interactionEvent.isVeto()) + throw toException(interactionEvent); } /** @@ -488,21 +460,14 @@ private void notifyListenersAndVetoIfRequired(final InteractionResult interactio * and returns it. */ private InteractionException toException(final InteractionEvent interactionEvent) { - if (!interactionEvent.isVeto()) { - throw new IllegalArgumentException("Provided interactionEvent must be a veto"); - } - if (interactionEvent instanceof ValidityEvent) { - final ValidityEvent validityEvent = (ValidityEvent) interactionEvent; - return new InvalidException(validityEvent); - } - if (interactionEvent instanceof VisibilityEvent) { - final VisibilityEvent visibilityEvent = (VisibilityEvent) interactionEvent; - return new HiddenException(visibilityEvent); - } - if (interactionEvent instanceof UsabilityEvent) { - final UsabilityEvent usabilityEvent = (UsabilityEvent) interactionEvent; - return new DisabledException(usabilityEvent); - } + if (!interactionEvent.isVeto()) + throw new IllegalArgumentException("Provided interactionEvent must be a veto"); + if (interactionEvent instanceof final ValidityEvent validityEvent) + return new InvalidException(validityEvent); + if (interactionEvent instanceof final VisibilityEvent visibilityEvent) + return new HiddenException(visibilityEvent); + if (interactionEvent instanceof final UsabilityEvent usabilityEvent) + return new DisabledException(usabilityEvent); throw new IllegalArgumentException("Provided interactionEvent must be a VisibilityEvent, UsabilityEvent or a ValidityEvent"); } @@ -513,7 +478,8 @@ private MetaModelContext mmc() { } private void runValidationTask(final WrapperInvocation wrapperInvocation, final Runnable task) { - if(wrapperInvocation.syncControl().isSkipRules()) return; + if(wrapperInvocation.syncControl().isSkipRules()) + return; try { task.run(); } catch(Exception ex) { @@ -531,7 +497,8 @@ private void handleCommandListeners( if(commandRecordSupplier!=null && wrapperInvocation.syncControl().commandListeners().isNotEmpty()) { var commandRecord = commandRecordSupplier.get(); - if(commandRecord==null) return; + if(commandRecord==null) + return; wrapperInvocation.syncControl().commandListeners() .forEach(listener->listener .onCommand( @@ -545,7 +512,8 @@ private X runExecutionTask( final WrapperInvocation wrapperInvocation, final Supplier task, final Supplier exceptionLoggerSupplier) { - if(wrapperInvocation.syncControl().isSkipExecute()) return null; + if(wrapperInvocation.syncControl().isSkipExecute()) + return null; try { return task.get(); } catch(Exception ex) { @@ -570,21 +538,19 @@ private Object handleException( } private Object singleArgUnderlyingElseNull(final Object[] args, final String name) { - if (args.length != 1) { - throw _Exceptions.illegalArgument("Invoking '%s' should only have a single argument", name); - } + if (args.length != 1) + throw _Exceptions.illegalArgument("Invoking '%s' should only have a single argument", name); var argumentObj = underlying(args[0]); return argumentObj; } private void zeroArgsElseThrow(final Object[] args, final String name) { - if (!_NullSafe.isEmpty(args)) { - throw _Exceptions.illegalArgument("Invoking '%s' should have no arguments", name); - } + if (!_NullSafe.isEmpty(args)) + throw _Exceptions.illegalArgument("Invoking '%s' should have no arguments", name); } record ExceptionLogger(String what, ManagedObject mo) { - String msg(Exception ex) { + String msg(final Exception ex) { LogicalType logicalType = mo.objSpec().logicalType(); String id = mo.isBookmarkMemoized() ? mo.getBookmarkElseFail().identifier() From 0504eb9b3f0cb4072bf7d8b56c7660bb72ca88f0 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 07:41:23 +0100 Subject: [PATCH 15/25] CAUSEWAY-3752: work on access restriction --- .../interaction/core/AccessRestriction.java | 31 ++++++++++ .../core/metamodel/consent/Consent.java | 10 +-- .../DomainObjectInvocationHandler.java | 62 +++++++++---------- 3 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 core/interaction/src/main/java/org/apache/causeway/core/interaction/core/AccessRestriction.java diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/AccessRestriction.java b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/AccessRestriction.java new file mode 100644 index 00000000000..43b8f3ef348 --- /dev/null +++ b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/AccessRestriction.java @@ -0,0 +1,31 @@ +/* + * 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.interaction.core; + +import java.util.Optional; + +import org.apache.causeway.core.metamodel.consent.Consent; + +public record AccessRestriction( + boolean canView, + boolean canEdit, + Optional vetoReasonOpt + ) { +} + diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java index 4ffab01eca3..7eee4f7c807 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/consent/Consent.java @@ -114,15 +114,15 @@ public Optional toOptional() { /** * {@code Pi}: origin=PROGRAMMING_MODEL, nature=implicit (NO_ICON_UNLESS_PROTOTYPING)
* {@code Pe}: origin=PROGRAMMING_MODEL, nature=explicit (SHOW_BAN_ICON)
- * {@code S(e)}: origin=SECURITY, nature=explicit (SHOW_BAN_ICON)
+ * {@code Se}: origin=SECURITY, nature=explicit (SHOW_BAN_ICON)
*

* {@code Pi à§¹ Pi := pick any or concat}
* {@code Pe à§¹ Pe := pick any or concat}
- * {@code S(e) à§¹ S(e) := pick any or concat}
+ * {@code Se à§¹ Se := pick any or concat}
*
* {@code Pi à§¹ Pe := Pe}
- * {@code Pi à§¹ S(e) := Pi}
- * {@code Pe à§¹ S(e) := Pe}
+ * {@code Pi à§¹ Se := Pi}
+ * {@code Pe à§¹ Se := Pe}
* In other words: winner picking is driven by origin first and nature second. */ public VetoReason reduce(final VetoReason other) { @@ -187,7 +187,7 @@ public static VetoReason delegatedTo(final @NonNull ClassWill correspond to the {@link InteractionResult#getReason() reason} in * the contained {@link #getInteractionResult() InteractionResult} (if one * was specified). 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 a8b8fcd584e..7910ad8f7a9 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 @@ -258,13 +258,14 @@ private Object handleGetterMethodOnProperty( zeroArgsElseThrow(wrapperInvocation.args(), "get"); + var iConstraint = iConstraint(wrapperInvocation); runValidationTask(wrapperInvocation, ()->{ - checkVisibility(wrapperInvocation, targetAdapter, property); + checkVisibility(iConstraint, targetAdapter, property); }); return runExecutionTask(wrapperInvocation, ()->{ - var currentReferencedAdapter = property.get(targetAdapter, iConstraint(wrapperInvocation).initiatedBy()); + var currentReferencedAdapter = property.get(targetAdapter, iConstraint.initiatedBy()); var currentReferencedObj = MmUnwrapUtils.single(currentReferencedAdapter); @@ -283,16 +284,17 @@ private Object handleSetterMethodOnProperty( var singleArg = singleArgUnderlyingElseNull(wrapperInvocation.args(), "setter"); + var iConstraint = iConstraint(wrapperInvocation); runValidationTask(wrapperInvocation, ()->{ - checkVisibility(wrapperInvocation, targetAdapter, property); - checkUsability(wrapperInvocation, targetAdapter, property); + checkVisibility(iConstraint, targetAdapter, property); + checkUsability(iConstraint, targetAdapter, property); }); var argumentAdapter = property.getObjectManager().adapt(singleArg); runValidationTask(wrapperInvocation, ()->{ var interactionResult = property.isAssociationValid( - targetAdapter, argumentAdapter, iConstraint(wrapperInvocation).initiatedBy()) + targetAdapter, argumentAdapter, iConstraint.initiatedBy()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); }); @@ -301,7 +303,7 @@ targetAdapter, argumentAdapter, iConstraint(wrapperInvocation).initiatedBy()) .forProperty(InteractionHead.regular(targetAdapter), property, argumentAdapter)); return runExecutionTask(wrapperInvocation, ()->{ - property.set(targetAdapter, argumentAdapter, iConstraint(wrapperInvocation).initiatedBy()); + property.set(targetAdapter, argumentAdapter, iConstraint.initiatedBy()); return null; }, ()->new ExceptionLogger("setter " + property.getId(), targetAdapter)); } @@ -314,13 +316,14 @@ private Object handleGetterMethodOnCollection( zeroArgsElseThrow(wrapperInvocation.args(), "get"); + var iConstraint = iConstraint(wrapperInvocation); runValidationTask(wrapperInvocation, ()->{ - checkVisibility(wrapperInvocation, targetAdapter, collection); + checkVisibility(iConstraint, targetAdapter, collection); }); return runExecutionTask(wrapperInvocation, ()->{ - var currentReferencedAdapter = collection.get(targetAdapter, iConstraint(wrapperInvocation).initiatedBy()); + var currentReferencedAdapter = collection.get(targetAdapter, iConstraint.initiatedBy()); var currentReferencedObj = MmUnwrapUtils.single(currentReferencedAdapter); @@ -379,9 +382,10 @@ private Object handleActionMethod( : ManagedObject.empty(paramSpec); })); + var iConstraint = iConstraint(wrapperInvocation); runValidationTask(wrapperInvocation, ()->{ - checkVisibility(wrapperInvocation, targetAdapter, objectAction); - checkUsability(wrapperInvocation, targetAdapter, objectAction); + checkVisibility(iConstraint, targetAdapter, objectAction); + checkUsability(iConstraint, targetAdapter, objectAction); checkValidity(wrapperInvocation, head, objectAction, argAdapters); }); @@ -389,7 +393,7 @@ private Object handleActionMethod( .forAction(head, objectAction, argAdapters)); return runExecutionTask(wrapperInvocation, ()->{ - var returnedAdapter = objectAction.execute(head, argAdapters, iConstraint(wrapperInvocation).initiatedBy()); + var returnedAdapter = objectAction.execute(head, argAdapters, iConstraint.initiatedBy()); return MmUnwrapUtils.single(returnedAdapter); }, ()->new ExceptionLogger("action " + objectAction.getId(), targetAdapter)); } @@ -411,35 +415,20 @@ private Object underlying(final Object arg) { : arg; } - private static InteractionConstraint iConstraint(final WrapperInvocation wrapperInvocation) { - return new InteractionConstraint( - new WhatViewer(wrapperInvocation.syncControl().viewerId()), - wrapperInvocation.syncControl().isSkipRules() - ? InteractionInitiatedBy.FRAMEWORK - : InteractionInitiatedBy.USER, - wrapperInvocation.syncControl().where()); - } - private void checkVisibility( - final WrapperInvocation wrapperInvocation, - final ManagedObject targetObjectAdapter, + final InteractionConstraint iConstraint, + final ManagedObject targetMo, final ObjectMember objectMember) { - - var iConstraint = iConstraint(wrapperInvocation); - var interactionResult = objectMember.isVisible(targetObjectAdapter, iConstraint.initiatedBy(), iConstraint.where()) + var interactionResult = objectMember.isVisible(targetMo, iConstraint.initiatedBy(), iConstraint.where()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } private void checkUsability( - final WrapperInvocation wrapperInvocation, - final ManagedObject targetObjectAdapter, + final InteractionConstraint iConstraint, + final ManagedObject targetMo, final ObjectMember objectMember) { - - - var iConstraint = iConstraint(wrapperInvocation); - - var interactionResult = objectMember.isUsable(targetObjectAdapter, iConstraint.initiatedBy(), iConstraint.where()) + var interactionResult = objectMember.isUsable(targetMo, iConstraint.initiatedBy(), iConstraint.where()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -477,6 +466,15 @@ private MetaModelContext mmc() { return targetSpec.getMetaModelContext(); } + private static InteractionConstraint iConstraint(final WrapperInvocation wrapperInvocation) { + return new InteractionConstraint( + new WhatViewer(wrapperInvocation.syncControl().viewerId()), + wrapperInvocation.syncControl().isSkipRules() + ? InteractionInitiatedBy.FRAMEWORK + : InteractionInitiatedBy.USER, + wrapperInvocation.syncControl().where()); + } + private void runValidationTask(final WrapperInvocation wrapperInvocation, final Runnable task) { if(wrapperInvocation.syncControl().isSkipRules()) return; From 23f13409f44bd41eab5c5fe30339ceed07a6f844 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 08:12:32 +0100 Subject: [PATCH 16/25] CAUSEWAY-3752: simplified handling of VisibilityContext providing for debugging --- .../interactions/InteractionUtils.java | 19 +++++----- .../use/ActionUsabilityContext.java | 6 --- .../use/CollectionUsabilityContext.java | 7 ---- .../use/ParamUsabilityContext.java | 7 ---- .../use/PropertyUsabilityContext.java | 6 --- .../interactions/use/UsabilityContext.java | 5 ++- .../metamodel/spec/feature/ObjectMember.java | 37 +++++-------------- .../impl/ObjectActionParameterAbstract.java | 29 +++++++-------- .../spec/impl/ObjectMemberAbstract.java | 29 +++++++-------- 9 files changed, 49 insertions(+), 96 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java index 5830881c3f7..960fc6bbc0d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java @@ -19,6 +19,7 @@ package org.apache.causeway.core.metamodel.interactions; import java.util.Optional; +import java.util.function.Supplier; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; @@ -70,7 +71,8 @@ public InteractionResult isVisibleResult(final FacetHolder facetHolder, final Vi return builder.build(); } - public InteractionResult isUsableResult(final FacetHolder facetHolder, final UsabilityContext context) { + public InteractionResult isUsableResult(final FacetHolder facetHolder, final UsabilityContext context, + final Supplier visibilityContextSupplierForDebugging) { var builder = InteractionResult.builder(context.createInteractionEvent()); @@ -81,11 +83,10 @@ public InteractionResult isUsableResult(final FacetHolder facetHolder, final Usa break; case SHOW_AS_DISABLED: case SHOW_AS_DISABLED_WITH_DIAGNOSTICS: - var visibilityContext = context.asVisibilityContext(); - facetHolder.streamFacets(HidingInteractionAdvisor.class) + facetHolder.streamFacets(HidingInteractionAdvisor.class) .filter(advisor->compatible(advisor, context)) .forEach(advisor->{ - _Strings.nonEmpty(advisor.hides(visibilityContext)) + _Strings.nonEmpty(advisor.hides(visibilityContextSupplierForDebugging.get())) .map(Consent.VetoReason::explicit) .ifPresent(hidingReason->{ if(ifHiddenPolicy.isShowAsDisabledWithDiagnostics()) { @@ -158,13 +159,11 @@ private Optional guardAgainstEmptyReasonString( private static boolean compatible(final InteractionAdvisor advisor, final InteractionContext ic) { if(ic.initiatedBy().isPassThrough() - && isDomainEventAdvisor(advisor)) { - //[CAUSEWAY-3810] when pass-through, then don't trigger any domain events + && isDomainEventAdvisor(advisor)) + //[CAUSEWAY-3810] when pass-through, then don't trigger any domain events return false; - } - if(advisor instanceof ActionDomainEventFacet) { - return ic instanceof ActionInteractionContext; - } + if(advisor instanceof ActionDomainEventFacet) + return ic instanceof ActionInteractionContext; return true; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java index 6780cbff485..e989d222030 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java @@ -27,7 +27,6 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; -import org.apache.causeway.core.metamodel.interactions.vis.ActionVisibilityContext; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -63,9 +62,4 @@ public ActionUsabilityEvent createInteractionEvent() { return new ActionUsabilityEvent(MmUnwrapUtils.single(target()), identifier()); } - @Override - public ActionVisibilityContext asVisibilityContext() { - return new ActionVisibilityContext(head(), objectAction(), identifier(), - initiatedBy(), where(), renderPolicy()); - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java index d494fefb1de..a2270f0f0ef 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java @@ -26,7 +26,6 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; -import org.apache.causeway.core.metamodel.interactions.vis.CollectionVisibilityContext; /** * See {@link InteractionContext} for overview; analogous to @@ -55,10 +54,4 @@ public CollectionUsabilityContext( public CollectionUsabilityEvent createInteractionEvent() { return new CollectionUsabilityEvent(target().getPojo(), identifier()); } - - @Override - public CollectionVisibilityContext asVisibilityContext() { - return new CollectionVisibilityContext(head(), identifier(), - initiatedBy(), where(), renderPolicy()); - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java index a28348cbb85..06a6eb9a646 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java @@ -29,7 +29,6 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; -import org.apache.causeway.core.metamodel.interactions.vis.ParamVisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -73,10 +72,4 @@ public ActionArgumentUsabilityEvent createInteractionEvent() { position()); } - @Override - public ParamVisibilityContext asVisibilityContext() { - return new ParamVisibilityContext(head(), objectAction(), identifier(), - args, position, initiatedBy(), renderPolicy()); - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java index 8ab024f0e05..2f22814d2c2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java @@ -26,7 +26,6 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; -import org.apache.causeway.core.metamodel.interactions.vis.PropertyVisibilityContext; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; /** @@ -57,9 +56,4 @@ public PropertyUsabilityEvent createInteractionEvent() { return new PropertyUsabilityEvent(MmUnwrapUtils.single(target()), identifier()); } - @Override - public PropertyVisibilityContext asVisibilityContext() { - return new PropertyVisibilityContext(head(), identifier(), - initiatedBy(), where(), renderPolicy()); - } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java index 9edbce3254c..9e7f5ac5455 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java @@ -22,13 +22,14 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionEventSupplier; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; public sealed interface UsabilityContext extends InteractionContext, InteractionEventSupplier permits ActionUsabilityContext, CollectionUsabilityContext, ParamUsabilityContext, PropertyUsabilityContext { + /** + * for debugging visibility when prototyping + */ RenderPolicy renderPolicy(); - VisibilityContext asVisibilityContext(); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java index f72c4bc4f59..ea454491659 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java @@ -60,10 +60,6 @@ public interface ObjectMember extends ObjectFeature { */ ObjectSpecification getDeclaringType(); - // ///////////////////////////////////////////////////////////// - // Name, Description, Help (convenience for facets) - // ///////////////////////////////////////////////////////////// - /** * Return the help text for this member - the field or action - to * complement the description. @@ -72,10 +68,6 @@ public interface ObjectMember extends ObjectFeature { */ String getHelp(); - // ///////////////////////////////////////////////////////////// - // Hidden (or visible) - // ///////////////////////////////////////////////////////////// - /** * When the member is always hidden. * @@ -93,13 +85,9 @@ public interface ObjectMember extends ObjectFeature { * @param where */ Consent isVisible( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); - - // ///////////////////////////////////////////////////////////// - // Disabled (or enabled) - // ///////////////////////////////////////////////////////////// + ManagedObject target, + InteractionInitiatedBy interactionInitiatedBy, + Where where); /** * Determines whether this member is usable (not disabled), represented as a @@ -110,13 +98,9 @@ Consent isVisible( * @param where */ Consent isUsable( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); - - // ///////////////////////////////////////////////////////////// - // isAssociation, isAction - // ///////////////////////////////////////////////////////////// + ManagedObject target, + InteractionInitiatedBy interactionInitiatedBy, + Where where); /** * Whether this member represents a {@link ObjectAssociation}. @@ -166,9 +150,7 @@ default boolean isMixedIn() { */ boolean isExplicitlyAnnotated(); - // ///////////////////////////////////////////////////////////// - // Debugging - // ///////////////////////////////////////////////////////////// + // -- DEBUGGING /** * Thrown if the user is not authorized to access an action or any property/collection of an entity. @@ -276,9 +258,8 @@ default Optional> getElementComparator(){ .map(SortedByFacet::value) .orElse(null); - if(sortedBy == null) { - return Optional.empty(); - } + if(sortedBy == null) + return Optional.empty(); var pojoComparator = _Casts.>uncheckedCast( _InstanceUtil.createInstance(sortedBy)); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionParameterAbstract.java index 744b4aad4e3..b78e797df44 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionParameterAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionParameterAbstract.java @@ -21,6 +21,8 @@ import java.util.Optional; import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.exceptions.unrecoverable.DomainModelException; import org.apache.causeway.commons.collections.Can; @@ -51,7 +53,6 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter; import lombok.Getter; -import org.jspecify.annotations.NonNull; abstract class ObjectActionParameterAbstract implements @@ -188,9 +189,8 @@ public Can getAutoComplete( final InteractionInitiatedBy interactionInitiatedBy) { var autoCompleteFacet = getFacet(ActionParameterAutoCompleteFacet.class); - if (autoCompleteFacet == null) { - return Can.empty(); - } + if (autoCompleteFacet == null) + return Can.empty(); var paramSpec = getElementType(); @@ -226,9 +226,8 @@ public Can getChoices( var paramSpec = getElementType(); var choicesFacet = getFacet(ActionParameterChoicesFacet.class); - if (choicesFacet == null) { - return Can.empty(); - } + if (choicesFacet == null) + return Can.empty(); var visibleChoices = choicesFacet.getChoices(paramSpec, pendingArgs.actionInteractionHead(), @@ -296,11 +295,10 @@ static void checkChoicesOrAutoCompleteType( // in other words is assignable from // TODO: should implement this instead as a MetaModelValidator (subject to [CAUSEWAY-3172]) - if (!choiceWrappedSpec.isOfType(paramWrappedSpec)) { - throw new DomainModelException(String.format( + if (!choiceWrappedSpec.isOfType(paramWrappedSpec)) + throw new DomainModelException(String.format( "Type incompatible with parameter type; expected %s, but was %s", paramSpec.getFullIdentifier(), choiceClass.getName())); - } } } @@ -318,7 +316,7 @@ head, parentAction, getFeatureIdentifier(), pendingArgs, position, interactionIn } @Override - public Consent isVisible( + public final Consent isVisible( final InteractionHead head, final Can pendingArgs, final InteractionInitiatedBy interactionInitiatedBy) { @@ -348,7 +346,7 @@ private ParamUsabilityContext createArgumentUsabilityContext( } @Override - public Consent isUsable( + public final Consent isUsable( final InteractionHead head, final Can pendingArgs, final InteractionInitiatedBy interactionInitiatedBy) { @@ -356,8 +354,9 @@ public Consent isUsable( var usabilityContext = createArgumentUsabilityContext( head, pendingArgs, getParameterIndex(), interactionInitiatedBy); - var usableResult = InteractionUtils.isUsableResult(this, usabilityContext); - return usableResult.createConsent(); + return InteractionUtils.isUsableResult(this, usabilityContext, ()->createArgumentVisibilityContext( + head, pendingArgs, getParameterIndex(), interactionInitiatedBy)) + .createConsent(); } // -- Validation @@ -374,7 +373,7 @@ public ParamValidityContext createProposedArgumentInteractionContext( } @Override - public Consent isValid( + public final Consent isValid( final InteractionHead head, final Can pendingArgs, final InteractionInitiatedBy interactionInitiatedBy) { 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 c293cc0bfde..00e8635bbb5 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 @@ -26,6 +26,8 @@ import java.util.function.Function; import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.iactn.InteractionProvider; @@ -61,7 +63,6 @@ import org.apache.causeway.schema.cmd.v2.CommandDto; import lombok.Getter; -import org.jspecify.annotations.NonNull; abstract class ObjectMemberAbstract implements @@ -84,9 +85,8 @@ protected ObjectMemberAbstract( this.featureIdentifier = featureIdentifier; this.facetedMethod = facetedMethod; this.featureType = featureType; - if (getId() == null) { - throw new IllegalArgumentException("Id must always be set"); - } + if (getId() == null) + throw new IllegalArgumentException("Id must always be set"); } // -- IDENTIFIERS @@ -113,13 +113,12 @@ public final String getFriendlyName(final Supplier domainObjectPr var namedFacet = getFacet(MemberNamedFacet.class); - if(namedFacet==null) { - throw _Exceptions.unrecoverable("no MemberNamedFacet preset on %s", getFeatureIdentifier()); - } + if(namedFacet==null) + throw _Exceptions.unrecoverable("no MemberNamedFacet preset on %s", getFeatureIdentifier()); return namedFacet .getSpecialization() - .fold( textFacet->textFacet.translated(), + .fold( HasStaticText::translated, textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).target())); } @@ -138,7 +137,7 @@ public final Optional getDescription(final Supplier domai return lookupFacet(MemberDescribedFacet.class) .map(MemberDescribedFacet::getSpecialization) .map(specialization->specialization - .fold(textFacet->textFacet.translated(), + .fold(HasStaticText::translated, textFacet->textFacet.textElseNull(headFor(domainObjectProvider.get()).target()))); } @@ -209,7 +208,7 @@ public boolean isAlwaysHidden() { * returns true only if none hide the member. */ @Override - public Consent isVisible( + public final Consent isVisible( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final Where where) { @@ -239,13 +238,14 @@ protected abstract UsabilityContext createUsableInteractionContext( * returns true only if none disables the member. */ @Override - public Consent isUsable( + public final Consent isUsable( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final Where where) { var usabilityContext = createUsableInteractionContext(target, interactionInitiatedBy, where); - return InteractionUtils.isUsableResult(this, usabilityContext).createConsent(); + return InteractionUtils.isUsableResult(this, usabilityContext, ()->createVisibleInteractionContext(target, interactionInitiatedBy, where)) + .createConsent(); } // -- PREDICATES @@ -277,9 +277,8 @@ protected ManagedObject mixinAdapterFor( final @NonNull ManagedObject mixee) { // nullable for action parameter mixins - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(mixee)) { - return ManagedObject.empty(mixinSpec); - } + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(mixee)) + return ManagedObject.empty(mixinSpec); var mixinPojo = getFactoryService().mixin(mixinSpec.getCorrespondingClass(), mixee.getPojo()); return ManagedObject.mixin(mixinSpec, mixinPojo); From e1d936b82d38a24c43b2816f814dff3d6cff12a2 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 17:01:30 +0100 Subject: [PATCH 17/25] CAUSEWAY-3752: lets viewers provide their visibility contraints --- .../core/InteractionConstraint.java | 6 + .../impl/ObjectValidPropertiesFacetImpl.java | 12 +- .../object/value/CompositeValueUpdater.java | 5 +- .../interactions/InteractionContext.java | 6 - .../interactions/VisibilityConstraint.java | 39 +++ .../metamodel/interactions}/WhatViewer.java | 2 +- .../managed/ActionInteraction.java | 24 +- .../managed/CollectionInteraction.java | 6 +- .../interactions/managed/ManagedAction.java | 25 +- .../managed/ManagedCollection.java | 17 +- .../interactions/managed/ManagedMember.java | 12 +- .../interactions/managed/ManagedProperty.java | 21 +- .../managed/PropertyInteraction.java | 6 +- .../use/ActionUsabilityContext.java | 5 +- .../use/CollectionUsabilityContext.java | 5 +- .../use/ParamUsabilityContext.java | 4 +- .../use/PropertyUsabilityContext.java | 5 +- .../interactions/use/UsabilityContext.java | 2 +- .../interactions/val/ValidityContext.java | 6 - .../vis/ActionVisibilityContext.java | 8 +- .../vis/CollectionVisibilityContext.java | 8 +- .../vis/ObjectVisibilityContext.java | 9 +- .../vis/ParamVisibilityContext.java | 5 +- .../vis/PropertyVisibilityContext.java | 8 +- .../interactions/vis/VisibilityContext.java | 17 ++ .../authorization/AuthorizationFacet.java | 6 +- ...iddenFacetForNavigationFromHiddenType.java | 15 +- .../spec/feature/HasObjectAction.java | 9 +- .../metamodel/spec/feature/ObjectAction.java | 89 +++---- .../metamodel/spec/feature/ObjectMember.java | 7 +- .../spec/impl/ObjectActionDefault.java | 65 ++--- .../spec/impl/ObjectMemberAbstract.java | 22 +- .../impl/OneToManyAssociationDefault.java | 11 +- .../spec/impl/OneToOneAssociationDefault.java | 50 ++-- .../tabular/DataTableInteractive.java | 3 +- .../tabular/internal/DataRowInternal.java | 9 +- .../tabular/internal/DataTableInternal.java | 37 +-- .../metamodel/tabular/simple/DataRow.java | 10 +- .../impl/ObjectAssociationAbstractTest.java | 7 +- ...tAssociationAbstractTest_alwaysHidden.java | 6 +- .../impl/OneToOneAssociationAbstractTest.java | 9 +- .../DomainObjectInvocationHandler.java | 6 +- .../publishing/PublishingTestFactoryJpa.java | 242 +++++++----------- .../DomainObjectTesterFactory.java | 28 +- .../interaction/InteractionTestAbstract.java | 11 +- .../interact/CollectionInteractionTest.java | 3 +- .../value/PropertyInteractionProbeImpl.java | 13 +- .../value/ValueSemanticsTester.java | 10 +- .../services/menu/model/MenuAction.java | 6 +- .../commons/model/action/UiActionForm.java | 17 +- .../services/menu/_MenuItemBuilder.java | 6 +- .../viewer/graphql/model/context/Context.java | 19 +- .../rich/mutation/RichMutationForAction.java | 26 +- .../mutation/RichMutationForProperty.java | 28 +- .../rich/query/RichActionInvokeResult.java | 26 +- .../RichActionParamsParamAutoComplete.java | 15 +- .../query/RichActionParamsParamChoices.java | 15 +- .../query/RichActionParamsParamDefault.java | 9 +- .../domain/rich/query/RichMemberDisabled.java | 9 +- .../domain/rich/query/RichMemberHidden.java | 9 +- .../domain/rich/query/RichPropertySet.java | 26 +- .../mutation/SimpleMutationForAction.java | 26 +- .../mutation/SimpleMutationForProperty.java | 28 +- .../domain/simple/query/SimpleAction.java | 57 ++--- .../rendering/IResourceContext.java | 6 + .../rendering/context/ResourceContext.java | 54 ++-- .../AbstractObjectMemberReprRenderer.java | 34 ++- .../DomainObjectReprRenderer.java | 48 ++-- .../ObjectActionReprRenderer.java | 30 +-- .../ObjectCollectionReprRenderer.java | 17 +- .../ObjectPropertyReprRenderer.java | 21 +- ...NegotiationServiceOrgApacheCausewayV2.java | 61 ++--- .../DomainObjectResourceServerside.java | 44 ++-- .../resources/ObjectAdapterAccessHelper.java | 15 +- .../resources/ObjectAdapterUpdateHelper.java | 20 +- .../resources/_DomainResourceHelper.java | 29 +-- .../models/coll/CollectionModelParented.java | 5 +- .../coll/CollectionModelStandalone.java | 7 +- .../models/interaction/WktVisibility.java | 37 +++ .../interaction/act/ActionInteractionWkt.java | 20 +- .../prop/PropertyInteractionWkt.java | 3 +- .../parented/ParentedCollectionPanel.java | 3 +- 82 files changed, 827 insertions(+), 880 deletions(-) create mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java rename core/{interaction/src/main/java/org/apache/causeway/core/interaction/core => metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions}/WhatViewer.java (96%) create mode 100644 viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/WktVisibility.java diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java index b84067ea71f..6d7fc44a0d7 100644 --- a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java +++ b/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/InteractionConstraint.java @@ -20,6 +20,8 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; public record InteractionConstraint( WhatViewer whatViewer, @@ -35,4 +37,8 @@ public InteractionConstraint withInitiatedBy(final InteractionInitiatedBy initia return new InteractionConstraint(whatViewer, initiatedBy, where); } + public VisibilityConstraint asVisibilityConstraint() { + return new VisibilityConstraint(whatViewer, where); + } + } 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 086d41fd642..c970a26df94 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 @@ -21,6 +21,7 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.object.objectvalidprops.ObjectValidPropertiesFacetAbstract; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.val.ObjectValidityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.MixedIn; @@ -45,9 +46,11 @@ public String invalidReason( final StringBuilder buf = new StringBuilder(); final ManagedObject adapter = context.target(); + var visibilityConstraint = VisibilityConstraint.invalid(where); + adapter.objSpec().streamProperties(MixedIn.EXCLUDED) - .filter(property->property.isVisible(adapter, context.initiatedBy(), where).isVetoed()) // ignore hidden properties - .filter(property->property.isUsable(adapter, context.initiatedBy(), where).isVetoed()) // ignore disabled properties + .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()) { @@ -57,9 +60,8 @@ public String invalidReason( buf.append(property.getFriendlyName(context::target)); } }); - if (buf.length() > 0) { - return "Invalid properties: " + buf.toString(); - } + if (buf.length() > 0) + return "Invalid properties: " + buf.toString(); return null; } 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 f9d30c19c3a..444eff437a3 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 @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.facets.object.value.CompositeValueUpdater.CompositeValueUpdaterForParameter; import org.apache.causeway.core.metamodel.facets.object.value.CompositeValueUpdater.CompositeValueUpdaterForProperty; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -68,8 +69,8 @@ default CompositeValueUpdater overrideFacets() { // -- OBJECT ACTION MOCKUP - @Override default Consent isVisible(final ManagedObject a, final InteractionInitiatedBy b, final Where c) { return Allow.DEFAULT; } - @Override default Consent isUsable(final ManagedObject a, final InteractionInitiatedBy b, final Where c) { return Allow.DEFAULT; } + @Override default Consent isVisible(final ManagedObject a, final InteractionInitiatedBy b, final VisibilityConstraint c) { return Allow.DEFAULT; } + @Override default Consent isUsable(final ManagedObject a, final InteractionInitiatedBy b, final VisibilityConstraint c) { return Allow.DEFAULT; } @Override default PromptStyle getPromptStyle() { return PromptStyle.INLINE_AS_IF_EDIT; } @Override default SemanticsOf getSemantics() { return SemanticsOf.SAFE; } 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 c7c15861a05..1570aaa4a11 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 @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.InteractionEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -93,11 +92,6 @@ public interface InteractionContext { */ InteractionHead head(); - /** - * Where the element is to be rendered. - */ - Where where(); - /** * The target object that this interaction is associated with. */ diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java new file mode 100644 index 00000000000..e301021b1d3 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java @@ -0,0 +1,39 @@ +/* + * 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.interactions; + +import org.apache.causeway.applib.annotation.Where; + +public record VisibilityConstraint( + WhatViewer whatViewer, + Where where) { + + public VisibilityConstraint withWhere(final Where where) { + return new VisibilityConstraint(whatViewer, where); + } + + /** + * temporary for refactoring + */ + @Deprecated + public static VisibilityConstraint invalid(final Where where) { + return new VisibilityConstraint(WhatViewer.invalid(), where); + } + +} diff --git a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/WhatViewer.java similarity index 96% rename from core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/WhatViewer.java index 24b9b66771c..73e8c94dcca 100644 --- a/core/interaction/src/main/java/org/apache/causeway/core/interaction/core/WhatViewer.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/WhatViewer.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.causeway.core.interaction.core; +package org.apache.causeway.core.metamodel.interactions; import org.apache.causeway.applib.services.command.CommandExecutorService; import org.apache.causeway.applib.services.wrapper.WrapperFactory; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteraction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteraction.java index 86e3fb2962e..d1ff4704ee7 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteraction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ActionInteraction.java @@ -24,11 +24,11 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.functional.Railway; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.core.metamodel.facets.object.value.ValueFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.spec.feature.MixedIn; @@ -66,17 +66,17 @@ public static interface ParameterInvalidCallback { public static ActionInteraction start( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { - return startWithMultiselect(owner, memberId, where, Can::empty); + final @NonNull VisibilityConstraint visibilityConstraint) { + return startWithMultiselect(owner, memberId, visibilityConstraint, Can::empty); } public static ActionInteraction startWithMultiselect( final @NonNull ManagedObject owner, final @NonNull String actionId, - final @NonNull Where where, + final @NonNull VisibilityConstraint visibilityConstraint, final @NonNull MultiselectChoices multiselectChoices) { - var managedAction = ManagedAction.lookupActionWithMultiselect(owner, actionId, where, multiselectChoices); + var managedAction = ManagedAction.lookupActionWithMultiselect(owner, actionId, visibilityConstraint, multiselectChoices); final InteractionRailway railway = managedAction.isPresent() ? InteractionRailway.success(managedAction.get()) @@ -84,7 +84,7 @@ public static ActionInteraction startWithMultiselect( return new ActionInteraction( actionId, - managedAction.map(x->x.getAction()), + managedAction.map(ManagedAction::getAction), railway); } @@ -92,7 +92,7 @@ public static ActionInteraction startWithMultiselect( public static ActionInteraction startAsBoundToProperty( final ManagedProperty associatedWithProperty, final String memberId, - final Where where) { + final VisibilityConstraint visibilityConstraint) { var propertyOwner = associatedWithProperty.getOwner(); var prop = associatedWithProperty.getMetaModel(); var elementType = prop.getElementType(); @@ -117,12 +117,12 @@ public static ActionInteraction startAsBoundToProperty( var mixinAction = valueFacet.selectCompositeValueMixinForProperty(associatedWithProperty); if(mixinAction.isPresent()) { - var managedAction = ManagedAction.of(compositeValue, mixinAction.get(), where); + var managedAction = ManagedAction.of(compositeValue, mixinAction.get(), visibilityConstraint); return ActionInteraction.wrap(managedAction); } } // fallback if not a composite value - return ActionInteraction.start(propertyOwner, memberId, where); + return ActionInteraction.start(propertyOwner, memberId, visibilityConstraint); } /** Supports composite-value-types via mixin (in case detected). */ @@ -130,7 +130,7 @@ public static ActionInteraction startAsBoundToParameter( final ParameterNegotiationModel parameterNegotiationModel, final int paramIndex, final String memberId, - final Where where) { + final VisibilityConstraint visibilityConstraint) { var actionOwner = parameterNegotiationModel.getActionTarget(); var param = parameterNegotiationModel.getParamModels().getElseFail(paramIndex); @@ -155,13 +155,13 @@ public static ActionInteraction startAsBoundToParameter( var mixinAction = valueFacet.selectCompositeValueMixinForParameter(parameterNegotiationModel, paramIndex); if(mixinAction.isPresent()) { - var managedAction = ManagedAction.of(compositeValue, mixinAction.get(), where); + var managedAction = ManagedAction.of(compositeValue, mixinAction.get(), visibilityConstraint); return ActionInteraction.wrap(managedAction); } } // else if not a composite value - return ActionInteraction.start(actionOwner, memberId, where); + return ActionInteraction.start(actionOwner, memberId, visibilityConstraint); } public static ActionInteraction wrap(final @NonNull ManagedAction managedAction) { diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/CollectionInteraction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/CollectionInteraction.java index d8879f43140..fc733248605 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/CollectionInteraction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/CollectionInteraction.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; public record CollectionInteraction( @@ -34,9 +34,9 @@ public record CollectionInteraction( public static final CollectionInteraction start( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { - var managedCollection = ManagedCollection.lookupCollection(owner, memberId, where); + var managedCollection = ManagedCollection.lookupCollection(owner, memberId, visibilityConstraint); final InteractionRailway railway = managedCollection.isPresent() ? InteractionRailway.success(managedCollection.get()) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java index 5b21c9409c2..12b76a44ffa 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java @@ -25,7 +25,6 @@ import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.registry.ServiceRegistry; import org.apache.causeway.applib.services.routing.RoutingService; import org.apache.causeway.commons.collections.Can; @@ -36,6 +35,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.objectmanager.ObjectManager; @@ -55,27 +55,27 @@ public final class ManagedAction extends ManagedMember { public static final ManagedAction of( final @NonNull ManagedObject owner, final @NonNull ObjectAction action, - final @NonNull Where where) { - return new ManagedAction(owner, action, where, Can::empty); + final @NonNull VisibilityConstraint visibilityConstraint) { + return new ManagedAction(owner, action, visibilityConstraint, Can::empty); } public static final Optional lookupAction( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.ACTION, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(objectAction -> of(owner, objectAction, visibilityConstraint)); } public static final Optional lookupActionWithMultiselect( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where, + final @NonNull VisibilityConstraint visibilityConstraint, final @NonNull MultiselectChoices multiselectChoices) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.ACTION, memberId) - .map(objectAction -> new ManagedAction(owner, objectAction, where, multiselectChoices)); + .map(objectAction -> new ManagedAction(owner, objectAction, visibilityConstraint, multiselectChoices)); } // -- IMPLEMENTATION @@ -86,10 +86,10 @@ public static final Optional lookupActionWithMultiselect( private ManagedAction( final @NonNull ManagedObject owner, final @NonNull ObjectAction action, - final @NonNull Where where, + final @NonNull VisibilityConstraint visibilityConstraint, final @NonNull MultiselectChoices multiselectChoices) { - super(owner, where); + super(owner, visibilityConstraint); /* entities might become removed, but even though removed, an entity delete mixin say, may still want to provide an action result, that does not need the mixee instance to be produced; eg. delete ApplicationUser mixin that returns a collection of all remaining users @@ -158,7 +158,7 @@ public final ManagedObject invokeWithRuleChecking( // under the hood intercepts cases, where the owner is a value-type; // executions on value-types have no rule checking and trigger no domain events .executeWithRuleChecking( - interactionHead(), actionParameters, InteractionInitiatedBy.USER, getWhere()); + interactionHead(), actionParameters, InteractionInitiatedBy.USER, visibilityConstraint().where()); return route(actionResult); } @@ -167,9 +167,8 @@ public final ManagedObject invokeWithRuleChecking( private ManagedObject route(final @Nullable ManagedObject actionResult) { - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionResult)) { - return ManagedObject.empty(action.getReturnType()); - } + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionResult)) + return ManagedObject.empty(action.getReturnType()); var resultPojo = actionResult.getPojo(); var objManager = mmc().getObjectManager(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedCollection.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedCollection.java index 6cf1b7e8b9e..aefd00b0902 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedCollection.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedCollection.java @@ -21,18 +21,19 @@ import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation; import org.apache.causeway.core.metamodel.tabular.DataTableInteractive; import lombok.Getter; -import org.jspecify.annotations.NonNull; public final class ManagedCollection extends ManagedMember { @@ -41,17 +42,17 @@ public final class ManagedCollection extends ManagedMember { public static final ManagedCollection of( final @NonNull ManagedObject owner, final @NonNull OneToManyAssociation collection, - final @NonNull Where where) { - return new ManagedCollection(owner, collection, where); + final @NonNull VisibilityConstraint visibilityConstraint) { + return new ManagedCollection(owner, collection, visibilityConstraint); } public static final Optional lookupCollection( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.COLLECTION, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(objectAction -> of(owner, objectAction, visibilityConstraint)); } // -- IMPLEMENTATION @@ -61,9 +62,9 @@ public static final Optional lookupCollection( private ManagedCollection( final @NonNull ManagedObject owner, final @NonNull OneToManyAssociation collection, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { - super(owner, where); + super(owner, visibilityConstraint); this.collection = collection; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedMember.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedMember.java index 036d664117b..65745bf850a 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedMember.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedMember.java @@ -23,10 +23,10 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.Veto; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; @@ -34,6 +34,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -59,7 +60,7 @@ public enum RepresentationMode { @Getter @NonNull private ManagedObject owner; - @Getter @NonNull private final Where where; + @Getter @Accessors(fluent = true) @NonNull private final VisibilityConstraint visibilityConstraint; /** * Allows a managed property of a view model to replace its owner with a clone. @@ -110,11 +111,10 @@ public Optional getDescription() { * @return non-empty if hidden */ public Optional checkVisibility() { - try { var visibilityConsent = getMetaModel() - .isVisible(getOwner(), InteractionInitiatedBy.USER, where); + .isVisible(getOwner(), InteractionInitiatedBy.USER, visibilityConstraint); return visibilityConsent.isVetoed() ? Optional.of(InteractionVeto.hidden(visibilityConsent)) @@ -133,12 +133,10 @@ public Optional checkVisibility() { * @return non-empty if not usable/editable (meaning if read-only) */ public Optional checkUsability() { - try { - var usabilityConsent = getMetaModel() - .isUsable(getOwner(), InteractionInitiatedBy.USER, where); + .isUsable(getOwner(), InteractionInitiatedBy.USER, visibilityConstraint); return usabilityConsent.isVetoed() ? Optional.of(InteractionVeto.readonly(usabilityConsent)) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedProperty.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedProperty.java index 9dd7f766f72..2f0b96c8062 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedProperty.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedProperty.java @@ -20,22 +20,22 @@ import java.util.Optional; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.binding.Observable; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.binding._Observables; import org.apache.causeway.commons.internal.binding._Observables.LazyObservable; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.Veto; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import lombok.Getter; -import org.jspecify.annotations.NonNull; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -47,17 +47,17 @@ public final class ManagedProperty public static final ManagedProperty of( final @NonNull ManagedObject owner, final @NonNull OneToOneAssociation property, - final @NonNull Where where) { - return new ManagedProperty(owner, property, where); + final @NonNull VisibilityConstraint visibilityConstraint) { + return new ManagedProperty(owner, property, visibilityConstraint); } public static final Optional lookupProperty( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.PROPERTY, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(objectAction -> of(owner, objectAction, visibilityConstraint)); } // -- IMPLEMENTATION @@ -72,8 +72,8 @@ public static final Optional lookupProperty( private ManagedProperty( final @NonNull ManagedObject owner, final @NonNull OneToOneAssociation property, - final @NonNull Where where) { - super(owner, where); + final @NonNull VisibilityConstraint visibilityConstraint) { + super(owner, visibilityConstraint); this.property = property; observablePropValue = _Observables.lazy(this::reassessPropertyValue); } @@ -132,9 +132,8 @@ public Optional modifyProperty(final @Nullable ManagedObject ne private ManagedObject reassessPropertyValue() { var property = getProperty(); var owner = getOwner(); - - return property.isVisible(owner, InteractionInitiatedBy.FRAMEWORK, getWhere()).isAllowed() - && property.isVisible(owner, InteractionInitiatedBy.USER, getWhere()).isAllowed() + return property.isVisible(owner, InteractionInitiatedBy.FRAMEWORK, visibilityConstraint()).isAllowed() + && property.isVisible(owner, InteractionInitiatedBy.USER, visibilityConstraint()).isAllowed() ? property.get(owner, InteractionInitiatedBy.USER) : ManagedObject.empty(property.getElementType()); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyInteraction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyInteraction.java index 097593bb387..fd7ce7114d8 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyInteraction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyInteraction.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; public record PropertyInteraction( @@ -34,9 +34,9 @@ public record PropertyInteraction( public static final PropertyInteraction start( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull VisibilityConstraint visibilityConstraint) { - var managedProperty = ManagedProperty.lookupProperty(owner, memberId, where); + var managedProperty = ManagedProperty.lookupProperty(owner, memberId, visibilityConstraint); final InteractionRailway railway = managedProperty.isPresent() ? InteractionRailway.success(managedProperty.get()) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java index e989d222030..6b2c4be3e1f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ActionUsabilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.use; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.ActionUsabilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -39,7 +38,6 @@ public record ActionUsabilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, RenderPolicy renderPolicy, ObjectAction objectAction ) @@ -50,10 +48,9 @@ public ActionUsabilityContext( final ObjectAction objectAction, final Identifier id, final InteractionInitiatedBy initiatedBy, - final Where where, final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_USABLE, - head, id, initiatedBy, where, renderPolicy, + head, id, initiatedBy, renderPolicy, objectAction); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java index a2270f0f0ef..56c9552a304 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/CollectionUsabilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.use; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.CollectionUsabilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -36,7 +35,6 @@ public record CollectionUsabilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, RenderPolicy renderPolicy) implements UsabilityContext { @@ -44,10 +42,9 @@ public CollectionUsabilityContext( final InteractionHead head, final Identifier identifier, final InteractionInitiatedBy initiatedBy, - final Where where, final RenderPolicy renderPolicy) { this(InteractionContextType.COLLECTION_USABLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, initiatedBy, renderPolicy); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java index 06a6eb9a646..2f141e711a2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/ParamUsabilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.use; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.events.ActionArgumentUsabilityEvent; import org.apache.causeway.applib.services.wrapper.events.ActionArgumentEvent; import org.apache.causeway.commons.collections.Can; @@ -42,7 +41,6 @@ public record ParamUsabilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, RenderPolicy renderPolicy, ObjectAction objectAction, Can args, @@ -59,7 +57,7 @@ public ParamUsabilityContext( final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_PARAMETER_USABLE, - head, id, initiatedBy, Where.OBJECT_FORMS, renderPolicy, + head, id, initiatedBy, renderPolicy, objectAction, args, position); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java index 2f22814d2c2..71be348a788 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/PropertyUsabilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.use; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.PropertyUsabilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -37,7 +36,6 @@ public record PropertyUsabilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, RenderPolicy renderPolicy) implements UsabilityContext { @@ -45,10 +43,9 @@ public PropertyUsabilityContext( final InteractionHead head, final Identifier identifier, final InteractionInitiatedBy initiatedBy, - final Where where, final RenderPolicy renderPolicy) { this(InteractionContextType.PROPERTY_USABLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, initiatedBy, renderPolicy); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java index 9e7f5ac5455..3aafe9c9fee 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/use/UsabilityContext.java @@ -28,7 +28,7 @@ public sealed interface UsabilityContext permits ActionUsabilityContext, CollectionUsabilityContext, ParamUsabilityContext, PropertyUsabilityContext { /** - * for debugging visibility when prototyping + * for debugging usability when prototyping */ RenderPolicy renderPolicy(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ValidityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ValidityContext.java index 04c1610c9df..af8dac64ebf 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ValidityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ValidityContext.java @@ -20,7 +20,6 @@ import java.util.function.Supplier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.ValidityEvent; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionEventSupplier; @@ -35,9 +34,4 @@ default String friendlyName() { return friendlyNameProvider().get(); } - @Override - default Where where() { - return Where.NOT_SPECIFIED; - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java index f9415271a89..437d72f3c80 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.vis; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.ActionVisibilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -27,6 +26,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -39,7 +39,7 @@ public record ActionVisibilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, + VisibilityConstraint visibilityConstraint, RenderPolicy renderPolicy, ObjectAction objectAction) implements VisibilityContext, ActionInteractionContext { @@ -49,10 +49,10 @@ public ActionVisibilityContext( final ObjectAction objectAction, final Identifier identifier, final InteractionInitiatedBy initiatedBy, - final Where where, + final VisibilityConstraint visibilityConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_VISIBLE, - head, identifier, initiatedBy, where, renderPolicy, + head, identifier, initiatedBy, visibilityConstraint, renderPolicy, objectAction); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java index 4ee46ff2bec..ae47e092d4f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java @@ -19,13 +19,13 @@ package org.apache.causeway.core.metamodel.interactions.vis; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.CollectionVisibilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; /** @@ -37,7 +37,7 @@ public record CollectionVisibilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, + VisibilityConstraint visibilityConstraint, RenderPolicy renderPolicy) implements VisibilityContext { @@ -45,10 +45,10 @@ public CollectionVisibilityContext( final InteractionHead head, final Identifier identifierAdapter, final InteractionInitiatedBy initiatedBy, - final Where where, + final VisibilityConstraint visibilityConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.COLLECTION_VISIBLE, - head, identifierAdapter, initiatedBy, where, renderPolicy); + head, identifierAdapter, initiatedBy, visibilityConstraint, renderPolicy); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java index 44188f58c9b..1545feac004 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java @@ -27,6 +27,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.ProposedHolder; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; @@ -39,7 +40,7 @@ public record ObjectVisibilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, + VisibilityConstraint visibilityConstraint, RenderPolicy renderPolicy) implements VisibilityContext, ProposedHolder { @@ -56,7 +57,7 @@ public static ObjectVisibilityContext createForRegular( InteractionHead.regular(domainObject), domainObject.objSpec().getFeatureIdentifier(), initiatedBy, - where, + VisibilityConstraint.invalid(where), RenderPolicy.forNonActionParam(domainObject)); } @@ -66,10 +67,10 @@ public ObjectVisibilityContext( final InteractionHead head, final Identifier identifier, final InteractionInitiatedBy initiatedBy, - final Where where, + final VisibilityConstraint visibilityConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.OBJECT_VISIBILITY, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, initiatedBy, visibilityConstraint, renderPolicy); } @Override 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 b09699b922b..bbf580cdd0a 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 @@ -29,6 +29,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -42,7 +43,7 @@ public record ParamVisibilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, + VisibilityConstraint visibilityConstraint, RenderPolicy renderPolicy, ObjectAction objectAction, Can args, @@ -59,7 +60,7 @@ public ParamVisibilityContext( final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_PARAMETER_VISIBLE, - head, id, initiatedBy, Where.OBJECT_FORMS, renderPolicy, + head, id, initiatedBy, VisibilityConstraint.invalid(Where.OBJECT_FORMS), renderPolicy, objectAction, args, position); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java index 0fad557d06e..7ae42f6bfae 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java @@ -19,13 +19,13 @@ package org.apache.causeway.core.metamodel.interactions.vis; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.PropertyVisibilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; /** @@ -37,7 +37,7 @@ public record PropertyVisibilityContext( InteractionHead head, Identifier identifier, InteractionInitiatedBy initiatedBy, - Where where, + VisibilityConstraint visibilityConstraint, RenderPolicy renderPolicy ) implements VisibilityContext { @@ -45,11 +45,11 @@ public PropertyVisibilityContext( final InteractionHead head, final Identifier identifier, final InteractionInitiatedBy initiatedBy, - final Where where, + final VisibilityConstraint visibilityConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.PROPERTY_VISIBLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, initiatedBy, visibilityConstraint, renderPolicy); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/VisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/VisibilityContext.java index 418df088599..70afbaf8cb9 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/VisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/VisibilityContext.java @@ -18,10 +18,12 @@ */ package org.apache.causeway.core.metamodel.interactions.vis; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.VisibilityEvent; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionEventSupplier; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; /** * See {@link InteractionContext} for overview; analogous to @@ -32,6 +34,21 @@ public sealed interface VisibilityContext permits ParamVisibilityContext, ActionVisibilityContext, CollectionVisibilityContext, ObjectVisibilityContext, PropertyVisibilityContext { + /** + * for debugging visibility when prototyping + */ RenderPolicy renderPolicy(); + /** + * Where and by what viewer the element is to be rendered. + */ + VisibilityConstraint visibilityConstraint(); + + /** + * Where the element is to be rendered. + */ + default Where where() { + return visibilityConstraint().where(); + } + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java index b66df8ab8be..05dc74d6a49 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/allbutparam/authorization/AuthorizationFacet.java @@ -51,7 +51,7 @@ public static boolean hidesProperty( vc.head(), property.getFeatureIdentifier(), vc.initiatedBy(), - vc.where(), + vc.visibilityConstraint(), vc.renderPolicy())) != null) .orElse(false); } @@ -66,7 +66,7 @@ public static boolean hidesCollection( vc.head(), collection.getFeatureIdentifier(), vc.initiatedBy(), - vc.where(), + vc.visibilityConstraint(), vc.renderPolicy())) != null) .orElse(false); } @@ -82,7 +82,7 @@ public static boolean hidesAction( action, action.getFeatureIdentifier(), vc.initiatedBy(), - vc.where(), + vc.visibilityConstraint(), vc.renderPolicy())) != null) .orElse(false); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java index 127578a7af8..b93e8b04e5f 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/members/navigation/HiddenFacetForNavigationFromHiddenType.java @@ -52,19 +52,18 @@ public static Optional create(final ObjectSpecificatio } @Override - public String hides(final VisibilityContext ic) { + public String hides(final VisibilityContext vc) { var facet = navigatedType.getFacet(HiddenFacetForNoMembersAuthorized.class); - if(facet == null) { - // not expected to happen; this facet should only be installed for object members + if(facet == null) + // not expected to happen; this facet should only be installed for object members // that navigate to a class that has the HiddenTypeFacet return null; - } var objVisibilityContext = new ObjectVisibilityContext( - ic.head(), + vc.head(), Identifier.classIdentifier(navigatedType.logicalType()), - ic.initiatedBy(), - ic.where(), - ic.renderPolicy()); + vc.initiatedBy(), + vc.visibilityConstraint(), + vc.renderPolicy()); final String hides = facet.hides(objVisibilityContext); return hides; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java index 2729dd71e34..8eec11b0339 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ActionScope; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -55,11 +56,11 @@ public interface HasObjectAction extends ObjectAction { @Override default boolean isAlwaysHidden() { return getObjectAction().isAlwaysHidden(); } - @Override default Consent isVisible(final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final Where where) { - return getObjectAction().isVisible(target, interactionInitiatedBy, where); + @Override default Consent isVisible(final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final VisibilityConstraint visConstraint) { + return getObjectAction().isVisible(target, interactionInitiatedBy, visConstraint); } - @Override default Consent isUsable(final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final Where where) { - return getObjectAction().isUsable(target, interactionInitiatedBy, where); + @Override default Consent isUsable(final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, final VisibilityConstraint visConstraint) { + return getObjectAction().isUsable(target, interactionInitiatedBy, visConstraint); } @Override default boolean isPropertyOrCollection() { return getObjectAction().isPropertyOrCollection(); 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 7c9dd3de031..bfd9d4f0dff 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 @@ -49,6 +49,7 @@ import org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet; import org.apache.causeway.core.metamodel.facets.object.promptStyle.PromptStyleFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; @@ -271,10 +272,9 @@ default PromptStyle getPromptStyle() { // whereas for INLINE it would render a form with no fields || getParameterCount() == 0) { if (promptStyle.isPresent()) { - if (promptStyle.get().isDialogAny()) { - // preserve dialog specialization + if (promptStyle.get().isDialogAny()) + // preserve dialog specialization return promptStyle.get(); - } } // fallback to generic dialog return PromptStyle.DIALOG; @@ -283,16 +283,13 @@ default PromptStyle getPromptStyle() { var needsFallback = promptStyle.isEmpty() || promptStyle.get() == PromptStyle.AS_CONFIGURED; - if(needsFallback) { - // modal vs side-bar - switch (getWicketViewerSettings().dialogMode()) { - case SIDEBAR: - return PromptStyle.DIALOG_SIDEBAR; - case MODAL: - default: - return PromptStyle.DIALOG_MODAL; - } - } + if(needsFallback) + // modal vs side-bar + return switch (getWicketViewerSettings().dialogMode()) { + case SIDEBAR -> PromptStyle.DIALOG_SIDEBAR; + case MODAL -> PromptStyle.DIALOG_MODAL; + default -> PromptStyle.DIALOG_MODAL; + }; return promptStyle.get(); } @@ -309,9 +306,8 @@ public static boolean returnsBlobOrClob(final ObjectAction objectAction) { if (returnType != null) { Class cls = returnType.getCorrespondingClass(); if (Blob.class.isAssignableFrom(cls) - || Clob.class.isAssignableFrom(cls)) { - return true; - } + || Clob.class.isAssignableFrom(cls)) + return true; } return false; } @@ -320,18 +316,15 @@ public static boolean isDirectlyAssociatedWithAnyProperty( final ObjectAction action) { var layoutGroupFacet = action.getFacet(LayoutGroupFacet.class); - if (layoutGroupFacet == null) { - return false; - } + if (layoutGroupFacet == null) + return false; var layoutGroupId = layoutGroupFacet.getGroupId(); - if (_Strings.isNullOrEmpty(layoutGroupId)) { - return false; - } + if (_Strings.isNullOrEmpty(layoutGroupId)) + return false; var prop = action.getDeclaringType().getProperty(layoutGroupId, MixedIn.INCLUDED) .orElse(null); - if (prop == null) { - return false; - } + if (prop == null) + return false; return true; } @@ -374,7 +367,7 @@ public static Stream streamTopBarActions( .isSharingAnyLayoutGroupOf(spec.streamAssociations(MixedIn.INCLUDED)) .negate()) .filter(Predicates - .dynamicallyVisible(adapter, InteractionInitiatedBy.USER, Where.ANYWHERE)); + .dynamicallyVisible(adapter, InteractionInitiatedBy.USER, VisibilityConstraint.invalid(Where.ANYWHERE))); } public static Stream findForAssociation( @@ -388,15 +381,13 @@ public static Stream findForAssociation( public static PromptStyle promptStyleFor(final ObjectAction objectAction) { PromptStyleFacet facet = objectAction.getFacet(PromptStyleFacet.class); - if(facet == null) { - // don't think this can occur, see PromptStyleFallback + if(facet == null) + // don't think this can occur, see PromptStyleFallback return PromptStyle.INLINE; - } final PromptStyle promptStyle = facet.value(); - if(promptStyle == PromptStyle.AS_CONFIGURED) { - // don't think this can occur, see PromptStyleConfiguration + if(promptStyle == PromptStyle.AS_CONFIGURED) + // don't think this can occur, see PromptStyleConfiguration return PromptStyle.INLINE; - } return promptStyle; } @@ -436,13 +427,11 @@ public static Predicate isSameLayoutGroupAs( return (final ObjectAction objectAction) -> { var layoutGroupFacet = objectAction.getFacet(LayoutGroupFacet.class); - if (layoutGroupFacet == null) { - return false; - } + if (layoutGroupFacet == null) + return false; var layoutGroupId = layoutGroupFacet.getGroupId(); - if (_Strings.isNullOrEmpty(layoutGroupId)) { - return false; - } + if (_Strings.isNullOrEmpty(layoutGroupId)) + return false; return layoutGroupId.equals(memberId); }; } @@ -457,13 +446,11 @@ private static Predicate isSharingAnyLayoutGroupOf( return (final ObjectAction objectAction) -> { var layoutGroupFacet = objectAction.getFacet(LayoutGroupFacet.class); - if (layoutGroupFacet == null) { - return false; - } + if (layoutGroupFacet == null) + return false; var layoutGroupId = layoutGroupFacet.getGroupId(); - if (_Strings.isNullOrEmpty(layoutGroupId)) { - return false; - } + if (_Strings.isNullOrEmpty(layoutGroupId)) + return false; return associationIds.contains(layoutGroupId); }; } @@ -512,13 +499,11 @@ public HasChoicesFrom(final @NonNull ObjectAssociation objectAssociation) { @Override public boolean test(final ObjectAction objectAction) { var choicesFromFacet = objectAction.getFacet(ChoicesFromFacet.class); - if(choicesFromFacet == null) { - return false; - } + if(choicesFromFacet == null) + return false; var choicesFromMemberName = choicesFromFacet.value(); - if (choicesFromMemberName == null) { - return false; - } + if (choicesFromMemberName == null) + return false; var memberNameLowerCase = choicesFromMemberName.toLowerCase(); return Objects.equals(memberId, memberNameLowerCase); } @@ -541,10 +526,10 @@ public boolean test(final ObjectAction objectAction) { private static Predicate dynamicallyVisible( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visConstraint) { return (final ObjectAction objectAction) -> { - final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, where); + final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, visConstraint); return visible.isAllowed(); }; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java index ea454491659..2dec105f634 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java @@ -39,6 +39,7 @@ import org.apache.causeway.core.metamodel.facets.collections.sortedby.SortedByFacet; import org.apache.causeway.core.metamodel.facets.object.paged.PagedFacet; import org.apache.causeway.core.metamodel.facets.object.tabledec.TableDecoratorFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmSortUtils; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -87,7 +88,7 @@ public interface ObjectMember extends ObjectFeature { Consent isVisible( ManagedObject target, InteractionInitiatedBy interactionInitiatedBy, - Where where); + VisibilityConstraint visibilityConstraint); /** * Determines whether this member is usable (not disabled), represented as a @@ -95,12 +96,12 @@ Consent isVisible( * @param target * may be null if just checking for authorization. * @param interactionInitiatedBy - * @param where + * @param visibilityConstraint only ever used for debugging while prototyping */ Consent isUsable( ManagedObject target, InteractionInitiatedBy interactionInitiatedBy, - Where where); + VisibilityConstraint visibilityConstraint); /** * Whether this member represents a {@link ObjectAssociation}. 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 124a32cf8fa..13573115286 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 @@ -54,6 +54,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.ActionUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.ActionValidityContext; @@ -78,9 +79,8 @@ class ObjectActionDefault public static ActionScope getType(final String typeStr) { final ActionScope type = ActionScope.valueOf(typeStr); - if (type == null) { - throw new IllegalArgumentException(); - } + if (type == null) + throw new IllegalArgumentException(); return type; } @@ -135,9 +135,8 @@ private ObjectSpecification loadDeclaringType() { .map(ActionInvocationFacet::getDeclaringType); // JUnit support if(testing - && declaringType.isEmpty()) { - return specLoaderInternal().loadSpecification(getFacetedMethod().methodFacade().getDeclaringClass()); - } + && declaringType.isEmpty()) + return specLoaderInternal().loadSpecification(getFacetedMethod().methodFacade().getDeclaringClass()); return declaringType.orElseThrow(()->_Exceptions .illegalState("missing ActionInvocationFacet on action %s", getFeatureIdentifier())); } @@ -175,9 +174,8 @@ private ObjectSpecification loadReturnType() { .map(ActionInvocationFacet::getReturnType); // JUnit support if(testing - && returType.isEmpty()) { - return specLoaderInternal().loadSpecification(getFacetedMethod().methodFacade().getReturnType()); - } + && returType.isEmpty()) + return specLoaderInternal().loadSpecification(getFacetedMethod().methodFacade().getReturnType()); return returType.orElseThrow(()->_Exceptions .illegalState("framework bug: missing ActionInvocationFacet on action %s", getFeatureIdentifier())); } @@ -188,10 +186,9 @@ private ObjectSpecification loadReturnType() { */ @Override public boolean hasReturn() { - if(getReturnType() == null) { - // this shouldn't happen; return Type always defined, even if represents void.class + if(getReturnType() == null) + // this shouldn't happen; return Type always defined, even if represents void.class return false; - } return !getReturnType().isVoidPrimitive(); } @@ -269,10 +266,9 @@ public Can getParameters(final Predicate= parameters.size()) { - throw new IllegalArgumentException( + if (position >= parameters.size()) + throw new IllegalArgumentException( "getParameter(int): only " + parameters.size() + " parameters, position=" + position); - } return parameters.getElseFail(position); } @@ -282,13 +278,13 @@ ObjectActionParameter getParameter(final int position) { public VisibilityContext createVisibleInteractionContext( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return new ActionVisibilityContext( headFor(target), this, getFeatureIdentifier(), interactionInitiatedBy, - where, + visibilityConstraint, RenderPolicy.forNonActionParam(target)); } @@ -297,14 +293,12 @@ public VisibilityContext createVisibleInteractionContext( @Override public UsabilityContext createUsableInteractionContext( final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionInitiatedBy interactionInitiatedBy) { return new ActionUsabilityContext( headFor(target), this, getFeatureIdentifier(), interactionInitiatedBy, - where, RenderPolicy.forNonActionParam(target)); } @@ -403,25 +397,24 @@ public ManagedObject executeWithRuleChecking( final InteractionInitiatedBy interactionInitiatedBy, final Where where) { + var visibilityConstraint = VisibilityConstraint.invalid(where); + var target = head.owner(); // see it? - final Consent visibility = isVisible(target, interactionInitiatedBy, where); - if (visibility.isVetoed()) { - throw new HiddenException(); - } + final Consent visibility = isVisible(target, interactionInitiatedBy, visibilityConstraint); + if (visibility.isVetoed()) + throw new HiddenException(); // use it? - final Consent usability = isUsable(target, interactionInitiatedBy, where); - if(usability.isVetoed()) { - throw new DisabledException(usability.getReasonAsString().orElse("no reason given")); - } + final Consent usability = isUsable(target, interactionInitiatedBy, visibilityConstraint); + if(usability.isVetoed()) + throw new DisabledException(usability.getReasonAsString().orElse("no reason given")); // do it? final Consent validity = isArgumentSetValid(head, arguments, interactionInitiatedBy); - if(validity.isVetoed()) { - throw new RecoverableException(validity.getReasonAsString().orElse("no reason given")); - } + if(validity.isVetoed()) + throw new RecoverableException(validity.getReasonAsString().orElse("no reason given")); return execute(head, arguments, interactionInitiatedBy); } @@ -531,9 +524,8 @@ public void setupCommand( final InteractionHead head, final Can argumentAdapters) { - if(head.owner().objSpec().isValue()) { - return; // do not record value type mixin actions - } + if(head.owner().objSpec().isValue()) + return; // do not record value type mixin actions setupCommand(head, interactionId->commandDtoFor(interactionId, head, argumentAdapters)); @@ -572,9 +564,8 @@ public FacetHolder getFacetHolder() { // -- HELPER protected String argsFor(final Can parameters, final Can arguments) { - if(parameters.size() != arguments.size()) { - return "???"; // shouldn't happen - } + if(parameters.size() != arguments.size()) + return "???"; // shouldn't happen return parameters.stream().map(IndexedFunction.zeroBased((i, param) -> { var id = param.getId(); var argStr = argStr(id, arguments, i); 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 00e8635bbb5..9572d448772 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 @@ -52,6 +52,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.acc.AccessContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; @@ -194,9 +195,9 @@ public final Optional getCanonicalDescription() { * {@link AccessContext} accesses) have no corresponding vetoing methods. */ protected abstract VisibilityContext createVisibleInteractionContext( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); + ManagedObject target, + InteractionInitiatedBy interactionInitiatedBy, + VisibilityConstraint visibilityConstraint); @Override public boolean isAlwaysHidden() { @@ -211,9 +212,9 @@ public boolean isAlwaysHidden() { public final Consent isVisible( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { - var visibilityContext = createVisibleInteractionContext(target, interactionInitiatedBy, where); + var visibilityContext = createVisibleInteractionContext(target, interactionInitiatedBy, visibilityConstraint); return InteractionUtils.isVisibleResult(this, visibilityContext).createConsent(); } @@ -229,9 +230,8 @@ public final Consent isVisible( * {@link AccessContext} accesses) have no corresponding vetoing methods. */ protected abstract UsabilityContext createUsableInteractionContext( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); + ManagedObject target, + InteractionInitiatedBy interactionInitiatedBy); /** * Loops over all {@link DisablingInteractionAdvisor} {@link Facet}s and @@ -241,10 +241,10 @@ protected abstract UsabilityContext createUsableInteractionContext( public final Consent isUsable( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { - var usabilityContext = createUsableInteractionContext(target, interactionInitiatedBy, where); - return InteractionUtils.isUsableResult(this, usabilityContext, ()->createVisibleInteractionContext(target, interactionInitiatedBy, where)) + var usabilityContext = createUsableInteractionContext(target, interactionInitiatedBy); + return InteractionUtils.isUsableResult(this, usabilityContext, ()->createVisibleInteractionContext(target, interactionInitiatedBy, visibilityConstraint)) .createConsent(); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java index 1186be575cf..b75da93e7ce 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationDefault.java @@ -21,7 +21,6 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.annotation.Collection; import org.apache.causeway.applib.annotation.CollectionLayout; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedType; @@ -32,6 +31,7 @@ import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.CollectionUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.CollectionVisibilityContext; @@ -79,20 +79,19 @@ private ResolvedType resolveTypeOfAnyCardinality() { public VisibilityContext createVisibleInteractionContext( final ManagedObject ownerAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return new CollectionVisibilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, + headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, visibilityConstraint, RenderPolicy.forNonActionParam(ownerAdapter)); } @Override public UsabilityContext createUsableInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionInitiatedBy interactionInitiatedBy) { return new CollectionUsabilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, + headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, RenderPolicy.forNonActionParam(ownerAdapter)); } 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 0a131f6789f..37835599c72 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 @@ -23,7 +23,6 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.annotation.Property; import org.apache.causeway.applib.annotation.PropertyLayout; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.command.Command; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._NullSafe; @@ -45,6 +44,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.PropertyUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.PropertyModifyContext; @@ -89,19 +89,18 @@ protected OneToOneAssociationDefault( public VisibilityContext createVisibleInteractionContext( final ManagedObject ownerAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return new PropertyVisibilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, + headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, visibilityConstraint, RenderPolicy.forNonActionParam(ownerAdapter)); } @Override public UsabilityContext createUsableInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionInitiatedBy interactionInitiatedBy) { return new PropertyUsabilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, + headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, RenderPolicy.forNonActionParam(ownerAdapter)); } @@ -158,11 +157,10 @@ public ManagedObject get( var referencedPojo = propertyOrCollectionAccessorFacet.getAssociationValueAsPojo(ownerAdapter, interactionInitiatedBy); - if (referencedPojo == null) { - // TODO: perhaps this should instead return ManagedObject.empty(getSpecification()) ? + if (referencedPojo == null) + // TODO: perhaps this should instead return ManagedObject.empty(getSpecification()) ? // however, that's a far-reaching change to make. return null; - } return getObjectManager().adapt(referencedPojo); } @@ -195,11 +193,10 @@ public final ManagedObject set( setupCommand(InteractionHead.regular(ownerAdapter), newValue); } - if (ManagedObjects.isNullOrUnspecifiedOrEmpty(newValue)) { - return clearValue(ownerAdapter, interactionInitiatedBy); - } else { - return setValue(ownerAdapter, newValue, interactionInitiatedBy); - } + if (ManagedObjects.isNullOrUnspecifiedOrEmpty(newValue)) + return clearValue(ownerAdapter, interactionInitiatedBy); + else + return setValue(ownerAdapter, newValue, interactionInitiatedBy); } private ManagedObject setValue( @@ -208,9 +205,8 @@ private ManagedObject setValue( final InteractionInitiatedBy interactionInitiatedBy) { var propertySetterFacet = getFacet(PropertySetterFacet.class); - if (propertySetterFacet == null) { - throw _Exceptions.unexpectedCodeReach(); - } + if (propertySetterFacet == null) + throw _Exceptions.unexpectedCodeReach(); MmEntityUtils.requiresWhenFirstIsBookmarkableSecondIsAlso(ownerAdapter, newReferencedAdapter); @@ -223,9 +219,8 @@ private ManagedObject clearValue( var propertyClearFacet = getFacet(PropertyClearFacet.class); - if (propertyClearFacet == null) { - throw _Exceptions.unexpectedCodeReach(); - } + if (propertyClearFacet == null) + throw _Exceptions.unexpectedCodeReach(); return propertyClearFacet.clearProperty(this, ownerAdapter, interactionInitiatedBy); } @@ -242,18 +237,16 @@ public ManagedObject getDefault(final ManagedObject ownerAdapter) { if (propertyDefaultFacet == null) { propertyDefaultFacet = this.getElementType().getFacet(PropertyDefaultFacet.class); } - if (propertyDefaultFacet == null) { - return null; - } + if (propertyDefaultFacet == null) + return null; return propertyDefaultFacet.getDefault(ownerAdapter); } @Override public void toDefault(final ManagedObject ownerAdapter) { // default only mandatory fields - if (!MandatoryFacet.isMandatory(this)) { - return; - } + if (!MandatoryFacet.isMandatory(this)) + return; final ManagedObject defaultValue = getDefault(ownerAdapter); if (defaultValue != null) { @@ -274,9 +267,8 @@ public Can getChoices( final InteractionInitiatedBy interactionInitiatedBy) { var propertyChoicesFacet = getFacet(PropertyChoicesFacet.class); - if (propertyChoicesFacet == null) { - return Can.empty(); - } + if (propertyChoicesFacet == null) + return Can.empty(); return propertyChoicesFacet.getChoices( ownerAdapter, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataTableInteractive.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataTableInteractive.java index 5ae6e23e323..3bde11973d9 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataTableInteractive.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataTableInteractive.java @@ -29,6 +29,7 @@ import org.apache.causeway.commons.binding.Bindable; import org.apache.causeway.commons.binding.Observable; import org.apache.causeway.commons.collections.Can; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection; @@ -89,7 +90,7 @@ public Optional> asComparator(final Can lookupColumnById(final @NonNull String columnId) { public Can getCellElementsForColumn(final @NonNull DataColumn column) { final ObjectAssociation assoc = column.associationMetaModel(); var interactionInitiatedBy = InteractionInitiatedBy.PASS_THROUGH; + var visibilityConstraint = VisibilityConstraint.invalid(Where.ALL_TABLES); return assoc.getSpecialization().fold( property-> Can.of( // similar to ManagedProperty#reassessPropertyValue - property.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() + property.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() ? property.get(rowElement(), interactionInitiatedBy) : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( - collection.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() + collection.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() ? collection.get(rowElement(), interactionInitiatedBy) : null )); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataTableInternal.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataTableInternal.java index ac4e2564da0..d7a3ba64554 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataTableInternal.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataTableInternal.java @@ -42,6 +42,8 @@ import org.apache.causeway.commons.internal.binding._Observables.LazyObservable; import org.apache.causeway.commons.internal.collections._Streams; import org.apache.causeway.commons.internal.exceptions._Exceptions; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection; @@ -74,7 +76,7 @@ public static DataTableInternal empty(final ManagedMember managedMember, final W public static DataTableInternal forCollection( final ManagedCollection managedCollection) { - return new DataTableInternal(managedCollection, managedCollection.getWhere(), + return new DataTableInternal(managedCollection, managedCollection.visibilityConstraint().where(), managedCollection .streamElements() .collect(Can.toCan())); @@ -85,16 +87,15 @@ public static DataTableInternal forAction( final ManagedObject actionResult) { if(actionResult==null) { - new DataTableInternal(managedAction, managedAction.getWhere(), Can.empty()); - } - if(!(actionResult instanceof PackedManagedObject)) { - throw _Exceptions.unexpectedCodeReach(); + new DataTableInternal(managedAction, managedAction.visibilityConstraint().where(), Can.empty()); } + if(!(actionResult instanceof PackedManagedObject)) + throw _Exceptions.unexpectedCodeReach(); var elements = ((PackedManagedObject)actionResult).unpack(); elements.forEach(ManagedObject::getBookmark); - return new DataTableInternal(managedAction, managedAction.getWhere(), elements); + return new DataTableInternal(managedAction, managedAction.visibilityConstraint().where(), elements); } // -- CONSTRUCTION @@ -356,22 +357,20 @@ public Set getSelectedRowIndexes() { } @Override - public ActionInteraction startAssociatedActionInteraction(final String actionId, final Where where) { + public ActionInteraction startAssociatedActionInteraction(final String actionId, final VisibilityConstraint visibilityConstraint) { if(managedMember.getOwner().specialization().isEmpty() - || managedMember.getOwner().getEntityState().isTransientOrRemoved()) { - throw _Exceptions.illegalArgument("cannot start action interaction on missing or deleted action owner"); - } + || managedMember.getOwner().getEntityState().isTransientOrRemoved()) + throw _Exceptions.illegalArgument("cannot start action interaction on missing or deleted action owner"); var featureId = managedMember.getIdentifier(); - if(!featureId.type().isPropertyOrCollection()) { - return ActionInteraction.empty(String.format("[no such collection %s; instead got %s;" + if(!featureId.type().isPropertyOrCollection()) + return ActionInteraction.empty(String.format("[no such collection %s; instead got %s;" + "(while searching for an associated action %s)]", featureId, featureId.type(), actionId)); - } - return ActionInteraction.startWithMultiselect(managedMember.getOwner(), actionId, where, this); + return ActionInteraction.startWithMultiselect(managedMember.getOwner(), actionId, visibilityConstraint, this); } // -- EXPORT @@ -385,7 +384,7 @@ public DataTable export() { .map(DataColumn::associationMetaModel), dataRowsFilteredAndSortedObservable().getValue() .stream() - .map(dr->dr.rowElement()) + .map(DataRow::rowElement) .collect(Can.toCan())); } @@ -447,10 +446,12 @@ static Memento create( public DataTableInternal recreateDataTableModel(final ManagedObject owner) { var memberId = featureId.memberLogicalName(); + var visibilityConstraint = new VisibilityConstraint(WhatViewer.noViewer(), where); + final ManagedMember managedMember = featureId.type().isPropertyOrCollection() - ? ManagedCollection.lookupCollection(owner, memberId, where) + ? ManagedCollection.lookupCollection(owner, memberId, visibilityConstraint) .orElseThrow() - : ManagedAction.lookupAction(owner, memberId, where) + : ManagedAction.lookupAction(owner, memberId, visibilityConstraint) .orElseThrow(); var dataTableInteractive = new DataTableInternal(managedMember, where, @@ -484,7 +485,7 @@ public void setupBindings(final DataTableInteractive tableInteractive) { this.selectedRowIndexes = tableInteractive.getSelectedRowIndexes(); }); } - + @Override public String toString() { return "Memento[featureId=%s,dataTable.rowCount=%d]".formatted( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java index 3fad7bbdb41..f3765a7a522 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java @@ -18,14 +18,15 @@ */ package org.apache.causeway.core.metamodel.tabular.simple; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; -import org.jspecify.annotations.NonNull; - /** * Represents a single domain object (typically an entity instance) * and it's associated values as cell elements. @@ -41,17 +42,18 @@ public record DataRow( public Can getCellElements( final @NonNull DataColumn column, final InteractionInitiatedBy interactionInitiatedBy) { + var visibilityConstraint = VisibilityConstraint.invalid(Where.ALL_TABLES); var assoc = column.metamodel(); return assoc.getSpecialization().fold( property-> Can.of( // similar to ManagedProperty#reassessPropertyValue interactionInitiatedBy.isPassThrough() - || property.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() + || property.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() ? property.get(rowElement(), interactionInitiatedBy) : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( interactionInitiatedBy.isPassThrough() - || collection.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() + || collection.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() ? collection.get(rowElement(), interactionInitiatedBy) : null )); diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest.java index b12bb89f02d..6059e7823c9 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest.java @@ -28,7 +28,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.inject.ServiceInjector; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._Casts; @@ -40,6 +39,7 @@ import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.objectvalue.mandatory.MandatoryFacet; import org.apache.causeway.core.metamodel.facets.properties.choices.PropertyChoicesFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -106,15 +106,14 @@ public void toDefault(final ManagedObject target) { @Override public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy) { return null; } @Override public VisibilityContext createVisibleInteractionContext( final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return null; } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java index 51d2d6b0893..652f19c485d 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest_alwaysHidden.java @@ -40,6 +40,7 @@ import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.members.hidden.HiddenFacetForLayoutAbstract; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -104,15 +105,14 @@ public void toDefault(final ManagedObject target) { @Override public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy) { return null; } @Override public VisibilityContext createVisibleInteractionContext( final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return null; } diff --git a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationAbstractTest.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationAbstractTest.java index b774a2e6283..11292a49af3 100644 --- a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationAbstractTest.java +++ b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationAbstractTest.java @@ -28,7 +28,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.inject.ServiceInjector; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._Casts; @@ -38,6 +37,7 @@ import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence; import org.apache.causeway.core.metamodel.facets.FacetedMethod; import org.apache.causeway.core.metamodel.facets.propcoll.memserexcl.SnapshotExcludeFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -73,7 +73,7 @@ public void setup() { facetedMethod.getFeatureIdentifier(), facetedMethod, objectSpecification) { private static final long serialVersionUID = 1L; - + @Override public ManagedObject get( final ManagedObject fromObject, @@ -104,15 +104,14 @@ public void toDefault(final ManagedObject target) { @Override public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy) { return null; } @Override public VisibilityContext createVisibleInteractionContext( final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return null; } 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 7910ad8f7a9..493aeeb256f 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 @@ -46,13 +46,13 @@ import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.commons.internal.reflection._GenericResolver; import org.apache.causeway.core.interaction.core.InteractionConstraint; -import org.apache.causeway.core.interaction.core.WhatViewer; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.InteractionResult; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; import org.apache.causeway.core.metamodel.facets.ImperativeFacet.Intent; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmAssertionUtils; import org.apache.causeway.core.metamodel.object.MmEntityUtils; @@ -419,7 +419,7 @@ private void checkVisibility( final InteractionConstraint iConstraint, final ManagedObject targetMo, final ObjectMember objectMember) { - var interactionResult = objectMember.isVisible(targetMo, iConstraint.initiatedBy(), iConstraint.where()) + var interactionResult = objectMember.isVisible(targetMo, iConstraint.initiatedBy(), iConstraint.asVisibilityConstraint()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -428,7 +428,7 @@ private void checkUsability( final InteractionConstraint iConstraint, final ManagedObject targetMo, final ObjectMember objectMember) { - var interactionResult = objectMember.isUsable(targetMo, iConstraint.initiatedBy(), iConstraint.where()) + var interactionResult = objectMember.isUsable(targetMo, iConstraint.initiatedBy(), iConstraint.asVisibilityConstraint()) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } diff --git a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java index 77805fae6c1..d6ebdba13d5 100644 --- a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java +++ b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java @@ -43,6 +43,7 @@ import org.apache.causeway.commons.internal.debug._Probe; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.commons.internal.functions._Functions.CheckedConsumer; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.PropertyInteraction; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -128,73 +129,55 @@ protected void programmaticExecution( // This test does not trigger command or execution publishing, however it does trigger // entity-change-publishing. - switch(context.scenario()) { - case ENTITY_CREATION: - - context.runGiven(); - //when + switch (context.scenario()) { + case ENTITY_CREATION -> { + context.runGiven(); + //when factoryService.detachedEntity(JpaBook.fromDto(BookDto.sample())); // should trigger an ObjectCreatedEvent - factoryService.detachedEntity(JpaBook.class); // should trigger a second ObjectCreatedEvent - break; - - case ENTITY_PERSISTING: - - context.runGiven(); - //when + factoryService.detachedEntity(JpaBook.class); // should trigger a second ObjectCreatedEvent + } + case ENTITY_PERSISTING -> { + context.runGiven(); + //when setupBookForJpa(); - break; - - case ENTITY_LOADING: - - context.runGiven(); - //when + } + case ENTITY_LOADING -> { + context.runGiven(); + //when withBookDo(book->{ assertNotNull(book); }); - break; - - case PROPERTY_UPDATE: - - withBookDo(book->{ - - context.runGiven(); - - // when - direct change (circumventing the framework) - context.changeProperty(()->book.setName("Book #2")); - - repository.persistAndFlush(book); - - }); + } + case PROPERTY_UPDATE -> withBookDo(book->{ - break; - case ACTION_INVOCATION: + context.runGiven(); - withBookDo(book->{ + // when - direct change (circumventing the framework) + context.changeProperty(()->book.setName("Book #2")); - context.runGiven(); + repository.persistAndFlush(book); - // when - direct action method invocation (circumventing the framework) - context.executeAction(()->book.doubleThePrice()); + }); + case ACTION_INVOCATION -> withBookDo(book->{ - repository.persistAndFlush(book); + context.runGiven(); - }); + // when - direct action method invocation (circumventing the framework) + context.executeAction(()->book.doubleThePrice()); - break; - case ENTITY_REMOVAL: + repository.persistAndFlush(book); - withBookDo(book->{ + }); + case ENTITY_REMOVAL -> withBookDo(book->{ - context.runGiven(); - //when - repository.removeAndFlush(book); - - }); + context.runGiven(); + //when + repository.removeAndFlush(book); - break; - default: - throw _Exceptions.unmatchedCase(context.scenario()); - } + }); + default -> throw _Exceptions.unmatchedCase(context.scenario()); + } + ; } @@ -206,53 +189,44 @@ protected void interactionApiExecution( context.bind(commitListener); - switch(context.scenario()) { - - case PROPERTY_UPDATE: - - withBookDo(book->{ - - context.runGiven(); - - // when - context.changeProperty(()->{ + switch (context.scenario()) { + case PROPERTY_UPDATE -> withBookDo(book->{ - var bookAdapter = objectManager.adapt(book); - var propertyInteraction = PropertyInteraction.start(bookAdapter, "name", Where.OBJECT_FORMS); - var managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement()); - var propertyModel = managedProperty.startNegotiation(); - var propertySpec = managedProperty.getElementType(); - propertyModel.getValue().setValue(ManagedObject.value(propertySpec, "Book #2")); - propertyModel.submit(); + context.runGiven(); - }); + // when + context.changeProperty(()->{ - }); + var bookAdapter = objectManager.adapt(book); + var propertyInteraction = PropertyInteraction.start(bookAdapter, "name", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + var managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement()); + var propertyModel = managedProperty.startNegotiation(); + var propertySpec = managedProperty.getElementType(); + propertyModel.getValue().setValue(ManagedObject.value(propertySpec, "Book #2")); + propertyModel.submit(); - break; - case ACTION_INVOCATION: + }); - withBookDo(book->{ + }); + case ACTION_INVOCATION -> withBookDo(book->{ - context.runGiven(); + context.runGiven(); - // when - context.executeAction(()->{ + // when + context.executeAction(()->{ - var bookAdapter = objectManager.adapt(book); + var bookAdapter = objectManager.adapt(book); - var actionInteraction = ActionInteraction.start(bookAdapter, "doubleThePrice", Where.OBJECT_FORMS); - var managedAction = actionInteraction.getManagedActionElseThrow(__->_Exceptions.noSuchElement()); - // this test action is always disabled, so don't enforce rules here, just invoke - managedAction.invoke(Can.empty()); // no-arg action - }); + var actionInteraction = ActionInteraction.start(bookAdapter, "doubleThePrice", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + var managedAction = actionInteraction.getManagedActionElseThrow(__->_Exceptions.noSuchElement()); + // this test action is always disabled, so don't enforce rules here, just invoke + managedAction.invoke(Can.empty()); // no-arg action + }); - }); - - break; - default: - throw _Exceptions.unmatchedCase(context.scenario()); - } + }); + default -> throw _Exceptions.unmatchedCase(context.scenario()); + } + ; } @@ -264,37 +238,28 @@ protected void wrapperSyncExecutionNoRules( context.bind(commitListener); - switch(context.scenario()) { - - case PROPERTY_UPDATE: - - withBookDo(book->{ - - context.runGiven(); + switch (context.scenario()) { + case PROPERTY_UPDATE -> withBookDo(book->{ - // when - running synchronous - var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules - context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2")); + context.runGiven(); - }); - - break; - case ACTION_INVOCATION: - - withBookDo(book->{ + // when - running synchronous + var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules + context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2")); - context.runGiven(); + }); + case ACTION_INVOCATION -> withBookDo(book->{ - // when - running synchronous - var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules - context.executeAction(()->wrapper.wrap(book, syncControl).doubleThePrice()); + context.runGiven(); - }); + // when - running synchronous + var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules + context.executeAction(()->wrapper.wrap(book, syncControl).doubleThePrice()); - break; - default: - throw _Exceptions.unmatchedCase(context.scenario()); - } + }); + default -> throw _Exceptions.unmatchedCase(context.scenario()); + } + ; } @@ -304,43 +269,34 @@ protected void wrapperSyncExecutionWithRules( context.bind(commitListener); - switch(context.scenario()) { - - case PROPERTY_UPDATE: - - withBookDo(book->{ - - context.runGiven(); + switch (context.scenario()) { + case PROPERTY_UPDATE -> withBookDo(book->{ - // when - running synchronous - var syncControl = SyncControl.defaults().withCheckRules(); // enforce rules + context.runGiven(); - //assertThrows(DisabledException.class, ()->{ - wrapper.wrap(book, syncControl).setName("Book #2"); // should throw DisabledException - //}); + // when - running synchronous + var syncControl = SyncControl.defaults().withCheckRules(); // enforce rules - }); - - break; - case ACTION_INVOCATION: + //assertThrows(DisabledException.class, ()->{ + wrapper.wrap(book, syncControl).setName("Book #2"); // should throw DisabledException + //}); - withBookDo(book->{ + }); + case ACTION_INVOCATION -> withBookDo(book->{ - context.runGiven(); + context.runGiven(); - // when - running synchronous - var syncControl = SyncControl.defaults().withCheckRules(); // enforce rules + // when - running synchronous + var syncControl = SyncControl.defaults().withCheckRules(); // enforce rules - //assertThrows(DisabledException.class, ()->{ - wrapper.wrap(book, syncControl).doubleThePrice(); // should throw DisabledException - //}); + //assertThrows(DisabledException.class, ()->{ + wrapper.wrap(book, syncControl).doubleThePrice(); // should throw DisabledException + //}); - }); - - break; - default: - throw _Exceptions.unmatchedCase(context.scenario()); - } + }); + default -> throw _Exceptions.unmatchedCase(context.scenario()); + } + ; } diff --git a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java index 4e89f0813a0..55058075b6d 100644 --- a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java +++ b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java @@ -62,8 +62,10 @@ import org.apache.causeway.core.metamodel.facets.object.icon.IconFacet; import org.apache.causeway.core.metamodel.facets.object.layout.LayoutPrefixFacet; import org.apache.causeway.core.metamodel.facets.object.value.ValueFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.CollectionInteraction; +import org.apache.causeway.core.metamodel.interactions.managed.InteractionVeto; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection; import org.apache.causeway.core.metamodel.interactions.managed.ManagedMember; @@ -94,7 +96,7 @@ public class DomainObjectTesterFactory implements HasMetaModelContext { public ObjectTester objectTester( final T domainObject) { var tester = getServiceInjector().injectServicesInto( - new ObjectTester(domainObject)); + new ObjectTester<>(domainObject)); return tester; } @@ -103,7 +105,7 @@ public ActionTester actionTester( final String actionName, final Where where) { var tester = getServiceInjector().injectServicesInto( - new ActionTester(domainObject, actionName, where)); + new ActionTester<>(domainObject, actionName, where)); tester.init(); return tester; } @@ -125,7 +127,7 @@ public PropertyTester propertyTester( final String propertyName, final Where where) { var tester = getServiceInjector().injectServicesInto( - new PropertyTester(domainObject, propertyName, where)); + new PropertyTester<>(domainObject, propertyName, where)); tester.init(); return tester; } @@ -135,7 +137,7 @@ public CollectionTester collectionTester( final String collectionName, final Where where) { var tester = getServiceInjector().injectServicesInto( - new CollectionTester(domainObject, collectionName, where)); + new CollectionTester<>(domainObject, collectionName, where)); tester.init(); return tester; } @@ -290,7 +292,7 @@ private ActionTester( super(domainObject, managedAction.getId(), "actionName", - managedAction.getWhere()); + managedAction.visibilityConstraint().where()); this.actionInteraction = actionInteraction; this.parameterNegotiationStarter = ()-> actionInteraction @@ -350,7 +352,7 @@ public Optional getElementType() { protected Optional startInteractionOn(final ManagedObject viewModel) { if(parameterNegotiationStarter==null) { this.actionInteraction = ActionInteraction - .start(viewModel, getMemberName(), Where.NOT_SPECIFIED); + .start(viewModel, getMemberName(), visibilityConstraint.withWhere(Where.NOT_SPECIFIED)); } assertNotNull(actionInteraction); return getManagedAction(); @@ -743,7 +745,7 @@ protected Optional getElementType() { @Override protected Optional startInteractionOn(final ManagedObject viewModel) { return this.managedPropertyIfAny = PropertyInteraction - .start(viewModel, getMemberName(), where) + .start(viewModel, getMemberName(), visibilityConstraint) .getManagedProperty(); } @@ -954,7 +956,7 @@ protected Optional getElementType() { @Override protected Optional startInteractionOn(final ManagedObject viewModel) { return this.managedCollectionIfAny = CollectionInteraction - .start(viewModel, getMemberName(), Where.NOT_SPECIFIED) + .start(viewModel, getMemberName(), visibilityConstraint.withWhere(Where.NOT_SPECIFIED)) .getManagedCollection(); } @@ -1002,7 +1004,7 @@ private static abstract class MemberTester @Getter private final String memberName; private final String memberSort; - protected final Where where; + protected final VisibilityConstraint visibilityConstraint; private Optional managedMemberIfAny; @@ -1014,7 +1016,7 @@ protected MemberTester( super(domainObject); this.memberName = memberName; this.memberSort = memberSort; - this.where = where; + this.visibilityConstraint = VisibilityConstraint.invalid(where); } protected final MemberTester init() { @@ -1110,7 +1112,7 @@ private final void assertVisibilityIsVetoedWith(final @Nullable String expectedV final String actualVetoResaon = managedCollection .checkVisibility() - .flatMap(veto->veto.getReasonAsString()) + .flatMap(InteractionVeto::getReasonAsString) .orElse(null); assertEquals(expectedVetoReason, actualVetoResaon); @@ -1131,7 +1133,7 @@ public final void assertUsabilityIsVetoedWithAll(final Can expectedVetoR interactionService.runAnonymous(()->{ final String actualVetoReason = managedMember .checkUsability() - .flatMap(veto->veto.getReasonAsString()) + .flatMap(InteractionVeto::getReasonAsString) .orElse(null); if(!expectedVetoReasons.isEmpty() @@ -1162,7 +1164,7 @@ public final void assertUsabilityIsVetoedWith(final @Nullable String expectedVet interactionService.runAnonymous(()->{ final String actualVetoReason = managedMember .checkUsability() - .flatMap(veto->veto.getReasonAsString()) + .flatMap(InteractionVeto::getReasonAsString) .orElse(null); assertEquals(expectedVetoReason, actualVetoReason); diff --git a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java index cbf76d1baf0..47e5a07efb6 100644 --- a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java +++ b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java @@ -27,17 +27,18 @@ import jakarta.inject.Inject; +import org.jspecify.annotations.Nullable; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.jspecify.annotations.Nullable; - import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.iactnlayer.InteractionService; import org.apache.causeway.applib.services.wrapper.WrapperFactory; import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.commons.internal.collections._Sets; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.CollectionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.PropertyInteraction; @@ -70,19 +71,19 @@ protected ManagedObject newViewmodel(final Class type) { protected ActionInteraction startActionInteractionOn(final Class type, final String actionId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return ActionInteraction.start(managedObject, actionId, where); + return ActionInteraction.start(managedObject, actionId, VisibilityConstraint.invalid(where)); } protected PropertyInteraction startPropertyInteractionOn(final Class type, final String propertyId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return PropertyInteraction.start(managedObject, propertyId, where); + return PropertyInteraction.start(managedObject, propertyId, VisibilityConstraint.invalid(where)); } protected CollectionInteraction startCollectionInteractionOn(final Class type, final String collectionId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return CollectionInteraction.start(managedObject, collectionId, where); + return CollectionInteraction.start(managedObject, collectionId, VisibilityConstraint.invalid(where)); } // -- SHORTCUTS diff --git a/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java b/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java index c866fb89ef5..3c38a323774 100644 --- a/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java +++ b/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java @@ -30,6 +30,7 @@ import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.config.presets.CausewayPresets; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; import org.apache.causeway.testdomain.conf.Configuration_headless; import org.apache.causeway.testdomain.model.interaction.Configuration_usingInteractionDomain; @@ -113,7 +114,7 @@ void choicesFromMultiselect() { var table = tableTester.getDataTable(); var actionInteraction = table - .startAssociatedActionInteraction("doSomethingWithItems", Where.OBJECT_FORMS); + .startAssociatedActionInteraction("doSomethingWithItems", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); var actTester = testerFactory.actionTesterForSpecificInteraction(InteractionDemo.class, actionInteraction); actTester.assertVisibilityIsNotVetoed(); diff --git a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java index 9356babc085..afe927e35bf 100644 --- a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java +++ b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java @@ -45,6 +45,7 @@ import org.apache.causeway.commons.internal.assertions._Assert; import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.services.schema.SchemaValueMarshaller; @@ -103,7 +104,7 @@ public void testComposer( var spec = specLoader.specForTypeElseFail(valueMixin.getClass()); var interaction = ActionInteraction - .start(ManagedObject.mixin(spec, valueMixin), "act", Where.ANYWHERE); + .start(ManagedObject.mixin(spec, valueMixin), "act", VisibilityConstraint.invalid(Where.ANYWHERE)); var pendingParams = interaction .startParameterNegotiation() @@ -169,9 +170,8 @@ public void testParser( }); - if(example.getParseExpectations().isNotEmpty()) { - return; // skip round-trip test - } + if(example.getParseExpectations().isNotEmpty()) + return; // skip round-trip test //TODO eventually all examples should have their ParseExpectations, so we can remove // Parser round-trip test @@ -192,11 +192,10 @@ public void testParser( //|| valueType.equals(ZonedDateTime.class) ) { - if(stringified.endsWith("Z")) { - // skip format variations on UTC time-zone + if(stringified.endsWith("Z")) + // skip format variations on UTC time-zone //System.err.printf("DEBUG: skipping stringified: %s%n", stringified); return; - } var with4digitZone = _Strings.substring(stringified, 0, -3) + "00"; var with2digitZone = _Strings.substring(stringified, 0, -3); diff --git a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java index d147b260139..d51c5598bee 100644 --- a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java +++ b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java @@ -24,6 +24,8 @@ import jakarta.inject.Inject; +import org.jspecify.annotations.NonNull; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -40,6 +42,7 @@ import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.core.metamodel.facets.object.value.ValueFacet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty; @@ -49,7 +52,6 @@ import org.apache.causeway.core.metamodel.specloader.SpecificationLoader; import org.apache.causeway.testdomain.model.valuetypes.ValueTypeExample; -import org.jspecify.annotations.NonNull; import lombok.SneakyThrows; class ValueSemanticsTester { @@ -91,7 +93,7 @@ public void actionInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var actInteraction = ActionInteraction - .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, Where.OBJECT_FORMS)); + .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); var params = actInteraction.startParameterNegotiation().orElseThrow(); var singleArgPojoToUse = actionArgumentProvider.get(); @@ -111,7 +113,7 @@ public void actionInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var actInteraction = ActionInteraction - .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, Where.OBJECT_FORMS)); + .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); var params = actInteraction.startParameterNegotiation().orElseThrow(); @@ -199,7 +201,7 @@ public void propertyInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var propInteraction = PropertyInteraction - .wrap(ManagedProperty.of(ManagedObject.adaptSingular(objSpec, domainObject), prop, Where.OBJECT_FORMS)); + .wrap(ManagedProperty.of(ManagedObject.adaptSingular(objSpec, domainObject), prop, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); propInteraction.modifyProperty(managedProp-> ManagedObject.adaptSingular(managedProp.getElementType(), newProperyValueProvider.apply(managedProp))); diff --git a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java index a98beadb512..4bf341269b5 100644 --- a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java +++ b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java @@ -29,6 +29,8 @@ import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facets.members.iconfa.FaLayersProvider; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.managed.InteractionVeto; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.core.metamodel.util.Facets; @@ -57,7 +59,7 @@ static DecorationModel of(final @NonNull ManagedAction managedAction) { .isPrototype(action.isPrototype()) .paramCount(action.getParameterCount()) .interactionVetoOpt(managedAction.checkUsability() - .flatMap(veto->veto.getReason())) + .flatMap(InteractionVeto::getReason)) .fontAwesomeLayersOpt(ObjectAction.Util.cssClassFaFactoryFor( managedAction.getAction(), managedAction.getOwner()) @@ -80,7 +82,7 @@ public static MenuAction of(final @NonNull ManagedAction managedAction) { public Optional managedAction(){ var mmc = MetaModelContext.instanceElseFail(); var service = mmc.getObjectManager().debookmark(serviceBookmark); - return ManagedAction.lookupAction(service, actionId.memberLogicalName(), Where.NOT_SPECIFIED); + return ManagedAction.lookupAction(service, actionId.memberLogicalName(), VisibilityConstraint.invalid(Where.NOT_SPECIFIED)); } } diff --git a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java index 2ec15693118..8e9c8d8fbb3 100644 --- a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java +++ b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java @@ -26,6 +26,7 @@ import org.apache.causeway.core.metamodel.consent.Consent; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.Veto; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.object.MmTitleUtils; import org.apache.causeway.viewer.commons.model.UiModel; @@ -43,10 +44,11 @@ public interface UiActionForm // -- USABILITY default Consent getUsabilityConsent() { + var visibilityConstraint = VisibilityConstraint.invalid(Where.OBJECT_FORMS); return getAction().isUsable( getActionOwner(), InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + visibilityConstraint); } // -- VISABILITY @@ -55,19 +57,18 @@ default Consent getVisibilityConsent() { // guard against missing action owner var actionOwner = getActionOwner(); - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionOwner)) { - return Veto.DEFAULT; // veto, so we don't render the action - } + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(actionOwner)) + return Veto.DEFAULT; // veto, so we don't render the action // check whether action owner type is hidden - if (getActionOwner().objSpec().isHidden()) { - return Veto.DEFAULT; - } + if (getActionOwner().objSpec().isHidden()) + return Veto.DEFAULT; + var visibilityConstraint = VisibilityConstraint.invalid(Where.OBJECT_FORMS); return getAction().isVisible( actionOwner, InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + visibilityConstraint); } // -- VALIDITY diff --git a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java index c09ba54396a..176ecc7fe54 100644 --- a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java +++ b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java @@ -20,6 +20,8 @@ import java.util.concurrent.atomic.LongAdder; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.ServiceActionLayoutData; import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenu; @@ -27,11 +29,11 @@ import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuSection; import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto; import org.apache.causeway.viewer.commons.services.userprof.UserProfileUiServiceDefault; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -78,7 +80,7 @@ static void buildMenuItems( } var managedAction = ManagedAction - .lookupAction(serviceAdapter, actionLayoutData.getId(), Where.EVERYWHERE) + .lookupAction(serviceAdapter, actionLayoutData.getId(), VisibilityConstraint.invalid(Where.EVERYWHERE)) .orElse(null); if (managedAction == null) { log.warn("No such action: bean-name '{}' action-id '{}'", diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java index 3eef3831c94..1f03ba2ac73 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/context/Context.java @@ -33,6 +33,7 @@ import org.springframework.stereotype.Component; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.id.HasLogicalType; import org.apache.causeway.applib.services.bookmark.BookmarkService; import org.apache.causeway.applib.services.registry.ServiceRegistry; @@ -40,6 +41,8 @@ import org.apache.causeway.commons.functional.Either; import org.apache.causeway.core.config.CausewayConfiguration; import org.apache.causeway.core.config.environment.CausewaySystemEnvironment; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.objectmanager.ObjectManager; import org.apache.causeway.core.metamodel.spec.ActionScope; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -105,9 +108,8 @@ public List objectSpecifications(final Predicate< } private void computeLogicalTypeNames() { - if (logicalTypeNames != null) { - return; - } + if (logicalTypeNames != null) + return; logicalTypeNames = doComputeLogicalTypeNames(); graphQLTypeRegistry.addTypeIfNotAlreadyPresent(logicalTypeNames); } @@ -125,4 +127,15 @@ private GraphQLEnumType doComputeLogicalTypeNames() { ) .build(); } + + // -- VISIBILITY CONSTRAINTS + + private static WhatViewer WHAT_VIEWER = new WhatViewer("Graphql"); + public static VisibilityConstraint visibilityConstraint(final Where where) { + return new VisibilityConstraint(WHAT_VIEWER, where); + } + private static VisibilityConstraint VISIBILITY_CONSTRAINT_DEFAULT = visibilityConstraint(Where.ANYWHERE); + public static VisibilityConstraint visibilityConstraint() { + return VISIBILITY_CONSTRAINT_DEFAULT; + } } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java index 4f43941f888..02e6387fc5c 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java @@ -33,7 +33,6 @@ import org.jspecify.annotations.Nullable; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -159,33 +158,30 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment String key = ObjectFeatureUtils.keyFor(refValue); BookmarkedPojo value = environment.getGraphQlContext().get(key); result = Optional.of(value).map(BookmarkedPojo::getTargetPojo); - } else { - throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); - } + } else + throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); } sourcePojo = result .orElseThrow(); // TODO: better error handling if no such object found. } ManagedObject managedObject = ManagedObject.adaptSingular(objectSpec, sourcePojo); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(objectAction.getFeatureIdentifier()); - var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(objectAction.getFeatureIdentifier()); - } + var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(objectAction.getFeatureIdentifier()); var head = objectAction.interactionHead(managedObject); var argumentManagedObjects = argumentManagedObjectsFor(environment, objectAction); var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - } + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); return resultManagedObject.getPojo(); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java index 0664977b249..e69f46c89a3 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java @@ -28,15 +28,14 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import org.apache.causeway.viewer.graphql.model.context.Context; -import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.Element; +import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.SchemaType; import org.apache.causeway.viewer.graphql.model.domain.TypeNames; import org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils; @@ -108,9 +107,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var key = ObjectFeatureUtils.keyFor(refValue); BookmarkedPojo value = environment.getGraphQlContext().get(key); result = Optional.of(value).map(BookmarkedPojo::getTargetPojo); - } else { - throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); - } + } else + throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); } Object sourcePojo = result .orElseThrow(); // TODO: better error handling if no such object found. @@ -120,21 +118,19 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Map arguments = dataFetchingEnvironment.getArguments(); Object argumentValue = arguments.get(oneToOneAssociation.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(oneToOneAssociation, argumentValue); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - } + var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - var usableConsent = oneToOneAssociation.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); - } + var usableConsent = oneToOneAssociation.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); oneToOneAssociation.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java index 249f06d01b7..527d8ab8328 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java @@ -27,7 +27,6 @@ import org.jspecify.annotations.Nullable; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -106,30 +105,27 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var environment = new Environment.ForTunnelled(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return null; - } + if (objectSpecification == null) + return null; var objectAction = actionInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(objectAction.getFeatureIdentifier()); - var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(objectAction.getFeatureIdentifier()); - } + var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(objectAction.getFeatureIdentifier()); var head = objectAction.interactionHead(managedObject); var argumentManagedObjects = actionInteractor.argumentManagedObjectsFor(environment, objectAction, context.bookmarkService); var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - } + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); return resultManagedObject.getPojo(); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java index f5f6970df16..96e27be7ed0 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java @@ -34,12 +34,12 @@ import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; import org.apache.causeway.core.metamodel.object.ManagedObject; - import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; - import org.apache.causeway.viewer.graphql.model.context.Context; -import org.apache.causeway.viewer.graphql.model.domain.Environment; +import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; +import org.apache.causeway.viewer.graphql.model.context.Context; import org.apache.causeway.viewer.graphql.model.domain.Element; +import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor; - import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; +import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; import org.apache.causeway.viewer.graphql.model.types.TypeMapper; import lombok.extern.slf4j.Slf4j; @@ -79,9 +79,8 @@ protected List fetchData(final DataFetchingEnvironment dataFetchingEnvir var sourcePojo = BookmarkedPojo.sourceFrom(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return Collections.emptyList(); - } + if (objectSpecification == null) + return Collections.emptyList(); var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -90,7 +89,7 @@ protected List fetchData(final DataFetchingEnvironment dataFetchingEnvir var objectActionParameter = objectAction.getParameterById(objectFeature.asciiId()); var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var managedAction = ManagedAction.of(managedObject, objectAction, Where.ANYWHERE); + var managedAction = ManagedAction.of(managedObject, objectAction, Context.visibilityConstraint(Where.ANYWHERE)); var pendingArgs = ParameterNegotiationModel.of(managedAction, argumentManagedObjects); var searchArg = dataFetchingEnvironment.getArgument(SEARCH_PARAM_NAME); var autoCompleteManagedObjects = objectActionParameter.getAutoComplete(pendingArgs, searchArg, InteractionInitiatedBy.USER); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java index 05d843ad0ea..e101cf7b5a5 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java @@ -32,12 +32,12 @@ import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; import org.apache.causeway.core.metamodel.object.ManagedObject; - import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; - import org.apache.causeway.viewer.graphql.model.context.Context; -import org.apache.causeway.viewer.graphql.model.domain.Environment; +import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; +import org.apache.causeway.viewer.graphql.model.context.Context; import org.apache.causeway.viewer.graphql.model.domain.Element; +import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor; - import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; +import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; import org.apache.causeway.viewer.graphql.model.types.TypeMapper; import lombok.extern.slf4j.Slf4j; @@ -71,9 +71,8 @@ protected List fetchData(final DataFetchingEnvironment dataFetchingEnvir var sourcePojo = BookmarkedPojo.sourceFrom(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return Collections.emptyList(); - } + if (objectSpecification == null) + return Collections.emptyList(); var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -82,7 +81,7 @@ protected List fetchData(final DataFetchingEnvironment dataFetchingEnvir var objectActionParameter = objectAction.getParameterById(objectFeature.asciiId()); var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var managedAction = ManagedAction.of(managedObject, objectAction, Where.ANYWHERE); + var managedAction = ManagedAction.of(managedObject, objectAction, Context.visibilityConstraint(Where.ANYWHERE)); var pendingArgs = ParameterNegotiationModel.of(managedAction, argumentManagedObjects); var choices = objectActionParameter.getChoices(pendingArgs, InteractionInitiatedBy.USER); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java index c5bf94b5200..e28e85a47b2 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java @@ -30,8 +30,8 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature; import org.apache.causeway.viewer.graphql.model.context.Context; -import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.Element; +import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor; import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo; import org.apache.causeway.viewer.graphql.model.types.TypeMapper; @@ -65,15 +65,14 @@ public RichActionParamsParamDefault( protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment) { var sourcePojo = BookmarkedPojo.sourceFrom(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return Collections.emptyList(); - } + if (objectSpecification == null) + return Collections.emptyList(); var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); final ObjectFeature objectFeature = actionParamInteractor.getObjectActionParameter(); var objectActionParameter = objectAction.getParameterById(objectFeature.asciiId()); var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var managedAction = ManagedAction.of(managedObject, objectAction, Where.ANYWHERE); + var managedAction = ManagedAction.of(managedObject, objectAction, Context.visibilityConstraint(Where.ANYWHERE)); var pendingArgs = ParameterNegotiationModel.of(managedAction, argumentManagedObjects); var defaultManagedObject = objectActionParameter.getDefault(pendingArgs); return defaultManagedObject.getPojo(); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberDisabled.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberDisabled.java index 12cd63b068d..d3f3f0e4198 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberDisabled.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberDisabled.java @@ -22,7 +22,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; @@ -58,14 +57,12 @@ protected String fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - return String.format("Disabled; could not determine target object's type ('%s')", sourcePojoClass.getName()); - } + if (objectSpecification == null) + return String.format("Disabled; could not determine target object's type ('%s')", sourcePojoClass.getName()); var objectMember = memberInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); - - var usable = objectMember.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); + var usable = objectMember.isUsable(managedObject, InteractionInitiatedBy.USER, Context.visibilityConstraint()); return usable.getReasonAsString().orElse(null); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberHidden.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberHidden.java index 4bf8f1ed12f..c87b8db8e85 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberHidden.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichMemberHidden.java @@ -22,7 +22,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; @@ -58,15 +57,13 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - // not expected + if (objectSpecification == null) + // not expected return true; - } var objectMember = memberInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); - - var visibleConsent = objectMember.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); + var visibleConsent = objectMember.isVisible(managedObject, InteractionInitiatedBy.USER, Context.visibilityConstraint()); return visibleConsent.isVetoed(); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java index 94e601666cf..236ea24222b 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java @@ -24,7 +24,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.viewer.graphql.model.context.Context; @@ -64,9 +63,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - return null; - } + if (objectSpecification == null) + return null; var otoa = propertyInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -74,21 +72,19 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Map arguments = dataFetchingEnvironment.getArguments(); Object argumentValue = arguments.get(otoa.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(otoa, argumentValue); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = otoa.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(otoa.getFeatureIdentifier()); - } + var visibleConsent = otoa.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(otoa.getFeatureIdentifier()); - var usableConsent = otoa.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(otoa.getFeatureIdentifier()); - } + var usableConsent = otoa.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(otoa.getFeatureIdentifier()); var validityConsent = otoa.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); otoa.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java index 9c4adf2bbc4..0886c3ea46f 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java @@ -33,7 +33,6 @@ import org.jspecify.annotations.Nullable; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -158,33 +157,30 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var key = ObjectFeatureUtils.keyFor(refValue); BookmarkedPojo value = environment.getGraphQlContext().get(key); result = Optional.of(value).map(BookmarkedPojo::getTargetPojo); - } else { - throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); - } + } else + throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); } sourcePojo = result .orElseThrow(); // TODO: better error handling if no such object found. } ManagedObject managedObject = ManagedObject.adaptSingular(objectSpec, sourcePojo); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(objectAction.getFeatureIdentifier()); - var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(objectAction.getFeatureIdentifier()); - } + var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(objectAction.getFeatureIdentifier()); var head = objectAction.interactionHead(managedObject); var argumentManagedObjects = argumentManagedObjectsFor(environment, objectAction); var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - } + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); return resultManagedObject.getPojo(); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java index cf547124bf9..97aae39d272 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java @@ -28,15 +28,14 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import org.apache.causeway.viewer.graphql.model.context.Context; -import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.Element; +import org.apache.causeway.viewer.graphql.model.domain.Environment; import org.apache.causeway.viewer.graphql.model.domain.SchemaType; import org.apache.causeway.viewer.graphql.model.domain.TypeNames; import org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils; @@ -110,9 +109,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment String key = ObjectFeatureUtils.keyFor(refValue); BookmarkedPojo value = environment.getGraphQlContext().get(key); result = Optional.of(value).map(BookmarkedPojo::getTargetPojo); - } else { - throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); - } + } else + throw new IllegalArgumentException("Either 'id' or 'ref' must be specified for a DomainObject input type"); } Object sourcePojo = result .orElseThrow(); // TODO: better error handling if no such object found. @@ -122,21 +120,19 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Map arguments = dataFetchingEnvironment.getArguments(); Object argumentValue = arguments.get(oneToOneAssociation.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(oneToOneAssociation, argumentValue); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - } + var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - var usableConsent = oneToOneAssociation.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); - } + var usableConsent = oneToOneAssociation.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); oneToOneAssociation.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java index 981bb3ee2c7..7b185341783 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java @@ -32,7 +32,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.applib.services.bookmark.BookmarkService; import org.apache.causeway.commons.collections.Can; @@ -152,10 +151,8 @@ public static Can argumentManagedObjectsFor( case ENTITY: case VIEW_MODEL: - if (argumentValue == null) { - return ManagedObject.empty(elementType); - } - // fall through + if (argumentValue == null) + return ManagedObject.empty(elementType); case ABSTRACT: // if the parameter is abstract, we still attempt to figure out the arguments. @@ -191,9 +188,8 @@ private static ManagedObject adaptValue( final Context context) { var elementType = oap.getElementType(); - if (argumentValue == null) { - return ManagedObject.empty(elementType); - } + if (argumentValue == null) + return ManagedObject.empty(elementType); var argPojo = context.typeMapper.unmarshal(argumentValue, elementType); return ManagedObject.adaptParameter(oap, argPojo); @@ -211,22 +207,19 @@ public static Optional asPojo( if (refValue != null) { String key = ObjectFeatureUtils.keyFor(refValue); BookmarkedPojo bookmarkedPojo = environment.getGraphQlContext().get(key); - if (bookmarkedPojo == null) { - throw new IllegalArgumentException(String.format( + if (bookmarkedPojo == null) + throw new IllegalArgumentException(String.format( "Could not find object referenced '%s' in the execution context; was it saved previously using \"saveAs\" ?", refValue)); - } var targetPojoClass = bookmarkedPojo.getTargetPojo().getClass(); var targetPojoSpec = context.specificationLoader.loadSpecification(targetPojoClass); - if (targetPojoSpec == null) { - throw new IllegalArgumentException(String.format( + if (targetPojoSpec == null) + throw new IllegalArgumentException(String.format( "The object referenced '%s' is not part of the metamodel (has class '%s')", refValue, targetPojoClass.getCanonicalName())); - } - if (!elementType.isPojoCompatible(bookmarkedPojo.getTargetPojo())) { - throw new IllegalArgumentException(String.format( + if (!elementType.isPojoCompatible(bookmarkedPojo.getTargetPojo())) + throw new IllegalArgumentException(String.format( "The object referenced '%s' has a type '%s' that is not assignable to the required type '%s'", refValue, targetPojoSpec.logicalTypeName(), elementType.logicalTypeName())); - } return Optional.of(bookmarkedPojo).map(BookmarkedPojo::getTargetPojo); } @@ -236,11 +229,10 @@ public static Optional asPojo( Optional bookmarkIfAny; if(elementType.isAbstract()) { var objectSpecArg = (ObjectSpecification)argumentValue.get("logicalTypeName"); - if (objectSpecArg == null) { - throw new IllegalArgumentException(String.format( + if (objectSpecArg == null) + throw new IllegalArgumentException(String.format( "The 'logicalTypeName' is required along with the 'id', because the input type '%s' is abstract", elementType.logicalTypeName())); - } bookmarkIfAny = Optional.of(Bookmark.forLogicalTypeNameAndIdentifier(objectSpecArg.logicalTypeName(), idValue)); } else { bookmarkIfAny = context.bookmarkService.bookmarkFor(paramClass, idValue); @@ -301,30 +293,27 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var environment = new Environment.For(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return null; - } + if (objectSpecification == null) + return null; var objectAction = getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); + var visibilityConstraint = Context.visibilityConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(objectAction.getFeatureIdentifier()); - var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(objectAction.getFeatureIdentifier()); - } + var usableConsent = objectAction.isUsable(managedObject, InteractionInitiatedBy.USER, visibilityConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(objectAction.getFeatureIdentifier()); var head = objectAction.interactionHead(managedObject); var argumentManagedObjects = argumentManagedObjectsFor(environment, objectAction, context.bookmarkService); var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - } + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); return resultManagedObject.getPojo(); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java index 778a1fa3e61..0dfb17949d1 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java @@ -29,7 +29,9 @@ import org.apache.causeway.core.config.CausewayConfiguration.Viewer.Restfulobjects; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.HasMetaModelContext; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; +import org.apache.causeway.viewer.restfulobjects.rendering.context.ResourceContext; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo; import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService; @@ -68,7 +70,11 @@ public interface IResourceContext extends HasMetaModelContext { */ InteractionInitiatedBy interactionInitiatedBy(); + @Deprecated Where where(); + default VisibilityConstraint visibilityConstraint() { + return ResourceContext.visibilityConstraint(where()); + } ObjectAdapterLinkTo objectAdapterLinkTo(); List> followLinks(); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java index 71e3a8bc0be..3ff8753e61a 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java @@ -43,6 +43,8 @@ import org.apache.causeway.commons.io.UrlUtils; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation; @@ -140,13 +142,12 @@ private ResourceContext( private void ensureDomainModelQueryParamSupported() { final DomainModel domainModel = arg(queryStringAsJsonRepr(), RequestParameter.DOMAIN_MODEL); - if(domainModel != DomainModel.FORMAL) { - throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST, + if(domainModel != DomainModel.FORMAL) + throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST, "x-ro-domain-model of '%s' is not supported".formatted(domainModel)); - } } - private static JsonRepresentation requestArgsAsMap(final Map params, RequestParams urlUnencodedQueryString) { + private static JsonRepresentation requestArgsAsMap(final Map params, final RequestParams urlUnencodedQueryString) { if(simpleQueryArgs(params)) { // try to process regular params and build up JSON repr final JsonRepresentation map = JsonRepresentation.newMap(); @@ -164,31 +165,26 @@ private static JsonRepresentation requestArgsAsMap(final Map p } } return map; - } else { - return Optional.ofNullable(urlUnencodedQueryString) + } else + return Optional.ofNullable(urlUnencodedQueryString) .orElseGet(RequestParams::ofEmptyQueryString) .asMap(); - } } static String stripQuotes(final String str) { - if(_Strings.isNullOrEmpty(str)) { - return str; - } - if(str.startsWith("\"") && str.endsWith("\"")) { - return str.substring(1, str.lastIndexOf("\"")); - } + if(_Strings.isNullOrEmpty(str)) + return str; + if(str.startsWith("\"") && str.endsWith("\"")) + return str.substring(1, str.lastIndexOf("\"")); return str; } private static boolean simpleQueryArgs(final Map params) { - if(params==null || params.isEmpty()) { - return false; - } + if(params==null || params.isEmpty()) + return false; for(String paramId: params.keySet()) { - if("x-causeway-querystring".equals(paramId) || paramId.startsWith("{")) { - return false; - } + if("x-causeway-querystring".equals(paramId) || paramId.startsWith("{")) + return false; } return true; } @@ -237,16 +233,22 @@ public ManagedObject lookupServiceAdapterElseFail( .map(this::lookupServiceAdapterById) .orElse(null); - if(serviceAdapter==null) { - throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.NOT_FOUND, + if(serviceAdapter==null) + throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.NOT_FOUND, "Could not locate service '%s'".formatted(serviceIdOrAlias)); - } return serviceAdapter; } + // -- VISIBILITY CONSTRAINTS + + public static WhatViewer WHAT_VIEWER = new WhatViewer("Restful"); + public static VisibilityConstraint visibilityConstraint(final Where where) { + return new VisibilityConstraint(WHAT_VIEWER, where); + } + // -- JUNIT - public static ResourceContext forTesting(String queryString, HttpServletRequest servletRequest) { + public static ResourceContext forTesting(final String queryString, final HttpServletRequest servletRequest) { return new ResourceContext(MetaModelContext.instanceNullable(), ResourceDescriptor.empty(), null, null, RequestParams.ofQueryString(UrlUtils.urlDecodeUtf8(queryString)), @@ -255,9 +257,9 @@ public static ResourceContext forTesting(String queryString, HttpServletRequest } public static ResourceContext forTesting( - ResourceDescriptor resourceDescriptor, - HttpServletRequest servletRequest, - HttpHeaders httpHeaders) { + final ResourceDescriptor resourceDescriptor, + final HttpServletRequest servletRequest, + final HttpHeaders httpHeaders) { return new ResourceContext(MetaModelContext.instanceNullable(), resourceDescriptor, null, null, null, //RequestParams diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java index 6af3b08e0c2..f684374e2af 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java @@ -18,14 +18,13 @@ */ package org.apache.causeway.viewer.restfulobjects.rendering.domainobjects; -import tools.jackson.databind.node.NullNode; - import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.core.metamodel.consent.Consent; import org.apache.causeway.core.metamodel.facetapi.Facet; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ManagedMember; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; @@ -37,6 +36,9 @@ import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext; import org.apache.causeway.viewer.restfulobjects.rendering.LinkFollowSpecs; import org.apache.causeway.viewer.restfulobjects.rendering.ReprRendererAbstract; +import org.apache.causeway.viewer.restfulobjects.rendering.context.ResourceContext; + +import tools.jackson.databind.node.NullNode; public abstract class AbstractObjectMemberReprRenderer extends ReprRendererAbstract { @@ -86,7 +88,7 @@ public boolean isEventSerialization() { * Used to determine whether to follow links; only populated for {@link Mode#INLINE inline} Mode. */ private String memberId; - protected final Where where; + protected final VisibilityConstraint visibilityConstraint; public AbstractObjectMemberReprRenderer( final IResourceContext resourceContext, @@ -97,7 +99,7 @@ public AbstractObjectMemberReprRenderer( final Where where) { super(resourceContext, linkFollower, representationType, representation); this.memberId = memberId; - this.where = where; + this.visibilityConstraint = ResourceContext.visibilityConstraint(where); } protected String getMemberId() { @@ -221,9 +223,8 @@ private void addLinkToUp() { * mutators}. */ protected void addLinkFor(final @NonNull MutatorSpec mutatorSpec) { - if (!mutatorSpec.appliesTo(objectMember)) { - return; - } + if (!mutatorSpec.appliesTo(objectMember)) + return; final JsonRepresentation arguments = mutatorArgs(mutatorSpec); final RepresentationType representationType = objectMemberType.getRepresentationType(); final JsonRepresentation mutatorLink = linkToForMutatorInvoke().memberBuilder(mutatorSpec.rel, objectMemberType, objectMember, representationType, mutatorSpec.suffix).withHttpMethod(mutatorSpec.httpMethod).withArguments(arguments).build(); @@ -243,9 +244,8 @@ protected ObjectAdapterLinkTo linkToForMutatorInvoke() { * overridden (ie by actions) if required. */ protected JsonRepresentation mutatorArgs(final MutatorSpec mutatorSpec) { - if (mutatorSpec.arguments.isNone()) { - return null; - } + if (mutatorSpec.arguments.isNone()) + return null; if (mutatorSpec.arguments.isOne()) { final JsonRepresentation repr = JsonRepresentation.newMap(); repr.mapPutJsonNode("value", NullNode.getInstance()); // force a null into @@ -257,9 +257,8 @@ protected JsonRepresentation mutatorArgs(final MutatorSpec mutatorSpec) { } private void addDetailsLinkIfPersistent() { - if (!ManagedObjects.isIdentifiable(objectAdapter)) { - return; - } + if (!ManagedObjects.isIdentifiable(objectAdapter)) + return; final JsonRepresentation link = linkTo.memberBuilder(Rel.DETAILS, objectMemberType, objectMember).build(); getLinks().arrayAdd(link); @@ -278,9 +277,8 @@ private void addDetailsLinkIfPersistent() { protected abstract void followDetailsLink(JsonRepresentation detailsLink); protected final void putDisabledReasonIfDisabled() { - if(resourceContext.config().suppressMemberDisabledReason()) { - return; - } + if(resourceContext.config().suppressMemberDisabledReason()) + return; final String disabledReasonRep = usability().getReasonAsString().orElse(null); representation.mapPutString("disabledReason", disabledReasonRep); } @@ -304,11 +302,11 @@ protected F getMemberSpecFacet(final Class facetType) { } protected Consent usability() { - return objectMember.isUsable(objectAdapter, getInteractionInitiatedBy(), where); + return objectMember.isUsable(objectAdapter, getInteractionInitiatedBy(), visibilityConstraint); } protected Consent visibility() { - return objectMember.isVisible(objectAdapter, getInteractionInitiatedBy(), where); + return objectMember.isVisible(objectAdapter, getInteractionInitiatedBy(), visibilityConstraint); } } diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java index fe1146a79eb..0a188b6750a 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java @@ -161,9 +161,8 @@ public DomainObjectReprRenderer with(final ManagedObject objectAdapter) { @Override public JsonRepresentation render() { - if(representation == null) { - return null; - } + if(representation == null) + return null; final boolean isService = objectAdapter.objSpec().isInjectable(); @@ -310,21 +309,20 @@ private void addProperties(final ManagedObject objectAdapter, final JsonRepresen for (final ObjectAssociation assoc : associations) { if (mode.checkVisibility()) { - final Consent visibility = assoc.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.where()); + final Consent visibility = assoc.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.visibilityConstraint()); if (!visibility.isAllowed()) { continue; } } - if (!(assoc instanceof OneToOneAssociation)) { + if (!(assoc instanceof final OneToOneAssociation property)) { continue; } - final OneToOneAssociation property = (OneToOneAssociation) assoc; final LinkFollowSpecs linkFollowerForProp = getLinkFollowSpecs().follow("members[" + property.getId() + "]"); final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap(); final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(getResourceContext(), linkFollowerForProp, property.getId(), propertyRepresentation); - renderer.with(ManagedProperty.of(objectAdapter, property, resourceContext.where())).usingLinkTo(linkToBuilder); + renderer.with(ManagedProperty.of(objectAdapter, property, resourceContext.visibilityConstraint())).usingLinkTo(linkToBuilder); if (mode.isArgs()) { renderer.asArguments(); @@ -345,27 +343,23 @@ private void addCollections(final ManagedObject objectAdapter, final JsonReprese for (final ObjectAssociation assoc : associations) { if (mode.checkVisibility()) { - final Consent visibility = assoc.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.where()); + final Consent visibility = assoc.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.visibilityConstraint()); if (!visibility.isAllowed()) { continue; } } - if (!(assoc instanceof OneToManyAssociation)) { + if (!(assoc instanceof final OneToManyAssociation collection)) { continue; } - final OneToManyAssociation collection = (OneToManyAssociation) assoc; - final LinkFollowSpecs linkFollowerForColl = getLinkFollowSpecs().follow( "members[" + collection.getId() + "]"); final JsonRepresentation collectionRepresentation = JsonRepresentation.newMap(); final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(getResourceContext(), linkFollowerForColl, collection.getId(), collectionRepresentation); - var where = resourceContext.where(); - - renderer.with(ManagedCollection.of(objectAdapter, collection, where)).usingLinkTo(linkToBuilder); + renderer.with(ManagedCollection.of(objectAdapter, collection, resourceContext.visibilityConstraint())).usingLinkTo(linkToBuilder); if(mode.isEventSerialization()) { renderer.asEventSerialization(); } @@ -381,7 +375,7 @@ private void addActions( actions .filter(action->{ - final Consent visibility = action.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.where()); + final Consent visibility = action.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.visibilityConstraint()); return visibility.isAllowed(); }) .forEach(action->{ @@ -390,18 +384,15 @@ private void addActions( new ObjectActionReprRenderer(getResourceContext(), linkFollowSpecs, action.getId(), JsonRepresentation.newMap()); - var where = resourceContext.where(); - - renderer.with(ManagedAction.of(objectAdapter, action, where)).usingLinkTo(linkToBuilder); + renderer.with(ManagedAction.of(objectAdapter, action, resourceContext.visibilityConstraint())).usingLinkTo(linkToBuilder); members.mapPutJsonRepresentation(action.getId(), renderer.render()); }); } private void addPersistLinkIfTransientAndPersistable() { - if (ManagedObjects.isIdentifiable(objectAdapter)) { - return; - } + if (ManagedObjects.isIdentifiable(objectAdapter)) + return; final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getResourceContext(), null, JsonRepresentation.newMap()); final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asPersistLinkArguments().render(); @@ -428,16 +419,13 @@ public DomainObjectReprRenderer asEventSerialization() { } private void addUpdatePropertiesLinkIfRequired() { - if(mode.isEventSerialization()) { - return; - } - if (!ManagedObjects.isIdentifiable(objectAdapter)) { - return; - } + if(mode.isEventSerialization()) + return; + if (!ManagedObjects.isIdentifiable(objectAdapter)) + return; final boolean isService = objectAdapter.objSpec().isInjectable(); - if(isService) { - return; - } + if(isService) + return; final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getResourceContext(), null, JsonRepresentation.newMap()); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java index a289319f086..c07c2a06956 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java @@ -21,8 +21,6 @@ import java.util.List; import java.util.Map; -import tools.jackson.databind.node.NullNode; - import org.apache.causeway.applib.annotation.SemanticsOf; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.internal.collections._Lists; @@ -37,8 +35,11 @@ import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType; import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext; import org.apache.causeway.viewer.restfulobjects.rendering.LinkFollowSpecs; +import org.apache.causeway.viewer.restfulobjects.rendering.context.ResourceContext; import org.apache.causeway.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer; +import tools.jackson.databind.node.NullNode; + public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer { @@ -75,9 +76,8 @@ public JsonRepresentation render() { */ @Override protected void followDetailsLink(final JsonRepresentation detailsLink) { - var where = resourceContext.where(); final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(getResourceContext(), getLinkFollowSpecs(), null, JsonRepresentation.newMap()); - renderer.with(ManagedAction.of(objectAdapter, objectMember, where)).usingLinkTo(linkTo).asFollowed(); + renderer.with(ManagedAction.of(objectAdapter, objectMember, resourceContext.visibilityConstraint())).usingLinkTo(linkTo).asFollowed(); detailsLink.mapPutJsonRepresentation("value", renderer.render()); } @@ -85,9 +85,8 @@ protected void followDetailsLink(final JsonRepresentation detailsLink) { @Override protected void addMutatorLinksIfEnabled() { - if (usability().isVetoed()) { - return; - } + if (usability().isVetoed()) + return; final Map mutators = objectMemberType.getMutators(); final SemanticsOf actionSemantics = objectMember.getSemantics(); @@ -122,7 +121,7 @@ private Object argValueFor(final int i) { private ObjectActionReprRenderer addParameterDetails() { final Map parameters = _Maps.newLinkedHashMap(); if(objectMember.getParameterCount()>0) { - var act = ManagedAction.of(objectAdapter, objectMember, Where.ANYWHERE); + var act = ManagedAction.of(objectAdapter, objectMember, ResourceContext.visibilityConstraint(Where.ANYWHERE)); var paramNeg = act.startParameterNegotiation(); for(var paramMod : paramNeg.getParamModels()) { var paramMeta = paramMod.getMetaModel(); @@ -157,9 +156,8 @@ private Object choicesFor( final ParameterNegotiationModel paramNeg) { var paramMeta = paramMod.getMetaModel(); var choiceAdapters = paramMeta.getChoices(paramNeg, getInteractionInitiatedBy()); - if (choiceAdapters == null || choiceAdapters.isEmpty()) { - return null; - } + if (choiceAdapters == null || choiceAdapters.isEmpty()) + return null; final List list = _Lists.newArrayList(); for (var choiceAdapter : choiceAdapters) { // REVIEW: previously was using the spec of the parameter, but think instead it should be the spec of the adapter itself @@ -171,9 +169,8 @@ private Object choicesFor( private Object defaultFor(final ManagedParameter paramMod) { var defaultAdapter = paramMod.getValue().getValue(); - if (ManagedObjects.isNullOrUnspecifiedOrEmpty(defaultAdapter)) { - return null; - } + if (ManagedObjects.isNullOrUnspecifiedOrEmpty(defaultAdapter)) + return null; // REVIEW: previously was using the spec of the parameter, but think instead it should be the spec of the adapter itself // final ObjectSpecification defaultSpec = param.getSpecification(); var paramMeta = paramMod.getMetaModel(); @@ -184,9 +181,8 @@ private Object defaultFor(final ManagedParameter paramMod) { @Override protected void addLinksToFormalDomainModel() { - if(resourceContext.config().suppressDescribedByLinks()) { - return; - } + if(resourceContext.config().suppressDescribedByLinks()) + return; final JsonRepresentation link = ActionDescriptionReprRenderer.newLinkToBuilder(resourceContext, Rel.DESCRIBEDBY, objectAdapter.objSpec(), objectMember).build(); getLinks().arrayAdd(link); } diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java index b4848ee03cb..d6deaccf31d 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java @@ -55,9 +55,8 @@ public ObjectCollectionReprRenderer( @Override public JsonRepresentation render() { - if(representation == null) { - return null; - } + if(representation == null) + return null; renderMemberContent(); @@ -88,9 +87,8 @@ public JsonRepresentation render() { private void addValue(final LinkFollowSpecs linkFollower) { var valueAdapter = objectMember.get(objectAdapter, getInteractionInitiatedBy()); - if (valueAdapter == null) { - return; - } + if (valueAdapter == null) + return; final LinkFollowSpecs followHref = linkFollower.follow("href"); final boolean eagerlyRender = !followHref.isTerminated() @@ -130,7 +128,7 @@ private void addValue(final LinkFollowSpecs linkFollower) { protected void followDetailsLink(final JsonRepresentation detailsLink) { var objectCollectionReprRenderer = new ObjectCollectionReprRenderer(getResourceContext(), getLinkFollowSpecs(), null, JsonRepresentation.newMap()) - .with(ManagedCollection.of(objectAdapter, objectMember, resourceContext.where())) + .with(ManagedCollection.of(objectAdapter, objectMember, resourceContext.visibilityConstraint())) .asFollowed(); detailsLink.mapPutJsonRepresentation("value", objectCollectionReprRenderer.render()); } @@ -146,9 +144,8 @@ protected void addMutatorLinksIfEnabled() { @Override protected void addLinksToFormalDomainModel() { - if(resourceContext.config().suppressDescribedByLinks()) { - return; - } + if(resourceContext.config().suppressDescribedByLinks()) + return; final JsonRepresentation link = CollectionDescriptionReprRenderer .newLinkToBuilder(resourceContext, Rel.DESCRIBEDBY, objectAdapter.objSpec(), objectMember).build(); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java index 3dcee2cb88b..20428943edd 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java @@ -20,8 +20,6 @@ import java.util.List; -import tools.jackson.databind.node.NullNode; - import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.internal.collections._Lists; import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty; @@ -38,6 +36,8 @@ import org.apache.causeway.viewer.restfulobjects.rendering.domaintypes.PropertyDescriptionReprRenderer; import org.apache.causeway.viewer.restfulobjects.rendering.service.valuerender.JsonValueConverter; +import tools.jackson.databind.node.NullNode; + public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer { @@ -137,7 +137,7 @@ private void addValue(final LinkFollowSpecs linkFollower) { protected void followDetailsLink(final JsonRepresentation detailsLink) { final JsonRepresentation representation = JsonRepresentation.newMap(); final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(getResourceContext(), getLinkFollowSpecs(), null, representation); - renderer.with(ManagedProperty.of(objectAdapter, objectMember, super.where)).asFollowed(); + renderer.with(ManagedProperty.of(objectAdapter, objectMember, super.visibilityConstraint)).asFollowed(); detailsLink.mapPutJsonRepresentation("value", renderer.render()); } @@ -145,9 +145,8 @@ protected void followDetailsLink(final JsonRepresentation detailsLink) { @Override protected void addMutatorLinksIfEnabled() { - if (usability().isVetoed()) { - return; - } + if (usability().isVetoed()) + return; objectMemberType.getMutators() .values() .forEach(this::addLinkFor); @@ -167,9 +166,8 @@ private Object propertyChoices() { var choiceAdapters = objectMember .getChoices(objectAdapter, getInteractionInitiatedBy()); - if (choiceAdapters == null || choiceAdapters.isEmpty()) { - return null; - } + if (choiceAdapters == null || choiceAdapters.isEmpty()) + return null; final List list = _Lists.newArrayList(); for (var choiceAdapter : choiceAdapters) { // REVIEW: previously was using the spec of the member, but think instead it should be the spec of the adapter itself @@ -185,9 +183,8 @@ private Object propertyChoices() { @Override protected void addLinksToFormalDomainModel() { - if(resourceContext.config().suppressDescribedByLinks()) { - return; - } + if(resourceContext.config().suppressDescribedByLinks()) + return; final JsonRepresentation link = PropertyDescriptionReprRenderer.newLinkToBuilder(getResourceContext(), Rel.DESCRIBEDBY, objectAdapter.objSpec(), objectMember).build(); getLinks().arrayAdd(link); } diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java index 4df7714e34b..f1062b3a3f1 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java @@ -24,14 +24,13 @@ import java.util.stream.Stream; import jakarta.inject.Named; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import tools.jackson.databind.node.POJONode; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.jspecify.annotations.Nullable; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.apache.causeway.applib.annotation.PriorityPrecedence; @@ -58,6 +57,8 @@ import lombok.RequiredArgsConstructor; +import tools.jackson.databind.node.POJONode; + /** * @since 1.x {@index} */ @@ -198,11 +199,10 @@ public ResponseEntity buildResponse( switch (resultType) { case DOMAIN_OBJECT: - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(returnedAdapter)) { - // 404 not found + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(returnedAdapter)) + // 404 not found return ResponseFactory.notFound(); - - } else { + else { rootRepresentation = JsonRepresentation.newMap(); appendObjectTo(resourceContext, returnedAdapter, rootRepresentation, suppression); } @@ -213,12 +213,10 @@ public ResponseEntity buildResponse( case LIST: - if(!objectAndActionInvocation.hasElements()) { - // 404 not found + if(!objectAndActionInvocation.hasElements()) + // 404 not found return ResponseFactory.notFound(); - } - rootRepresentation = JsonRepresentation.newArray(); objectAndActionInvocation.streamElementAdapters() @@ -238,12 +236,10 @@ public ResponseEntity buildResponse( case SCALAR_VALUES: - if(!objectAndActionInvocation.hasElements()) { - // 404 not found + if(!objectAndActionInvocation.hasElements()) + // 404 not found return ResponseFactory.notFound(); - } - rootRepresentation = JsonRepresentation.newArray(); objectAndActionInvocation.streamElementAdapters() @@ -260,10 +256,9 @@ public ResponseEntity buildResponse( case SCALAR_VALUE: var dto = dtoForValue(returnedAdapter).orElse(null); - if(dto==null) { - // 404 not found + if(dto==null) + // 404 not found return ResponseFactory.notFound(); - } var jsonNode = new POJONode(dto); rootRepresentation = new JsonRepresentation(jsonNode); @@ -286,9 +281,8 @@ public ResponseEntity buildResponse( private Optional dtoForValue(final @Nullable ManagedObject valueObject) { if(ManagedObjects.isNullOrUnspecifiedOrEmpty(valueObject) - || !valueObject.objSpec().isValue()) { - return Optional.empty(); - } + || !valueObject.objSpec().isValue()) + return Optional.empty(); var valSpec = valueObject.objSpec(); var dto = valSpec.isCompositeValue() ? ScalarValueDtoV2.forValue(valueObject.getPojo(), @@ -317,7 +311,7 @@ private void appendObjectTo( appendPropertiesTo(resourceContext, owner, rootRepresentation, suppression); - var where = resourceContext.where(); + var visibilityConstraint = resourceContext.visibilityConstraint(); owner.objSpec() .streamCollections(MixedIn.INCLUDED) @@ -327,12 +321,11 @@ private void appendObjectTo( rootRepresentation.mapPutJsonRepresentation(collection.getId(), collectionRepresentation); var interactionInitiatedBy = resourceContext.interactionInitiatedBy(); - var visibilityConsent = collection.isVisible(owner, interactionInitiatedBy, where); - if (!visibilityConsent.isAllowed()) { - return; - } + var visibilityConsent = collection.isVisible(owner, interactionInitiatedBy, visibilityConstraint); + if (!visibilityConsent.isAllowed()) + return; - var managedCollection = ManagedCollection.of(owner, collection, where); + var managedCollection = ManagedCollection.of(owner, collection, visibilityConstraint); appendCollectionTo(resourceContext, managedCollection, collectionRepresentation, suppression); }); @@ -346,21 +339,21 @@ private void appendPropertiesTo( final EnumSet suppression) { var interactionInitiatedBy = resourceContext.interactionInitiatedBy(); - var where = resourceContext.where(); + var visibilityConstraint = resourceContext.visibilityConstraint(); + final Stream properties = objectAdapter.objSpec() .streamProperties(MixedIn.INCLUDED); properties.forEach(property->{ - final Consent visibility = property.isVisible(objectAdapter, interactionInitiatedBy, where); - if (!visibility.isAllowed()) { - return; - } + final Consent visibility = property.isVisible(objectAdapter, interactionInitiatedBy, visibilityConstraint); + if (!visibility.isAllowed()) + return; final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap(); var renderer = new ObjectPropertyReprRenderer(resourceContext, null, property.getId(), propertyRepresentation) .asStandalone() - .with(ManagedProperty.of(objectAdapter, property, where)); + .with(ManagedProperty.of(objectAdapter, property, visibilityConstraint)); final JsonRepresentation propertyValueRepresentation = renderer.render(); diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java index 042c6b73980..f3b6b4fe5f6 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java @@ -81,45 +81,40 @@ public ResponseEntity persist( RepresentationService.Intent.JUST_CREATED, ResourceLink.OBJECT)); final JsonRepresentation objectRepr = RequestParams.ofRequestBody(object).asMap(); - if (!objectRepr.isMap()) { - throw _EndpointLogging.error(log, "POST /objects/{}", domainType, + if (!objectRepr.isMap()) + throw _EndpointLogging.error(log, "POST /objects/{}", domainType, RestfulObjectsApplicationException .createWithMessage(HttpStatus.BAD_REQUEST, "Body is not a map; got %s".formatted(objectRepr))); - } var domainTypeSpec = getSpecificationLoader().specForLogicalTypeName(domainType) .orElse(null); - if (domainTypeSpec == null) { - throw _EndpointLogging.error(log, "POST /objects/{}", domainType, + if (domainTypeSpec == null) + throw _EndpointLogging.error(log, "POST /objects/{}", domainType, RestfulObjectsApplicationException .createWithMessage(HttpStatus.BAD_REQUEST, "Could not determine type of domain object to persist (no class with domainType Id of '%s')".formatted(domainType))); - } final ManagedObject adapter = domainTypeSpec.createObject(); final ObjectAdapterUpdateHelper updateHelper = new ObjectAdapterUpdateHelper(resourceContext, adapter); final JsonRepresentation membersMap = objectRepr.getMap("members"); - if (membersMap == null) { - throw _EndpointLogging.error(log, "POST /objects/{}", domainType, + if (membersMap == null) + throw _EndpointLogging.error(log, "POST /objects/{}", domainType, RestfulObjectsApplicationException .createWithMessage(HttpStatus.BAD_REQUEST, "Could not find members map; got %s".formatted(objectRepr))); - } - if (!updateHelper.copyOverProperties(membersMap, ObjectAdapterUpdateHelper.Intent.PERSISTING_NEW)) { - throw _EndpointLogging.error(log, "POST /objects/{}", domainType, + if (!updateHelper.copyOverProperties(membersMap, ObjectAdapterUpdateHelper.Intent.PERSISTING_NEW)) + throw _EndpointLogging.error(log, "POST /objects/{}", domainType, RestfulObjectsApplicationException .createWithBody(HttpStatus.BAD_REQUEST, objectRepr, "Illegal property value")); - } final Consent validity = adapter.objSpec().isValid(adapter, InteractionInitiatedBy.USER); - if (validity.isVetoed()) { - throw _EndpointLogging.error(log, "POST /objects/{}", domainType, + if (validity.isVetoed()) + throw _EndpointLogging.error(log, "POST /objects/{}", domainType, RestfulObjectsApplicationException .createWithBody(HttpStatus.BAD_REQUEST, objectRepr, validity.getReasonAsString().orElse(null))); - } MmEntityUtils.persistInCurrentTransaction(adapter); @@ -159,31 +154,28 @@ public ResponseEntity object( RepresentationService.Intent.ALREADY_PERSISTENT, ResourceLink.OBJECT)); final JsonRepresentation argRepr = RequestParams.ofRequestBody(object).asMap(); - if (!argRepr.isMap()) { - throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, + if (!argRepr.isMap()) + throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, RestfulObjectsApplicationException .createWithMessage( HttpStatus.BAD_REQUEST, "Body is not a map; got %s".formatted(argRepr))); - } var objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId, roEx->_EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, roEx)); final ObjectAdapterUpdateHelper updateHelper = new ObjectAdapterUpdateHelper(resourceContext, objectAdapter); - if (!updateHelper.copyOverProperties(argRepr, ObjectAdapterUpdateHelper.Intent.UPDATE_EXISTING)) { - throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, + if (!updateHelper.copyOverProperties(argRepr, ObjectAdapterUpdateHelper.Intent.UPDATE_EXISTING)) + throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, RestfulObjectsApplicationException .createWithBody( HttpStatus.BAD_REQUEST, argRepr, "Illegal property value")); - } final Consent validity = objectAdapter.objSpec().isValid(objectAdapter, InteractionInitiatedBy.USER); - if (validity.isVetoed()) { - throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, + if (validity.isVetoed()) + throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId, RestfulObjectsApplicationException .createWithBody( HttpStatus.BAD_REQUEST, argRepr, validity.getReasonAsString().orElse(null))); - } var domainResourceHelper = _DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter); @@ -353,7 +345,7 @@ public ResponseEntity modifyProperty( roEx->_EndpointLogging.error(log, "PUT /objects/{}/{}/properties/{}", domainType, instanceId, propertyId, roEx)); PropertyInteraction - .start(objectAdapter, propertyId, resourceContext.where()) + .start(objectAdapter, propertyId, resourceContext.visibilityConstraint()) .checkVisibility() .checkUsability(AccessIntent.MUTATE) .modifyProperty(property->{ @@ -384,7 +376,7 @@ public ResponseEntity clearProperty( var objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId, roEx->_EndpointLogging.error(log, "DELETE /objects/{}/{}/properties/{}", domainType, instanceId, propertyId, roEx)); - PropertyInteraction.start(objectAdapter, propertyId, resourceContext.where()) + PropertyInteraction.start(objectAdapter, propertyId, resourceContext.visibilityConstraint()) .checkVisibility() .checkUsability(AccessIntent.MUTATE) .modifyProperty(property->null) diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java index b46ecf98629..53ee6863864 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterAccessHelper.java @@ -18,7 +18,9 @@ */ package org.apache.causeway.viewer.restfulobjects.viewer.resources; -import org.apache.causeway.applib.annotation.Where; +import org.jspecify.annotations.NonNull; + +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteraction.SemanticConstraint; import org.apache.causeway.core.metamodel.interactions.managed.CollectionInteraction; @@ -30,7 +32,6 @@ import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; /** @@ -45,11 +46,11 @@ public static ObjectAdapterAccessHelper of( final ManagedObject managedObject) { return new ObjectAdapterAccessHelper( managedObject, - resourceContext.where()); + resourceContext.visibilityConstraint()); } private final ManagedObject managedObject; - private final Where where; + private final VisibilityConstraint visibilityConstraint; public ManagedAction getObjectActionThatIsVisibleForIntentAndSemanticConstraint( final @NonNull String actionId, @@ -57,7 +58,7 @@ public ManagedAction getObjectActionThatIsVisibleForIntentAndSemanticConstraint( final @NonNull SemanticConstraint semanticConstraint) { return ActionInteraction - .start(managedObject, actionId, where) + .start(managedObject, actionId, visibilityConstraint) .checkVisibility() .checkUsability(AccessIntent.MUTATE) .checkSemanticConstraint(semanticConstraint) @@ -69,7 +70,7 @@ public ManagedProperty getPropertyThatIsVisibleForIntent( final @NonNull AccessIntent intent) { return PropertyInteraction - .start(managedObject, propertyId, where) + .start(managedObject, propertyId, visibilityConstraint) .checkVisibility() .checkUsability(intent) .getManagedPropertyElseThrow(InteractionFailureHandler::onFailure); @@ -81,7 +82,7 @@ public ManagedCollection getCollectionThatIsVisibleForIntent( final @NonNull AccessIntent intent) { return CollectionInteraction - .start(managedObject, collectionId, where) + .start(managedObject, collectionId, visibilityConstraint) .checkVisibility() .checkUsability(intent) .getManagedCollectionElseThrow(InteractionFailureHandler::onFailure); diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java index 1810b222dd7..94eaf7dff3f 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java @@ -88,12 +88,11 @@ private boolean copyOverProperty( final Consent visibility = property.isVisible( objectAdapter, resourceContext.interactionInitiatedBy(), - resourceContext.where()); + ResourceContext.visibilityConstraint(resourceContext.where())); final Consent usability = property.isUsable( objectAdapter, resourceContext.interactionInitiatedBy(), - resourceContext.where() - ); + ResourceContext.visibilityConstraint(resourceContext.where())); final boolean invisible = visibility.isVetoed(); final boolean disabled = usability.isVetoed(); @@ -103,15 +102,13 @@ private boolean copyOverProperty( // no value provided if(intent.shouldValidate()) { - if(invisible || disabled) { - // that's ok, indeed expected + if(invisible || disabled) + // that's ok, indeed expected return allOk; - } } - if (!property.isMandatory()) { - // optional, so also not a problem + if (!property.isMandatory()) + // optional, so also not a problem return allOk; - } // otherwise, is an error. final String invalidReason = propertiesMap.getString("x-ro-invalidReason"); @@ -127,11 +124,10 @@ private boolean copyOverProperty( if(intent.shouldValidate()) { // value has been provided - if (invisible) { - // silently ignore; don't want to acknowledge the + if (invisible) + // silently ignore; don't want to acknowledge the // existence of this property to the caller return allOk; - } if (disabled) { // not allowed to update propertyRepr.mapPutString("invalidReason", usability.getReasonAsString().orElse(null)); diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java index a5b2a9bfe35..2b64c317a51 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java @@ -200,22 +200,19 @@ private ResponseEntity invokeAction( final @NonNull JsonRepresentation arguments, final ActionResultReprRenderer.@NonNull SelfLink selfLink) { - var where = resourceContext.where(); - // lombok issue, needs explicit cast here - var actionInteraction = ActionInteraction.start(objectAdapter, actionId, where) + var actionInteraction = ActionInteraction.start(objectAdapter, actionId, resourceContext.visibilityConstraint()) .checkVisibility() .checkUsability(intent) .checkSemanticConstraint(semanticConstraint); var pendingArgs = actionInteraction.startParameterNegotiation().orElse(null); - if(pendingArgs==null) { - // no such action or not visible or not usable + if(pendingArgs==null) + // no such action or not visible or not usable throw InteractionFailureHandler.onFailure(actionInteraction .getInteractionVeto() .orElseGet(()->InteractionVeto.notFound(Identifier.Type.ACTION, actionId))); // unexpected code reach - } var hasParams = pendingArgs.getParamCount()>0; @@ -238,10 +235,9 @@ private ResponseEntity invokeAction( }); - if(vetoCount.intValue()>0) { - throw InteractionFailureHandler.onParameterListInvalid( + if(vetoCount.intValue()>0) + throw InteractionFailureHandler.onParameterListInvalid( InteractionVeto.actionParamInvalid("error parsing arguments"), arguments); - } var argAdapters = paramsOrVetos.map(Railway::getSuccessElseFail); pendingArgs.setParamValues(argAdapters); @@ -258,25 +254,22 @@ private ResponseEntity invokeAction( } }); - if(vetoCount.intValue()>0) { - throw InteractionFailureHandler.onParameterListInvalid( + if(vetoCount.intValue()>0) + throw InteractionFailureHandler.onParameterListInvalid( InteractionVeto.actionParamInvalid( String.format("%d argument(s) failed validation", vetoCount.intValue())), arguments); - } } var actionConsent = pendingArgs.validateParameterSetForAction(); - if(actionConsent.isVetoed()) { - throw InteractionFailureHandler.onParameterListInvalid( + if(actionConsent.isVetoed()) + throw InteractionFailureHandler.onParameterListInvalid( InteractionVeto.invalid(actionConsent), arguments); - } - if(resourceContext.isValidateOnly()) { - return ResponseEntity.noContent().build(); // do not progress any further - } + if(resourceContext.isValidateOnly()) + return ResponseEntity.noContent().build(); // do not progress any further var resultOrVeto = actionInteraction.invokeWith(pendingArgs); diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelParented.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelParented.java index 7dfc746e896..5e19a7c07b1 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelParented.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelParented.java @@ -19,6 +19,7 @@ package org.apache.causeway.viewer.wicket.model.models.coll; import org.apache.wicket.Component; +import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.layout.component.CollectionLayoutData; @@ -29,9 +30,9 @@ import org.apache.causeway.viewer.wicket.model.hints.UiHintContainer; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import lombok.Getter; -import org.jspecify.annotations.NonNull; public final class CollectionModelParented extends CollectionModelAbstract @@ -55,7 +56,7 @@ public static CollectionModelParented forParentObjectModel( .getCollectionElseFail(layoutData.getId()); // collection's member-id var bookmarkedObject = objectModel.bookmarkedObjectModel(); var tableInteractive = DataTableInteractive.forCollection( - ManagedCollection.of(bookmarkedObject.getObject(), coll, Where.NOT_SPECIFIED)); + ManagedCollection.of(bookmarkedObject.getObject(), coll, WktVisibility.visibilityConstraint(Where.NOT_SPECIFIED))); return new CollectionModelParented( bookmarkedObject, diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelStandalone.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelStandalone.java index e675c92d707..8edd013862c 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelStandalone.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/coll/CollectionModelStandalone.java @@ -18,14 +18,15 @@ */ package org.apache.causeway.viewer.wicket.model.models.coll; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.object.PackedManagedObject; import org.apache.causeway.core.metamodel.tabular.DataTableInteractive; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; - -import org.jspecify.annotations.NonNull; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; public final class CollectionModelStandalone extends CollectionModelAbstract { @@ -40,7 +41,7 @@ public static CollectionModelStandalone forActionModel( var bookmarkedObject = BookmarkedObjectWkt.ofAdapter(actionModel.getParentObject()); var tableInteractive = DataTableInteractive.forAction( - ManagedAction.of(bookmarkedObject.getObject(), actionModel.getAction(), Where.NOT_SPECIFIED), + ManagedAction.of(bookmarkedObject.getObject(), actionModel.getAction(), WktVisibility.visibilityConstraint(Where.NOT_SPECIFIED)), collectionAsAdapter); return new CollectionModelStandalone(bookmarkedObject, tableInteractive); diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/WktVisibility.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/WktVisibility.java new file mode 100644 index 00000000000..579bd1e1efd --- /dev/null +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/WktVisibility.java @@ -0,0 +1,37 @@ +/* + * 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.viewer.wicket.model.models.interaction; + +import org.apache.causeway.applib.annotation.Where; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class WktVisibility { + + // -- VISIBILITY CONSTRAINTS + + public static WhatViewer WHAT_VIEWER = new WhatViewer("Wicket"); + public static VisibilityConstraint visibilityConstraint(final Where where) { + return new VisibilityConstraint(WHAT_VIEWER, where); + } + +} diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java index 2cf1497ae99..a3abdda3707 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java @@ -23,7 +23,6 @@ import java.util.stream.Stream; import org.apache.wicket.model.ChainingModel; - import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; @@ -45,6 +44,7 @@ import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModel; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.HasBookmarkedOwnerAbstract; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; /** * The parent (container) model of multiple parameter models which implement @@ -146,25 +146,25 @@ private void setObjectAction(final ObjectAction objectAction) { @Override protected ActionInteraction load() { + var visibilityConstraint = WktVisibility.visibilityConstraint(where); + if(associatedWithParameterIfAny!=null) { final int paramIndex = associatedWithParameterIfAny.getParameterIndex(); // supports composite-value-types via mixin return ActionInteraction.startAsBoundToParameter( - associatedWithParameterIfAny.getParameterNegotiationModel(), paramIndex, memberId, where); + associatedWithParameterIfAny.getParameterNegotiationModel(), paramIndex, memberId, visibilityConstraint); } - if(associatedWithCollectionIfAny!=null) { - return ActionInteraction.startWithMultiselect(getBookmarkedOwner(), memberId, where, + if(associatedWithCollectionIfAny!=null) + return ActionInteraction.startWithMultiselect(getBookmarkedOwner(), memberId, visibilityConstraint, associatedWithCollectionIfAny.getDataTableModel()); - } - if(associatedWithPropertyIfAny!=null) { - // supports composite-value-types via mixin + if(associatedWithPropertyIfAny!=null) + // supports composite-value-types via mixin return ActionInteraction.startAsBoundToProperty( - associatedWithPropertyIfAny.getManagedProperty(), memberId, where); - } + associatedWithPropertyIfAny.getManagedProperty(), memberId, visibilityConstraint); - return ActionInteraction.start(getBookmarkedOwner(), memberId, where); + return ActionInteraction.start(getBookmarkedOwner(), memberId, visibilityConstraint); } public final ActionInteraction actionInteraction() { diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/prop/PropertyInteractionWkt.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/prop/PropertyInteractionWkt.java index 025ce157291..c315507a07e 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/prop/PropertyInteractionWkt.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/prop/PropertyInteractionWkt.java @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.HasBookmarkedOwnerAbstract; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; /** * The parent (container) model of multiple property models which implement @@ -119,7 +120,7 @@ private Optional startPropertyNegotiation() { private PropertyInteraction loadPropertyInteraction() { return PropertyInteraction.wrap( - ManagedProperty.lookupProperty(getBookmarkedOwner(), memberId, where) + ManagedProperty.lookupProperty(getBookmarkedOwner(), memberId, WktVisibility.visibilityConstraint(where)) .orElseThrow(()->_Exceptions.noSuchElement("property '%s' in %s", memberId, getBookmarkedOwner().objSpec()))); diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java index 840e9ef5a81..4c457c70414 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/parented/ParentedCollectionPanel.java @@ -35,6 +35,7 @@ import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModel; import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModelParented; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.model.util.ComponentHintKey; import org.apache.causeway.viewer.wicket.ui.components.actionlinks.entityactions.ActionLinksPanel; import org.apache.causeway.viewer.wicket.ui.components.collection.CollectionPanel; @@ -127,7 +128,7 @@ private void buildGui() { var objectAdapter = getModel().getObject(); final Consent visibility = collectionMetaModel - .isVisible(objectAdapter, InteractionInitiatedBy.USER, Where.OBJECT_FORMS); + .isVisible(objectAdapter, InteractionInitiatedBy.USER, WktVisibility.visibilityConstraint(Where.OBJECT_FORMS)); if(visibility.isAllowed()) { From e227dd6b20f8ce892f4d24a9a222e25069314de9 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 17:06:33 +0100 Subject: [PATCH 18/25] CAUSEWAY-3752: ro cleanup --- .../viewer/restfulobjects/rendering/IResourceContext.java | 8 +------- .../restfulobjects/rendering/context/ResourceContext.java | 6 ++---- .../viewer/resources/ObjectAdapterUpdateHelper.java | 4 ++-- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java index 0dfb17949d1..99e56529cc7 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java @@ -24,14 +24,12 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.core.config.CausewayConfiguration.Viewer.Restfulobjects; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.HasMetaModelContext; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; -import org.apache.causeway.viewer.restfulobjects.rendering.context.ResourceContext; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo; import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService; @@ -70,11 +68,7 @@ public interface IResourceContext extends HasMetaModelContext { */ InteractionInitiatedBy interactionInitiatedBy(); - @Deprecated - Where where(); - default VisibilityConstraint visibilityConstraint() { - return ResourceContext.visibilityConstraint(where()); - } + VisibilityConstraint visibilityConstraint(); ObjectAdapterLinkTo objectAdapterLinkTo(); List> followLinks(); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java index 3ff8753e61a..aa7289570f2 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/context/ResourceContext.java @@ -72,6 +72,7 @@ public record ResourceContext( boolean isValidateOnly, InteractionInitiatedBy interactionInitiatedBy, + VisibilityConstraint visibilityConstraint, JsonRepresentation queryStringAsJsonRepr, ObjectAdapterLinkTo objectAdapterLinkTo, @@ -118,6 +119,7 @@ private ResourceContext( Collections.unmodifiableList(arg(requestArgsAsMap, RequestParameter.FOLLOW_LINKS)), arg(requestArgsAsMap, RequestParameter.VALIDATE_ONLY), interactionInitiatedBy, + ResourceContext.visibilityConstraint(resourceDescriptor.where()), requestArgsAsMap, switch(resourceDescriptor.resourceLink()) { case NONE -> null; @@ -129,10 +131,6 @@ private ResourceContext( ensureDomainModelQueryParamSupported(); } - @Override public Where where() { - return resourceDescriptor().where(); - } - /** * Only applies to rendering of objects */ diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java index 94eaf7dff3f..062601841eb 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectAdapterUpdateHelper.java @@ -88,11 +88,11 @@ private boolean copyOverProperty( final Consent visibility = property.isVisible( objectAdapter, resourceContext.interactionInitiatedBy(), - ResourceContext.visibilityConstraint(resourceContext.where())); + resourceContext.visibilityConstraint()); final Consent usability = property.isUsable( objectAdapter, resourceContext.interactionInitiatedBy(), - ResourceContext.visibilityConstraint(resourceContext.where())); + resourceContext.visibilityConstraint()); final boolean invisible = visibility.isVetoed(); final boolean disabled = usability.isVetoed(); From b15d4d9499cb7707d86bbfb8682d520b4da22a61 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 17:17:20 +0100 Subject: [PATCH 19/25] CAUSEWAY-3752: work on removal of invalid visibility constraints (1) --- .../services/header/HeaderUiService.java | 4 +++- .../applib/services/menu/MenuUiService.java | 3 ++- .../services/menu/model/MenuAction.java | 5 +++-- .../commons/model/action/UiActionForm.java | 9 +++++---- .../header/HeaderUiServiceDefault.java | 5 +++-- .../services/menu/MenuUiServiceDefault.java | 13 +++++++------ .../services/menu/_MenuItemBuilder.java | 4 +++- .../wicket/model/models/ActionModel.java | 19 +++++++++---------- .../serviceactions/ServiceActionUtil.java | 5 +++-- .../widgets/actionlink/ActionLink.java | 7 ++++--- .../viewer/wicket/ui/panels/PanelBase.java | 3 ++- 11 files changed, 44 insertions(+), 33 deletions(-) diff --git a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiService.java b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiService.java index 1bd3315c7a1..891994f5d10 100644 --- a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiService.java +++ b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/header/HeaderUiService.java @@ -18,11 +18,13 @@ */ package org.apache.causeway.viewer.commons.applib.services.header; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; + /** * @since 2.0 {@index}} */ public interface HeaderUiService { - HeaderUiModel getHeader(); + HeaderUiModel getHeader(WhatViewer whatViewer); } diff --git a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java index 8579198cca5..b78830b8bdc 100644 --- a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java +++ b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/MenuUiService.java @@ -18,6 +18,7 @@ */ package org.apache.causeway.viewer.commons.applib.services.menu; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.viewer.commons.applib.services.menu.model.NavbarUiModel; /** @@ -25,6 +26,6 @@ */ public interface MenuUiService { - NavbarUiModel getMenu(); + NavbarUiModel getMenu(WhatViewer whatViewer); } diff --git a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java index 4bf341269b5..24d93e11a9d 100644 --- a/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java +++ b/viewers/commons/applib/src/main/java/org/apache/causeway/viewer/commons/applib/services/menu/model/MenuAction.java @@ -30,6 +30,7 @@ import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facets.members.iconfa.FaLayersProvider; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed.InteractionVeto; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -79,10 +80,10 @@ public static MenuAction of(final @NonNull ManagedAction managedAction) { DecorationModel.of(managedAction)); } - public Optional managedAction(){ + public Optional managedAction(final WhatViewer whatViewer){ var mmc = MetaModelContext.instanceElseFail(); var service = mmc.getObjectManager().debookmark(serviceBookmark); - return ManagedAction.lookupAction(service, actionId.memberLogicalName(), VisibilityConstraint.invalid(Where.NOT_SPECIFIED)); + return ManagedAction.lookupAction(service, actionId.memberLogicalName(), new VisibilityConstraint(whatViewer, Where.NOT_SPECIFIED)); } } diff --git a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java index 8e9c8d8fbb3..11ff89656e7 100644 --- a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java +++ b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/action/UiActionForm.java @@ -27,6 +27,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.Veto; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.object.MmTitleUtils; import org.apache.causeway.viewer.commons.model.UiModel; @@ -43,8 +44,8 @@ public interface UiActionForm // -- USABILITY - default Consent getUsabilityConsent() { - var visibilityConstraint = VisibilityConstraint.invalid(Where.OBJECT_FORMS); + default Consent getUsabilityConsent(final WhatViewer whatViewer) { + var visibilityConstraint = new VisibilityConstraint(whatViewer, Where.OBJECT_FORMS); return getAction().isUsable( getActionOwner(), InteractionInitiatedBy.USER, @@ -53,7 +54,7 @@ default Consent getUsabilityConsent() { // -- VISABILITY - default Consent getVisibilityConsent() { + default Consent getVisibilityConsent(final WhatViewer whatViewer) { // guard against missing action owner var actionOwner = getActionOwner(); @@ -64,7 +65,7 @@ default Consent getVisibilityConsent() { if (getActionOwner().objSpec().isHidden()) return Veto.DEFAULT; - var visibilityConstraint = VisibilityConstraint.invalid(Where.OBJECT_FORMS); + var visibilityConstraint = new VisibilityConstraint(whatViewer, Where.OBJECT_FORMS); return getAction().isVisible( actionOwner, InteractionInitiatedBy.USER, diff --git a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java index 6b5a23a4692..25825d68e9e 100644 --- a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java +++ b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/header/HeaderUiServiceDefault.java @@ -26,6 +26,7 @@ import org.springframework.stereotype.Service; import org.apache.causeway.applib.annotation.PriorityPrecedence; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.viewer.commons.applib.services.branding.BrandingUiService; import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel; import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiService; @@ -48,11 +49,11 @@ public class HeaderUiServiceDefault private final MenuUiService menuUiService; @Override - public HeaderUiModel getHeader() { + public HeaderUiModel getHeader(final WhatViewer whatViewer) { return new HeaderUiModel( brandingUiService.getHeaderBranding(), userProfileUiService.userProfile(), - menuUiService.getMenu()); + menuUiService.getMenu(whatViewer)); } } diff --git a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java index c5f60bfbfe9..15d4e439c2e 100644 --- a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java +++ b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java @@ -33,6 +33,7 @@ import org.apache.causeway.applib.services.menu.MenuBarsService; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto; import org.apache.causeway.viewer.commons.applib.services.menu.MenuUiService; import org.apache.causeway.viewer.commons.applib.services.menu.model.MenuDropdownBuilder; @@ -54,23 +55,23 @@ public class MenuUiServiceDefault private final MenuBarsService menuBarsService; @Override - public NavbarUiModel getMenu() { + public NavbarUiModel getMenu(final WhatViewer whatViewer) { return new NavbarUiModel( - buildNavBarSection(MenuBar.PRIMARY), - buildNavBarSection(MenuBar.SECONDARY), - buildNavBarSection(MenuBar.TERTIARY)); + buildNavBarSection(whatViewer, MenuBar.PRIMARY), + buildNavBarSection(whatViewer, MenuBar.SECONDARY), + buildNavBarSection(whatViewer, MenuBar.TERTIARY)); } // -- HELPER - private NavbarSection buildNavBarSection(final MenuBar menuBarSelect) { + private NavbarSection buildNavBarSection(final WhatViewer whatViewer, final MenuBar menuBarSelect) { var menuBar = (BSMenuBar) menuBarsService.menuBars() .menuBarFor(menuBarSelect); var topLevelEntries = new ArrayList(); - _MenuItemBuilder.buildMenuItems(metaModelContext, menuBar, new _MenuItemBuilder.Visitor() { + _MenuItemBuilder.buildMenuItems(metaModelContext, whatViewer, menuBar, new _MenuItemBuilder.Visitor() { private MenuDropdownBuilder currentMenu; diff --git a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java index 176ecc7fe54..9c5998dcb8b 100644 --- a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java +++ b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/_MenuItemBuilder.java @@ -30,6 +30,7 @@ import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction; import org.apache.causeway.viewer.commons.applib.services.menu.MenuItemDto; import org.apache.causeway.viewer.commons.services.userprof.UserProfileUiServiceDefault; @@ -55,6 +56,7 @@ static interface Visitor { static void buildMenuItems( final MetaModelContext mmc, + final WhatViewer whatViewer, final BSMenuBar menuBar, final Visitor menuBuilder) { @@ -80,7 +82,7 @@ static void buildMenuItems( } var managedAction = ManagedAction - .lookupAction(serviceAdapter, actionLayoutData.getId(), VisibilityConstraint.invalid(Where.EVERYWHERE)) + .lookupAction(serviceAdapter, actionLayoutData.getId(), new VisibilityConstraint(whatViewer, Where.EVERYWHERE)) .orElse(null); if (managedAction == null) { log.warn("No such action: bean-name '{}' action-id '{}'", diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java index ac8f51d2fa2..31be6707405 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/ActionModel.java @@ -40,6 +40,7 @@ import org.apache.causeway.viewer.commons.model.action.UiActionForm; import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModel; import org.apache.causeway.viewer.wicket.model.models.coll.CollectionModelParented; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.model.models.interaction.act.ActionInteractionWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.act.UiParameterWkt; import org.apache.causeway.viewer.wicket.model.util.PageParameterUtils; @@ -153,8 +154,8 @@ public static ActionModel forCollection( public static ActionModel forPropertyOrParameter( final ObjectAction action, final UiAttributeWkt attributeModel) { - return attributeModel instanceof PropertyModel - ? forProperty(action, (PropertyModel)attributeModel) + return attributeModel instanceof PropertyModel p + ? forProperty(action, p) : forParameter(action, (ParameterModel)attributeModel); } @@ -175,14 +176,13 @@ public static ActionModel forParameter( //XXX[CAUSEWAY-3080] only supported, when parameter type is a singular composite value-type var param = parameterModel.getMetaModel(); if(param.isSingular() - && param.getElementType().isCompositeValue()) { - return ActionModel.forEntity( + && param.getElementType().isCompositeValue()) + return ActionModel.forEntity( parameterModel.getParentUiModel(), action.getFeatureIdentifier(), Where.OBJECT_FORMS, ColumnActionModifier.NONE, null, parameterModel, null); - } return null; } @@ -262,11 +262,11 @@ public Optional getAssociatedParameter() { } public boolean isVisible() { - return getVisibilityConsent().isAllowed(); + return getVisibilityConsent(WktVisibility.WHAT_VIEWER).isAllowed(); } public boolean isEnabled() { - return getUsabilityConsent().isAllowed(); + return getUsabilityConsent(WktVisibility.WHAT_VIEWER).isAllowed(); } @Override @@ -309,11 +309,10 @@ public String toString() { private static void guardAgainstNotBookmarkable(final ManagedObject objectAdapter) { var isIdentifiable = ManagedObjects.isIdentifiable(objectAdapter); - if (!isIdentifiable) { - throw new IllegalArgumentException(String.format( + if (!isIdentifiable) + throw new IllegalArgumentException(String.format( "Object '%s' is not identifiable (has no identifier).", objectAdapter.getTitle())); - } } } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/serviceactions/ServiceActionUtil.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/serviceactions/ServiceActionUtil.java index d772acee3f5..eab49adbb81 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/serviceactions/ServiceActionUtil.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/serviceactions/ServiceActionUtil.java @@ -34,6 +34,7 @@ import org.apache.causeway.viewer.commons.model.decorators.ActionDecorators.ActionStyle; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.ui.components.widgets.actionlink.ActionLink; import org.apache.causeway.viewer.wicket.ui.util.Wkt; import org.apache.causeway.viewer.wicket.ui.util.WktDecorators; @@ -107,8 +108,8 @@ public void onSectionSpacer() { } @Override - public void onMenuAction(MenuAction menuAction) { - var menuItem = CssMenuItem.newMenuItemWithLink(menuAction.name(), newActionLink(menuAction.managedAction().orElseThrow())); + public void onMenuAction(final MenuAction menuAction) { + var menuItem = CssMenuItem.newMenuItemWithLink(menuAction.name(), newActionLink(menuAction.managedAction(WktVisibility.WHAT_VIEWER).orElseThrow())); currentTopLevelMenu.addSubMenuItem(menuItem); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java index 1d09eba3ade..e499cda6b3f 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/actionlink/ActionLink.java @@ -41,6 +41,7 @@ import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.ActionPromptProvider; import org.apache.causeway.viewer.wicket.model.models.ActionPromptWithExtraContent; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.model.util.PageParameterUtils; import org.apache.causeway.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; import org.apache.causeway.viewer.wicket.ui.app.registry.HasComponentFactoryRegistry; @@ -134,18 +135,18 @@ protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { public String getReasonDisabledIfAny() { // no point evaluating if not visible return isVisible() - ? getActionModel().getUsabilityConsent().getReasonAsString().orElse(null) + ? getActionModel().getUsabilityConsent(WktVisibility.WHAT_VIEWER).getReasonAsString().orElse(null) : null; } @Override public boolean isVisible() { - return getActionModel().getVisibilityConsent().isAllowed(); + return getActionModel().getVisibilityConsent(WktVisibility.WHAT_VIEWER).isAllowed(); } @Override public boolean isEnabled() { - return getActionModel().getUsabilityConsent().isAllowed(); + return getActionModel().getUsabilityConsent(WktVisibility.WHAT_VIEWER).isAllowed(); } @SuppressWarnings("deprecation") diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/PanelBase.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/PanelBase.java index bc31613afa5..9c6736cb147 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/PanelBase.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/PanelBase.java @@ -31,6 +31,7 @@ import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiService; import org.apache.causeway.viewer.wicket.model.hints.UiHintContainer; import org.apache.causeway.viewer.wicket.model.models.IconResourceReferenceFactory; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; import org.apache.causeway.viewer.wicket.ui.app.registry.HasComponentFactoryRegistry; import org.apache.causeway.viewer.wicket.ui.components.tree.themes.TreeThemeProvider; @@ -95,7 +96,7 @@ protected PageNavigationService getPageNavigationService() { private transient HeaderUiService headerUiService; protected HeaderUiModel getHeaderModel() { headerUiService = computeIfAbsent(HeaderUiService.class, headerUiService); - return headerUiService.getHeader(); + return headerUiService.getHeader(WktVisibility.WHAT_VIEWER); } // Hint support From 989aa589bd6ca9cc16c6105475762b1db3b2f93e Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 17:46:30 +0100 Subject: [PATCH 20/25] CAUSEWAY-3752: work on removal of invalid visibility constraints (2) - don't adapt tests for what-viewer yet --- .../ObjectValidPropertiesFacet.java | 3 +- .../interactions/VisibilityConstraint.java | 4 ++ .../vis/ObjectVisibilityContext.java | 5 +- .../metamodel/object/MmVisibilityUtils.java | 31 ++++------- .../metamodel/spec/feature/ObjectAction.java | 13 ++--- .../MemberExecutorServiceDefault.java | 55 +++++++++---------- .../publishing/PublishingTestFactoryJpa.java | 4 +- .../DomainObjectTesterFactory.java | 2 +- .../interaction/InteractionTestAbstract.java | 6 +- .../interact/CollectionInteractionTest.java | 2 +- .../value/PropertyInteractionProbeImpl.java | 2 +- .../object/header/ObjectHeaderPanel.java | 3 +- 12 files changed, 59 insertions(+), 71 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 92ce07058d6..8172dcbc059 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 @@ -33,8 +33,7 @@ public interface ObjectValidPropertiesFacet extends Facet, ValidatingInteraction /** * The reason the object is invalid. * - *

- * . If the object is actually valid, should return null. + *

If the object is actually valid, should return null. */ public String invalidReason(ObjectValidityContext context); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java index e301021b1d3..6562665ef1d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java @@ -24,6 +24,10 @@ public record VisibilityConstraint( WhatViewer whatViewer, Where where) { + public static VisibilityConstraint noViewer(final Where where) { + return new VisibilityConstraint(WhatViewer.noViewer(), where); + } + public VisibilityConstraint withWhere(final Where where) { return new VisibilityConstraint(whatViewer, where); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java index 1545feac004..5d7b1e5f3e2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java @@ -19,7 +19,6 @@ package org.apache.causeway.core.metamodel.interactions.vis; import org.apache.causeway.applib.Identifier; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.services.wrapper.events.ObjectVisibilityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -52,12 +51,12 @@ public record ObjectVisibilityContext( public static ObjectVisibilityContext createForRegular( final ManagedObject domainObject, final InteractionInitiatedBy initiatedBy, - final Where where) { + final VisibilityConstraint visibilityConstraint) { return new ObjectVisibilityContext( InteractionHead.regular(domainObject), domainObject.objSpec().getFeatureIdentifier(), initiatedBy, - VisibilityConstraint.invalid(where), + visibilityConstraint, RenderPolicy.forNonActionParam(domainObject)); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java index 4a27cffc8c7..e004dcf556b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java @@ -26,8 +26,8 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; import org.apache.causeway.core.metamodel.interactions.vis.ObjectVisibilityContext; -import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; import lombok.experimental.UtilityClass; @@ -90,35 +90,24 @@ public static boolean isVisible( final ManagedObject adapter, final InteractionInitiatedBy interactionInitiatedBy) { - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) { - // a choices list could include a null (eg example in ToDoItems#choices1Categorized()); want to show as "visible" + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) + // a choices list could include a null (eg example in ToDoItems#choices1Categorized()); want to show as "visible" return true; - } var spec = adapter.objSpec(); if(spec.isEntity()) { - if(MmEntityUtils.getEntityState(adapter).isTransientOrRemoved()) { - return false; - } - } - if(!interactionInitiatedBy.isUser()) { - return true; + if(MmEntityUtils.getEntityState(adapter).isTransientOrRemoved()) + return false; } - var visibilityContext = createVisibleInteractionContext( + if(!interactionInitiatedBy.isUser()) + return true; + + var visibilityContext = ObjectVisibilityContext.createForRegular( adapter, InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + VisibilityConstraint.invalid(Where.OBJECT_FORMS)); return InteractionUtils.isVisibleResult(spec, visibilityContext) .isAllowing(); } - private static VisibilityContext createVisibleInteractionContext( - final ManagedObject objectAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - - return ObjectVisibilityContext - .createForRegular(objectAdapter, interactionInitiatedBy, where); - } - } 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 bfd9d4f0dff..d8234446a58 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 @@ -50,6 +50,7 @@ import org.apache.causeway.core.metamodel.facets.object.promptStyle.PromptStyleFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed.ActionInteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; @@ -356,9 +357,10 @@ public static Optional cssClassFaFactoryFor( /** * Returns a Stream of those to be rendered with the entity header panel. + * @param whatViewer */ public static Stream streamTopBarActions( - final ManagedObject adapter) { + final ManagedObject adapter, final WhatViewer whatViewer) { var spec = adapter.objSpec(); @@ -367,7 +369,7 @@ public static Stream streamTopBarActions( .isSharingAnyLayoutGroupOf(spec.streamAssociations(MixedIn.INCLUDED)) .negate()) .filter(Predicates - .dynamicallyVisible(adapter, InteractionInitiatedBy.USER, VisibilityConstraint.invalid(Where.ANYWHERE))); + .dynamicallyVisible(adapter, InteractionInitiatedBy.USER, new VisibilityConstraint(whatViewer, Where.ANYWHERE))); } public static Stream findForAssociation( @@ -526,12 +528,9 @@ public boolean test(final ObjectAction objectAction) { private static Predicate dynamicallyVisible( final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final VisibilityConstraint visConstraint) { + final VisibilityConstraint visibilityConstraint) { - return (final ObjectAction objectAction) -> { - final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, visConstraint); - return visible.isAllowed(); - }; + return (final ObjectAction objectAction) -> objectAction.isVisible(target, interactionInitiatedBy, visibilityConstraint).isAllowed(); } } 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 616808c4ad8..427700ec4b4 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 @@ -18,10 +18,18 @@ */ package org.apache.causeway.core.runtimeservices.executor; -import static org.apache.causeway.core.metamodel.facets.members.publish.command.CommandPublishingFacet.isPublishingEnabled; - import java.util.Optional; +import jakarta.annotation.Priority; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.inject.Provider; + +import org.jspecify.annotations.NonNull; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + import org.apache.causeway.applib.annotation.PriorityPrecedence; import org.apache.causeway.applib.services.clock.ClockService; import org.apache.causeway.applib.services.command.Command; @@ -65,14 +73,9 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectMember; import org.apache.causeway.core.runtimeservices.CausewayModuleCoreRuntimeServices; import org.apache.causeway.schema.ixn.v2.ActionInvocationDto; -import org.jspecify.annotations.NonNull; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; -import jakarta.annotation.Priority; -import jakarta.inject.Inject; -import jakarta.inject.Named; -import jakarta.inject.Provider; +import static org.apache.causeway.core.metamodel.facets.members.publish.command.CommandPublishingFacet.isPublishingEnabled; + import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -139,7 +142,7 @@ private ManagedObject invokeActionInternally( final ObjectAction owningAction = actionExecutor.getOwningAction(); final InteractionHead head = actionExecutor.getHead(); - + final Can argumentAdapters = actionExecutor.getArguments(); final InteractionInitiatedBy interactionInitiatedBy = actionExecutor.getInteractionInitiatedBy(); // final MethodFacade methodFacade, @@ -275,11 +278,10 @@ private ManagedObject setOrClearPropertyInternally( // TODO: should also sync DTO's 'threw' attribute here...? var executionExceptionIfAny = priorExecution.getThrew(); - if(executionExceptionIfAny != null) { - throw executionExceptionIfAny instanceof RuntimeException - ? ((RuntimeException)executionExceptionIfAny) + if(executionExceptionIfAny != null) + throw executionExceptionIfAny instanceof RuntimeException r + ? r : new RuntimeException(executionExceptionIfAny); - } // publish (if not a contributed association, query-only mixin) if (ExecutionPublishingFacet.isPublishingEnabled(propertyModifier.getFacetHolder())) { @@ -307,17 +309,14 @@ private Object invokeMethodPassThrough( private void setCommandResultIfEntity( final Command command, final ManagedObject resultAdapter) { - if(command.getResult() != null) { - // don't trample over any existing result, eg subsequent mixins. + if(command.getResult() != null) + // don't trample over any existing result, eg subsequent mixins. return; - } - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) { - return; - } + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) + return; var entityState = resultAdapter.getEntityState(); - if(!entityState.isPersistable()) { - return; - } + if(!entityState.isPersistable()) + return; if(entityState.isHollow() || entityState.isDetached()) { // ensure that any still-to-be-persisted adapters get persisted to DB. @@ -337,14 +336,12 @@ private ManagedObject resultFilteredHonoringVisibility( final ManagedObject resultAdapter, final InteractionInitiatedBy interactionInitiatedBy) { - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) { - return resultAdapter; - } + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) + return resultAdapter; if (!getConfiguration().core().metaModel().filterVisibility() - || resultAdapter instanceof PackedManagedObject) { - return resultAdapter; - } + || resultAdapter instanceof PackedManagedObject) + return resultAdapter; return MmVisibilityUtils.isVisible(resultAdapter, interactionInitiatedBy) ? resultAdapter diff --git a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java index d6ebdba13d5..604c7dfb67f 100644 --- a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java +++ b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/publishing/PublishingTestFactoryJpa.java @@ -198,7 +198,7 @@ protected void interactionApiExecution( context.changeProperty(()->{ var bookAdapter = objectManager.adapt(book); - var propertyInteraction = PropertyInteraction.start(bookAdapter, "name", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + var propertyInteraction = PropertyInteraction.start(bookAdapter, "name", VisibilityConstraint.noViewer(Where.OBJECT_FORMS)); var managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement()); var propertyModel = managedProperty.startNegotiation(); var propertySpec = managedProperty.getElementType(); @@ -217,7 +217,7 @@ protected void interactionApiExecution( var bookAdapter = objectManager.adapt(book); - var actionInteraction = ActionInteraction.start(bookAdapter, "doubleThePrice", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + var actionInteraction = ActionInteraction.start(bookAdapter, "doubleThePrice", VisibilityConstraint.noViewer(Where.OBJECT_FORMS)); var managedAction = actionInteraction.getManagedActionElseThrow(__->_Exceptions.noSuchElement()); // this test action is always disabled, so don't enforce rules here, just invoke managedAction.invoke(Can.empty()); // no-arg action diff --git a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java index 55058075b6d..3f1f1bf5dff 100644 --- a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java +++ b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/DomainObjectTesterFactory.java @@ -1016,7 +1016,7 @@ protected MemberTester( super(domainObject); this.memberName = memberName; this.memberSort = memberSort; - this.visibilityConstraint = VisibilityConstraint.invalid(where); + this.visibilityConstraint = VisibilityConstraint.noViewer(where); } protected final MemberTester init() { diff --git a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java index 47e5a07efb6..20db1cfe08e 100644 --- a/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java +++ b/regressiontests/base/src/main/java/org/apache/causeway/testdomain/util/interaction/InteractionTestAbstract.java @@ -71,19 +71,19 @@ protected ManagedObject newViewmodel(final Class type) { protected ActionInteraction startActionInteractionOn(final Class type, final String actionId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return ActionInteraction.start(managedObject, actionId, VisibilityConstraint.invalid(where)); + return ActionInteraction.start(managedObject, actionId, VisibilityConstraint.noViewer(where)); } protected PropertyInteraction startPropertyInteractionOn(final Class type, final String propertyId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return PropertyInteraction.start(managedObject, propertyId, VisibilityConstraint.invalid(where)); + return PropertyInteraction.start(managedObject, propertyId, VisibilityConstraint.noViewer(where)); } protected CollectionInteraction startCollectionInteractionOn(final Class type, final String collectionId, final Where where) { var viewModel = factoryService.viewModel(type); var managedObject = objectManager.adapt(viewModel); - return CollectionInteraction.start(managedObject, collectionId, VisibilityConstraint.invalid(where)); + return CollectionInteraction.start(managedObject, collectionId, VisibilityConstraint.noViewer(where)); } // -- SHORTCUTS diff --git a/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java b/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java index 3c38a323774..7c4267687ae 100644 --- a/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java +++ b/regressiontests/interact/src/test/java/org/apache/causeway/testdomain/interact/CollectionInteractionTest.java @@ -114,7 +114,7 @@ void choicesFromMultiselect() { var table = tableTester.getDataTable(); var actionInteraction = table - .startAssociatedActionInteraction("doSomethingWithItems", VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + .startAssociatedActionInteraction("doSomethingWithItems", VisibilityConstraint.noViewer(Where.OBJECT_FORMS)); var actTester = testerFactory.actionTesterForSpecificInteraction(InteractionDemo.class, actionInteraction); actTester.assertVisibilityIsNotVetoed(); diff --git a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java index afe927e35bf..06f437863a8 100644 --- a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java +++ b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/PropertyInteractionProbeImpl.java @@ -104,7 +104,7 @@ public void testComposer( var spec = specLoader.specForTypeElseFail(valueMixin.getClass()); var interaction = ActionInteraction - .start(ManagedObject.mixin(spec, valueMixin), "act", VisibilityConstraint.invalid(Where.ANYWHERE)); + .start(ManagedObject.mixin(spec, valueMixin), "act", VisibilityConstraint.noViewer(Where.ANYWHERE)); var pendingParams = interaction .startParameterNegotiation() diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java index 88b94dfc32d..eb7d42c2670 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/object/header/ObjectHeaderPanel.java @@ -26,6 +26,7 @@ import org.apache.causeway.viewer.commons.model.components.UiComponentType; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.ui.ComponentFactory; import org.apache.causeway.viewer.wicket.ui.components.actionlinks.entityactions.ActionLinksPanel; import org.apache.causeway.viewer.wicket.ui.panels.PanelAbstract; @@ -72,7 +73,7 @@ private void buildEntityActionsGui() { final UiObjectWkt model = getModel(); var adapter = model.getObject(); if (adapter != null) { - var topLevelActions = ObjectAction.Util.streamTopBarActions(adapter) + var topLevelActions = ObjectAction.Util.streamTopBarActions(adapter, WktVisibility.WHAT_VIEWER) .map(act->ActionModel.forEntity(act, model)) .collect(Can.toCan()); From 11f538ca5f24b2e8c80463d14551b711b9f06adc Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sat, 6 Dec 2025 18:02:07 +0100 Subject: [PATCH 21/25] CAUSEWAY-3752: param visibility --- .../object/value/CompositeValueUpdater.java | 3 +-- .../interactions/managed/ManagedAction.java | 2 +- .../vis/ActionVisibilityContext.java | 14 +++++------ .../vis/CollectionVisibilityContext.java | 12 +++++----- .../vis/ObjectVisibilityContext.java | 12 +++++----- .../vis/ParamVisibilityContext.java | 24 +++++++++++-------- .../vis/PropertyVisibilityContext.java | 12 +++++----- .../spec/feature/HasObjectAction.java | 5 ++-- .../metamodel/spec/feature/ObjectAction.java | 2 +- .../spec/impl/ObjectActionDefault.java | 7 ++---- 10 files changed, 46 insertions(+), 47 deletions(-) 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 444eff437a3..c9047ba29ac 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 @@ -20,7 +20,6 @@ import org.apache.causeway.applib.annotation.PromptStyle; import org.apache.causeway.applib.annotation.SemanticsOf; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.commons.CanonicalInvoker; import org.apache.causeway.core.metamodel.commons.ParameterConverters; @@ -81,7 +80,7 @@ default CompositeValueUpdater overrideFacets() { } @Override default ManagedObject executeWithRuleChecking( final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy, final Where where) throws AuthorizationException { + final InteractionInitiatedBy interactionInitiatedBy, final VisibilityConstraint visibilityConstraint) throws AuthorizationException { return execute(head, parameters, interactionInitiatedBy); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java index 12b76a44ffa..8470a18115b 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java @@ -158,7 +158,7 @@ public final ManagedObject invokeWithRuleChecking( // under the hood intercepts cases, where the owner is a value-type; // executions on value-types have no rule checking and trigger no domain events .executeWithRuleChecking( - interactionHead(), actionParameters, InteractionInitiatedBy.USER, visibilityConstraint().where()); + interactionHead(), actionParameters, InteractionInitiatedBy.USER, visibilityConstraint()); return route(actionResult); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java index 437d72f3c80..54489c173ff 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ActionVisibilityContext.java @@ -35,13 +35,13 @@ * {@link ActionVisibilityEvent}. */ public record ActionVisibilityContext( - InteractionContextType interactionType, - InteractionHead head, - Identifier identifier, - InteractionInitiatedBy initiatedBy, - VisibilityConstraint visibilityConstraint, - RenderPolicy renderPolicy, - ObjectAction objectAction) + InteractionContextType interactionType, + InteractionHead head, + Identifier identifier, + InteractionInitiatedBy initiatedBy, + VisibilityConstraint visibilityConstraint, + RenderPolicy renderPolicy, + ObjectAction objectAction) implements VisibilityContext, ActionInteractionContext { public ActionVisibilityContext( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java index ae47e092d4f..cfb2c1c1a5c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/CollectionVisibilityContext.java @@ -33,12 +33,12 @@ * {@link CollectionVisibilityEvent}. */ public record CollectionVisibilityContext( - InteractionContextType interactionType, - InteractionHead head, - Identifier identifier, - InteractionInitiatedBy initiatedBy, - VisibilityConstraint visibilityConstraint, - RenderPolicy renderPolicy) + InteractionContextType interactionType, + InteractionHead head, + Identifier identifier, + InteractionInitiatedBy initiatedBy, + VisibilityConstraint visibilityConstraint, + RenderPolicy renderPolicy) implements VisibilityContext { public CollectionVisibilityContext( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java index 5d7b1e5f3e2..460c2b8df1d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/ObjectVisibilityContext.java @@ -35,12 +35,12 @@ * {@link ObjectVisibilityEvent}. */ public record ObjectVisibilityContext( - InteractionContextType interactionType, - InteractionHead head, - Identifier identifier, - InteractionInitiatedBy initiatedBy, - VisibilityConstraint visibilityConstraint, - RenderPolicy renderPolicy) + InteractionContextType interactionType, + InteractionHead head, + Identifier identifier, + InteractionInitiatedBy initiatedBy, + VisibilityConstraint visibilityConstraint, + RenderPolicy renderPolicy) implements VisibilityContext, ProposedHolder { // -- FACTORIES 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 bbf580cdd0a..31ebcf36410 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 @@ -39,15 +39,15 @@ * {@link ActionArgumentEvent}. */ public record ParamVisibilityContext( - InteractionContextType interactionType, - InteractionHead head, - Identifier identifier, - InteractionInitiatedBy initiatedBy, - VisibilityConstraint visibilityConstraint, - RenderPolicy renderPolicy, - ObjectAction objectAction, - Can args, - int position) + InteractionContextType interactionType, + InteractionHead head, + Identifier identifier, + InteractionInitiatedBy initiatedBy, + VisibilityConstraint visibilityConstraint, + RenderPolicy renderPolicy, + ObjectAction objectAction, + Can args, + int position) implements VisibilityContext, ActionInteractionContext { public ParamVisibilityContext( @@ -59,8 +59,12 @@ public ParamVisibilityContext( final InteractionInitiatedBy initiatedBy, final RenderPolicy renderPolicy) { + // assumption: param visibility is never directly constraint by WhatViewer or Where; + // instead those constraints apply only to their 'owning' actions + // 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, - head, id, initiatedBy, VisibilityConstraint.invalid(Where.OBJECT_FORMS), renderPolicy, + head, id, initiatedBy, VisibilityConstraint.noViewer(Where.ANYWHERE), renderPolicy, objectAction, args, position); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java index 7ae42f6bfae..e1aeb044ddd 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/vis/PropertyVisibilityContext.java @@ -33,12 +33,12 @@ * {@link PropertyVisibilityEvent}. */ public record PropertyVisibilityContext( - InteractionContextType interactionType, - InteractionHead head, - Identifier identifier, - InteractionInitiatedBy initiatedBy, - VisibilityConstraint visibilityConstraint, - RenderPolicy renderPolicy + InteractionContextType interactionType, + InteractionHead head, + Identifier identifier, + InteractionInitiatedBy initiatedBy, + VisibilityConstraint visibilityConstraint, + RenderPolicy renderPolicy ) implements VisibilityContext { public PropertyVisibilityContext( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java index 8eec11b0339..fe45a269212 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java @@ -25,7 +25,6 @@ import org.jspecify.annotations.NonNull; import org.apache.causeway.applib.annotation.SemanticsOf; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.collections.CanVector; import org.apache.causeway.core.metamodel.consent.Consent; @@ -130,8 +129,8 @@ default FacetHolder getFacetHolder() { return getObjectAction().hasReturn(); } @Override default ManagedObject executeWithRuleChecking(final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy, final Where where) throws AuthorizationException { - return getObjectAction().executeWithRuleChecking(head, parameters, interactionInitiatedBy, where); + final InteractionInitiatedBy interactionInitiatedBy, final VisibilityConstraint visibilityConstraint) throws AuthorizationException { + return getObjectAction().executeWithRuleChecking(head, parameters, interactionInitiatedBy, visibilityConstraint); } @Override default ManagedObject execute(final InteractionHead head, final Can parameters, final InteractionInitiatedBy interactionInitiatedBy) { 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 d8234446a58..985db5cb6e5 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 @@ -106,7 +106,7 @@ ManagedObject executeWithRuleChecking( InteractionHead head, Can parameters, InteractionInitiatedBy interactionInitiatedBy, - Where where) throws AuthorizationException; + VisibilityConstraint visibilityConstraint) throws AuthorizationException; /** * Invokes the action's method on the target object given the specified set 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 13573115286..3c6dc5b69b6 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 @@ -30,7 +30,6 @@ import org.apache.causeway.applib.annotation.Action; import org.apache.causeway.applib.annotation.ActionLayout; import org.apache.causeway.applib.annotation.SemanticsOf; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.exceptions.RecoverableException; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.applib.services.command.Command; @@ -391,13 +390,11 @@ ActionValidityContext createActionInvocationInteractionContext( // -- EXECUTE @Override - public ManagedObject executeWithRuleChecking( + public final ManagedObject executeWithRuleChecking( final InteractionHead head, final Can arguments, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - - var visibilityConstraint = VisibilityConstraint.invalid(where); + final VisibilityConstraint visibilityConstraint) { var target = head.owner(); From 320e0a0dcb04013451611bd0e2e6854f3b84bb5b Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sun, 7 Dec 2025 05:32:38 +0100 Subject: [PATCH 22/25] CAUSEWAY-3752: more work on invalid vis. contexts - flattens ObjectValidPropertiesFacetImpl --- .../ObjectValidPropertiesFacet.java | 2 +- .../ObjectValidPropertiesFacetAbstract.java | 46 ------- .../impl/ObjectValidPropertiesFacetImpl.java | 76 ++++++----- .../vis/ParamVisibilityContext.java | 2 +- .../metamodel/spec/ObjectSpecification.java | 44 +++---- .../spec/impl/ObjectSpecificationDefault.java | 118 ++++++++---------- .../DomainObjectInvocationHandler.java | 3 +- 7 files changed, 117 insertions(+), 174 deletions(-) delete mode 100644 core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/ObjectValidPropertiesFacetAbstract.java 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 * *

If the object is actually valid, should return null. */ - 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 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 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 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 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 onM private final _Lazy> elementSpecification = _Lazy.threadSafe(()->lookupFacet(TypeOfFacet.class) - .map(typeOfFacet -> typeOfFacet.elementSpec())); + .map(TypeOfFacet::elementSpec)); @Override public Optional 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 introspectionContextProvider) { + private void introspectUpTo(final IntrospectionState upTo, final Supplier 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 getAliases() { // -- ICON @Override - public Optional getIcon(final ManagedObject domainObject, ObjectSupport.IconSize iconSize) { + public Optional 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 implements Predicate interfaces() { @Override public Can 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 streamDeclaredActions( * Creates all mixed in properties and collections for this spec. */ private Stream 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 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 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); }); From a4337a1b2c068bf5e14cbc6c6fd4d7562ccebe6d Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sun, 7 Dec 2025 12:03:40 +0100 Subject: [PATCH 23/25] CAUSEWAY-3752: table cell visibility --- .../core/metamodel/tabular/DataColumn.java | 2 +- .../tabular/internal/DataColumnInternal.java | 4 +-- .../tabular/internal/DataRowInternal.java | 19 ++++------- .../metamodel/tabular/simple/DataRow.java | 34 +++++++++++++------ .../metamodel/tabular/simple/DataTable.java | 16 ++++----- .../metamodel/tabular/simple/TabularUtil.java | 12 ++----- .../DomainModelTest_usingGoodDomain.java | 22 ++++++------ .../ajaxtable/columns/PluralColumn.java | 9 +++-- 8 files changed, 59 insertions(+), 59 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataColumn.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataColumn.java index 609f99b330c..42c9ac07e74 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataColumn.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataColumn.java @@ -29,8 +29,8 @@ public interface DataColumn { * Corresponds to the association's id. */ String columnId(); + ObjectAssociation associationMetaModel(); Observable columnFriendlyNameObservable(); Observable> columnDescriptionObservable(); - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataColumnInternal.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataColumnInternal.java index 75c0278c1b4..2b9a5b82434 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataColumnInternal.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataColumnInternal.java @@ -20,13 +20,13 @@ import java.util.Optional; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.internal.binding._Observables; import org.apache.causeway.commons.internal.binding._Observables.LazyObservable; import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation; import org.apache.causeway.core.metamodel.tabular.DataColumn; -import org.jspecify.annotations.NonNull; - record DataColumnInternal( @NonNull String columnId, @NonNull ObjectAssociation associationMetaModel, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataRowInternal.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataRowInternal.java index 135220db727..747d314cb13 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataRowInternal.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/internal/DataRowInternal.java @@ -60,30 +60,22 @@ public Optional lookupColumnById(final @NonNull String columnId) { .findFirst(); } - /** - * Can be none, one or many per table cell. - */ @Override public Can getCellElementsForColumn(final @NonNull DataColumn column) { final ObjectAssociation assoc = column.associationMetaModel(); - var interactionInitiatedBy = InteractionInitiatedBy.PASS_THROUGH; - var visibilityConstraint = VisibilityConstraint.invalid(Where.ALL_TABLES); return assoc.getSpecialization().fold( property-> Can.of( // similar to ManagedProperty#reassessPropertyValue - property.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() - ? property.get(rowElement(), interactionInitiatedBy) + property.isVisible(rowElement(), InteractionInitiatedBy.USER, VISIBILITY_CONSTRAINT).isAllowed() + ? property.get(rowElement(), InteractionInitiatedBy.USER) : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( - collection.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() - ? collection.get(rowElement(), interactionInitiatedBy) + collection.isVisible(rowElement(), InteractionInitiatedBy.USER, VISIBILITY_CONSTRAINT).isAllowed() + ? collection.get(rowElement(), InteractionInitiatedBy.USER) : null )); } - /** - * Can be none, one or many per table cell. (returns empty Can if column not found) - */ @Override public Can getCellElementsForColumn(final @NonNull String columnId) { return lookupColumnById(columnId) @@ -91,4 +83,7 @@ public Can getCellElementsForColumn(final @NonNull String columnI .orElseGet(Can::empty); } + // we are always checking whether a property is visible, constraint by Where.ALL_TABLES (but not by WhatViewer) + private final static VisibilityConstraint VISIBILITY_CONSTRAINT = VisibilityConstraint.noViewer(Where.ALL_TABLES); + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java index f3765a7a522..59e103c5ec1 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataRow.java @@ -38,25 +38,37 @@ public record DataRow( /** * Can be none, one or many per table cell. + * @param column for which to get the cell elements (none, one or many) + * @param accessMode use PASS_THROUGH for faster processing, when you know, + * that you don't need the full access check processing and also can skip associated event processing */ public Can getCellElements( final @NonNull DataColumn column, - final InteractionInitiatedBy interactionInitiatedBy) { - var visibilityConstraint = VisibilityConstraint.invalid(Where.ALL_TABLES); + final DataTable.AccessMode accessMode) { + + var initiatedBy = switch(accessMode) { + case PASS_THROUGH -> InteractionInitiatedBy.PASS_THROUGH; + default -> InteractionInitiatedBy.USER; + }; + var assoc = column.metamodel(); return assoc.getSpecialization().fold( property-> Can.of( - // similar to ManagedProperty#reassessPropertyValue - interactionInitiatedBy.isPassThrough() - || property.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() - ? property.get(rowElement(), interactionInitiatedBy) - : ManagedObject.empty(property.getElementType())), + // similar to ManagedProperty#reassessPropertyValue + initiatedBy.isPassThrough() + || property.isVisible(rowElement(), InteractionInitiatedBy.USER, VISIBILITY_CONSTRAINT).isAllowed() + ? property.get(rowElement(), initiatedBy) + : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( - interactionInitiatedBy.isPassThrough() - || collection.isVisible(rowElement(), interactionInitiatedBy, visibilityConstraint).isAllowed() - ? collection.get(rowElement(), interactionInitiatedBy) - : null + initiatedBy.isPassThrough() + || collection.isVisible(rowElement(), InteractionInitiatedBy.USER, VISIBILITY_CONSTRAINT).isAllowed() + ? collection.get(rowElement(), initiatedBy) + : null )); } + // we are checking whether a property is visible, constraint by Where.ALL_TABLES (but not by WhatViewer) + // when accessMode is PASS_THROUGH, we simply assume, that the Where.ALL_TABLES constraint is already honored by previous column filtering logic. + private final static VisibilityConstraint VISIBILITY_CONSTRAINT = VisibilityConstraint.noViewer(Where.ALL_TABLES); + } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataTable.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataTable.java index 6c644477a67..902b1a174c1 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataTable.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/DataTable.java @@ -25,6 +25,7 @@ import java.util.function.Predicate; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.annotation.Where; @@ -39,7 +40,6 @@ import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.commons.internal.functions._Predicates; import org.apache.causeway.commons.tabular.TabularModel.TabularSheet; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.objectmanager.ObjectManager; @@ -50,8 +50,6 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import org.apache.causeway.core.metamodel.util.Facets; -import org.jspecify.annotations.NonNull; - /** * Represents a collection of domain objects (typically entity instances). * @@ -204,7 +202,7 @@ public DataTable withDataElementsFrom(final @Nullable DataTable otherTable) { */ public DataTable withDataElements(final @Nullable Iterable dataElements) { var newDataRows = Can.ofIterable(dataElements) - .map(domainObject->new DataRow(domainObject)); + .map(DataRow::new); return new DataTable(elementType, dataColumns, newDataRows, tableFriendlyName); } /** @@ -254,16 +252,16 @@ default void onRowLeave(final DataRow row) {} void onCell(DataColumn column, Can cellValues); } - public DataTable visit(final CellVisitor visitor) { - return visit(visitor, _Predicates.alwaysTrue()); + public DataTable visit(final CellVisitor visitor, final DataTable.AccessMode accessMode) { + return visit(visitor, accessMode, _Predicates.alwaysTrue()); } - public DataTable visit(final CellVisitor visitor, final Predicate columnFilter) { + public DataTable visit(final CellVisitor visitor, final DataTable.AccessMode accessMode, final Predicate columnFilter) { var columnsOfInterest = dataColumns().filter(columnFilter); if(columnsOfInterest.isNotEmpty()) { dataRows().forEach(row->{ visitor.onRowEnter(row); columnsOfInterest.forEach(col->{ - visitor.onCell(col, row.getCellElements(col, InteractionInitiatedBy.PASS_THROUGH)); + visitor.onCell(col, row.getCellElements(col, accessMode)); }); visitor.onRowLeave(row); }); @@ -327,7 +325,7 @@ public final static Predicate columnFilterExcludingMixins() { public final static Predicate columnFilterIncludingEnabledForSnapshot() { return (final ObjectAssociation assoc) -> _Casts.castTo(OneToOneAssociation.class, assoc) - .map(prop->prop.isIncludedWithSnapshots()) + .map(OneToOneAssociation::isIncludedWithSnapshots) .orElse(false); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/TabularUtil.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/TabularUtil.java index 46e832e580e..7ffc51f8a41 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/TabularUtil.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/simple/TabularUtil.java @@ -21,7 +21,6 @@ import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.functional.IndexedFunction; import org.apache.causeway.commons.tabular.TabularModel; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import lombok.experimental.UtilityClass; @@ -35,15 +34,10 @@ class TabularUtil { TabularModel.TabularSheet toTabularSheet( final DataTable dataTable, final DataTable.AccessMode accessMode) { - var interactionInitiatedBy = switch(accessMode) { - case PASS_THROUGH -> InteractionInitiatedBy.PASS_THROUGH; - default -> InteractionInitiatedBy.USER; - }; - var columns = dataTable.dataColumns() .map(IndexedFunction.zeroBased(TabularUtil::tabularColumn)); var rows = dataTable.dataRows() - .map(dr->tabularRow(dataTable.dataColumns(), dr, interactionInitiatedBy)); + .map(dr->tabularRow(dataTable.dataColumns(), dr, accessMode)); return new TabularModel.TabularSheet(dataTable.tableFriendlyName(), columns, rows); } @@ -59,9 +53,9 @@ private TabularModel.TabularColumn tabularColumn(final int index, final DataColu private TabularModel.TabularRow tabularRow( final Can dataColumns, final DataRow dataRow, - final InteractionInitiatedBy interactionInitiatedBy) { + final DataTable.AccessMode accessMode) { var cells = dataColumns.map(dataColumn->{ - var cellElements = dataRow.getCellElements(dataColumn, interactionInitiatedBy); + var cellElements = dataRow.getCellElements(dataColumn, accessMode); final int cardinality = cellElements.size(); final boolean forceUseTitle = !dataColumn.metamodel().getElementType().isValue(); diff --git a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java index 751096377d9..21119e82a1c 100644 --- a/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java +++ b/regressiontests/domainmodel/src/test/java/org/apache/causeway/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java @@ -25,6 +25,7 @@ import jakarta.inject.Inject; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -79,7 +80,9 @@ import org.apache.causeway.core.metamodel.spec.feature.MixedIn; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.core.metamodel.specloader.SpecificationLoader; +import org.apache.causeway.core.metamodel.specloader.validator.ValidationFailure; import org.apache.causeway.core.metamodel.tabular.simple.DataTable; +import org.apache.causeway.core.metamodel.tabular.simple.DataTable.AccessMode; import org.apache.causeway.schema.metamodel.v2.DomainClassDto; import org.apache.causeway.testdomain.conf.Configuration_headless; import org.apache.causeway.testdomain.model.good.Configuration_usingValidDomain; @@ -181,7 +184,7 @@ void goodDomain_shouldPassValidation() { fail(String.format("%d problems found:\n%s", validationFailures.size(), validationFailures.stream() - .map(validationFailure->validationFailure.message()) + .map(ValidationFailure::message) .collect(Collectors.joining("\n")))); } } @@ -337,9 +340,8 @@ void metamodelContributingMembers_shouldBeInheritable(final Class type) { void metamodelContributingActions_shouldBeUnique_whenOverridden(final Class type) { if(type.isInterface() - && type.getSuperclass()==null) { - return; // not implemented for interface that don't extend from others - } + && type.getSuperclass()==null) + return; // not implemented for interface that don't extend from others var holderSpec = specificationLoader.specForTypeElseFail(type); @@ -360,9 +362,8 @@ void metamodelContributingActions_shouldBeUnique_whenOverridden(final Class t void metamodelContributingProperties_shouldBeUnique_whenOverridden(final Class type) { if(type.isInterface() - && type.getSuperclass()==null) { - return; // not implemented for interface that don't extend from others - } + && type.getSuperclass()==null) + return; // not implemented for interface that don't extend from others var holderSpec = specificationLoader.specForTypeElseFail(type); @@ -865,8 +866,8 @@ void properMemberSupportDiscovery(final Class classUnderTest) { // hide1PlaceOrder(y): boolean = false act.assertParameterVisibility( false, // skip rule checking - arg0Visible->assertFalse(arg0Visible), - arg1Visible->assertTrue(arg1Visible)); + Assertions::assertFalse, + Assertions::assertTrue); // disable0PlaceOrder(x): String = "my disable reason-0" // disable1PlaceOrder(z): String = "my disable reason-1" @@ -1123,7 +1124,8 @@ private String tableToString(final DataTable dataTable) { dataTable.visit((column, cellValues) -> sb.append(String.format("%s: %s\n", column.columnFriendlyName(), - "" + cellValues.getFirstElseFail().getPojo()))); + "" + cellValues.getFirstElseFail().getPojo())), + AccessMode.PASS_THROUGH); return sb.toString(); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/PluralColumn.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/PluralColumn.java index 693998ffc5e..adc963f96d0 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/PluralColumn.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/collection/present/ajaxtable/columns/PluralColumn.java @@ -57,13 +57,13 @@ public PluralColumn( final ObjectSpecification elementType, final CollectionModel.Variant collectionVariant, final IModel columnNameModel, - final String propertyId, + final String collectioId, final String parentTypeName, final Optional describedAs, final RenderOptions opts) { super(elementType, collectionVariant, columnNameModel, Optional.empty(), // empty sortProperty (hence never sortable) - propertyId, parentTypeName, describedAs); + collectioId, parentTypeName, describedAs); this.opts = opts; } @@ -74,12 +74,11 @@ protected Component createCellComponent(final String componentId, final DataRowW var cellElements = dataRow.getCellElementsForColumn(dataColumn); // if empty, render the 'empty' badge or blank based on RenderOptions - if(cellElements.isEmpty()) { - return Wkt.markup(componentId, + if(cellElements.isEmpty()) + return Wkt.markup(componentId, opts.isRenderEmptyBadge() ? getPlaceholderRenderService().asHtml(PlaceholderLiteral.NULL_REPRESENTATION) : ""); - } var container = new RepeatingView(componentId); cellElements.stream() From 61ae46cd605092fb5f86cf69cbb33745e12b49f3 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sun, 7 Dec 2025 12:32:09 +0100 Subject: [PATCH 24/25] CAUSEWAY-3752: minor: javadoc --- .../metamodel/object/MmVisibilityUtils.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java index e004dcf556b..a92ac88d7a6 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java @@ -82,27 +82,27 @@ public static Object visiblePojosAutofit( } /** - * @param adapter - wrapper of domain object whose visibility is being checked, + * @param mo - wrapper of domain object whose visibility is being checked, * must not be a mixin * @param interactionInitiatedBy */ public static boolean isVisible( - final ManagedObject adapter, + final ManagedObject mo, final InteractionInitiatedBy interactionInitiatedBy) { - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(mo)) // a choices list could include a null (eg example in ToDoItems#choices1Categorized()); want to show as "visible" return true; - var spec = adapter.objSpec(); - if(spec.isEntity()) { - if(MmEntityUtils.getEntityState(adapter).isTransientOrRemoved()) - return false; - } + var spec = mo.objSpec(); + if(spec.isEntity() + && MmEntityUtils.getEntityState(mo).isTransientOrRemoved()) + return false; + if(!interactionInitiatedBy.isUser()) return true; var visibilityContext = ObjectVisibilityContext.createForRegular( - adapter, + mo, InteractionInitiatedBy.USER, VisibilityConstraint.invalid(Where.OBJECT_FORMS)); From 607d9119371b27012499d7d05073bfab25d82bc9 Mon Sep 17 00:00:00 2001 From: andi-huber Date: Sun, 7 Dec 2025 13:02:20 +0100 Subject: [PATCH 25/25] CAUSEWAY-3752: working on object visibility (1) --- .../metamodel/execution/ActionExecutor.java | 21 +++++++---- .../execution/MemberExecutorService.java | 8 ++-- .../invocation/ActionInvocationFacet.java | 4 +- .../ActionInvocationFacetForAction.java | 6 ++- ...onFacetForMixedInPropertyOrCollection.java | 6 ++- .../object/value/CompositeValueUpdater.java | 9 +++-- .../PropertyAccessorFacetViaAccessor.java | 3 +- .../interactions/VisibilityConstraint.java | 8 ---- .../interactions/managed/ManagedAction.java | 2 +- .../metamodel/object/MmVisibilityUtils.java | 8 ++-- .../spec/feature/HasObjectAction.java | 5 ++- .../metamodel/spec/feature/ObjectAction.java | 3 +- .../spec/impl/ObjectActionDefault.java | 13 ++++--- .../spec/impl/ObjectActionMixedIn.java | 7 +++- .../impl/OneToManyAssociationMixedIn.java | 8 ++-- .../spec/impl/OneToOneAssociationMixedIn.java | 8 ++-- .../CommandExecutorServiceDefault.java | 37 ++++++++----------- .../MemberExecutorServiceDefault.java | 8 ++-- .../DomainObjectInvocationHandler.java | 2 +- .../value/ValueSemanticsTester.java | 6 +-- .../viewer/commons/model/object/UiObject.java | 5 ++- .../rich/mutation/RichMutationForAction.java | 2 +- .../rich/query/RichActionInvokeResult.java | 2 +- .../mutation/SimpleMutationForAction.java | 2 +- .../domain/simple/query/SimpleAction.java | 2 +- .../wicket/ui/pages/obj/DomainObjectPage.java | 20 +++++----- 26 files changed, 109 insertions(+), 96 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 c8363fc6bbf..2aba4eea9d8 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 @@ -23,6 +23,8 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.applib.events.domain.AbstractDomainEvent; import org.apache.causeway.applib.events.domain.ActionDomainEvent; import org.apache.causeway.applib.services.bookmark.Bookmark; @@ -42,6 +44,7 @@ import org.apache.causeway.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetAbstract; import org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.object.MmUnwrapUtils; @@ -52,9 +55,9 @@ import static org.apache.causeway.commons.internal.base._Casts.uncheckedCast; import lombok.Getter; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.experimental.Accessors; @RequiredArgsConstructor //@Slf4j @@ -68,6 +71,7 @@ public final class ActionExecutor public static ActionExecutor forAction( final @NonNull FacetHolder facetHolder, final @NonNull InteractionInitiatedBy interactionInitiatedBy, + final @NonNull WhatViewer whatViewer, final @NonNull InteractionHead head, final @NonNull Can argumentAdapters, final @NonNull ObjectAction owningAction, @@ -77,15 +81,14 @@ public static ActionExecutor forAction( "action's parameter count and provided argument count must match"); // guard against malformed argumentAdapters - argumentAdapters.forEach(arg->{if(!ManagedObjects.isSpecified(arg)) { - throw _Exceptions.illegalArgument("arguments must be specified for action %s", owningAction); - }}); + argumentAdapters.forEach(arg->{if(!ManagedObjects.isSpecified(arg)) + throw _Exceptions.illegalArgument("arguments must be specified for action %s", owningAction);}); var method = actionInvocationFacetAbstract.methods().getFirstElseFail(); return new ActionExecutor( owningAction.getMetaModelContext(), facetHolder, - interactionInitiatedBy, owningAction, method, head, argumentAdapters, actionInvocationFacetAbstract); + interactionInitiatedBy, whatViewer, owningAction, method, head, argumentAdapters, actionInvocationFacetAbstract); } // -- CONSTRUCTION @@ -97,6 +100,9 @@ public static ActionExecutor forAction( private final @NonNull FacetHolder facetHolder; @Getter private final @NonNull InteractionInitiatedBy interactionInitiatedBy; + @Getter @Accessors(fluent = true) + private final @NonNull WhatViewer whatViewer; + @Getter private final @NonNull ObjectAction owningAction; @Getter @@ -225,9 +231,8 @@ private Object invokeMethodElseFromCache( ()->CanonicalInvoker.invoke(method, targetPojo, executionParameters), targetPojo.getClass(), method.getName(), targetPojoPlusExecutionParameters); - } else { - return CanonicalInvoker.invoke(method, targetPojo, executionParameters); - } + } else + return CanonicalInvoker.invoke(method, targetPojo, executionParameters); } private static Can updateArguments( diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/MemberExecutorService.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/MemberExecutorService.java index 03a5534d839..1e98e91ad61 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/MemberExecutorService.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/execution/MemberExecutorService.java @@ -20,6 +20,8 @@ import java.util.Optional; +import org.jspecify.annotations.NonNull; + import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -30,12 +32,11 @@ import org.apache.causeway.core.metamodel.facets.properties.update.clear.PropertyClearFacet; import org.apache.causeway.core.metamodel.facets.properties.update.modify.PropertySetterFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; -import org.jspecify.annotations.NonNull; - /** * Used by ActionInvocationFacets and PropertySetterOrClearFacets to submit their executions. *

@@ -70,6 +71,7 @@ default InteractionInternal getInteractionElseFail() { default ManagedObject invokeAction( final @NonNull FacetHolder facetHolder, final @NonNull InteractionInitiatedBy interactionInitiatedBy, + final @NonNull WhatViewer whatViewer, final @NonNull InteractionHead head, // action specifics final @NonNull Can argumentAdapters, @@ -78,7 +80,7 @@ default ManagedObject invokeAction( var actionExecutor = ActionExecutor.forAction( facetHolder, interactionInitiatedBy, - head, + whatViewer, head, argumentAdapters, owningAction, actionInvocationFacetAbstract); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java index 9b058f37926..c56ff501108 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacet.java @@ -22,6 +22,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -39,7 +40,8 @@ ManagedObject invoke( ObjectAction owningAction, InteractionHead head, Can argumentAdapters, - InteractionInitiatedBy interactionInitiatedBy); + InteractionInitiatedBy interactionInitiatedBy, + WhatViewer whatViewer); ObjectSpecification getReturnType(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForAction.java index 91abed72ce2..1b07c32348d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForAction.java @@ -25,6 +25,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.DomainEventHolder; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -51,10 +52,11 @@ public ManagedObject invoke( final ObjectAction owningAction, final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { return memberExecutorService.invokeAction(facetHolder(), interactionInitiatedBy, - head, argumentAdapters, owningAction, this); + whatViewer, head, argumentAdapters, owningAction, this); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForMixedInPropertyOrCollection.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForMixedInPropertyOrCollection.java index 95cdea4e04b..7799d89bfdb 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForMixedInPropertyOrCollection.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForMixedInPropertyOrCollection.java @@ -28,6 +28,7 @@ import org.apache.causeway.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacet; import org.apache.causeway.core.metamodel.facets.properties.property.modify.PropertyDomainEventFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -61,9 +62,10 @@ public ManagedObject invoke( final ObjectAction owningAction, final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { return memberExecutorService.invokeAction(facetHolder(), interactionInitiatedBy, - head, argumentAdapters, owningAction, this); + whatViewer, head, argumentAdapters, owningAction, this); } } 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 c9047ba29ac..3a3c69c1bb4 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 @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.facets.object.value.CompositeValueUpdater.CompositeValueUpdaterForProperty; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -75,13 +76,15 @@ default CompositeValueUpdater overrideFacets() { @Override default ManagedObject execute( final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { return map(simpleExecute(head, parameters)); } @Override default ManagedObject executeWithRuleChecking( final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy, final VisibilityConstraint visibilityConstraint) throws AuthorizationException { - return execute(head, parameters, interactionInitiatedBy); + final InteractionInitiatedBy interactionInitiatedBy, + final VisibilityConstraint visibilityConstraint) throws AuthorizationException { + return execute(head, parameters, interactionInitiatedBy, visibilityConstraint.whatViewer()); } // -- IMPLEMENTATIONS diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java index dbf5b053d8a..54a3469e800 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/accessor/PropertyAccessorFacetViaAccessor.java @@ -29,6 +29,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.ImperativeFacet; import org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacetAbstract; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmInvokeUtils; import org.apache.causeway.core.metamodel.object.MmVisibilityUtils; @@ -69,7 +70,7 @@ public Object getAssociationValueAsPojo( if(isConfiguredToFilterForVisibility()) { final ManagedObject referencedAdapter = getObjectManager().adapt(referencedObject); final boolean visible = MmVisibilityUtils - .isVisible(referencedAdapter, interactionInitiatedBy); + .isVisible(referencedAdapter, interactionInitiatedBy, WhatViewer.invalid()); if (!visible) return null; } return referencedObject; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java index 6562665ef1d..ebda1a73edc 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/VisibilityConstraint.java @@ -32,12 +32,4 @@ public VisibilityConstraint withWhere(final Where where) { return new VisibilityConstraint(whatViewer, where); } - /** - * temporary for refactoring - */ - @Deprecated - public static VisibilityConstraint invalid(final Where where) { - return new VisibilityConstraint(WhatViewer.invalid(), where); - } - } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java index 8470a18115b..1931fb43080 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ManagedAction.java @@ -140,7 +140,7 @@ public Railway invoke( final ManagedObject actionResult = getAction() // under the hood intercepts cases, where the owner is a value-type; // executions on value-types have no rule checking and trigger no domain events - .execute(interactionHead(), actionParameters, interactionInitiatedBy); + .execute(interactionHead(), actionParameters, interactionInitiatedBy, visibilityConstraint().whatViewer()); return Railway.success(route(actionResult)); } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java index a92ac88d7a6..7d63f1135d8 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java @@ -27,6 +27,7 @@ import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.vis.ObjectVisibilityContext; import lombok.experimental.UtilityClass; @@ -35,7 +36,7 @@ public final class MmVisibilityUtils { public static Predicate filterOn(final InteractionInitiatedBy interactionInitiatedBy) { - return $->MmVisibilityUtils.isVisible($, interactionInitiatedBy); + return $->MmVisibilityUtils.isVisible($, interactionInitiatedBy, WhatViewer.invalid()); } /** @@ -88,7 +89,8 @@ public static Object visiblePojosAutofit( */ public static boolean isVisible( final ManagedObject mo, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { if(ManagedObjects.isNullOrUnspecifiedOrEmpty(mo)) // a choices list could include a null (eg example in ToDoItems#choices1Categorized()); want to show as "visible" @@ -104,7 +106,7 @@ public static boolean isVisible( var visibilityContext = ObjectVisibilityContext.createForRegular( mo, InteractionInitiatedBy.USER, - VisibilityConstraint.invalid(Where.OBJECT_FORMS)); + new VisibilityConstraint(whatViewer, Where.OBJECT_FORMS)); return InteractionUtils.isVisibleResult(spec, visibilityContext) .isAllowing(); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java index fe45a269212..d301ce18af7 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ActionScope; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -133,8 +134,8 @@ default FacetHolder getFacetHolder() { return getObjectAction().executeWithRuleChecking(head, parameters, interactionInitiatedBy, visibilityConstraint); } @Override default ManagedObject execute(final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy) { - return getObjectAction().execute(head, parameters, interactionInitiatedBy); + final InteractionInitiatedBy interactionInitiatedBy, final WhatViewer whatViewer) { + return getObjectAction().execute(head, parameters, interactionInitiatedBy, whatViewer); } @Override default Consent isArgumentSetValid(final InteractionHead head, final Can proposedArguments, final InteractionInitiatedBy interactionInitiatedBy) { 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 985db5cb6e5..cb52e9d0b8c 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 @@ -119,7 +119,8 @@ ManagedObject executeWithRuleChecking( ManagedObject execute( InteractionHead head, Can parameters, - InteractionInitiatedBy interactionInitiatedBy); + InteractionInitiatedBy interactionInitiatedBy, + WhatViewer whatViewer); // -- isArgumentSetValid, isArgumentSetValidForParameters, isArgumentSetValidForAction 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 3c6dc5b69b6..df4278d9a92 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 @@ -54,6 +54,7 @@ import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; import org.apache.causeway.core.metamodel.interactions.VisibilityConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.use.ActionUsabilityContext; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; import org.apache.causeway.core.metamodel.interactions.val.ActionValidityContext; @@ -413,7 +414,7 @@ public final ManagedObject executeWithRuleChecking( if(validity.isVetoed()) throw new RecoverableException(validity.getReasonAsString().orElse("no reason given")); - return execute(head, arguments, interactionInitiatedBy); + return execute(head, arguments, interactionInitiatedBy, visibilityConstraint.whatViewer()); } /** @@ -424,7 +425,8 @@ public final ManagedObject executeWithRuleChecking( public ManagedObject execute( final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { _Assert.assertEquals(this.getParameterCount(), argumentAdapters.size(), "action's parameter count and provided argument count must match"); @@ -446,7 +448,7 @@ public ManagedObject execute( } } - return this.executeInternal(head, argumentAdapters, interactionInitiatedBy); + return this.executeInternal(head, argumentAdapters, interactionInitiatedBy, whatViewer); } /** @@ -455,10 +457,11 @@ public ManagedObject execute( protected ManagedObject executeInternal( final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { var actionInvocationFacet = getFacet(ActionInvocationFacet.class); return actionInvocationFacet - .invoke(this, head, argumentAdapters, interactionInitiatedBy); + .invoke(this, head, argumentAdapters, interactionInitiatedBy, whatViewer); } protected Optional getActionInvocationFacet() { 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 d878bd98e1c..ad20a0a7d4b 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 @@ -36,6 +36,7 @@ import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacetForStaticMemberName; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.spec.feature.MixedInAction; @@ -154,7 +155,8 @@ protected ManagedObject mixinAdapterFor(final ManagedObject mixeeAdapter) { public ManagedObject execute( final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { final ManagedObject owner = head.owner(); final ManagedObject target = mixinAdapterFor(mixinSpec, owner); @@ -178,7 +180,8 @@ public ManagedObject execute( return mixinAction.executeInternal( head, argumentAdapters, - interactionInitiatedBy); + interactionInitiatedBy, + whatViewer); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationMixedIn.java index 3d1a98f03be..54e0d890f71 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationMixedIn.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToManyAssociationMixedIn.java @@ -34,6 +34,7 @@ import org.apache.causeway.core.metamodel.facets.members.disabled.DisabledFacetForContributee; import org.apache.causeway.core.metamodel.facets.properties.update.SnapshotExcludeFacetFromImmutableMember; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.services.publishing.ExecutionPublisher; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -131,9 +132,8 @@ protected InteractionHead headFor(final ManagedObject mixedInAdapter) { private DisabledFacet disabledFacet() { final DisabledFacet originalFacet = facetHolder.getFacet(DisabledFacet.class); if( originalFacet != null && - originalFacet.where().isAlways()) { - return originalFacet; - } + originalFacet.where().isAlways()) + return originalFacet; // ensure that the contributed association is always disabled return new DisabledFacetForContributee(VetoReason.mixedinCollection(), this); } @@ -145,7 +145,7 @@ public ManagedObject get( return executionPublisher().withPublishingSuppressed( () -> mixinAction.executeInternal( - headFor(ownerAdapter), Can.empty(), interactionInitiatedBy)); + headFor(ownerAdapter), Can.empty(), interactionInitiatedBy, WhatViewer.invalid())); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationMixedIn.java index bd6a030883c..06d7e82527c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationMixedIn.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/OneToOneAssociationMixedIn.java @@ -31,6 +31,7 @@ import org.apache.causeway.core.metamodel.facets.members.disabled.DisabledFacet; import org.apache.causeway.core.metamodel.facets.members.disabled.DisabledFacetForContributee; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.services.publishing.ExecutionPublisher; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -112,9 +113,8 @@ protected InteractionHead headFor(final ManagedObject mixeeAdapter) { private DisabledFacet disabledFacet() { final DisabledFacet originalFacet = facetHolder.getFacet(DisabledFacet.class); if( originalFacet != null && - originalFacet.where().isAlways()) { - return originalFacet; - } + originalFacet.where().isAlways()) + return originalFacet; // ensure that the contributed association is always disabled return new DisabledFacetForContributee(VetoReason.mixedinProperty(), this); } @@ -127,7 +127,7 @@ public ManagedObject get( var head = headFor(mixedInAdapter); return executionPublisher().withPublishingSuppressed( - () -> mixinAction.executeInternal(head, Can.empty(), interactionInitiatedBy) + () -> mixinAction.executeInternal(head, Can.empty(), interactionInitiatedBy, WhatViewer.invalid()) ); } diff --git a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java index 7bb3af9c740..a21fa54a1b4 100644 --- a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java +++ b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java @@ -50,6 +50,7 @@ import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.core.metamodel.commons.UtilStr; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.services.publishing.CommandPublisher; @@ -149,10 +150,9 @@ private Try doExecute( Try result = transactionService.callWithinCurrentTransactionElseCreateNew( () -> { - if (interactionContextPolicy == InteractionContextPolicy.NO_SWITCH) { - // short-circuit + if (interactionContextPolicy == InteractionContextPolicy.NO_SWITCH) + // short-circuit return doExecuteCommand(dto); - } return sudoService.call( context -> interactionContextPolicy.mapper.apply(context, dto), () -> doExecuteCommand(dto)); @@ -199,7 +199,7 @@ private Bookmark doExecuteCommand(final CommandDto dto) { var interactionHead = objectAction.interactionHead(targetAdapter); - var resultAdapter = objectAction.execute(interactionHead, argAdapters, InteractionInitiatedBy.FRAMEWORK); + var resultAdapter = objectAction.execute(interactionHead, argAdapters, InteractionInitiatedBy.FRAMEWORK, WhatViewer.noViewer()); // flush any PersistenceCommands pending // (else might get transient objects for the return value) @@ -213,10 +213,9 @@ private Bookmark doExecuteCommand(final CommandDto dto) { // Object unused = priorExecution.getReturned(); // - if(resultAdapter != null) { - return ManagedObjects.bookmark(resultAdapter) + if(resultAdapter != null) + return ManagedObjects.bookmark(resultAdapter) .orElse(null); - } } else { var propertyDto = (PropertyDto) memberDto; @@ -226,10 +225,9 @@ private Bookmark doExecuteCommand(final CommandDto dto) { var targetAdapter = valueMarshaller.recoverReferenceFrom(targetOidDto); - if(ManagedObjects.isNullOrUnspecifiedOrEmpty(targetAdapter)) { - throw _Exceptions.unrecoverable("cannot recreate ManagedObject from bookmark %s", + if(ManagedObjects.isNullOrUnspecifiedOrEmpty(targetAdapter)) + throw _Exceptions.unrecoverable("cannot recreate ManagedObject from bookmark %s", Bookmark.forOidDto(targetOidDto)); - } var property = findOneToOneAssociation(targetAdapter, logicalMemberIdentifier); var newValueAdapter = valueMarshaller.recoverPropertyFrom(propertyDto); @@ -249,12 +247,9 @@ private String targetBookmarkStrFor(final CommandDto dto) { private String argStrFor(final CommandDto dto) { var memberDto = dto.getMember(); - if(memberDto instanceof ActionDto) { - var actionDto = (ActionDto) memberDto; - return paramNameArgValuesFor(actionDto); - } - if(memberDto instanceof PropertyDto) { - var propertyDto = (PropertyDto) memberDto; + if(memberDto instanceof ActionDto actionDto) + return paramNameArgValuesFor(actionDto); + if(memberDto instanceof PropertyDto propertyDto) { var proposedValue = valueMarshaller.recoverPropertyFrom(propertyDto); return proposedValue.getTitle(); } @@ -274,9 +269,8 @@ private static ObjectAction findObjectAction( var localActionId = localPartOf(logicalMemberIdentifier); var objectAction = findActionElseNull(objectSpecification, localActionId); - if(objectAction == null) { - throw new RuntimeException(String.format("Unknown action '%s'", localActionId)); - } + if(objectAction == null) + throw new RuntimeException(String.format("Unknown action '%s'", localActionId)); return objectAction; } @@ -292,9 +286,8 @@ private static OneToOneAssociation findOneToOneAssociation( var objectSpecification = targetAdapter.objSpec(); var property = findOneToOneAssociationElseNull(objectSpecification, localPropertyId); - if(property == null) { - throw new RuntimeException(String.format("Unknown property '%s'", localPropertyId)); - } + if(property == null) + throw new RuntimeException(String.format("Unknown property '%s'", localPropertyId)); return property; } 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 427700ec4b4..4589ff3604a 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 @@ -57,6 +57,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacet; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.object.MmEntityUtils; @@ -216,7 +217,7 @@ private ManagedObject invokeActionInternally( executionPublisher().publishActionInvocation(priorExecution); } - var result = resultFilteredHonoringVisibility(returnedAdapter, interactionInitiatedBy); + var result = resultFilteredHonoringVisibility(returnedAdapter, interactionInitiatedBy, actionExecutor.whatViewer()); _Xray.exitInvocation(xrayHandle); return result; } @@ -334,7 +335,8 @@ private void setCommandResultIfEntity( private ManagedObject resultFilteredHonoringVisibility( final ManagedObject resultAdapter, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionInitiatedBy interactionInitiatedBy, + final WhatViewer whatViewer) { if(ManagedObjects.isNullOrUnspecifiedOrEmpty(resultAdapter)) return resultAdapter; @@ -343,7 +345,7 @@ private ManagedObject resultFilteredHonoringVisibility( || resultAdapter instanceof PackedManagedObject) return resultAdapter; - return MmVisibilityUtils.isVisible(resultAdapter, interactionInitiatedBy) + return MmVisibilityUtils.isVisible(resultAdapter, interactionInitiatedBy, whatViewer) ? resultAdapter : null; } 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 fad1f3d6ee8..d410811c297 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 @@ -394,7 +394,7 @@ private Object handleActionMethod( .forAction(head, objectAction, argAdapters)); return runExecutionTask(wrapperInvocation, ()->{ - var returnedAdapter = objectAction.execute(head, argAdapters, iConstraint.initiatedBy()); + var returnedAdapter = objectAction.execute(head, argAdapters, iConstraint.initiatedBy(), iConstraint.whatViewer()); return MmUnwrapUtils.single(returnedAdapter); }, ()->new ExceptionLogger("action " + objectAction.getId(), targetAdapter)); } diff --git a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java index d51c5598bee..6599fa1725a 100644 --- a/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java +++ b/regressiontests/value/src/test/java/org/apache/causeway/testdomain/value/ValueSemanticsTester.java @@ -93,7 +93,7 @@ public void actionInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var actInteraction = ActionInteraction - .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); + .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.noViewer(Where.OBJECT_FORMS))); var params = actInteraction.startParameterNegotiation().orElseThrow(); var singleArgPojoToUse = actionArgumentProvider.get(); @@ -113,7 +113,7 @@ public void actionInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var actInteraction = ActionInteraction - .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); + .wrap(ManagedAction.of(ManagedObject.adaptSingular(objSpec, domainObject), act, VisibilityConstraint.noViewer(Where.OBJECT_FORMS))); var params = actInteraction.startParameterNegotiation().orElseThrow(); @@ -201,7 +201,7 @@ public void propertyInteraction( var command = interactionService.currentInteractionElseFail().getCommand(); var propInteraction = PropertyInteraction - .wrap(ManagedProperty.of(ManagedObject.adaptSingular(objSpec, domainObject), prop, VisibilityConstraint.invalid(Where.OBJECT_FORMS))); + .wrap(ManagedProperty.of(ManagedObject.adaptSingular(objSpec, domainObject), prop, VisibilityConstraint.noViewer(Where.OBJECT_FORMS))); propInteraction.modifyProperty(managedProp-> ManagedObject.adaptSingular(managedProp.getElementType(), newProperyValueProvider.apply(managedProp))); diff --git a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/object/UiObject.java b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/object/UiObject.java index 1533c42c609..fd091ac9f24 100644 --- a/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/object/UiObject.java +++ b/viewers/commons/model/src/main/java/org/apache/causeway/viewer/commons/model/object/UiObject.java @@ -19,6 +19,7 @@ package org.apache.causeway.viewer.commons.model.object; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmVisibilityUtils; import org.apache.causeway.viewer.commons.model.UiModel; @@ -27,9 +28,9 @@ public interface UiObject extends UiModel { ManagedObject getManagedObject(); - default boolean isVisible() { + default boolean isVisible(final WhatViewer whatViewer) { return MmVisibilityUtils - .isVisible(getManagedObject(), InteractionInitiatedBy.USER); + .isVisible(getManagedObject(), InteractionInitiatedBy.USER, whatViewer); } } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java index 02e6387fc5c..5b2c2909190 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java @@ -183,7 +183,7 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment if (validityConsent.isVetoed()) throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER, visibilityConstraint.whatViewer()); return resultManagedObject.getPojo(); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java index 527d8ab8328..7dcd831e99c 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeResult.java @@ -127,7 +127,7 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment if (validityConsent.isVetoed()) throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER, visibilityConstraint.whatViewer()); return resultManagedObject.getPojo(); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java index 0886c3ea46f..608c7997cfc 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java @@ -182,7 +182,7 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment if (validityConsent.isVetoed()) throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER, visibilityConstraint.whatViewer()); return resultManagedObject.getPojo(); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java index 7b185341783..1b49b4f318b 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java @@ -315,7 +315,7 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment if (validityConsent.isVetoed()) throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER, visibilityConstraint.whatViewer()); return resultManagedObject.getPojo(); } diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/obj/DomainObjectPage.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/obj/DomainObjectPage.java index c64c154addf..20193db03cd 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/obj/DomainObjectPage.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/pages/obj/DomainObjectPage.java @@ -45,6 +45,7 @@ import org.apache.causeway.viewer.commons.model.components.UiComponentType; import org.apache.causeway.viewer.wicket.model.hints.UiHintContainer; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; +import org.apache.causeway.viewer.wicket.model.models.interaction.WktVisibility; import org.apache.causeway.viewer.wicket.model.util.PageParameterUtils; import org.apache.causeway.viewer.wicket.model.util.PageUtils; import org.apache.causeway.viewer.wicket.model.whereAmI.WhereAmI; @@ -85,9 +86,8 @@ public class DomainObjectPage extends PageAbstract { */ public static DomainObjectPage forPageParameters(final PageParameters pageParameters) { var bookmark = PageParameterUtils.toBookmark(pageParameters); - if(!bookmark.isPresent()) { - throw new RestartResponseException(Application.get().getHomePage()); - } + if(!bookmark.isPresent()) + throw new RestartResponseException(Application.get().getHomePage()); return new DomainObjectPage( pageParameters, UiObjectWkt.ofPageParameters(pageParameters)); @@ -143,9 +143,8 @@ private void buildPage() { } // check that the entity overall can be viewed. - if(!model.isVisible()) { - throw new ObjectMember.AuthorizationException(); - } + if(!model.isVisible(WktVisibility.WHAT_VIEWER)) + throw new ObjectMember.AuthorizationException(); var objectSpec = model.getTypeOfSpecification(); @@ -209,7 +208,7 @@ protected void onDetach() { super.onDetach(); model.detach(); } - + // -- REFRESH ENTITIES @Override @@ -217,7 +216,7 @@ public void onNewRequestCycle() { var mo = model.getObject(); if(!PageUtils.isAjax()) { //CAUSEWAY-3944: on normal page request, make sure entities are in sync with the db before rendering - ManagedObjects.refreshEntity(mo); + ManagedObjects.refreshEntity(mo); } ManagedObjects.refreshViewmodel(mo, ()->PageParameterUtils @@ -245,9 +244,8 @@ private void onRenderingOrRendered( final Can pageRenderSubscribers, final BiFunction handler) { - if(pageRenderSubscribers.isEmpty()) { - return; - } + if(pageRenderSubscribers.isEmpty()) + return; // guard against unspecified ManagedObjects.asSpecified(model.getObject())