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..9aa952af2d1 --- /dev/null +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/appfeat/ApplicationFeatureFilter.java @@ -0,0 +1,41 @@ +/* + * 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}. + * + *

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 { + + /** + * Whether to include given {@link ApplicationFeature}. + */ + boolean filter(ApplicationFeature feature); + +} 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..7dc3d5edcd6 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; @@ -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/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/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/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/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/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/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 51% 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 ff3f1ef9dd6..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 @@ -19,31 +19,46 @@ package org.apache.causeway.core.metamodel.facets.actions.action.prototype; import java.util.Optional; -import java.util.function.Supplier; +import java.util.function.BiConsumer; 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.HiddenFacetForDeploymentType; +import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; -public class PrototypeFacetForActionAnnotation -extends PrototypeFacetAbstract { +public record HiddenFacetForDeploymentTypeViaActionAnnotation( + DeploymentType deploymentType, + FacetHolder facetHolder + ) 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(holder, lazyDeploymentType.get())); - + .map(Action::restrictTo) + .filter(restrictTo -> restrictTo == RestrictTo.PROTOTYPING) + .map(restrictTo -> new HiddenFacetForDeploymentTypeViaActionAnnotation(deploymentType, holder)); } - private PrototypeFacetForActionAnnotation(final FacetHolder holder, final DeploymentType deploymentType) { - super(holder, deploymentType); - } + @Override public Class facetType() { return HiddenFacetForDeploymentType.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) { + 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 89% 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 cab8fd3ba3a..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 @@ -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 HiddenFacetForDeploymentType extends HidingInteractionAdvisor { } 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/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/ApplicationFeatureFilters.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/ApplicationFeatureFilters.java new file mode 100644 index 00000000000..447c7edb6e8 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/ApplicationFeatureFilters.java @@ -0,0 +1,91 @@ +/* + * 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 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)); + } + + // -- + +// boolean filter(ApplicationFeature feature) { +// +// } + +} 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..4521b0da5b7 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterFactory.java @@ -0,0 +1,62 @@ +/* + * 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 java.util.Optional; + +import jakarta.inject.Inject; + +import org.apache.causeway.commons.internal.ioc.SpringContextHolder; +import org.apache.causeway.core.metamodel.context.MetaModelContext; +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 { + + private final ApplicationFeatureFilters applicationFeatureFilters; + + @Inject + public HiddenFacetForFeatureFilterFactory(final MetaModelContext mmc) { + super(mmc, FeatureType.EVERYTHING_BUT_PARAMETERS); + var springContext = Optional.ofNullable(mmc.getSystemEnvironment().springContextHolder()) + .map(SpringContextHolder::springContext) + .orElse(null); + this.applicationFeatureFilters = ApplicationFeatureFilters.collectFrom(springContext); + } + + @Override + public void process(final ProcessClassContext processClassContext) { + var facetHolder = processClassContext.getFacetHolder(); + //TODO WIP FacetUtil.addFacet(new HiddenFacetForFeatureFilterImpl(facetHolder)); + } + + @Override + public void process(final 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/members/hidden/method/HideForContextFacetNone.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java similarity index 67% rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/hidden/method/HideForContextFacetNone.java rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/hide/HiddenFacetForFeatureFilterImpl.java index b151fe944c6..aebbc38fb67 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/all/hide/HiddenFacetForFeatureFilterImpl.java @@ -16,24 +16,22 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.causeway.core.metamodel.facets.members.hidden.method; +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 class HideForContextFacetNone -extends HideForContextFacetAbstract { - - public HideForContextFacetNone(final FacetHolder holder) { - super(holder, Precedence.FALLBACK); - } - - /** - * Always returns null. - */ +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 ic) { - return null; + public String hides(final VisibilityContext vc) { + return null; } } 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 73% 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 ce145305973..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,37 +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 { - 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) { - 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/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/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 81% 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 c3a0fc53ece..85645c0f965 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,13 +50,13 @@ public HiddenFacetAbstract( } // to instantiate contributed facets - private HiddenFacetAbstract(final HiddenFacetAbstract toplevelFacet) { + private HiddenFacetForLayoutAbstract(final HiddenFacetForLayoutAbstract toplevelFacet) { super(type(), toplevelFacet.facetHolder(), toplevelFacet.where()); } @Override - public String hides(final VisibilityContext ic) { - return hiddenReason(ic.target(), ic.where()); + public final String hides(final VisibilityContext ic) { + return hiddenReason(ic.target(), ic.iConstraint().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/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 79% 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 84b495b703e..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 @@ -18,18 +18,16 @@ */ 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; /** - * 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 Facet, 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 70% 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 89b26eae214..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 @@ -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 HiddenFacetForMemberViaMethod( + Can methods, + FacetHolder facetHolder + ) implements HiddenFacetForMember, ImperativeFacet { + + @Override public Class facetType() { return HiddenFacetForMember.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override public Intent intent() { return Intent.CHECK_IF_HIDDEN;} -public class HideForContextFacetViaMethod -extends HideForContextFacetAbstract -implements ImperativeFacet { + public Can getMethods() { return methods(); } - @Getter(onMethod_ = {@Override}) private final @NonNull Can 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; + public HiddenFacetForMemberViaMethod(final ResolvedMethod method, final FacetHolder holder) { + 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); + HiddenFacetForMember.super.visitAttributes(visitor); ImperativeFacet.visitAttributes(this, visitor); } + + @Override + public String toString() { + return FacetUtil.toString(this); + } } 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/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/navigation/NavigationFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/members/navigation/HiddenFacetForNavigation.java similarity index 83% 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 10fc0cc1643..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,13 +18,12 @@ */ 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.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 Facet, 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/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/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 75% 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 f05d8e798ed..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 @@ -18,6 +18,11 @@ */ package org.apache.causeway.core.metamodel.facets.object.hidden; -public interface HiddenTypeFacet extends HiddenInstanceFacet { +import org.apache.causeway.core.metamodel.interactions.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/HiddenTypeFacetFromAuthorizationFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedFactory.java similarity index 84% 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 e501f314430..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 @@ -28,21 +28,21 @@ 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 +public class HiddenFacetForNoMembersAuthorizedFactory extends FacetFactoryAbstract { @Inject - public HiddenTypeFacetFromAuthorizationFactory(final MetaModelContext mmc) { + public HiddenFacetForNoMembersAuthorizedFactory(final MetaModelContext mmc) { super(mmc, FeatureType.OBJECTS_ONLY); } @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/HiddenTypeFacetFromAuthorization.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForNoMembersAuthorizedImpl.java similarity index 91% 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 3245f2a36f5..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,19 +25,12 @@ 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 Precedence precedence() { - return Precedence.HIGH; // facet has final say, don't override; - } + @Override public Class facetType() { return HiddenFacetForNoMembersAuthorized.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/HiddenObjectFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenFacetForObject.java similarity index 86% 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 217a021e1b7..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 @@ -19,10 +19,11 @@ package org.apache.causeway.core.metamodel.facets.object.hidden; 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 HiddenInstanceFacet { +public interface HiddenFacetForObject extends HidingInteractionAdvisor { /** * Copy this facet to another {@link FacetHolder}. @@ -31,6 +32,6 @@ public interface HiddenObjectFacet extends HiddenInstanceFacet { * {@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/HiddenInstanceFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.java deleted file mode 100644 index 2243cb6948c..00000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/HiddenInstanceFacet.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.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; - -/** - * 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 Facet, HidingInteractionAdvisor { - -} 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/method/HiddenObjectFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/hidden/method/HiddenFacetForObjectViaMethod.java similarity index 58% 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 0b3b36ebb7e..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 @@ -24,36 +24,30 @@ 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.facets.object.hidden.HiddenFacetForObject; 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 HiddenFacetForObjectViaMethod( + ImperativeAspect imperativeAspect, + FacetHolder facetHolder + ) implements HiddenFacetForObject, 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 HiddenFacetForObjectViaMethod(imperativeAspect, holder)); + } + + @Override public Class facetType() { return HiddenFacetForObject.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT;} @Override public String hides(final VisibilityContext ic) { @@ -62,19 +56,21 @@ public String hides(final VisibilityContext ic) { } @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); + public HiddenFacetForObjectViaMethod copyTo(final FacetHolder holder) { + return new HiddenFacetForObjectViaMethod(imperativeAspect, holder); } @Override public void visitAttributes(final BiConsumer visitor) { - super.visitAttributes(visitor); + HiddenFacetForObject.super.visitAttributes(visitor); imperativeAspect.visitAttributes(visitor); } + + // -- HELPER + + private String hiddenReason(final ManagedObject target) { + final boolean isHidden = imperativeAspect.eval(target, false); + return isHidden ? "Hidden" : null; + } + } 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/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/objectvalidprops/impl/ObjectValidPropertiesFacetImpl.java index 086d41fd642..1cabdaf197e 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 @@ -18,7 +18,6 @@ */ package org.apache.causeway.core.metamodel.facets.object.objectvalidprops.impl; -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.val.ObjectValidityContext; @@ -28,13 +27,6 @@ public class ObjectValidPropertiesFacetImpl extends ObjectValidPropertiesFacetAbstract { - // 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; - public ObjectValidPropertiesFacetImpl(final FacetHolder holder) { super(holder); } @@ -46,20 +38,19 @@ public String invalidReason( final ManagedObject adapter = context.target(); 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.iConstraint()).isVetoed()) // ignore hidden properties + .filter(property->property.isUsable(adapter, context.iConstraint()).isVetoed()) // ignore disabled properties .forEach(property->{ - final ManagedObject value = property.get(adapter, context.initiatedBy()); - if (property.isAssociationValid(adapter, value, context.initiatedBy()).isVetoed()) { + final ManagedObject value = property.get(adapter, context.iConstraint().initiatedBy()); + if (property.isAssociationValid(adapter, value, context.iConstraint()).isVetoed()) { if (buf.length() > 0) { buf.append(", "); } 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/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/object/value/CompositeValueUpdater.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/value/CompositeValueUpdater.java index f9d30c19c3a..da5cf046e84 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,19 +20,18 @@ 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; import org.apache.causeway.core.metamodel.consent.Allow; import org.apache.causeway.core.metamodel.consent.Consent; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence; import org.apache.causeway.core.metamodel.facetapi.FacetUtil; import org.apache.causeway.core.metamodel.facets.HasFacetedMethod; import org.apache.causeway.core.metamodel.facets.object.promptStyle.PromptStyleFacet; 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.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; @@ -68,20 +67,20 @@ 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 InteractionConstraint iConstraint) { return Allow.DEFAULT; } + @Override default Consent isUsable(final ManagedObject a, final InteractionConstraint iConstraint) { return Allow.DEFAULT; } @Override default PromptStyle getPromptStyle() { return PromptStyle.INLINE_AS_IF_EDIT; } @Override default SemanticsOf getSemantics() { return SemanticsOf.SAFE; } @Override default ManagedObject execute( final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return map(simpleExecute(head, parameters)); } @Override default ManagedObject executeWithRuleChecking( final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy, final Where where) throws AuthorizationException { - return execute(head, parameters, interactionInitiatedBy); + final InteractionConstraint iConstraint) throws AuthorizationException { + return execute(head, parameters, iConstraint); } // -- IMPLEMENTATIONS 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/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/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/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/ActionParameterHiddenFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/hide/HiddenFacetForActionParameter.java similarity index 91% 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 9def2099734..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 @@ -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; @@ -31,8 +30,8 @@ * In the standard Apache Causeway Programming Model, corresponds to invoking the * hideNXxx support method for an action. */ -public interface ActionParameterHiddenFacet -extends Facet, HidingInteractionAdvisor { +public interface HiddenFacetForActionParameter +extends HidingInteractionAdvisor { /** * Whether the parameter is hidden. 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 63% 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 1b042af9ba6..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 @@ -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,40 @@ 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.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; -import lombok.Getter; -import org.jspecify.annotations.NonNull; - -public class ActionParameterHiddenFacetViaMethod -extends ActionParameterHiddenFacetAbstract -implements ImperativeFacet { +public record HiddenFacetForActionParameterViaMethod( + Can methods, + Optional patConstructor, + FacetHolder facetHolder + ) implements HiddenFacetForActionParameter, ImperativeFacet { + + @Override public Class facetType() { return HiddenFacetForActionParameter.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } + @Override public Intent intent() { return Intent.CHECK_IF_VALID;} - @Getter(onMethod_ = {@Override}) private final @NonNull Can methods; - private final @NonNull Optional patConstructor; - - public ActionParameterHiddenFacetViaMethod( + public HiddenFacetForActionParameterViaMethod( 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 @@ -74,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) { - 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/property/modify/PropertyDomainEventFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacet.java index c13cb9df11d..18afb5e8042 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacet.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/modify/PropertyDomainEventFacet.java @@ -176,11 +176,9 @@ public String invalidates(final ValidityContext ic) { if(!isPostable()) return null; // bale out // if this is a mixin, then this ain't true. - if(!(ic instanceof ProposedHolder)) return null; + if(!(ic instanceof final ProposedHolder ph)) return null; - final ProposedHolder ph = (ProposedHolder) ic; - - final Object oldValue = getterFacetIfAny.getAssociationValueAsPojo(ic.target(), ic.initiatedBy()); + final Object oldValue = getterFacetIfAny.getAssociationValueAsPojo(ic.target(), ic.iConstraint().initiatedBy()); final ManagedObject proposedAdapter = ph.proposed(); final Object proposedValue = proposedAdapter != null ? proposedAdapter.getPojo() : null; @@ -192,9 +190,8 @@ public String invalidates(final ValidityContext ic) { oldValue, proposedValue); if (event != null && event.isInvalid()) { final TranslatableString reasonTranslatable = event.getInvalidityReasonTranslatable(); - if(reasonTranslatable != null) { - return reasonTranslatable.translate(translationService, translationContext); - } + if(reasonTranslatable != null) + return reasonTranslatable.translate(translationService, translationContext); return event.getInvalidityReason(); } 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/DisablingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/DisablingInteractionAdvisor.java index c7f2440c20c..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,7 +21,8 @@ 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.consent.InteractionAdvisor; +import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.interactions.use.UsabilityContext; /** @@ -32,7 +33,7 @@ * @see HidingInteractionAdvisor */ public interface DisablingInteractionAdvisor -extends InteractionAdvisorFacet, DisablingOrEnabling { +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 37ec3e6e4ed..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 @@ -18,18 +18,33 @@ */ package org.apache.causeway.core.metamodel.interactions; -import org.apache.causeway.core.metamodel.facetapi.FacetWithAttributes.HidingOrShowing; +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.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; /** - * 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 HiddenFacetForLayout + * @see HiddenFacetForObject + * @see HiddenFacetForNoMembersAuthorized * @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 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/InteractionConstraint.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionConstraint.java new file mode 100644 index 00000000000..a6c20e82612 --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/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.metamodel.interactions; + +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/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..44e5ca52f32 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,10 +19,8 @@ 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; import org.apache.causeway.core.metamodel.facetapi.Facet; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -71,10 +69,13 @@ public interface InteractionContext { */ InteractionContextType interactionType(); + /** + * Which viewer.
+ * Where the element is to be rendered.
* How the interaction was initiated. */ - InteractionInitiatedBy initiatedBy(); + InteractionConstraint iConstraint(); /** * The identifier of the object or member that this interaction is being @@ -93,11 +94,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/InteractionUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/InteractionUtils.java index d88b2f462a9..f78ecaed2c8 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 /** @@ -166,14 +157,12 @@ 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 + if(ic.iConstraint().initiatedBy().isPassThrough() + && 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; } @@ -181,25 +170,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/ValidatingInteractionAdvisor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/ValidatingInteractionAdvisor.java index 469505eeab3..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,8 +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.facetapi.FacetWithAttributes.Validating; import org.apache.causeway.core.metamodel.interactions.val.ValidityContext; /** @@ -33,7 +33,8 @@ * @see DisablingInteractionAdvisor * @see HidingInteractionAdvisor */ -public interface ValidatingInteractionAdvisor extends InteractionAdvisorFacet, Validating { +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/interactions/WhatViewer.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/WhatViewer.java new file mode 100644 index 00000000000..73e8c94dcca --- /dev/null +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/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.metamodel.interactions; + +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/interactions/acc/ObjectTitleContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/acc/ObjectTitleContext.java index 089a80f6db3..8f25f929c1d 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/acc/ObjectTitleContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/acc/ObjectTitleContext.java @@ -23,8 +23,10 @@ import org.apache.causeway.applib.services.wrapper.events.ObjectTitleEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; 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.MmUnwrapUtils; @@ -36,8 +38,7 @@ public record ObjectTitleContext( InteractionContextType interactionType, Identifier identifier, InteractionHead head, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, String title) implements AccessContext { @@ -46,9 +47,9 @@ public ObjectTitleContext( final Identifier identifier, final String title, final InteractionInitiatedBy initiatedBy) { - this(InteractionContextType.OBJECT_TITLE, - identifier, InteractionHead.regular(targetAdapter), initiatedBy, Where.NOT_SPECIFIED, + identifier, InteractionHead.regular(targetAdapter), + new InteractionConstraint(WhatViewer.noViewer(), initiatedBy, Where.NOT_SPECIFIED), title); } 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..9bb92d294b5 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.InteractionConstraint; 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 InteractionConstraint iConstraint) { + return startWithMultiselect(owner, memberId, iConstraint, Can::empty); } public static ActionInteraction startWithMultiselect( final @NonNull ManagedObject owner, final @NonNull String actionId, - final @NonNull Where where, + final @NonNull InteractionConstraint iConstraint, final @NonNull MultiselectChoices multiselectChoices) { - var managedAction = ManagedAction.lookupActionWithMultiselect(owner, actionId, where, multiselectChoices); + var managedAction = ManagedAction.lookupActionWithMultiselect(owner, actionId, iConstraint, 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 InteractionConstraint iConstraint) { 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(), iConstraint); return ActionInteraction.wrap(managedAction); } } // fallback if not a composite value - return ActionInteraction.start(propertyOwner, memberId, where); + return ActionInteraction.start(propertyOwner, memberId, iConstraint); } /** 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 InteractionConstraint iConstraint) { 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(), iConstraint); return ActionInteraction.wrap(managedAction); } } // else if not a composite value - return ActionInteraction.start(actionOwner, memberId, where); + return ActionInteraction.start(actionOwner, memberId, iConstraint); } 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..371f187c6d5 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.InteractionConstraint; 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 InteractionConstraint iConstraint) { - var managedCollection = ManagedCollection.lookupCollection(owner, memberId, where); + var managedCollection = ManagedCollection.lookupCollection(owner, memberId, iConstraint); 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..416273e3d05 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; @@ -35,6 +34,7 @@ import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; @@ -55,27 +55,26 @@ 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 InteractionConstraint iConstraint) { + return new ManagedAction(owner, action, iConstraint, Can::empty); } public static final Optional lookupAction( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { + final @NonNull InteractionConstraint iConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.ACTION, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(objectAction -> of(owner, objectAction, iConstraint)); } public static final Optional lookupActionWithMultiselect( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where, + final @NonNull InteractionConstraint iConstraint, 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, iConstraint, multiselectChoices)); } // -- IMPLEMENTATION @@ -86,10 +85,10 @@ public static final Optional lookupActionWithMultiselect( private ManagedAction( final @NonNull ManagedObject owner, final @NonNull ObjectAction action, - final @NonNull Where where, + final @NonNull InteractionConstraint iConstraint, final @NonNull MultiselectChoices multiselectChoices) { - super(owner, where); + super(owner, iConstraint); /* 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 @@ -136,11 +135,10 @@ public Identifier.Type getMemberType() { public Railway invoke( final @NonNull Can actionParameters, final @NonNull InteractionInitiatedBy interactionInitiatedBy) { - 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, iConstraint()); return Railway.success(route(actionResult)); } @@ -153,12 +151,11 @@ public Railway invoke( @SneakyThrows public final ManagedObject invokeWithRuleChecking( final @NonNull Can actionParameters) throws AuthorizationException { - 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 .executeWithRuleChecking( - interactionHead(), actionParameters, InteractionInitiatedBy.USER, getWhere()); + interactionHead(), actionParameters, iConstraint()); return route(actionResult); } @@ -167,9 +164,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..dbd5515e152 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.InteractionConstraint; 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,16 @@ 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 InteractionConstraint iConstraint) { + return new ManagedCollection(owner, collection, iConstraint); } public static final Optional lookupCollection( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { - + final @NonNull InteractionConstraint iConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.COLLECTION, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(coll -> of(owner, coll, iConstraint)); } // -- IMPLEMENTATION @@ -61,9 +61,8 @@ public static final Optional lookupCollection( private ManagedCollection( final @NonNull ManagedObject owner, final @NonNull OneToManyAssociation collection, - final @NonNull Where where) { - - super(owner, where); + final @NonNull InteractionConstraint iConstraint) { + super(owner, iConstraint); this.collection = collection; } @@ -90,11 +89,10 @@ public ManagedObject getCollectionValue() { /** * If visibility is vetoed, returns an empty Stream. - * @param interactionInitiatedBy * @return Stream of this collection's element values as to be used by the UI for representation */ - public Stream streamElements(final InteractionInitiatedBy interactionInitiatedBy) { - var valueAdapter = getCollection().get(getOwner(), interactionInitiatedBy); + public Stream streamElements(final InteractionInitiatedBy initiatedBy) { + var valueAdapter = getCollection().get(getOwner(), initiatedBy); return CollectionFacet.streamAdapters(valueAdapter); } 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..d573c56c726 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,9 @@ 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.InteractionConstraint; 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 +33,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -58,8 +58,7 @@ public enum RepresentationMode { } @Getter @NonNull private ManagedObject owner; - - @Getter @NonNull private final Where where; + @Getter @Accessors(fluent = true) @NonNull private final InteractionConstraint iConstraint; /** * Allows a managed property of a view model to replace its owner with a clone. @@ -110,47 +109,32 @@ public Optional getDescription() { * @return non-empty if hidden */ public Optional checkVisibility() { - try { - var visibilityConsent = - getMetaModel() - .isVisible(getOwner(), InteractionInitiatedBy.USER, where); - + var visibilityConsent = getMetaModel() + .isVisible(getOwner(), iConstraint); return visibilityConsent.isVetoed() - ? Optional.of(InteractionVeto.hidden(visibilityConsent)) - : Optional.empty(); - + ? Optional.of(InteractionVeto.hidden(visibilityConsent)) + : Optional.empty(); } catch (final Exception ex) { - log.warn(ex.getLocalizedMessage(), ex); return Optional.of(InteractionVeto.hidden(new Veto("failure during visibility evaluation"))); - } - } /** * @return non-empty if not usable/editable (meaning if read-only) */ public Optional checkUsability() { - try { - - var usabilityConsent = - getMetaModel() - .isUsable(getOwner(), InteractionInitiatedBy.USER, where); - + var usabilityConsent = getMetaModel() + .isUsable(getOwner(), iConstraint); return usabilityConsent.isVetoed() - ? Optional.of(InteractionVeto.readonly(usabilityConsent)) - : Optional.empty(); - + ? Optional.of(InteractionVeto.readonly(usabilityConsent)) + : Optional.empty(); } catch (final Exception ex) { - log.warn(ex.getLocalizedMessage(), ex); return Optional.of(InteractionVeto.readonly(new Veto("failure during usability evaluation"))); - } - } protected static Optional lookup( 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..09c4fe52edb 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.InteractionConstraint; 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,33 +47,27 @@ 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 InteractionConstraint iConstraint) { + return new ManagedProperty(owner, property, iConstraint); } public static final Optional lookupProperty( final @NonNull ManagedObject owner, final @NonNull String memberId, - final @NonNull Where where) { - + final @NonNull InteractionConstraint iConstraint) { return ManagedMember.lookup(owner.objSpec(), Identifier.Type.PROPERTY, memberId) - .map(objectAction -> of(owner, objectAction, where)); + .map(prop -> of(owner, prop, iConstraint)); } // -- IMPLEMENTATION @Getter private final OneToOneAssociation property; - //XXX suggestion: instead of holding the 'owner' object, let it hold a supplier of the 'owner' object, - //such that the supplier always returns the actual owner evaluated lazily without memoization. - //Such a change would better support eg. - //org.apache.causeway.viewer.wicket.model.models.ScalarPropertyModel.getManagedProperty() - //Or as an alternative use a memento instead of the ManagedObject. private ManagedProperty( final @NonNull ManagedObject owner, final @NonNull OneToOneAssociation property, - final @NonNull Where where) { - super(owner, where); + final @NonNull InteractionConstraint iConstraint) { + super(owner, iConstraint); this.property = property; observablePropValue = _Observables.lazy(this::reassessPropertyValue); } @@ -97,17 +91,13 @@ public Can getAssociatedActions() { public Optional checkValidity(final ManagedObject proposedNewValue) { try { var validityConsent = - property.isAssociationValid(getOwner(), proposedNewValue, InteractionInitiatedBy.USER); - + property.isAssociationValid(getOwner(), proposedNewValue, iConstraint()); return validityConsent.isVetoed() - ? Optional.of(InteractionVeto.invalid(validityConsent)) - : Optional.empty(); - + ? Optional.of(InteractionVeto.invalid(validityConsent)) + : Optional.empty(); } catch (final Exception ex) { - log.warn(ex.getLocalizedMessage(), ex); return Optional.of(InteractionVeto.invalid(new Veto("failure during validity evaluation"))); - } } @@ -132,9 +122,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, iConstraint().withInitiatedBy(InteractionInitiatedBy.FRAMEWORK)).isAllowed() //TODO strange API + && property.isVisible(owner, iConstraint()).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/ParameterNegotiationModel.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java index 6a9d0286ea3..41a067c03d5 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/ParameterNegotiationModel.java @@ -28,6 +28,7 @@ import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.Identifier; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.commons.binding.Bindable; import org.apache.causeway.commons.binding.Observable; import org.apache.causeway.commons.collections.Can; @@ -41,7 +42,9 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.consent.InteractionResult; import org.apache.causeway.core.metamodel.consent.Veto; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.managed._BindingUtil.TargetFormat; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.ManagedObjects; @@ -182,11 +185,12 @@ public Observable getObservableParamValidation(final int paramNr) { */ public String validateImmediately(final int paramIndex) { var actionInteractionHead = actionInteractionHead(); + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); return actionInteractionHead.getMetaModel().getParameterByIndex(paramIndex) .isValid( actionInteractionHead.interactionHead(), getParamValues(), - InteractionInitiatedBy.USER) + iConstraint) .getReasonAsString() .orElse(null); } @@ -220,16 +224,19 @@ public MultiselectChoices getMultiselectChoices() { /** validates all, the action and each individual parameter */ public Consent validateParameterSet() { - return act().isArgumentSetValid(interactionHead(), this.getParamValues(), InteractionInitiatedBy.USER); + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); + return act().isArgumentSetValid(interactionHead(), this.getParamValues(), iConstraint); } public Consent validateParameterSetForAction() { - return act().isArgumentSetValidForAction(interactionHead(), this.getParamValues(), InteractionInitiatedBy.USER); + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); + return act().isArgumentSetValidForAction(interactionHead(), this.getParamValues(), iConstraint); } public Can validateParameterSetForParameters() { + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); return act() - .isArgumentSetValidForParameters(interactionHead(), this.getParamValues(), InteractionInitiatedBy.USER) + .isArgumentSetValidForParameters(interactionHead(), this.getParamValues(), iConstraint) .stream() .map(InteractionResult::createConsent) .collect(Can.toCan()); @@ -411,16 +418,18 @@ private ParameterModel( bindableParamValueDirtyFlag().setValue(true); // set dirty whenever an update event happens }); + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); + // has either autoComplete, choices, or none this.observableParamChoices = metaModel().hasAutoComplete() ? _Observables.lazy(()-> metaModel().getAutoComplete( negotiationModel(), bindableParamSearchArgument().getValue(), - InteractionInitiatedBy.USER)) + iConstraint.initiatedBy())) : metaModel().hasChoices() ? _Observables.lazy(()-> - getMetaModel().getChoices(negotiationModel(), InteractionInitiatedBy.USER)) + getMetaModel().getChoices(negotiationModel(), iConstraint.initiatedBy())) : _Observables.lazy(Can::empty); // if has autoComplete, then activate the search argument @@ -436,16 +445,18 @@ private ParameterModel( ? negotiationModel().validateImmediately(paramIndex) : (String)null); + + this.observableVisibilityConsent = _Observables.lazy(()-> metaModel().isVisible( negotiationModel().interactionHead(), negotiationModel().getParamValues(), - InteractionInitiatedBy.USER)); + iConstraint)); this.observableUsabilityConsent = _Observables.lazy(()-> metaModel().isUsable( negotiationModel().interactionHead(), negotiationModel().getParamValues(), - InteractionInitiatedBy.USER)); + iConstraint)); // value types should have associated rederers via value semantics this.observableParamAsTitle = _BindingUtil @@ -538,10 +549,12 @@ public Observable> getChoices() { @Override public Optional checkUsability(@NonNull final Can params) { + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); + try { var usabilityConsent = getMetaModel() - .isUsable(negotiationModel().interactionHead(), params, InteractionInitiatedBy.USER); + .isUsable(negotiationModel().interactionHead(), params, iConstraint); return usabilityConsent.isVetoed() ? Optional.of(InteractionVeto.readonly(usabilityConsent)) 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..d02d34a68a9 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.InteractionConstraint; 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 InteractionConstraint iConstraint) { - var managedProperty = ManagedProperty.lookupProperty(owner, memberId, where); + var managedProperty = ManagedProperty.lookupProperty(owner, memberId, iConstraint); 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 6780cbff485..b4464a0575e 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,11 +19,10 @@ 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; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -39,8 +38,7 @@ public record ActionUsabilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy, ObjectAction objectAction ) @@ -50,12 +48,9 @@ public ActionUsabilityContext( final InteractionHead head, final ObjectAction objectAction, final Identifier id, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { - this(InteractionContextType.ACTION_USABLE, - head, id, initiatedBy, where, renderPolicy, - objectAction); + this(InteractionContextType.ACTION_USABLE, head, id, iConstraint, renderPolicy, objectAction); } @Override @@ -66,6 +61,7 @@ public ActionUsabilityEvent createInteractionEvent() { @Override public ActionVisibilityContext asVisibilityContext() { return new ActionVisibilityContext(head(), objectAction(), identifier(), - initiatedBy(), where(), renderPolicy()); + iConstraint, 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..4246dcf59f5 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,10 +19,9 @@ 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; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -36,19 +35,17 @@ public record CollectionUsabilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy) implements UsabilityContext { public CollectionUsabilityContext( final InteractionHead head, final Identifier identifier, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.COLLECTION_USABLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, iConstraint, renderPolicy); } @Override @@ -59,6 +56,6 @@ public CollectionUsabilityEvent createInteractionEvent() { @Override public CollectionVisibilityContext asVisibilityContext() { return new CollectionVisibilityContext(head(), identifier(), - initiatedBy(), where(), renderPolicy()); + iConstraint(), 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..3b7ed73d764 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,13 +19,12 @@ 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; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -42,8 +41,7 @@ public record ParamUsabilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy, ObjectAction objectAction, Can args, @@ -56,11 +54,11 @@ public ParamUsabilityContext( final Identifier id, final Can args, final int position, - final InteractionInitiatedBy initiatedBy, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_PARAMETER_USABLE, - head, id, initiatedBy, Where.OBJECT_FORMS, renderPolicy, + head, id, iConstraint, renderPolicy, objectAction, args, position); } @@ -76,7 +74,7 @@ public ActionArgumentUsabilityEvent createInteractionEvent() { @Override public ParamVisibilityContext asVisibilityContext() { return new ParamVisibilityContext(head(), objectAction(), identifier(), - args, position, initiatedBy(), renderPolicy()); + args, position, iConstraint, 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..4e0d79e80a3 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,10 +19,9 @@ 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; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -37,19 +36,17 @@ public record PropertyUsabilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy) implements UsabilityContext { public PropertyUsabilityContext( final InteractionHead head, final Identifier identifier, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.PROPERTY_USABLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, iConstraint, renderPolicy); } @Override @@ -60,6 +57,6 @@ public PropertyUsabilityEvent createInteractionEvent() { @Override public PropertyVisibilityContext asVisibilityContext() { return new PropertyVisibilityContext(head(), identifier(), - initiatedBy(), where(), renderPolicy()); + iConstraint(), renderPolicy()); } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ActionValidityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ActionValidityContext.java index 70ef933bf6b..e160fc2f516 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ActionValidityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ActionValidityContext.java @@ -24,8 +24,8 @@ import org.apache.causeway.applib.services.wrapper.events.ActionInvocationEvent; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -41,7 +41,7 @@ public record ActionValidityContext( InteractionHead head, Identifier identifier, Supplier friendlyNameProvider, - InteractionInitiatedBy initiatedBy, + InteractionConstraint iConstraint, ObjectAction objectAction, Can args ) implements ValidityContext, ActionInteractionContext { @@ -51,11 +51,10 @@ public ActionValidityContext( final ObjectAction objectAction, final Identifier id, final Can args, - final InteractionInitiatedBy initiatedBy) { + final InteractionConstraint iConstraint) { this(InteractionContextType.ACTION_INVOKE, - head, id, ()->objectAction.getFriendlyName(head::target), initiatedBy, - objectAction, args); + head, id, ()->objectAction.getFriendlyName(head::target), iConstraint, objectAction, args); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ObjectValidityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ObjectValidityContext.java index 9fafe3e4c07..38885e292d1 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ObjectValidityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ObjectValidityContext.java @@ -23,7 +23,7 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.services.wrapper.events.ObjectValidityEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.ProposedHolder; @@ -39,18 +39,18 @@ public record ObjectValidityContext( InteractionHead head, Identifier identifier, Supplier friendlyNameProvider, - InteractionInitiatedBy initiatedBy + InteractionConstraint iConstraint ) implements ValidityContext, ProposedHolder { public ObjectValidityContext( final ManagedObject targetAdapter, final Identifier identifier, - final InteractionInitiatedBy initiatedBy) { + final InteractionConstraint iConstraint) { this(InteractionContextType.OBJECT_VALIDATE, InteractionHead.regular(targetAdapter), identifier, ()->targetAdapter.objSpec().getSingularName(), - initiatedBy); + iConstraint); } @Override diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ParamValidityContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ParamValidityContext.java index 98355ffb03a..ea68a7cce09 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ParamValidityContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/ParamValidityContext.java @@ -24,8 +24,8 @@ import org.apache.causeway.applib.services.wrapper.events.ActionArgumentEvent; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.ProposedHolder; @@ -42,7 +42,7 @@ public record ParamValidityContext( InteractionHead head, Identifier identifier, Supplier friendlyNameProvider, - InteractionInitiatedBy initiatedBy, + InteractionConstraint iConstraint, ObjectAction objectAction, ManagedObject proposed, Can args, @@ -54,11 +54,11 @@ public ParamValidityContext( final Identifier id, final Can args, final int position, - final InteractionInitiatedBy initiatedBy) { + final InteractionConstraint iConstraint) { this(InteractionContextType.ACTION_PROPOSED_ARGUMENT, head, id, ()->objectAction.getParameters().getElseFail(position).getFriendlyName(head::target), - initiatedBy, + iConstraint, objectAction, args.getElseFail(position), args, diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/PropertyModifyContext.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/PropertyModifyContext.java index 4e2b9e80c68..7661cb25ff2 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/PropertyModifyContext.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/val/PropertyModifyContext.java @@ -23,7 +23,7 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.services.wrapper.events.PropertyModifyEvent; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.ProposedHolder; @@ -39,7 +39,7 @@ public record PropertyModifyContext( InteractionHead head, Identifier identifier, Supplier friendlyNameProvider, - InteractionInitiatedBy initiatedBy, + InteractionConstraint iConstraint, ManagedObject proposed) implements ValidityContext, ProposedHolder { public PropertyModifyContext( @@ -47,10 +47,9 @@ public PropertyModifyContext( final Identifier id, final ManagedObject proposed, final Supplier friendlyMemberNameProvider, - final InteractionInitiatedBy initiatedBy) { + final InteractionConstraint iConstraint) { this(InteractionContextType.PROPERTY_MODIFY, - head, id, friendlyMemberNameProvider, initiatedBy, - proposed); + head, id, friendlyMemberNameProvider, iConstraint, proposed); } @Override 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..68752942c12 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 @@ -18,12 +18,13 @@ */ package org.apache.causeway.core.metamodel.interactions.vis; +import org.jspecify.annotations.NonNull; + 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; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -38,22 +39,29 @@ public record ActionVisibilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy, ObjectAction objectAction) implements VisibilityContext, ActionInteractionContext { + public ActionVisibilityContext( + final @NonNull ObjectAction action, + final @NonNull VisibilityContext vc) { + this(InteractionContextType.ACTION_VISIBLE, + vc.head(), + action.getFeatureIdentifier(), + vc.iConstraint(), + vc.renderPolicy(), + action); + } + public ActionVisibilityContext( final InteractionHead head, final ObjectAction objectAction, final Identifier identifier, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { - this(InteractionContextType.ACTION_VISIBLE, - head, identifier, initiatedBy, where, renderPolicy, - objectAction); + this(InteractionContextType.ACTION_VISIBLE, head, identifier, iConstraint, renderPolicy, objectAction); } @Override 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..0e11526e3a6 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,10 +19,9 @@ 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.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -36,19 +35,30 @@ public record CollectionVisibilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy) implements VisibilityContext { +// public CollectionVisibilityContext( +// final @NonNull OneToManyAssociation collection, +// final @NonNull VisibilityContext vc) { +// this(InteractionContextType.COLLECTION_VISIBLE, +// vc.head(), +// collection.getFeatureIdentifier(), +// vc.initiatedBy(), +// vc.where(), +// vc.whatViewer(), +// vc.renderPolicy(), +// collection); +// } + public CollectionVisibilityContext( final InteractionHead head, final Identifier identifierAdapter, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.COLLECTION_VISIBLE, - head, identifierAdapter, initiatedBy, where, renderPolicy); + head, identifierAdapter, iConstraint, 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 4f542b7b043..1e267378ff3 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,13 +19,11 @@ 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; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; 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; @@ -39,8 +37,7 @@ public record ObjectVisibilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy) implements VisibilityContext, ProposedHolder { @@ -51,14 +48,12 @@ public record ObjectVisibilityContext( */ public static ObjectVisibilityContext createForRegular( final ManagedObject domainObject, - final InteractionInitiatedBy initiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new ObjectVisibilityContext( InteractionHead.regular(domainObject), domainObject.objSpec().getFeatureIdentifier(), - initiatedBy, - where, - InteractionUtils.renderPolicy(domainObject)); + iConstraint, + RenderPolicy.forNonActionParam(domainObject)); } // -- CONSTRUCTION @@ -66,11 +61,10 @@ public static ObjectVisibilityContext createForRegular( public ObjectVisibilityContext( final InteractionHead head, final Identifier identifier, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.OBJECT_VISIBILITY, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, iConstraint, 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..4277f71be8c 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 @@ -19,13 +19,12 @@ 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.events.ActionArgumentVisibilityEvent; import org.apache.causeway.applib.services.wrapper.events.ActionArgumentEvent; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.InteractionContextType; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.interactions.ActionInteractionContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -41,8 +40,7 @@ public record ParamVisibilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy, ObjectAction objectAction, Can args, @@ -55,11 +53,11 @@ public ParamVisibilityContext( final Identifier id, final Can args, final int position, - final InteractionInitiatedBy initiatedBy, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.ACTION_PARAMETER_VISIBLE, - head, id, initiatedBy, Where.OBJECT_FORMS, renderPolicy, + head, id, iConstraint, 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..03066ef691b 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,10 +19,9 @@ 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.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -36,20 +35,18 @@ public record PropertyVisibilityContext( InteractionContextType interactionType, InteractionHead head, Identifier identifier, - InteractionInitiatedBy initiatedBy, - Where where, + InteractionConstraint iConstraint, RenderPolicy renderPolicy ) implements VisibilityContext { public PropertyVisibilityContext( final InteractionHead head, final Identifier identifier, - final InteractionInitiatedBy initiatedBy, - final Where where, + final InteractionConstraint iConstraint, final RenderPolicy renderPolicy) { this(InteractionContextType.PROPERTY_VISIBLE, - head, identifier, initiatedBy, where, renderPolicy); + head, identifier, iConstraint, renderPolicy); } @Override 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/object/MmVisibilityUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmVisibilityUtils.java index 4a27cffc8c7..7f5f600200b 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 @@ -25,7 +25,9 @@ import org.apache.causeway.commons.internal.collections._Arrays; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.collections.CollectionFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.vis.ObjectVisibilityContext; import org.apache.causeway.core.metamodel.interactions.vis.VisibilityContext; @@ -90,19 +92,16 @@ 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; } + if(!interactionInitiatedBy.isUser()) + return true; var visibilityContext = createVisibleInteractionContext( adapter, InteractionInitiatedBy.USER, @@ -117,8 +116,10 @@ private static VisibilityContext createVisibleInteractionContext( final InteractionInitiatedBy interactionInitiatedBy, final Where where) { + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), interactionInitiatedBy, where); + return ObjectVisibilityContext - .createForRegular(objectAdapter, interactionInitiatedBy, where); + .createForRegular(objectAdapter, iConstraint); } } 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..c0eb0d87559 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 + * Optionally hides or disables 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, @@ -52,8 +50,7 @@ public static boolean hidesProperty( new PropertyVisibilityContext( vc.head(), property.getFeatureIdentifier(), - vc.initiatedBy(), - vc.where(), + vc.iConstraint(), vc.renderPolicy())) != null) .orElse(false); } @@ -67,8 +64,7 @@ public static boolean hidesCollection( new CollectionVisibilityContext( vc.head(), collection.getFeatureIdentifier(), - vc.initiatedBy(), - vc.where(), + vc.iConstraint(), vc.renderPolicy())) != null) .orElse(false); } @@ -83,8 +79,7 @@ public static boolean hidesAction( vc.head(), action, action.getFeatureIdentifier(), - vc.initiatedBy(), - vc.where(), + vc.iConstraint(), vc.renderPolicy())) != null) .orElse(false); } 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)); } } 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 67% 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 cd6874af027..d5e92b35b56 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 @@ -24,34 +24,28 @@ 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; +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 class NavigationFacetFromHiddenType -extends FacetAbstract -implements - NavigationFacet { +public record HiddenFacetForNavigationFromHiddenType( + ObjectSpecification navigatedType, + FacetHolder facetHolder + ) implements HiddenFacetForNavigation { - 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 HiddenFacetForNavigationFromHiddenType(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 HiddenFacetForNavigation.class; } + @Override public Precedence precedence() { return Precedence.DEFAULT; } - private NavigationFacetFromHiddenType(final ObjectSpecification navigatedType, final FacetHolder holder) { - super(type(), holder); - this.navigatedType = navigatedType; + public HiddenFacetForNavigationFromHiddenType { _Assert.assertTrue(navigatedType.isSingular(), ()->String.format( "framework bug: elementType must not match any supported plural (collection) types, " + "nevertheless got %s", navigatedType)); @@ -59,17 +53,15 @@ private NavigationFacetFromHiddenType(final ObjectSpecification navigatedType, f @Override public String hides(final VisibilityContext ic) { - var facet = navigatedType.getFacet(HiddenTypeFacet.class); - if(facet == null) { - // not expected to happen; this facet should only be installed for object members + 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 return null; - } var objVisibilityContext = new ObjectVisibilityContext( ic.head(), Identifier.classIdentifier(navigatedType.logicalType()), - ic.initiatedBy(), - ic.where(), + ic.iConstraint(), ic.renderPolicy()); final String hides = facet.hides(objVisibilityContext); return hides; @@ -77,7 +69,7 @@ public String hides(final VisibilityContext ic) { @Override public void visitAttributes(final BiConsumer visitor) { - 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/HasObjectAction.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/HasObjectAction.java index 2729dd71e34..4465e8ad383 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; @@ -33,6 +32,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionResultSet; import org.apache.causeway.core.metamodel.facetapi.FacetHolder; import org.apache.causeway.core.metamodel.facetapi.FeatureType; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ActionScope; @@ -55,11 +55,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 InteractionConstraint iConstraint) { + return getObjectAction().isVisible(target, iConstraint); } - @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 InteractionConstraint iConstraint) { + return getObjectAction().isUsable(target, iConstraint); } @Override default boolean isPropertyOrCollection() { return getObjectAction().isPropertyOrCollection(); @@ -129,24 +129,25 @@ 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 InteractionConstraint iConstraint) throws AuthorizationException { + return getObjectAction().executeWithRuleChecking(head, parameters, iConstraint); } + @Deprecated @Override default ManagedObject execute(final InteractionHead head, final Can parameters, - final InteractionInitiatedBy interactionInitiatedBy) { - return getObjectAction().execute(head, parameters, interactionInitiatedBy); + final InteractionConstraint iConstraint) { + return getObjectAction().execute(head, parameters, iConstraint); } @Override default Consent isArgumentSetValid(final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { - return getObjectAction().isArgumentSetValid(head, proposedArguments, interactionInitiatedBy); + final InteractionConstraint iConstraint) { + return getObjectAction().isArgumentSetValid(head, proposedArguments, iConstraint); } @Override default InteractionResultSet isArgumentSetValidForParameters(final InteractionHead head, - final Can proposedArguments, final InteractionInitiatedBy interactionInitiatedBy) { - return getObjectAction().isArgumentSetValidForParameters(head, proposedArguments, interactionInitiatedBy); + final Can proposedArguments, final InteractionConstraint iConstraint) { + return getObjectAction().isArgumentSetValidForParameters(head, proposedArguments, iConstraint); } @Override default Consent isArgumentSetValidForAction(final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { - return getObjectAction().isArgumentSetValidForAction(head, proposedArguments, interactionInitiatedBy); + final InteractionConstraint iConstraint) { + return getObjectAction().isArgumentSetValidForAction(head, proposedArguments, iConstraint); } @Override default InteractionHead interactionHead(@NonNull final ManagedObject actionOwner) { return getObjectAction().interactionHead(actionOwner); 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..5fba36b85a8 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,12 +43,14 @@ 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; import org.apache.causeway.core.metamodel.facets.object.promptStyle.PromptStyleFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; +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; @@ -103,8 +105,7 @@ default boolean isImmediateConfirmationRequired() { ManagedObject executeWithRuleChecking( InteractionHead head, Can parameters, - InteractionInitiatedBy interactionInitiatedBy, - Where where) throws AuthorizationException; + InteractionConstraint iConstraint) throws AuthorizationException; /** * Invokes the action's method on the target object given the specified set @@ -114,10 +115,11 @@ ManagedObject executeWithRuleChecking( * When a mixin action invokes its underlying mixedIn action, then will be populated * (so that the ActionDomainEvent can correctly provide the underlying mixin) */ + @Deprecated //FIXME bad API ManagedObject execute( InteractionHead head, Can parameters, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); // -- isArgumentSetValid, isArgumentSetValidForParameters, isArgumentSetValidForAction @@ -136,7 +138,7 @@ ManagedObject execute( Consent isArgumentSetValid( InteractionHead head, Can proposedArguments, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); /** * Normally action validation is all performed by @@ -154,7 +156,7 @@ Consent isArgumentSetValid( InteractionResultSet isArgumentSetValidForParameters( InteractionHead head, Can proposedArguments, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); /** * Normally action validation is all performed by @@ -172,7 +174,7 @@ InteractionResultSet isArgumentSetValidForParameters( Consent isArgumentSetValidForAction( InteractionHead head, Can proposedArguments, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); // -- INTERACTION HEAD @@ -271,10 +273,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 +284,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 +307,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 +317,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; } @@ -365,16 +359,16 @@ public static Optional cssClassFaFactoryFor( * Returns a Stream of those to be rendered with the entity header panel. */ public static Stream streamTopBarActions( - final ManagedObject adapter) { + final ManagedObject mo) { - var spec = adapter.objSpec(); + var spec = mo.objSpec(); return spec.streamRuntimeActions(MixedIn.INCLUDED) - .filter(Predicates + .filter(Predicates .isSharingAnyLayoutGroupOf(spec.streamAssociations(MixedIn.INCLUDED)) .negate()) - .filter(Predicates - .dynamicallyVisible(adapter, InteractionInitiatedBy.USER, Where.ANYWHERE)); + .filter(Predicates + .dynamicallyVisible(mo, new InteractionConstraint(WhatViewer.invalid(), InteractionInitiatedBy.USER, Where.ANYWHERE))); } public static Stream findForAssociation( @@ -388,15 +382,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 +428,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 +447,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); }; } @@ -480,10 +468,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 +479,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 @@ -512,13 +500,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); } @@ -540,11 +526,10 @@ public boolean test(final ObjectAction objectAction) { private static Predicate dynamicallyVisible( final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return (final ObjectAction objectAction) -> { - final Consent visible = objectAction.isVisible(target, interactionInitiatedBy, where); + final Consent visible = objectAction.isVisible(target, iConstraint); return visible.isAllowed(); }; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectActionParameter.java index 492396c7acf..ba8bc7faa24 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectActionParameter.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectActionParameter.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.apache.causeway.applib.annotation.Domain; @@ -30,6 +31,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facetapi.FeatureType; import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel; import org.apache.causeway.core.metamodel.interactions.val.ParamValidityContext; @@ -38,7 +40,6 @@ import org.apache.causeway.core.metamodel.spec.ObjectSpecification; import org.apache.causeway.core.metamodel.util.Facets; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; import lombok.experimental.UtilityClass; @@ -109,7 +110,7 @@ ParamValidityContext createProposedArgumentInteractionContext( InteractionHead head, Can args, int position, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); /** * Whether there is an autoComplete provided (eg autoCompleteXxx supporting @@ -203,7 +204,7 @@ default boolean reassessDefault(final ParameterNegotiationModel pendingArgs) { Consent isVisible( InteractionHead head, Can pendingArgs, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); /** * Whether this parameter is disabled given the entered previous arguments @@ -214,7 +215,7 @@ Consent isVisible( Consent isUsable( InteractionHead head, Can pendingArgs, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); /** * Whether proposed value for this parameter is valid. @@ -226,7 +227,7 @@ Consent isUsable( Consent isValid( InteractionHead head, Can pendingArgs, - InteractionInitiatedBy interactionInitiatedBy); + InteractionConstraint iConstraint); @Domain.Exclude @UtilityClass 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..8811b800088 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,10 +35,11 @@ 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; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.object.MmSortUtils; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -53,16 +54,12 @@ public interface ObjectMember extends ObjectFeature { * Returns the {@link ObjectSpecification} representing the class or interface * that declares the member represented by this object. * - *

- * If the member is a regular member, declared on a class, then this returns that type. - * But if the member is a mixin, then this will return the {@link ObjectSpecification} representing the mixin type. - *

+ *

If the member is a regular member, declared on a class, then this returns that type. + * But if the member is a mixin, then this will return the {@link ObjectSpecification} representing the mixin type. */ ObjectSpecification getDeclaringType(); - // ///////////////////////////////////////////////////////////// - // Name, Description, Help (convenience for facets) - // ///////////////////////////////////////////////////////////// + // -- Name, Description, Help (convenience for facets) /** * Return the help text for this member - the field or action - to @@ -72,16 +69,13 @@ public interface ObjectMember extends ObjectFeature { */ String getHelp(); - // ///////////////////////////////////////////////////////////// - // Hidden (or visible) - // ///////////////////////////////////////////////////////////// + // -- Hidden (or visible) /** * 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(); @@ -91,15 +85,13 @@ public interface ObjectMember extends ObjectFeature { * may be null if just checking for authorization. * @param interactionInitiatedBy * @param where + * @param whatViewer */ Consent isVisible( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); + ManagedObject target, + InteractionConstraint iConstraint); - // ///////////////////////////////////////////////////////////// - // Disabled (or enabled) - // ///////////////////////////////////////////////////////////// + // -- Disabled (or enabled) /** * Determines whether this member is usable (not disabled), represented as a @@ -110,19 +102,15 @@ Consent isVisible( * @param where */ Consent isUsable( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where); + ManagedObject target, + InteractionConstraint iConstraint); - // ///////////////////////////////////////////////////////////// - // isAssociation, isAction - // ///////////////////////////////////////////////////////////// + // -- PREDICATES /** * Whether this member represents a {@link ObjectAssociation}. * - *

- * If so, can be safely downcast to {@link ObjectAssociation}. + *

If so, can be safely downcast to {@link ObjectAssociation}. */ boolean isPropertyOrCollection(); default boolean isProperty() { return isOneToOneAssociation(); } @@ -131,16 +119,14 @@ Consent isUsable( /** * Whether this member represents a {@link OneToManyAssociation}. * - *

- * If so, can be safely downcast to {@link OneToManyAssociation}. + *

If so, can be safely downcast to {@link OneToManyAssociation}. */ boolean isOneToManyAssociation(); /** * Whether this member represents a {@link OneToOneAssociation}. * - *

- * If so, can be safely downcast to {@link OneToOneAssociation}. + *

If so, can be safely downcast to {@link OneToOneAssociation}. */ boolean isOneToOneAssociation(); @@ -166,24 +152,17 @@ 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. * - *

- * For the former case, is thrown by - * {@link ObjectAction#executeWithRuleChecking(org.apache.causeway.core.metamodel.interactions.InteractionHead, org.apache.causeway.commons.collections.Can, InteractionInitiatedBy, Where)} - * when the action being executed is not visible or not usable for the specified session. One reason this - * might occur if there was an attempt to construct a URL (eg a bookmarked action) and invoke in an unauthenticated session. - *

- * - *

- * For the latter case, is thrown by DomainObjectPage - * - *

+ *

For the former case, is thrown by + * {@link ObjectAction#executeWithRuleChecking(org.apache.causeway.core.metamodel.interactions.InteractionHead, org.apache.causeway.commons.collections.Can, InteractionInitiatedBy, Where)} + * when the action being executed is not visible or not usable for the specified session. One reason this + * might occur if there was an attempt to construct a URL (eg a bookmarked action) and invoke in an unauthenticated session. + * + *

For the latter case, is thrown by DomainObjectPage */ class AuthorizationException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java index 2573476ba1a..ca88a1d6612 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToOneAssociation.java @@ -19,8 +19,8 @@ package org.apache.causeway.core.metamodel.spec.feature; import org.apache.causeway.core.metamodel.consent.Consent; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.propcoll.memserexcl.SnapshotExcludeFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; /** @@ -34,7 +34,7 @@ public interface OneToOneAssociation MutableCurrentHolder { /** - * Initialise this field in the specified object with the specified + * Initialize this field in the specified object with the specified * reference - this call should only affect the specified object, and not * any related objects. It should also not be distributed. This is strictly * for re-initialising the object and not specifying an association, which @@ -47,9 +47,9 @@ public interface OneToOneAssociation * the specified object, represented as a {@link Consent}. */ Consent isAssociationValid( - final ManagedObject targetAdapter, - final ManagedObject proposedAdapter, - final InteractionInitiatedBy interactionInitiatedBy); + ManagedObject targetAdapter, + ManagedObject proposedAdapter, + InteractionConstraint iConstraint); /** * Returns true if calculated from other data in the object, that is, should 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..858046eed5c 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; @@ -48,11 +47,13 @@ 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.InteractionConstraint; 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; @@ -77,9 +78,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; } @@ -134,9 +134,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())); } @@ -174,9 +173,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())); } @@ -187,10 +185,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(); } @@ -202,7 +199,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; } @@ -268,27 +265,24 @@ 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); } // -- VISIBLE @Override - public VisibilityContext createVisibleInteractionContext( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + protected VisibilityContext createVisibleInteractionContext( + final ManagedObject target, + final InteractionConstraint iConstraint) { return new ActionVisibilityContext( headFor(target), this, getFeatureIdentifier(), - interactionInitiatedBy, - where, - InteractionUtils.renderPolicy(target)); + iConstraint, + RenderPolicy.forNonActionParam(target)); } // -- USABLE @@ -296,15 +290,13 @@ public VisibilityContext createVisibleInteractionContext( @Override public UsabilityContext createUsableInteractionContext( final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new ActionUsabilityContext( headFor(target), this, getFeatureIdentifier(), - interactionInitiatedBy, - where, - InteractionUtils.renderPolicy(target)); + iConstraint, + RenderPolicy.forNonActionParam(target)); } // -- VALIDATE @@ -313,14 +305,14 @@ public UsabilityContext createUsableInteractionContext( public Consent isArgumentSetValid( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { final InteractionResultSet resultSet = new InteractionResultSet(); - validateArgumentsIndividually(head, proposedArguments, interactionInitiatedBy, resultSet); + validateArgumentsIndividually(head, proposedArguments, iConstraint, resultSet); if (resultSet.isAllowed()) { // only check the action's own validity if all the arguments are OK. - validateArgumentSet(head, proposedArguments, interactionInitiatedBy, resultSet); + validateArgumentSet(head, proposedArguments, iConstraint, resultSet); } return resultSet.createConsent(); @@ -330,11 +322,11 @@ public Consent isArgumentSetValid( public InteractionResultSet isArgumentSetValidForParameters( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { final InteractionResultSet resultSet = new InteractionResultSet(); - validateArgumentsIndividually(head, proposedArguments, interactionInitiatedBy, resultSet); + validateArgumentsIndividually(head, proposedArguments, iConstraint, resultSet); return resultSet; } @@ -342,7 +334,7 @@ public InteractionResultSet isArgumentSetValidForParameters( private void validateArgumentsIndividually( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy, + final InteractionConstraint iConstraint, final InteractionResultSet resultSet) { var actionParameters = getParameters(); @@ -350,7 +342,7 @@ private void validateArgumentsIndividually( for (int i = 0; i < proposedArguments.size(); i++) { var validityContext = actionParameters.getElseFail(i) .createProposedArgumentInteractionContext( - head, proposedArguments, i, interactionInitiatedBy); + head, proposedArguments, i, iConstraint); InteractionUtils.isValidResultSet(getParameter(i), validityContext, resultSet); } @@ -361,10 +353,10 @@ private void validateArgumentsIndividually( public Consent isArgumentSetValidForAction( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { final InteractionResultSet resultSet = new InteractionResultSet(); - validateArgumentSet(head, proposedArguments, interactionInitiatedBy, resultSet); + validateArgumentSet(head, proposedArguments, iConstraint, resultSet); return resultSet.createConsent(); } @@ -372,57 +364,53 @@ public Consent isArgumentSetValidForAction( protected void validateArgumentSet( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy, + final InteractionConstraint iConstraint, final InteractionResultSet resultSet) { var validityContext = createActionInvocationInteractionContext( - head, proposedArguments, interactionInitiatedBy); + head, proposedArguments, iConstraint); InteractionUtils.isValidResultSet(this, validityContext, resultSet); } ActionValidityContext createActionInvocationInteractionContext( final InteractionHead head, final Can proposedArguments, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return new ActionValidityContext( head, this, getFeatureIdentifier(), proposedArguments, - interactionInitiatedBy); + iConstraint); } // -- EXECUTE @Override public ManagedObject executeWithRuleChecking( - final InteractionHead head, - final Can arguments, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionHead head, + final Can arguments, + final InteractionConstraint iConstraint) throws AuthorizationException { var target = head.owner(); // see it? - final Consent visibility = isVisible(target, interactionInitiatedBy, where); - if (visibility.isVetoed()) { - throw new HiddenException(); - } + final Consent visibility = isVisible(target, iConstraint); + 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, iConstraint); + 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")); - } + final Consent validity = isArgumentSetValid(head, arguments, iConstraint); + if(validity.isVetoed()) + throw new RecoverableException(validity.getReasonAsString().orElse("no reason given")); - return execute(head, arguments, interactionInitiatedBy); + return execute(head, arguments, iConstraint); } /** @@ -432,16 +420,16 @@ public ManagedObject executeWithRuleChecking( @Override public ManagedObject execute( final InteractionHead head, - final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final Can arguments, + final InteractionConstraint iConstraint) { - _Assert.assertEquals(this.getParameterCount(), argumentAdapters.size(), + _Assert.assertEquals(this.getParameterCount(), arguments.size(), "action's parameter count and provided argument count must match"); final ManagedObject owner = head.owner(); - if(!interactionInitiatedBy.isPassThrough()) { - setupCommand(head, argumentAdapters); + if(!iConstraint.initiatedBy().isPassThrough()) { + setupCommand(head, arguments); if(log.isInfoEnabled()) { Optional bookmarkIfAny = owner.getBookmark(); @@ -450,16 +438,16 @@ public ManagedObject execute( getFeatureIdentifier().logicalTypeName(), getFeatureIdentifier().memberLogicalName(), UtilStr.entityAsStr(bookmark, getSpecificationLoader()), - argsFor(getParameters(), argumentAdapters)); + argsFor(getParameters(), arguments)); }); } } - return this.executeInternal(head, argumentAdapters, interactionInitiatedBy); + return this.executeInternal(head, arguments, iConstraint.initiatedBy()); } /** - * private API, called by mixins + * internal API, called by mixins */ protected ManagedObject executeInternal( final InteractionHead head, @@ -530,9 +518,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)); @@ -571,9 +558,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/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectActionMixedIn.java index d878bd98e1c..08fd241be1e 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 @@ -35,6 +35,7 @@ import org.apache.causeway.core.metamodel.facetapi.FacetHolder; 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.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -154,14 +155,14 @@ protected ManagedObject mixinAdapterFor(final ManagedObject mixeeAdapter) { public ManagedObject execute( final InteractionHead head, final Can argumentAdapters, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { final ManagedObject owner = head.owner(); final ManagedObject target = mixinAdapterFor(mixinSpec, owner); _Assert.assertEquals(target.objSpec(), head.target().objSpec(), "head has the wrong target (should be a mixed-in adapter, but is the mixee adapter)"); - if(!interactionInitiatedBy.isPassThrough()) { + if(!iConstraint.initiatedBy().isPassThrough()) { setupCommand(head, argumentAdapters); if(log.isInfoEnabled()) { @@ -178,7 +179,7 @@ public ManagedObject execute( return mixinAction.executeInternal( head, argumentAdapters, - interactionInitiatedBy); + iConstraint.initiatedBy()); } @Override 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..63b1cfeb380 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,7 +21,10 @@ 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.annotation.Where; import org.apache.causeway.applib.exceptions.unrecoverable.DomainModelException; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.exceptions._Exceptions; @@ -37,6 +40,7 @@ import org.apache.causeway.core.metamodel.facets.param.autocomplete.MinLengthUtil; import org.apache.causeway.core.metamodel.facets.param.choices.ActionParameterChoicesFacet; import org.apache.causeway.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; import org.apache.causeway.core.metamodel.interactions.RenderPolicy; @@ -51,7 +55,6 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter; import lombok.Getter; -import org.jspecify.annotations.NonNull; abstract class ObjectActionParameterAbstract implements @@ -188,9 +191,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 +228,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 +297,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())); - } } } @@ -310,10 +310,10 @@ private ParamVisibilityContext createArgumentVisibilityContext( final InteractionHead head, final Can pendingArgs, final int position, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return new ParamVisibilityContext( - head, parentAction, getFeatureIdentifier(), pendingArgs, position, interactionInitiatedBy, + head, parentAction, getFeatureIdentifier(), pendingArgs, position, iConstraint.withWhere(Where.OBJECT_FORMS), RenderPolicy.forActionParameters()); } @@ -321,10 +321,10 @@ head, parentAction, getFeatureIdentifier(), pendingArgs, position, interactionIn public Consent isVisible( final InteractionHead head, final Can pendingArgs, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { var visibilityContext = createArgumentVisibilityContext( - head, pendingArgs, getParameterIndex(), interactionInitiatedBy); + head, pendingArgs, getParameterIndex(), iConstraint); return InteractionUtils.isVisibleResult(this, visibilityContext).createConsent(); } @@ -335,7 +335,7 @@ private ParamUsabilityContext createArgumentUsabilityContext( final InteractionHead head, final Can pendingArgs, final int position, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return new ParamUsabilityContext( head, @@ -343,7 +343,7 @@ private ParamUsabilityContext createArgumentUsabilityContext( getFeatureIdentifier(), pendingArgs, position, - interactionInitiatedBy, + iConstraint, RenderPolicy.forActionParameters()); } @@ -351,10 +351,10 @@ private ParamUsabilityContext createArgumentUsabilityContext( public Consent isUsable( final InteractionHead head, final Can pendingArgs, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { var usabilityContext = createArgumentUsabilityContext( - head, pendingArgs, getParameterIndex(), interactionInitiatedBy); + head, pendingArgs, getParameterIndex(), iConstraint); var usableResult = InteractionUtils.isUsableResult(this, usabilityContext); return usableResult.createConsent(); @@ -367,20 +367,20 @@ public ParamValidityContext createProposedArgumentInteractionContext( final InteractionHead head, final Can proposedArguments, final int position, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return new ParamValidityContext( - head, parentAction, getFeatureIdentifier(), proposedArguments, position, interactionInitiatedBy); + head, parentAction, getFeatureIdentifier(), proposedArguments, position, iConstraint); } @Override public Consent isValid( final InteractionHead head, final Can pendingArgs, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { var validityContext = createProposedArgumentInteractionContext( - head, pendingArgs, getParameterIndex(), interactionInitiatedBy); + head, pendingArgs, getParameterIndex(), iConstraint); var validResult = InteractionUtils.isValidResult(this, validityContext); return validResult.createConsent(); 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..fcb2c961b83 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; @@ -42,11 +44,12 @@ 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; import org.apache.causeway.core.metamodel.interactions.HidingInteractionAdvisor; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionHead; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; @@ -61,7 +64,6 @@ import org.apache.causeway.schema.cmd.v2.CommandDto; import lombok.Getter; -import org.jspecify.annotations.NonNull; abstract class ObjectMemberAbstract implements @@ -84,9 +86,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 +114,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 +138,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()))); } @@ -195,13 +195,12 @@ 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, + InteractionConstraint iConstraint); @Override public boolean isAlwaysHidden() { - return HiddenFacet.isAlwaysHidden(getFacetHolder()); + return HiddenFacetForLayout.isAlwaysHidden(getFacetHolder()); } /** @@ -209,16 +208,13 @@ public boolean isAlwaysHidden() { * returns true only if none hide the member. */ @Override - public Consent isVisible( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - - var visibilityContext = createVisibleInteractionContext(target, interactionInitiatedBy, where); + public final Consent isVisible(final ManagedObject target, final InteractionConstraint iConstraint) { + var visibilityContext = createVisibleInteractionContext(target, iConstraint); return InteractionUtils.isVisibleResult(this, visibilityContext).createConsent(); } // -- Disabled (or enabled) + /** * Create an {@link InteractionContext} to represent an attempt to * use this member (that is, to check if it is usable or not). @@ -230,21 +226,16 @@ public 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, + InteractionConstraint iConstraint); /** * Loops over all {@link DisablingInteractionAdvisor} {@link Facet}s and * returns true only if none disables the member. */ @Override - public Consent isUsable( - final ManagedObject target, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - - var usabilityContext = createUsableInteractionContext(target, interactionInitiatedBy, where); + public final Consent isUsable(final ManagedObject target, final InteractionConstraint iConstraint) { + var usabilityContext = createUsableInteractionContext(target, iConstraint); return InteractionUtils.isUsableResult(this, usabilityContext).createConsent(); } @@ -277,9 +268,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); 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..b434a4178c5 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 @@ -40,6 +40,7 @@ import org.apache.causeway.applib.annotation.DomainService; import org.apache.causeway.applib.annotation.Introspection.IntrospectionPolicy; import org.apache.causeway.applib.annotation.ObjectSupport; +import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.fa.FontAwesomeLayers; import org.apache.causeway.applib.id.LogicalType; import org.apache.causeway.applib.services.metamodel.BeanSort; @@ -75,7 +76,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; @@ -96,8 +97,10 @@ import org.apache.causeway.core.metamodel.facets.object.title.TitleRenderRequest; import org.apache.causeway.core.metamodel.facets.object.value.ValueFacet; import org.apache.causeway.core.metamodel.facets.object.viewmodel.ViewModelFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; import org.apache.causeway.core.metamodel.interactions.InteractionContext; import org.apache.causeway.core.metamodel.interactions.InteractionUtils; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.metamodel.interactions.acc.ObjectTitleContext; import org.apache.causeway.core.metamodel.interactions.val.ObjectValidityContext; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -165,7 +168,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 +276,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 +304,8 @@ private ObjectAction createAction(final FacetedMethod facetedMethod) { return this.isMixin() ? ObjectActionDefault.forMixinMain(facetedMethod) : ObjectActionDefault.forMethod(facetedMethod); - } else { - return null; - } + } else + return null; } // -- getObjectAction @@ -352,7 +353,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 +364,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 @@ -375,7 +376,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 +556,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 +593,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 +646,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 +803,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 +849,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 +920,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 +1058,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 +1068,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 +1099,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(); @@ -1173,7 +1162,8 @@ public InteractionResult isValidResult( @Override public ObjectValidityContext createValidityInteractionContext( final ManagedObject targetAdapter, final InteractionInitiatedBy interactionInitiatedBy) { - return new ObjectValidityContext(targetAdapter, getFeatureIdentifier(), interactionInitiatedBy); + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), interactionInitiatedBy, Where.ANYWHERE); + return new ObjectValidityContext(targetAdapter, getFeatureIdentifier(), iConstraint); } // -- convenience isXxx (looked up from facets) @@ -1184,7 +1174,7 @@ public boolean isImmutable() { @Override public boolean isHidden() { - return containsFacet(HiddenFacet.class); + return containsFacet(HiddenFacetForLayout.class); } @Override @@ -1205,14 +1195,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 +1216,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/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..232e1f65ad8 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; @@ -31,7 +30,8 @@ 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.InteractionConstraint; +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; @@ -78,22 +78,20 @@ private ResolvedType resolveTypeOfAnyCardinality() { @Override public VisibilityContext createVisibleInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new CollectionVisibilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + headFor(ownerAdapter), getFeatureIdentifier(), iConstraint, + RenderPolicy.forNonActionParam(ownerAdapter)); } @Override public UsabilityContext createUsableInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new CollectionUsabilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + headFor(ownerAdapter), getFeatureIdentifier(), iConstraint, + 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..e68253b2614 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; @@ -42,8 +41,10 @@ import org.apache.causeway.core.metamodel.facets.properties.update.clear.PropertyClearFacet; import org.apache.causeway.core.metamodel.facets.properties.update.init.PropertyInitializationFacet; import org.apache.causeway.core.metamodel.facets.properties.update.modify.PropertySetterFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; 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; @@ -87,21 +88,19 @@ protected OneToOneAssociationDefault( @Override public VisibilityContext createVisibleInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new PropertyVisibilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + headFor(ownerAdapter), getFeatureIdentifier(), iConstraint, + RenderPolicy.forNonActionParam(ownerAdapter)); } @Override public UsabilityContext createUsableInteractionContext( final ManagedObject ownerAdapter, - final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { + final InteractionConstraint iConstraint) { return new PropertyUsabilityContext( - headFor(ownerAdapter), getFeatureIdentifier(), interactionInitiatedBy, where, - InteractionUtils.renderPolicy(ownerAdapter)); + headFor(ownerAdapter), getFeatureIdentifier(), iConstraint, + RenderPolicy.forNonActionParam(ownerAdapter)); } // -- VALIDITY @@ -109,7 +108,7 @@ public UsabilityContext createUsableInteractionContext( private ValidityContext createValidateInteractionContext( final ManagedObject ownerAdapter, final ManagedObject proposedValue, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { var head = headFor(ownerAdapter); @@ -118,18 +117,18 @@ private ValidityContext createValidateInteractionContext( getFeatureIdentifier(), proposedValue, ()->getFriendlyName(head::target), - interactionInitiatedBy); + iConstraint); } @Override public Consent isAssociationValid( final ManagedObject ownerAdapter, final ManagedObject proposedValue, - final InteractionInitiatedBy interactionInitiatedBy) { + final InteractionConstraint iConstraint) { return InteractionUtils.isValidResult( this, createValidateInteractionContext( - ownerAdapter, proposedValue, interactionInitiatedBy)) + ownerAdapter, proposedValue, iConstraint)) .createConsent(); } @@ -157,11 +156,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); } @@ -194,11 +192,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( @@ -207,9 +204,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); @@ -222,9 +218,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); } @@ -241,18 +236,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) { @@ -273,9 +266,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/spec/impl/ProgrammingModelDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ProgrammingModelDefault.java index 5ce2f3c7c2f..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; @@ -36,7 +37,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; @@ -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; @@ -181,7 +182,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)); @@ -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/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/tabular/DataTableInteractive.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/tabular/DataTableInteractive.java index 5ae6e23e323..36183480467 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.InteractionConstraint; 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 iConstraint = new InteractionConstraint(WhatViewer.invalid(), interactionInitiatedBy, 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(), iConstraint).isAllowed() //TODO API: should not be required ? property.get(rowElement(), interactionInitiatedBy) : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( - collection.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() + collection.isVisible(rowElement(), iConstraint).isAllowed() //TODO API: should not be required ? 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..d3b653a2797 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,9 @@ 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.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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 +77,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.iConstraint().where(), managedCollection .streamElements() .collect(Can.toCan())); @@ -85,16 +88,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.iConstraint().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.iConstraint().where(), elements); } // -- CONSTRUCTION @@ -356,22 +358,20 @@ public Set getSelectedRowIndexes() { } @Override - public ActionInteraction startAssociatedActionInteraction(final String actionId, final Where where) { + public ActionInteraction startAssociatedActionInteraction(final String actionId, final InteractionConstraint iConstraint) { 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, iConstraint, this); } // -- EXPORT @@ -385,7 +385,7 @@ public DataTable export() { .map(DataColumn::associationMetaModel), dataRowsFilteredAndSortedObservable().getValue() .stream() - .map(dr->dr.rowElement()) + .map(DataRow::rowElement) .collect(Can.toCan())); } @@ -446,11 +446,11 @@ static Memento create( @Override public DataTableInternal recreateDataTableModel(final ManagedObject owner) { var memberId = featureId.memberLogicalName(); - + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.FRAMEWORK, where); final ManagedMember managedMember = featureId.type().isPropertyOrCollection() - ? ManagedCollection.lookupCollection(owner, memberId, where) + ? ManagedCollection.lookupCollection(owner, memberId, iConstraint) .orElseThrow() - : ManagedAction.lookupAction(owner, memberId, where) + : ManagedAction.lookupAction(owner, memberId, iConstraint) .orElseThrow(); var dataTableInteractive = new DataTableInternal(managedMember, where, @@ -484,7 +484,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..330579a57ec 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,16 @@ */ 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.InteractionConstraint; +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.jspecify.annotations.NonNull; - /** * Represents a single domain object (typically an entity instance) * and it's associated values as cell elements. @@ -42,18 +44,21 @@ public Can getCellElements( final @NonNull DataColumn column, final InteractionInitiatedBy interactionInitiatedBy) { var assoc = column.metamodel(); + + var iConstraint = new InteractionConstraint(WhatViewer.invalid(), interactionInitiatedBy, Where.ALL_TABLES); + return assoc.getSpecialization().fold( property-> Can.of( // similar to ManagedProperty#reassessPropertyValue interactionInitiatedBy.isPassThrough() - || property.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() - ? property.get(rowElement(), interactionInitiatedBy) - : ManagedObject.empty(property.getElementType())), + || property.isVisible(rowElement(), iConstraint).isAllowed() //TODO API: should not be required + ? property.get(rowElement(), interactionInitiatedBy) + : ManagedObject.empty(property.getElementType())), collection-> ManagedObjects.unpack( interactionInitiatedBy.isPassThrough() - || collection.isVisible(rowElement(), interactionInitiatedBy, Where.ALL_TABLES).isAllowed() - ? collection.get(rowElement(), interactionInitiatedBy) - : null + || collection.isVisible(rowElement(), iConstraint).isAllowed() //TODO API: should not be required + ? collection.get(rowElement(), interactionInitiatedBy) + : null )); } 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/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/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 63213d0d216..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,8 +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.PrototypeFacetAbstract; +import org.apache.causeway.core.metamodel.facets.actions.prototype.HiddenFacetForDeploymentType; class PrototypeFacetAnnotationFactoryTest extends FacetFactoryTestAbstract { @@ -64,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 PrototypeFacetAbstract); + 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 6ad5905f6f7..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,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.HiddenFacetForDeploymentTypeViaActionAnnotation; 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 HiddenFacetForDeploymentTypeViaActionAnnotation( + deploymentType, mockFacetHolder); // when final String reason = facet.hides(mockVisibilityContext); 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/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 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.java b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/spec/impl/ObjectAssociationAbstractTest.java index b12bb89f02d..ac021ac00f1 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.InteractionConstraint; 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; @@ -105,18 +105,16 @@ public void toDefault(final ManagedObject target) { } @Override - public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + protected UsabilityContext createUsableInteractionContext(final ManagedObject target, + final InteractionConstraint iConstraint) { + return null; + } @Override - public VisibilityContext createVisibleInteractionContext( - final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + protected VisibilityContext createVisibleInteractionContext(final ManagedObject target, + final InteractionConstraint iConstraint) { + return null; + } @Override public boolean containsNonFallbackFacet(final Class facetType) { 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..891d682e49a 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,12 @@ 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.InteractionConstraint; 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; @@ -102,18 +104,16 @@ public void toDefault(final ManagedObject target) { } @Override - public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + protected UsabilityContext createUsableInteractionContext(final ManagedObject target, + final InteractionConstraint iConstraint) { + return null; + } @Override - public VisibilityContext createVisibleInteractionContext( - final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + protected VisibilityContext createVisibleInteractionContext(final ManagedObject target, + final InteractionConstraint iConstraint) { + return null; + } @Override public boolean containsNonFallbackFacet(final Class facetType) { @@ -157,7 +157,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 +167,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 +177,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 +187,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 +197,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 +206,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/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..b322011d2a9 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.InteractionConstraint; 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, @@ -103,18 +103,16 @@ public void toDefault(final ManagedObject target) { } @Override - public UsabilityContext createUsableInteractionContext( - final ManagedObject target, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + public UsabilityContext createUsableInteractionContext(final ManagedObject ownerAdapter, + final InteractionConstraint iConstraint) { + return super.createUsableInteractionContext(ownerAdapter, iConstraint); + } @Override - public VisibilityContext createVisibleInteractionContext( - final ManagedObject targetObjectAdapter, final InteractionInitiatedBy interactionInitiatedBy, - final Where where) { - return null; - } + public VisibilityContext createVisibleInteractionContext(final ManagedObject ownerAdapter, + final InteractionConstraint iConstraint) { + return super.createVisibleInteractionContext(ownerAdapter, iConstraint); + } @Override public boolean containsNonFallbackFacet(final Class facetType) { 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..de3b9dadb67 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 @@ -33,6 +33,7 @@ import org.apache.causeway.applib.Identifier; import org.apache.causeway.applib.annotation.PriorityPrecedence; +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.applib.services.clock.ClockService; @@ -50,6 +51,8 @@ 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.InteractionConstraint; +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 +152,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 +201,8 @@ private Bookmark doExecuteCommand(final CommandDto dto) { var interactionHead = objectAction.interactionHead(targetAdapter); - var resultAdapter = objectAction.execute(interactionHead, argAdapters, InteractionInitiatedBy.FRAMEWORK); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.FRAMEWORK, Where.NOT_SPECIFIED); + var resultAdapter = objectAction.execute(interactionHead, argAdapters, iConstraint); // flush any PersistenceCommands pending // (else might get transient objects for the return value) @@ -213,10 +216,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 +228,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 +250,10 @@ private String targetBookmarkStrFor(final CommandDto dto) { private String argStrFor(final CommandDto dto) { var memberDto = dto.getMember(); - if(memberDto instanceof ActionDto) { - var actionDto = (ActionDto) memberDto; + if(memberDto instanceof ActionDto actionDto) { return paramNameArgValuesFor(actionDto); } - if(memberDto instanceof PropertyDto) { - var propertyDto = (PropertyDto) memberDto; + if(memberDto instanceof PropertyDto propertyDto) { var proposedValue = valueMarshaller.recoverPropertyFrom(propertyDto); return proposedValue.getTitle(); } @@ -274,9 +273,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 +290,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/wrapper/handlers/DomainObjectInvocationHandler.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/wrapper/handlers/DomainObjectInvocationHandler.java index 091d2dd3c20..181827d98fe 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; @@ -51,7 +50,9 @@ 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.InteractionConstraint; 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; @@ -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)) .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)); return MmUnwrapUtils.single(returnedAdapter); }, ()->new ExceptionLogger("action " + objectAction.getId(), targetAdapter)); } @@ -428,33 +400,33 @@ 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)) .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 interactionResult = objectMember.isVisible(targetObjectAdapter, iConstraint(wrapperInvocation)) + .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -463,10 +435,7 @@ private void checkUsability( final ManagedObject targetObjectAdapter, final ObjectMember objectMember) { - var interactionResult = objectMember.isUsable( - targetObjectAdapter, - getInteractionInitiatedBy(wrapperInvocation), - where) + var interactionResult = objectMember.isUsable(targetObjectAdapter, iConstraint(wrapperInvocation)) .getInteractionResult(); notifyListenersAndVetoIfRequired(interactionResult); } @@ -477,9 +446,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 +456,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 +474,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 +493,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 +508,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 +534,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() 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/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); + } } 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/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..2f76a8aacd2 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,9 @@ 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.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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.PropertyInteraction; import org.apache.causeway.core.metamodel.object.ManagedObject; @@ -128,73 +131,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->{ - case PROPERTY_UPDATE: + context.runGiven(); - withBookDo(book->{ + // when - direct change (circumventing the framework) + context.changeProperty(()->book.setName("Book #2")); - context.runGiven(); + repository.persistAndFlush(book); - // when - direct change (circumventing the framework) - context.changeProperty(()->book.setName("Book #2")); + }); + case ACTION_INVOCATION -> withBookDo(book->{ - repository.persistAndFlush(book); + context.runGiven(); - }); + // when - direct action method invocation (circumventing the framework) + context.executeAction(()->book.doubleThePrice()); - break; - case ACTION_INVOCATION: + repository.persistAndFlush(book); - withBookDo(book->{ + }); + case ENTITY_REMOVAL -> withBookDo(book->{ - context.runGiven(); + context.runGiven(); + //when + repository.removeAndFlush(book); - // when - direct action method invocation (circumventing the framework) - context.executeAction(()->book.doubleThePrice()); - - repository.persistAndFlush(book); - - }); - - break; - case ENTITY_REMOVAL: - - withBookDo(book->{ - - context.runGiven(); - //when - repository.removeAndFlush(book); - - }); - - break; - default: - throw _Exceptions.unmatchedCase(context.scenario()); - } + }); + default -> throw _Exceptions.unmatchedCase(context.scenario()); + } + ; } @@ -204,55 +189,47 @@ protected void programmaticExecution( protected void interactionApiExecution( final PublishingTestContext context) { - context.bind(commitListener); - - switch(context.scenario()) { - - case PROPERTY_UPDATE: - - withBookDo(book->{ - - context.runGiven(); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.OBJECT_FORMS); - // when - context.changeProperty(()->{ - - 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.bind(commitListener); - }); + switch (context.scenario()) { + case PROPERTY_UPDATE -> withBookDo(book->{ - }); + context.runGiven(); - break; - case ACTION_INVOCATION: + // when + context.changeProperty(()->{ + var bookAdapter = objectManager.adapt(book); + var propertyInteraction = PropertyInteraction.start(bookAdapter, "name", iConstraint); + var managedProperty = propertyInteraction.getManagedPropertyElseThrow(__->_Exceptions.noSuchElement()); + var propertyModel = managedProperty.startNegotiation(); + var propertySpec = managedProperty.getElementType(); + propertyModel.getValue().setValue(ManagedObject.value(propertySpec, "Book #2")); + propertyModel.submit(); - withBookDo(book->{ + }); - context.runGiven(); + }); + case ACTION_INVOCATION -> withBookDo(book->{ - // when - context.executeAction(()->{ + context.runGiven(); - var bookAdapter = objectManager.adapt(book); + // when + context.executeAction(()->{ - 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 bookAdapter = objectManager.adapt(book); - }); + var actionInteraction = ActionInteraction.start(bookAdapter, "doubleThePrice", iConstraint); + 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 +241,28 @@ protected void wrapperSyncExecutionNoRules( context.bind(commitListener); - switch(context.scenario()) { + switch (context.scenario()) { + case PROPERTY_UPDATE -> withBookDo(book->{ - case PROPERTY_UPDATE: - - withBookDo(book->{ + context.runGiven(); - context.runGiven(); + // when - running synchronous + var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules + context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2")); - // when - running synchronous - var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules - context.changeProperty(()->wrapper.wrap(book, syncControl).setName("Book #2")); + }); + case ACTION_INVOCATION -> withBookDo(book->{ - }); + context.runGiven(); - break; - case ACTION_INVOCATION: + // when - running synchronous + var syncControl = SyncControl.defaults().withSkipRules(); // don't enforce rules + context.executeAction(()->wrapper.wrap(book, syncControl).doubleThePrice()); - withBookDo(book->{ - - 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 +272,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..852a3fbcca8 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 @@ -55,6 +55,7 @@ import org.apache.causeway.core.config.CausewayConfiguration; import org.apache.causeway.core.config.environment.CausewaySystemEnvironment; import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.HasMetaModelContext; import org.apache.causeway.core.metamodel.context.MetaModelContext; import org.apache.causeway.core.metamodel.facetapi.Facet; @@ -62,8 +63,11 @@ 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.InteractionConstraint; +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.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; @@ -87,6 +91,7 @@ import lombok.Getter; import lombok.SneakyThrows; +import lombok.experimental.Accessors; @Service public class DomainObjectTesterFactory implements HasMetaModelContext { @@ -94,7 +99,7 @@ public class DomainObjectTesterFactory implements HasMetaModelContext { public ObjectTester objectTester( final T domainObject) { var tester = getServiceInjector().injectServicesInto( - new ObjectTester(domainObject)); + new ObjectTester<>(domainObject)); return tester; } @@ -102,8 +107,9 @@ public ActionTester actionTester( final T domainObject, final String actionName, final Where where) { + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); var tester = getServiceInjector().injectServicesInto( - new ActionTester(domainObject, actionName, where)); + new ActionTester<>(domainObject, actionName, iConstraint)); tester.init(); return tester; } @@ -124,8 +130,9 @@ public PropertyTester propertyTester( final T domainObject, final String propertyName, final Where where) { + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); var tester = getServiceInjector().injectServicesInto( - new PropertyTester(domainObject, propertyName, where)); + new PropertyTester<>(domainObject, propertyName, iConstraint)); tester.init(); return tester; } @@ -134,8 +141,9 @@ public CollectionTester collectionTester( final T domainObject, final String collectionName, final Where where) { + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); var tester = getServiceInjector().injectServicesInto( - new CollectionTester(domainObject, collectionName, where)); + new CollectionTester<>(domainObject, collectionName, iConstraint)); tester.init(); return tester; } @@ -290,7 +298,7 @@ private ActionTester( super(domainObject, managedAction.getId(), "actionName", - managedAction.getWhere()); + managedAction.iConstraint()); this.actionInteraction = actionInteraction; this.parameterNegotiationStarter = ()-> actionInteraction @@ -303,8 +311,8 @@ private ActionTester( private ActionTester( final @NonNull T domainObject, final @NonNull String actionName, - final @NonNull Where where) { - super(domainObject, actionName, "actionName", where); + final @NonNull InteractionConstraint iConstraint) { + super(domainObject, actionName, "actionName", iConstraint); this.parameterNegotiationStarter = null; } @@ -349,8 +357,9 @@ public Optional getElementType() { @Override protected Optional startInteractionOn(final ManagedObject viewModel) { if(parameterNegotiationStarter==null) { + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); this.actionInteraction = ActionInteraction - .start(viewModel, getMemberName(), Where.NOT_SPECIFIED); + .start(viewModel, getMemberName(), iConstraint); } assertNotNull(actionInteraction); return getManagedAction(); @@ -719,8 +728,8 @@ public static class PropertyTester private PropertyTester( final @NonNull T domainObject, final @NonNull String propertyName, - final @NonNull Where where) { - super(domainObject, propertyName, "property", where); + final @NonNull InteractionConstraint iConstraint) { + super(domainObject, propertyName, "property", iConstraint); } @Override @@ -743,7 +752,7 @@ protected Optional getElementType() { @Override protected Optional startInteractionOn(final ManagedObject viewModel) { return this.managedPropertyIfAny = PropertyInteraction - .start(viewModel, getMemberName(), where) + .start(viewModel, getMemberName(), iConstraint) .getManagedProperty(); } @@ -930,8 +939,8 @@ public static class CollectionTester private CollectionTester( final @NonNull T domainObject, final @NonNull String collectionName, - final @NonNull Where where) { - super(domainObject, collectionName, "collection", where); + final @NonNull InteractionConstraint iConstraint) { + super(domainObject, collectionName, "collection", iConstraint); } @Override @@ -953,8 +962,9 @@ protected Optional getElementType() { @Override protected Optional startInteractionOn(final ManagedObject viewModel) { + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); return this.managedCollectionIfAny = CollectionInteraction - .start(viewModel, getMemberName(), Where.NOT_SPECIFIED) + .start(viewModel, getMemberName(), iConstraint) .getManagedCollection(); } @@ -1002,7 +1012,7 @@ private static abstract class MemberTester @Getter private final String memberName; private final String memberSort; - protected final Where where; + @Getter @Accessors(fluent = true) protected final InteractionConstraint iConstraint; private Optional managedMemberIfAny; @@ -1010,11 +1020,11 @@ protected MemberTester( final @NonNull T domainObject, final @NonNull String memberName, final @NonNull String memberSort, - final @NonNull Where where) { + final @NonNull InteractionConstraint iConstraint) { super(domainObject); this.memberName = memberName; this.memberSort = memberSort; - this.where = where; + this.iConstraint = iConstraint; } protected final MemberTester init() { @@ -1110,7 +1120,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 +1141,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 +1172,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..5a3fd410428 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,20 @@ 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.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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.CollectionInteraction; import org.apache.causeway.core.metamodel.interactions.managed.PropertyInteraction; @@ -70,19 +73,22 @@ 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); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); + return ActionInteraction.start(managedObject, actionId, iConstraint); } 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); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); + return PropertyInteraction.start(managedObject, propertyId, iConstraint); } 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); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, where); + return CollectionInteraction.start(managedObject, collectionId, iConstraint); } // -- SHORTCUTS 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 @@ - + - + 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..2b69a9f2be0 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 @@ -113,7 +113,7 @@ void choicesFromMultiselect() { var table = tableTester.getDataTable(); var actionInteraction = table - .startAssociatedActionInteraction("doSomethingWithItems", Where.OBJECT_FORMS); + .startAssociatedActionInteraction("doSomethingWithItems", collTester.iConstraint().withWhere(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..f207d66aba3 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,8 @@ 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.InteractionConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; 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; @@ -100,10 +102,10 @@ public void testComposer( var valueMixin = (Object)null; if(valueMixin!=null) { - + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.ANYWHERE); var spec = specLoader.specForTypeElseFail(valueMixin.getClass()); var interaction = ActionInteraction - .start(ManagedObject.mixin(spec, valueMixin), "act", Where.ANYWHERE); + .start(ManagedObject.mixin(spec, valueMixin), "act", iConstraint); var pendingParams = interaction .startParameterNegotiation() @@ -169,9 +171,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 +193,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..eaef9f3c698 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; @@ -39,7 +41,10 @@ import org.apache.causeway.applib.value.semantics.ValueSemanticsProvider; import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.commons.internal.exceptions._Exceptions; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.facets.object.value.ValueFacet; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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.ManagedProperty; @@ -49,7 +54,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 { @@ -85,13 +89,14 @@ public void actionInteraction( var act = objSpec.getActionElseFail(actionId); var context = valueFacet(act.getParameters().getFirstElseFail()) .createValueSemanticsContext(act); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.OBJECT_FORMS); { var actionCommandWithNonEmptyArg = interactionService.call(interactionContext, ()->{ 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, iConstraint)); var params = actInteraction.startParameterNegotiation().orElseThrow(); var singleArgPojoToUse = actionArgumentProvider.get(); @@ -111,7 +116,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, iConstraint)); var params = actInteraction.startParameterNegotiation().orElseThrow(); @@ -172,6 +177,7 @@ public void propertyInteraction( var objSpec = specLoader.specForTypeElseFail(domainObject.getClass()); var prop = objSpec.getPropertyElseFail(propertyId); + var iConstraint = new InteractionConstraint(WhatViewer.noViewer(), InteractionInitiatedBy.USER, Where.OBJECT_FORMS); var context = valueFacet(prop) .createValueSemanticsContext(prop); @@ -199,7 +205,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, iConstraint)); 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/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 a98beadb512..5be820966a2 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 @@ -27,8 +27,12 @@ import org.apache.causeway.applib.fa.FontAwesomeLayers; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.core.metamodel.consent.Consent.VetoReason; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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.InteractionConstraint; +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; import org.apache.causeway.core.metamodel.util.Facets; @@ -57,7 +61,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()) @@ -77,10 +81,11 @@ 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(), Where.NOT_SPECIFIED); + var iConstraint = new InteractionConstraint(whatViewer, InteractionInitiatedBy.USER, Where.NOT_SPECIFIED); + return ManagedAction.lookupAction(service, actionId.memberLogicalName(), iConstraint); } } 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..1eb57f63ea9 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,8 @@ 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.InteractionConstraint; +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; @@ -42,37 +44,31 @@ public interface UiActionForm // -- USABILITY - default Consent getUsabilityConsent() { - return getAction().isUsable( - getActionOwner(), - InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + default Consent getUsabilityConsent(final WhatViewer whatViewer) { + var iConstraint = new InteractionConstraint(whatViewer, InteractionInitiatedBy.USER, Where.OBJECT_FORMS); + return getAction().isUsable(getActionOwner(), iConstraint); } // -- VISABILITY - default Consent getVisibilityConsent() { + default Consent getVisibilityConsent(final WhatViewer whatViewer) { // 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; - } - - return getAction().isVisible( - actionOwner, - InteractionInitiatedBy.USER, - Where.OBJECT_FORMS); + if (getActionOwner().objSpec().isHidden()) + return Veto.DEFAULT; + + var iConstraint = new InteractionConstraint(whatViewer, InteractionInitiatedBy.USER, Where.OBJECT_FORMS); + return getAction().isVisible(actionOwner, iConstraint); } // -- VALIDITY - default Consent getValidityConsent() { + default Consent getValidityConsent(final WhatViewer whatViewer) { var proposedArguments = streamPendingParamUiModels() .map(UiParameter::getValue) @@ -82,11 +78,8 @@ default Consent getValidityConsent() { var head = getAction().interactionHead(getActionOwner()); - return getAction().isArgumentSetValid( - head, - proposedArguments, - InteractionInitiatedBy.USER); - + var iConstraint = new InteractionConstraint(whatViewer, InteractionInitiatedBy.USER, Where.OBJECT_FORMS); + return getAction().isArgumentSetValid(head, proposedArguments, iConstraint); } // -- HAS TITLE 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 c09ba54396a..2f227dd0ba3 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,18 +20,22 @@ 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; import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBar; import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuSection; import org.apache.causeway.commons.internal.base._Strings; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.context.MetaModelContext; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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; -import org.jspecify.annotations.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -53,11 +57,12 @@ static interface Visitor { static void buildMenuItems( final MetaModelContext mmc, + final WhatViewer whatViewer, final BSMenuBar menuBar, final Visitor menuBuilder) { + var iConstraint = new InteractionConstraint(whatViewer, InteractionInitiatedBy.USER, Where.ANYWHERE); var itemsPerSectionCounter = new LongAdder(); - var menuVisitor = MenuProcessor.of(mmc, menuBuilder); for (var menu : menuBar.getMenus()) { @@ -78,7 +83,7 @@ static void buildMenuItems( } var managedAction = ManagedAction - .lookupAction(serviceAdapter, actionLayoutData.getId(), Where.EVERYWHERE) + .lookupAction(serviceAdapter, actionLayoutData.getId(), iConstraint) .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..f44016575e6 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,9 @@ 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.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +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; @@ -104,10 +108,22 @@ public List objectSpecifications(final Predicate< .toList(); } + // -- UTILITY + + private static WhatViewer WHAT_VIEWER = new WhatViewer("Graphql"); + public static InteractionConstraint iConstraint(final Where where) { + return new InteractionConstraint(WHAT_VIEWER, InteractionInitiatedBy.USER, where); + } + private static InteractionConstraint DEFAULT_INTERACTION_CONSTRAINT = iConstraint(Where.ANYWHERE); + public static InteractionConstraint iConstraint() { + return DEFAULT_INTERACTION_CONSTRAINT; + } + + // -- HELPER + private void computeLogicalTypeNames() { - if (logicalTypeNames != null) { - return; - } + if (logicalTypeNames != null) + return; logicalTypeNames = doComputeLogicalTypeNames(); graphQLTypeRegistry.addTypeIfNotAlreadyPresent(logicalTypeNames); } 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..5ace82877b2 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,10 +33,8 @@ 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; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -159,35 +157,32 @@ 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 iConstraint = Context.iConstraint(); + var managedObject = ManagedObject.adaptSingular(objectSpec, sourcePojo); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, iConstraint); + 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, iConstraint); + 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")); - } + var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, iConstraint); + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, iConstraint); 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..87c73fdf606 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,13 @@ 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 +106,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. @@ -121,22 +118,21 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Object argumentValue = arguments.get(oneToOneAssociation.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(oneToOneAssociation, argumentValue); - var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - } + var iConstraint = Context.iConstraint(); - var usableConsent = oneToOneAssociation.isUsable(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (usableConsent.isVetoed()) { - throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); - } + var visibleConsent = oneToOneAssociation.isVisible(managedObject, iConstraint); + if (visibleConsent.isVetoed()) + throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + var usableConsent = oneToOneAssociation.isUsable(managedObject, iConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); + + var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, iConstraint); + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); - oneToOneAssociation.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); + oneToOneAssociation.set(managedObject, argumentManagedObject, iConstraint.initiatedBy()); return managedObject; // return the original object because setters return void } 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..48be681cb21 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,8 +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; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; @@ -106,32 +104,29 @@ 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 iConstraint = Context.iConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, iConstraint); + 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, iConstraint); + 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")); - } + var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, iConstraint); + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, iConstraint); 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..e884859fbf7 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 @@ -29,17 +29,16 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLNonNull.nonNull; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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 +78,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 +88,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.iConstraint()); 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..e1531cdffbc 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 @@ -27,17 +27,16 @@ 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.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 +70,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 +80,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.iConstraint()); 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..720cd3b1704 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 @@ -24,14 +24,13 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.applib.annotation.Where; 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.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 +64,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.iConstraint()); 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/RichActionParamsParamDisabled.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java index eb6ac169585..45f291c4b10 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java @@ -22,7 +22,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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; @@ -57,9 +56,8 @@ protected String fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojo = BookmarkedPojo.sourceFrom(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return "Disabled"; - } + if (objectSpecification == null) + return "Disabled"; var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -69,7 +67,8 @@ protected String fetchData(final DataFetchingEnvironment dataFetchingEnvironment var objectActionParameter = objectAction.getParameterById(objectFeature.asciiId()); var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var usable = objectActionParameter.isUsable(actionInteractionHead, argumentManagedObjects, InteractionInitiatedBy.USER); + var iConstraint = Context.iConstraint(); + var usable = objectActionParameter.isUsable(actionInteractionHead, argumentManagedObjects, iConstraint); return usable.isVetoed() ? usable.getReasonAsString().orElse("Disabled") : null; } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java index a5586528c01..3e98c1d453a 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java @@ -23,14 +23,13 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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; @@ -60,9 +59,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - return true; - } + if (objectSpecification == null) + return true; var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -73,7 +71,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var visible = objectActionParameter.isVisible(actionInteractionHead, argumentManagedObjects, InteractionInitiatedBy.USER); + var iConstraint = Context.iConstraint(); + var visible = objectActionParameter.isVisible(actionInteractionHead, argumentManagedObjects, iConstraint); return visible.isVetoed(); } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java index 9db127ea7df..2b065c1bc02 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java @@ -22,7 +22,6 @@ import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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; @@ -59,9 +58,8 @@ protected String fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - return "Invalid"; - } + if (objectSpecification == null) + return "Invalid"; var objectAction = actionParamInteractor.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -72,7 +70,8 @@ protected String fetchData(final DataFetchingEnvironment dataFetchingEnvironment var argumentManagedObjects = actionParamInteractor.argumentManagedObjectsFor(new Environment.For(dataFetchingEnvironment), objectAction, context.bookmarkService); - var usable = objectActionParameter.isUsable(actionInteractionHead, argumentManagedObjects, InteractionInitiatedBy.USER); + var iConstraint = Context.iConstraint(); + var usable = objectActionParameter.isUsable(actionInteractionHead, argumentManagedObjects, iConstraint); return usable.isVetoed() ? usable.getReasonAsString().orElse("Invalid") : null; } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java index 2aaf5f6cdf2..c95e3477d88 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java @@ -26,7 +26,6 @@ import org.apache.causeway.commons.collections.Can; import org.apache.causeway.core.metamodel.consent.Consent; -import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; 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.ObjectActionParameter; @@ -70,10 +69,9 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojoClass = sourcePojo.getClass(); var specificationLoader = objectAction.getSpecificationLoader(); var objectSpecification = specificationLoader.loadSpecification(sourcePojoClass); - if (objectSpecification == null) { - // not expected + if (objectSpecification == null) + // not expected return null; - } var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); var actionInteractionHead = objectAction.interactionHead(managedObject); @@ -86,7 +84,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment return ManagedObject.adaptParameter(oap, argumentValue); }); - Consent consent = objectAction.isArgumentSetValid(actionInteractionHead, argumentManagedObjects, InteractionInitiatedBy.USER); + var iConstraint = Context.iConstraint(); + Consent consent = objectAction.isArgumentSetValid(actionInteractionHead, argumentManagedObjects, iConstraint); return consent.isVetoed() ? consent.getReasonAsString().orElse("Invalid") : null; } 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..8ec095fd94c 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,8 +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; import org.apache.causeway.viewer.graphql.model.context.Context; @@ -58,14 +56,14 @@ 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 iConstraint = Context.iConstraint(); + var usable = objectMember.isUsable(managedObject, iConstraint); 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..dbc3c9d313a 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,8 +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; import org.apache.causeway.viewer.graphql.model.context.Context; @@ -58,15 +56,15 @@ 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 iConstraint = Context.iConstraint(); + var visibleConsent = objectMember.isVisible(managedObject, iConstraint); 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..03b261728b5 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,8 +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; import org.apache.causeway.viewer.graphql.model.domain.Element; @@ -64,9 +62,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); @@ -75,22 +72,20 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Object argumentValue = arguments.get(otoa.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(otoa, argumentValue); - var visibleConsent = otoa.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(otoa.getFeatureIdentifier()); - } + var iConstraint = Context.iConstraint(); + var visibleConsent = otoa.isVisible(managedObject, iConstraint); + 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, iConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(otoa.getFeatureIdentifier()); - var validityConsent = otoa.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + var validityConsent = otoa.isAssociationValid(managedObject, argumentManagedObject, iConstraint); + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); - otoa.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); + otoa.set(managedObject, argumentManagedObject, iConstraint.initiatedBy()); return managedObject; // return the original object because setters return void } diff --git a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java index 7d30975e275..5d5528b3dca 100644 --- a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java +++ b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java @@ -19,11 +19,9 @@ package org.apache.causeway.viewer.graphql.model.domain.rich.query; import graphql.schema.DataFetchingEnvironment; -import graphql.schema.GraphQLOutputType; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; -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; import org.apache.causeway.viewer.graphql.model.domain.Element; @@ -43,7 +41,7 @@ public RichPropertyValidate( var fieldBuilder = newFieldDefinition() .name("validate") - .type((GraphQLOutputType) context.typeMapper.outputTypeFor(String.class)); + .type(context.typeMapper.outputTypeFor(String.class)); propertyInteractor.addGqlArgument(propertyInteractor.getObjectMember(), fieldBuilder, TypeMapper.InputContext.VALIDATE); setField(fieldBuilder.build()); @@ -55,9 +53,8 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var sourcePojo = BookmarkedPojo.sourceFrom(dataFetchingEnvironment); var objectSpecification = context.specificationLoader.loadSpecification(sourcePojo.getClass()); - if (objectSpecification == null) { - return null; - } + if (objectSpecification == null) + return null; var otoa = holder.getObjectMember(); var managedObject = ManagedObject.adaptSingular(objectSpecification, sourcePojo); @@ -66,7 +63,7 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment var argumentValue = arguments.get(otoa.asciiId()); var argumentManagedObject = ManagedObject.adaptProperty(otoa, argumentValue); - var valid = otoa.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); + var valid = otoa.isAssociationValid(managedObject, argumentManagedObject, Context.iConstraint()); return valid.isVetoed() ? valid.getReasonAsString().orElse("invalid") : null; } 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..c4f8d789eef 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,10 +33,8 @@ 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; import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -158,35 +156,32 @@ 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 iConstraint = Context.iConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, iConstraint); + 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, iConstraint); + 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")); - } + var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, iConstraint); + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, iConstraint); 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..e2777a966b0 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,13 @@ 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 +108,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,23 +119,21 @@ protected Object fetchData(final DataFetchingEnvironment dataFetchingEnvironment Map arguments = dataFetchingEnvironment.getArguments(); Object argumentValue = arguments.get(oneToOneAssociation.asciiId()); ManagedObject argumentManagedObject = ManagedObject.adaptProperty(oneToOneAssociation, argumentValue); + var iConstraint = Context.iConstraint(); - var visibleConsent = oneToOneAssociation.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(oneToOneAssociation.getFeatureIdentifier()); - } + var visibleConsent = oneToOneAssociation.isVisible(managedObject, iConstraint); + 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, iConstraint); + if (usableConsent.isVetoed()) + throw new DisabledException(oneToOneAssociation.getFeatureIdentifier()); - var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); - if (validityConsent.isVetoed()) { - throw new InvalidException(validityConsent); - } + var validityConsent = oneToOneAssociation.isAssociationValid(managedObject, argumentManagedObject, iConstraint); + if (validityConsent.isVetoed()) + throw new InvalidException(validityConsent); - oneToOneAssociation.set(managedObject, argumentManagedObject, InteractionInitiatedBy.USER); + oneToOneAssociation.set(managedObject, argumentManagedObject, iConstraint.initiatedBy()); return managedObject; // return the original object because setters return void } 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..4ea4341ba8d 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,11 +32,9 @@ 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; -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; import org.apache.causeway.core.metamodel.spec.ObjectSpecification; @@ -152,10 +150,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 +187,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 +206,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 +228,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,32 +292,29 @@ 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 iConstraint = Context.iConstraint(); - var visibleConsent = objectAction.isVisible(managedObject, InteractionInitiatedBy.USER, Where.ANYWHERE); - if (visibleConsent.isVetoed()) { - throw new HiddenException(objectAction.getFeatureIdentifier()); - } + var visibleConsent = objectAction.isVisible(managedObject, iConstraint); + 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, iConstraint); + 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")); - } + var validityConsent = objectAction.isArgumentSetValid(head, argumentManagedObjects, iConstraint); + if (validityConsent.isVetoed()) + throw new IllegalArgumentException(validityConsent.getReasonAsString().orElse("Invalid")); - var resultManagedObject = objectAction.execute(head, argumentManagedObjects, InteractionInitiatedBy.USER); + var resultManagedObject = objectAction.execute(head, argumentManagedObjects, iConstraint); 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..c198ed26c95 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,11 +24,10 @@ 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.InteractionConstraint; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer; import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo; @@ -39,7 +38,7 @@ * session-specific context (eg authentication) and * global context (eg configuration settings). * - * @since 1.x {@index} + * @since 1.x revised for 4.0 {@index} */ public interface IResourceContext extends HasMetaModelContext { @@ -62,13 +61,9 @@ public interface IResourceContext extends HasMetaModelContext { List acceptableMediaTypes(); /** - * Whether this interaction was initiated directly by a - * {@link InteractionInitiatedBy#USER user} (or indirectly by the - * {@link InteractionInitiatedBy#FRAMEWORK framework}. + * @since 4.0 */ - InteractionInitiatedBy interactionInitiatedBy(); - - Where where(); + InteractionConstraint iConstraint(); ObjectAdapterLinkTo objectAdapterLinkTo(); List> followLinks(); diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java index 5795181d4b4..5ab2b5ab8da 100644 --- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java +++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java @@ -71,7 +71,7 @@ public ReprRendererAbstract( private static InteractionInitiatedBy determineInteractionInitiatedByFrom( final IResourceContext resourceContext) { - return resourceContext.interactionInitiatedBy(); + return resourceContext.iConstraint().initiatedBy(); } protected InteractionInitiatedBy getInteractionInitiatedBy() { @@ -83,9 +83,8 @@ public LinkFollowSpecs getLinkFollowSpecs() { } private LinkFollowSpecs asProvidedElseCreate(final LinkFollowSpecs linkFollower) { - if (linkFollower != null) { - return linkFollower; - } + if (linkFollower != null) + return linkFollower; return LinkFollowSpecs.create(resourceContext.followLinks()); } @@ -112,9 +111,8 @@ public > R withLink(final Rel rel, final Strin public > R withLink(final Rel rel, final JsonRepresentation link) { final String relStr = link.getString("rel"); - if (relStr == null || !relStr.equals(rel.getName())) { - throw new IllegalArgumentException("Provided link does not have a 'rel' of '" + rel.getName() + "'; was: " + link); - } + if (relStr == null || !relStr.equals(rel.getName())) + throw new IllegalArgumentException("Provided link does not have a 'rel' of '" + rel.getName() + "'; was: " + link); if (link != null) { getLinks().arrayAdd(link); } @@ -134,9 +132,8 @@ protected JsonRepresentation getLinks() { } protected void addLink(final Rel rel, final ObjectSpecification objectSpec) { - if (objectSpec == null) { - return; - } + if (objectSpec == null) + return; final LinkBuilder linkBuilder = DomainTypeReprRenderer.newLinkToBuilder(getResourceContext(), rel, objectSpec); JsonRepresentation link = linkBuilder.build(); getLinks().arrayAdd(link); @@ -163,9 +160,8 @@ protected JsonRepresentation getExtensions() { } public ReprRendererAbstract withExtensions(final JsonRepresentation extensions) { - if (!extensions.isMap()) { - throw new IllegalArgumentException("extensions must be a map"); - } + if (!extensions.isMap()) + throw new IllegalArgumentException("extensions must be a map"); representation.mapPutJsonRepresentation("extensions", extensions); return this; } @@ -189,9 +185,8 @@ protected final void addExtensionsCausewayProprietaryChangedObjects() { } private void addToExtensions(final String key, final List adapters) { - if(adapters == null || adapters.isEmpty()) { - return; - } + if(adapters == null || adapters.isEmpty()) + return; final JsonRepresentation adapterList = JsonRepresentation.newArray(); getExtensions().mapPutJsonRepresentation(key, adapterList); for (var adapter : adapters) { 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..5ae393c4ab9 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 @@ -35,7 +35,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.apache.causeway.applib.annotation.Where; import org.apache.causeway.applib.id.LogicalType; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.commons.internal.base._Strings; @@ -43,6 +42,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.InteractionConstraint; +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; @@ -69,7 +70,7 @@ public record ResourceContext( List> followLinks, boolean isValidateOnly, - InteractionInitiatedBy interactionInitiatedBy, + InteractionConstraint iConstraint, JsonRepresentation queryStringAsJsonRepr, ObjectAdapterLinkTo objectAdapterLinkTo, @@ -94,7 +95,8 @@ public ResourceContext( metaModelContext, resourceDescriptor, applicationAbsoluteBase, restfulAbsoluteBase, - httpServletRequest, httpServletResponse, interactionInitiatedBy, + httpServletRequest, httpServletResponse, + new InteractionConstraint(new WhatViewer("Restful"), interactionInitiatedBy, resourceDescriptor.where()), requestArgsAsMap(requestParams, urlUnencodedQueryString)); } @@ -105,7 +107,7 @@ private ResourceContext( final String restfulAbsoluteBase, final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse, - final InteractionInitiatedBy interactionInitiatedBy, + final InteractionConstraint iConstraint, final JsonRepresentation requestArgsAsMap) { this(metaModelContext, resourceDescriptor, @@ -115,7 +117,7 @@ private ResourceContext( _Strings.suffix(restfulAbsoluteBase, "/"), Collections.unmodifiableList(arg(requestArgsAsMap, RequestParameter.FOLLOW_LINKS)), arg(requestArgsAsMap, RequestParameter.VALIDATE_ONLY), - interactionInitiatedBy, + iConstraint, requestArgsAsMap, switch(resourceDescriptor.resourceLink()) { case NONE -> null; @@ -127,10 +129,6 @@ private ResourceContext( ensureDomainModelQueryParamSupported(); } - @Override public Where where() { - return resourceDescriptor().where(); - } - /** * Only applies to rendering of objects */ @@ -140,13 +138,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 +161,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 +229,15 @@ 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; } // -- 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 +246,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..caa22d876d1 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.InteractionConstraint; 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; @@ -38,6 +37,8 @@ import org.apache.causeway.viewer.restfulobjects.rendering.LinkFollowSpecs; import org.apache.causeway.viewer.restfulobjects.rendering.ReprRendererAbstract; +import tools.jackson.databind.node.NullNode; + public abstract class AbstractObjectMemberReprRenderer extends ReprRendererAbstract { @@ -86,7 +87,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 InteractionConstraint iConstraint; public AbstractObjectMemberReprRenderer( final IResourceContext resourceContext, @@ -97,7 +98,7 @@ public AbstractObjectMemberReprRenderer( final Where where) { super(resourceContext, linkFollower, representationType, representation); this.memberId = memberId; - this.where = where; + this.iConstraint = new InteractionConstraint(resourceContext.iConstraint().whatViewer(), resourceContext.iConstraint().initiatedBy(), where); } protected String getMemberId() { @@ -221,9 +222,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 +243,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 +256,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 +276,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 +301,11 @@ protected F getMemberSpecFacet(final Class facetType) { } protected Consent usability() { - return objectMember.isUsable(objectAdapter, getInteractionInitiatedBy(), where); + return objectMember.isUsable(objectAdapter, iConstraint); } protected Consent visibility() { - return objectMember.isVisible(objectAdapter, getInteractionInitiatedBy(), where); + return objectMember.isVisible(objectAdapter, iConstraint); } } 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..75ec13c51c3 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, resourceContext.iConstraint()); 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.iConstraint())).usingLinkTo(linkToBuilder); if (mode.isArgs()) { renderer.asArguments(); @@ -345,27 +343,24 @@ 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, resourceContext.iConstraint()); 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.iConstraint())) + .usingLinkTo(linkToBuilder); if(mode.isEventSerialization()) { renderer.asEventSerialization(); } @@ -381,7 +376,7 @@ private void addActions( actions .filter(action->{ - final Consent visibility = action.isVisible(objectAdapter, getInteractionInitiatedBy(), resourceContext.where()); + final Consent visibility = action.isVisible(objectAdapter, resourceContext.iConstraint()); return visibility.isAllowed(); }) .forEach(action->{ @@ -390,18 +385,16 @@ 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.iConstraint())) + .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 +421,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..6af08371453 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; @@ -39,6 +37,8 @@ import org.apache.causeway.viewer.restfulobjects.rendering.LinkFollowSpecs; import org.apache.causeway.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer; +import tools.jackson.databind.node.NullNode; + public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer { @@ -51,8 +51,7 @@ public ObjectActionReprRenderer( final LinkFollowSpecs linkFollowSpecs, final String actionId, final JsonRepresentation representation) { - super(resourceContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation, - Where.OBJECT_FORMS); + super(resourceContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation, Where.OBJECT_FORMS); } @Override @@ -75,9 +74,10 @@ 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.iConstraint())) + .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.iConstraint()); 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..f012f055143 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.iConstraint())) .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..dcd41cf135a 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.iConstraint)).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..9f66a40df3d 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} */ @@ -87,7 +88,8 @@ public ResponseEntity buildResponse( final IResourceContext resourceContext, final ManagedObject objectAdapter) { - if(!canAccept(resourceContext)) return null; + if(!canAccept(resourceContext)) + return null; final EnumSet suppression = suppress(resourceContext); final boolean suppressRO = suppression.contains(SuppressionType.RO); @@ -128,7 +130,8 @@ public ResponseEntity buildResponse( final IResourceContext resourceContext, final ManagedCollection managedCollection) { - if(!canAccept(resourceContext)) return null; + if(!canAccept(resourceContext)) + return null; final EnumSet suppression = suppress(resourceContext); final boolean suppressRO = suppression.contains(SuppressionType.RO); @@ -177,7 +180,8 @@ public ResponseEntity buildResponse( final IResourceContext resourceContext, final ObjectAndActionInvocation objectAndActionInvocation) { - if(!canAccept(resourceContext)) return null; + if(!canAccept(resourceContext)) + return null; final EnumSet suppression = suppress(resourceContext); final boolean suppressRO = suppression.contains(SuppressionType.RO); @@ -198,11 +202,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 +216,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 +239,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 +259,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 +284,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,8 +314,6 @@ private void appendObjectTo( appendPropertiesTo(resourceContext, owner, rootRepresentation, suppression); - var where = resourceContext.where(); - owner.objSpec() .streamCollections(MixedIn.INCLUDED) .forEach(collection->{ @@ -326,13 +321,10 @@ private void appendObjectTo( var collectionRepresentation = JsonRepresentation.newArray(); 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, resourceContext.iConstraint()); + if (!visibilityConsent.isAllowed()) return; - var managedCollection = ManagedCollection.of(owner, collection, where); + var managedCollection = ManagedCollection.of(owner, collection, resourceContext.iConstraint()); appendCollectionTo(resourceContext, managedCollection, collectionRepresentation, suppression); }); @@ -345,22 +337,18 @@ private void appendPropertiesTo( final JsonRepresentation rootRepresentation, final EnumSet suppression) { - var interactionInitiatedBy = resourceContext.interactionInitiatedBy(); - var where = resourceContext.where(); 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, resourceContext.iConstraint()); + 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, resourceContext.iConstraint())); final JsonRepresentation propertyValueRepresentation = renderer.render(); @@ -401,9 +389,9 @@ private void appendCollectionTo( final JsonRepresentation representation, final EnumSet suppression) { - managedCollection.streamElements(resourceContext.interactionInitiatedBy()) - .forEach(element-> - appendElementTo(resourceContext, element, representation, suppression)); + managedCollection.streamElements(resourceContext.iConstraint().initiatedBy()) + .forEach(element-> + appendElementTo(resourceContext, element, representation, suppression)); } private void appendElementTo( 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..8340937d46a 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.iConstraint()) .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.iConstraint()) .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..8e5d429ab7c 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.InteractionConstraint; 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.iConstraint()); } private final ManagedObject managedObject; - private final Where where; + private final InteractionConstraint iConstraint; 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, iConstraint) .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, iConstraint) .checkVisibility() .checkUsability(intent) .getManagedPropertyElseThrow(InteractionFailureHandler::onFailure); @@ -81,11 +82,10 @@ public ManagedCollection getCollectionThatIsVisibleForIntent( final @NonNull AccessIntent intent) { return CollectionInteraction - .start(managedObject, collectionId, where) + .start(managedObject, collectionId, iConstraint) .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..6bee1c949ea 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 @@ -20,7 +20,6 @@ import org.apache.causeway.commons.internal.base._Refs; import org.apache.causeway.core.metamodel.consent.Consent; -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.MixedIn; @@ -85,17 +84,10 @@ private boolean copyOverProperty( final ObjectSpecification propertySpec = property.getElementType(); final String id = property.getId(); final JsonRepresentation propertyRepr = propertiesMap.getRepresentation(id); - final Consent visibility = property.isVisible( - objectAdapter, - resourceContext.interactionInitiatedBy(), - resourceContext.where()); - final Consent usability = property.isUsable( - objectAdapter, - resourceContext.interactionInitiatedBy(), - resourceContext.where() - ); - - final boolean invisible = visibility.isVetoed(); + final Consent visibility = property.isVisible(objectAdapter, resourceContext.iConstraint()); + final Consent usability = property.isUsable(objectAdapter, resourceContext.iConstraint()); + + final boolean hidden = visibility.isVetoed(); final boolean disabled = usability.isVetoed(); final boolean valueProvided = propertyRepr != null; @@ -103,15 +95,13 @@ private boolean copyOverProperty( // no value provided if(intent.shouldValidate()) { - if(invisible || disabled) { - // that's ok, indeed expected + if(hidden || 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 +117,10 @@ private boolean copyOverProperty( if(intent.shouldValidate()) { // value has been provided - if (invisible) { - // silently ignore; don't want to acknowledge the + if (hidden) + // 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)); @@ -151,13 +140,12 @@ private boolean copyOverProperty( return allOk; } // check if the proposed value is valid - final Consent validity = property.isAssociationValid(objectAdapter, valueAdapter, - InteractionInitiatedBy.USER); + final Consent validity = property.isAssociationValid(objectAdapter, valueAdapter, resourceContext.iConstraint()); if (validity.isAllowed()) { try { property.set( objectAdapter, valueAdapter, - resourceContext.interactionInitiatedBy()); + resourceContext.iConstraint().initiatedBy()); } catch (final IllegalArgumentException ex) { propertyRepr.mapPutString("invalidReason", ex.getMessage()); allOk = false; 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..fb6cd85b1b0 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.iConstraint()) .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/applib/src/main/java/module-info.java b/viewers/wicket/applib/src/main/java/module-info.java index d437ec420dc..c9d55553e98 100644 --- a/viewers/wicket/applib/src/main/java/module-info.java +++ b/viewers/wicket/applib/src/main/java/module-info.java @@ -18,6 +18,7 @@ */ module org.apache.causeway.viewer.wicket.applib { exports org.apache.causeway.viewer.wicket.applib; + exports org.apache.causeway.viewer.wicket.applib.annotation; exports org.apache.causeway.viewer.wicket.applib.mixins; requires jakarta.inject; diff --git a/viewers/wicket/applib/src/main/java/org/apache/causeway/viewer/wicket/applib/annotation/WicketViewer.java b/viewers/wicket/applib/src/main/java/org/apache/causeway/viewer/wicket/applib/annotation/WicketViewer.java new file mode 100644 index 00000000000..82650d7ab2c --- /dev/null +++ b/viewers/wicket/applib/src/main/java/org/apache/causeway/viewer/wicket/applib/annotation/WicketViewer.java @@ -0,0 +1,33 @@ +/* + * 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.applib.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.beans.factory.annotation.Qualifier; + +@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Qualifier("Wicket") +public @interface WicketViewer { + +} diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/CausewayModuleViewerWicketModel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/CausewayModuleViewerWicketModel.java index 6db06646573..cc3b7999875 100644 --- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/CausewayModuleViewerWicketModel.java +++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/CausewayModuleViewerWicketModel.java @@ -21,6 +21,10 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.apache.causeway.applib.annotation.Where; +import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; +import org.apache.causeway.core.metamodel.interactions.InteractionConstraint; +import org.apache.causeway.core.metamodel.interactions.WhatViewer; import org.apache.causeway.core.webapp.CausewayModuleCoreWebapp; /** @@ -32,4 +36,15 @@ CausewayModuleCoreWebapp.class, }) public class CausewayModuleViewerWicketModel { + + // -- INTERACTION + + private static WhatViewer WHAT_VIEWER = new WhatViewer("Wicket"); + public static WhatViewer whatViewer() { return WHAT_VIEWER; } + public static InteractionConstraint iConstraint(final InteractionInitiatedBy user, final Where where) { + return new InteractionConstraint(whatViewer(), user, where); + } + public static InteractionConstraint iConstraint(final Where where) { + return new InteractionConstraint(whatViewer(), InteractionInitiatedBy.USER, where); + } } 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..3cb36fafc24 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 @@ -38,6 +38,7 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.viewer.commons.model.action.HasManagedAction; import org.apache.causeway.viewer.commons.model.action.UiActionForm; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; 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.act.ActionInteractionWkt; @@ -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(CausewayModuleViewerWicketModel.whatViewer()).isAllowed(); } public boolean isEnabled() { - return getUsabilityConsent().isAllowed(); + return getUsabilityConsent(CausewayModuleViewerWicketModel.whatViewer()).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/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..6822039fb85 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; @@ -26,12 +27,12 @@ import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection; import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation; import org.apache.causeway.core.metamodel.tabular.DataTableInteractive; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; 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 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, CausewayModuleViewerWicketModel.iConstraint(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..74b4314f55a 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,15 +18,16 @@ */ 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.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; -import org.jspecify.annotations.NonNull; - 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(), CausewayModuleViewerWicketModel.iConstraint(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/act/ActionInteractionWkt.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java index 2cf1497ae99..bd428d273a1 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; @@ -38,6 +37,7 @@ import org.apache.causeway.core.metamodel.interactions.managed.PendingParamsSnapshot; import org.apache.causeway.core.metamodel.object.ManagedObjects; import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.models.InlinePromptContext; import org.apache.causeway.viewer.wicket.model.models.ParameterModel; import org.apache.causeway.viewer.wicket.model.models.PropertyModel; @@ -150,21 +150,23 @@ protected ActionInteraction load() { final int paramIndex = associatedWithParameterIfAny.getParameterIndex(); // supports composite-value-types via mixin return ActionInteraction.startAsBoundToParameter( - associatedWithParameterIfAny.getParameterNegotiationModel(), paramIndex, memberId, where); + associatedWithParameterIfAny.getParameterNegotiationModel(), paramIndex, memberId, + CausewayModuleViewerWicketModel.iConstraint(where)); } - if(associatedWithCollectionIfAny!=null) { - return ActionInteraction.startWithMultiselect(getBookmarkedOwner(), memberId, where, + if(associatedWithCollectionIfAny!=null) + return ActionInteraction.startWithMultiselect(getBookmarkedOwner(), memberId, + CausewayModuleViewerWicketModel.iConstraint(where), 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, + CausewayModuleViewerWicketModel.iConstraint(where)); - return ActionInteraction.start(getBookmarkedOwner(), memberId, where); + return ActionInteraction.start(getBookmarkedOwner(), memberId, + CausewayModuleViewerWicketModel.iConstraint(where)); } 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..12a8ed5eddd 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 @@ -32,6 +32,7 @@ import org.apache.causeway.core.metamodel.interactions.managed.PropertyInteraction; import org.apache.causeway.core.metamodel.interactions.managed.PropertyNegotiationModel; import org.apache.causeway.core.metamodel.object.ManagedObjects; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.models.interaction.BookmarkedObjectWkt; import org.apache.causeway.viewer.wicket.model.models.interaction.HasBookmarkedOwnerAbstract; @@ -119,7 +120,7 @@ private Optional startPropertyNegotiation() { private PropertyInteraction loadPropertyInteraction() { return PropertyInteraction.wrap( - ManagedProperty.lookupProperty(getBookmarkedOwner(), memberId, where) + ManagedProperty.lookupProperty(getBookmarkedOwner(), memberId, CausewayModuleViewerWicketModel.iConstraint(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/actionlinks/serviceactions/ServiceActionUtil.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/actionlinks/serviceactions/ServiceActionUtil.java index d772acee3f5..f94d522f0be 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 @@ -32,6 +32,7 @@ import org.apache.causeway.viewer.commons.applib.services.menu.model.NavbarSection; import org.apache.causeway.viewer.commons.model.decorators.ActionDecorators.ActionDecorationModel; import org.apache.causeway.viewer.commons.model.decorators.ActionDecorators.ActionStyle; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.UiObjectWkt; import org.apache.causeway.viewer.wicket.ui.components.widgets.actionlink.ActionLink; @@ -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(CausewayModuleViewerWicketModel.whatViewer()).orElseThrow())); currentTopLevelMenu.addSubMenuItem(menuItem); } 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; 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..7667bbeda66 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 @@ -31,6 +31,7 @@ import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; import org.apache.causeway.core.metamodel.object.ManagedObject; import org.apache.causeway.core.metamodel.util.Facets; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; 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.coll.CollectionModel; @@ -127,7 +128,7 @@ private void buildGui() { var objectAdapter = getModel().getObject(); final Consent visibility = collectionMetaModel - .isVisible(objectAdapter, InteractionInitiatedBy.USER, Where.OBJECT_FORMS); + .isVisible(objectAdapter, CausewayModuleViewerWicketModel.iConstraint(InteractionInitiatedBy.USER, Where.OBJECT_FORMS)); if(visibility.isAllowed()) { 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..1204334c58f 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 @@ -37,6 +37,7 @@ import org.apache.causeway.core.metamodel.spec.feature.ObjectAction; import org.apache.causeway.viewer.commons.model.action.HasManagedAction; import org.apache.causeway.viewer.commons.model.components.UiComponentType; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.links.Menuable; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.ActionPromptProvider; @@ -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(CausewayModuleViewerWicketModel.whatViewer()).getReasonAsString().orElse(null) : null; } @Override public boolean isVisible() { - return getActionModel().getVisibilityConsent().isAllowed(); + return getActionModel().getVisibilityConsent(CausewayModuleViewerWicketModel.whatViewer()).isAllowed(); } @Override public boolean isEnabled() { - return getActionModel().getUsabilityConsent().isAllowed(); + return getActionModel().getUsabilityConsent(CausewayModuleViewerWicketModel.whatViewer()).isAllowed(); } @SuppressWarnings("deprecation") diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/exec/FormExecutorDefault.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/exec/FormExecutorDefault.java index 05e5573d3ad..e32787e3fed 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/exec/FormExecutorDefault.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/exec/FormExecutorDefault.java @@ -30,6 +30,7 @@ import org.apache.causeway.applib.services.exceprecog.Recognition; import org.apache.causeway.commons.functional.Either; import org.apache.causeway.core.metamodel.context.HasMetaModelContext; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.models.ActionModel; import org.apache.causeway.viewer.wicket.model.models.FormExecutor; import org.apache.causeway.viewer.wicket.model.models.FormExecutorContext; @@ -72,8 +73,8 @@ public FormExecutionOutcome executeAndProcessResults( Category.CONSTRAINT_VIOLATION, actionOrPropertyModel .fold( - act->act.getValidityConsent().getReasonAsString().orElse(null), - prop->prop.getReasonInvalidIfAny())); + act->act.getValidityConsent(CausewayModuleViewerWicketModel.whatViewer()).getReasonAsString().orElse(null), + PropertyModel::getReasonInvalidIfAny)); if (invalidReasonIfAny.isPresent()) { raiseErrorMessage(ajaxTarget, feedbackFormIfAny, invalidReasonIfAny.get()); @@ -96,8 +97,8 @@ public FormExecutionOutcome executeAndProcessResults( //XXX triggers BookmarkedObjectWkt.getObjectAndReAttach() down the call-stack //XXX applies the pending property var resultAdapter = actionOrPropertyModel.fold( - act->act.executeActionAndReturnResult(), - prop->prop.applyValueThenReturnOwner()); + ActionModel::executeActionAndReturnResult, + PropertyModel::applyValueThenReturnOwner); // if we are in a nested dialog/form, that supports an action parameter, // the result must be fed back into the calling dialog's/form's parameter @@ -126,9 +127,8 @@ public FormExecutionOutcome executeAndProcessResults( // attempt to recognize this exception using the ExceptionRecognizers (but only when not in inline prompt context!?) if(!formExecutorContext.isWithinInlinePrompt() - && recognizeExceptionThenRaise(ex, ajaxTarget, feedbackFormIfAny).isPresent()) { - return FormExecutionOutcome.FAILURE_RECOVERABLE_SO_STAY_ON_PAGE; // invalid args, stay on page - } + && recognizeExceptionThenRaise(ex, ajaxTarget, feedbackFormIfAny).isPresent()) + return FormExecutionOutcome.FAILURE_RECOVERABLE_SO_STAY_ON_PAGE; // invalid args, stay on page // throwing an exception will get caught by WebRequestCycleForCauseway#onException(...) throw ex; // redirect to the error page. 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..e6e8e26b5be 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 @@ -29,6 +29,7 @@ import org.apache.causeway.core.metamodel.context.HasMetaModelContext; import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiModel; import org.apache.causeway.viewer.commons.applib.services.header.HeaderUiService; +import org.apache.causeway.viewer.wicket.model.CausewayModuleViewerWicketModel; import org.apache.causeway.viewer.wicket.model.hints.UiHintContainer; import org.apache.causeway.viewer.wicket.model.models.IconResourceReferenceFactory; import org.apache.causeway.viewer.wicket.ui.app.registry.ComponentFactoryRegistry; @@ -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(CausewayModuleViewerWicketModel.whatViewer()); } // Hint support diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/util/Wkt.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/util/Wkt.java index d53716e374a..027846c37e9 100644 --- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/util/Wkt.java +++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/util/Wkt.java @@ -146,13 +146,15 @@ public class Wkt { public T add(final @NonNull MarkupContainer container, final @Nullable T component) { - if(component==null) return null; + if(component==null) + return null; container.addOrReplace((Component)component); return component; } public T add(final @NonNull Component component, final @Nullable T behavior) { - if(behavior==null) return null; + if(behavior==null) + return null; component.add((Behavior)behavior); return behavior; } @@ -200,9 +202,8 @@ public T attributeReplace( final @Nullable String attributeName, final @Nullable String attributeValue) { if(component==null - || _Strings.isEmpty(attributeName)) { - return component; - } + || _Strings.isEmpty(attributeName)) + return component; if(_Strings.isEmpty(attributeValue)) { component.add(AttributeModifier.remove(attributeName)); return component; @@ -270,9 +271,8 @@ private static class ReplaceDisabledTagWithReadonlyTagBehavior extends Behavior private static final long serialVersionUID = 1L; @Override public void onComponentTag(final Component component, final ComponentTag tag) { super.onComponentTag(component, tag); - if(component.isEnabled()) { - return; - } + if(component.isEnabled()) + return; tag.remove("disabled"); tag.put("readonly","readonly"); } @@ -305,9 +305,8 @@ public Behavior behaviorAddConfirm( } public void behaviorAddReplaceDisabledTagWithReadonlyTag(final @Nullable Component component) { - if(component==null) { - return; - } + if(component==null) + return; if (component.getBehaviors(ReplaceDisabledTagWithReadonlyTagBehavior.class).isEmpty()) { component.add(new ReplaceDisabledTagWithReadonlyTagBehavior()); } @@ -321,7 +320,7 @@ public BookmarkablePageLink bookmarkablePageLinkWithVisibility( final PageParameters pageParameters, final SerializableBooleanSupplier dynamicVisibility) { - return new BookmarkablePageLink( + return new BookmarkablePageLink<>( id, pageClass, pageParameters) { private static final long serialVersionUID = 1L; @@ -510,7 +509,8 @@ public static AjaxCheckBox checkbox( * Hence we intercept such events and reset check-boxes to un-checked. */ @Override public void onEvent(final IEvent event) { - if(event==null) return; // just in case + if(event==null) + return; // just in case _Casts.castTo(CausewayEnvelopeEvent.class, event.getPayload()) .ifPresent(envelopeEvent->{ if(envelopeEvent.getLetter() instanceof CausewayActionCompletedEvent) { @@ -534,9 +534,8 @@ public static AjaxCheckBox checkbox( */ private boolean hasMemoizedDataRow(final IModel model) { if(model instanceof DataRowToggleWkt dataRowToggleWkt) { - if(dataRowToggleWkt.delegate() instanceof DataRowWkt dataRowWkt) { - return dataRowWkt.isTableDataLoaded(); - } + if(dataRowToggleWkt.delegate() instanceof DataRowWkt dataRowWkt) + return dataRowWkt.isTableDataLoaded(); } return false; } @@ -646,7 +645,7 @@ public ResourceLinkVolatile downloadLinkNoCache(final String id, final IResource public DropDownChoice dropDownChoice(final String id, final IModel model, final List choices) { - return new DropDownChoice(id, model, choices); + return new DropDownChoice<>(id, model, choices); } public DropDownChoice dropDownChoiceWithAjaxUpdate(final String id, @@ -674,9 +673,8 @@ public DropDownChoice dropDownChoiceWithAjaxUpdateAd */ public void fileDownloadClickHandler(final IModel model, final CommonMimeType mime, final String fileName) { final File file = model.getObject(); - if (file == null) { - throw _Exceptions.illegalState("Failed to retrieve a File object from model %s", model.getClass().getName()); - } + if (file == null) + throw _Exceptions.illegalState("Failed to retrieve a File object from model %s", model.getClass().getName()); RequestCycle.get().scheduleRequestHandlerAfterCurrent( Wkt.fileResourceStreamRequestHandler(file, mime) .setCacheDuration(Duration.ZERO) @@ -803,7 +801,7 @@ public Fragment fragmentAddNoTab(final MarkupContainer container, // -- FORM public static Form form(final String id) { - return new Form(id); + return new Form<>(id); } public static Form formAdd(final MarkupContainer container, final String id) { @@ -834,7 +832,7 @@ public Image imageEmbedded(final String id, final DataUri dataUri) { return new Image(id, "embedded") { private static final long serialVersionUID = 1L; @Override protected boolean shouldAddAntiCacheParameter() { return false; } - @Override protected String buildSrcAttribute(ComponentTag tag) { + @Override protected String buildSrcAttribute(final ComponentTag tag) { return dataUri.toExternalForm(); } }; @@ -919,7 +917,7 @@ public Label labelAddWithConverter( public ResourceLink link(final String id, final BufferedImage buffImg) { var imageResource = new BufferedDynamicImageResource(); imageResource.setImage(buffImg); - return new ResourceLink(id, imageResource); + return new ResourceLink<>(id, imageResource); } public AjaxLinkNoPropagate link(final String id, final SerializableConsumer onClick) { @@ -966,7 +964,7 @@ public ListView listView( final String id, final List list, final SerializableConsumer> itemPopulator) { - return new ListView(id, list) { + return new ListView<>(id, list) { private static final long serialVersionUID = 1L; @Override protected void populateItem(final ListItem item) { itemPopulator.accept(item); @@ -978,7 +976,7 @@ public ListView listView( final String id, final IModel> listModel, final SerializableConsumer> itemPopulator) { - return new ListView(id, listModel) { + return new ListView<>(id, listModel) { private static final long serialVersionUID = 1L; @Override protected void populateItem(final ListItem item) { itemPopulator.accept(item); @@ -1051,7 +1049,7 @@ public Item oddEvenItem( final String id, final int index, final IModel model, final SerializableFunction cssClassProvider) { - return new OddEvenItem(id, index, model) { + return new OddEvenItem<>(id, index, model) { private static final long serialVersionUID = 1L; @Override @@ -1065,11 +1063,11 @@ protected void onComponentTag(final ComponentTag tag) { // -- TEXT AREA public TextArea textArea(final String id, final IModel textModel) { - return new TextArea(id, textModel); + return new TextArea<>(id, textModel); } public TextArea textAreaNoTab(final String id, final IModel textModel) { - return new TextArea(id, textModel) { + return new TextArea<>(id, textModel) { private static final long serialVersionUID = 1L; @Override protected void onComponentTag(final ComponentTag tag) { super.onComponentTag(tag); @@ -1091,7 +1089,7 @@ public TextArea textAreaWithConverter( final @NonNull IModel model, final @NonNull Class type, final @NonNull Optional> converter) { - return new TextAreaWithConverter(id, model, type, converter); + return new TextAreaWithConverter<>(id, model, type, converter); } // -- TEXT FIELD @@ -1104,7 +1102,7 @@ public TextField textFieldWithConverter( final @NonNull IModel model, final @NonNull Class type, final @NonNull Optional> converter) { - return new TextFieldWithConverter(id, model, type, converter); + return new TextFieldWithConverter<>(id, model, type, converter); } public TextField passwordFieldWithConverter( @@ -1112,7 +1110,7 @@ public TextField passwordFieldWithConverter( final @NonNull IModel model, final @NonNull Class type, final @NonNull Optional> converter) { - return new TextFieldWithConverter(id, model, type, converter) { + return new TextFieldWithConverter<>(id, model, type, converter) { private static final long serialVersionUID = 2L; @Override protected void onComponentTag(final ComponentTag tag) { Attributes.set(tag, "type", "password"); @@ -1192,9 +1190,8 @@ public boolean errorMessageIgnoringResourceBundles( final @Nullable FormComponent formComponent, final @Nullable IValidationError error) { if(formComponent==null - || error==null) { - return true; - } + || error==null) + return true; if(error instanceof ValidationError) { var message = ((ValidationError)error).getMessage(); // use plain error message from ConversionException, circumventing resource bundles.