You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/01/14 09:25:57 UTC

[isis] branch master updated: ISIS-2943: reinstate ApplicationAdvice.APPLIES_EXCLUSIVELY

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

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


The following commit(s) were added to refs/heads/master by this push:
     new c5f0339  ISIS-2943: reinstate ApplicationAdvice.APPLIES_EXCLUSIVELY
c5f0339 is described below

commit c5f033912ed41ce1e1548a2c234cf688a2bf35ba
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jan 14 10:25:45 2022 +0100

    ISIS-2943: reinstate ApplicationAdvice.APPLIES_EXCLUSIVELY
---
 .../apache/isis/commons/internal/base/_Refs.java   |  8 +++++++
 .../isis/viewer/wicket/ui/ComponentFactory.java    | 23 ++++++++++++++++++-
 .../viewer/wicket/ui/ComponentFactoryAbstract.java | 10 +++++++++
 .../ComponentFactoryRegistryDefault.java           | 26 ++++++++++++++++++++--
 4 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/internal/base/_Refs.java b/commons/src/main/java/org/apache/isis/commons/internal/base/_Refs.java
index 86e8456..fd1f582 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/base/_Refs.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/base/_Refs.java
@@ -175,6 +175,14 @@ public final class _Refs {
             return value = operator.apply(value);
         }
 
+        public boolean isNull() {
+            return value==null;
+        }
+
+        public boolean isNotNull() {
+            return value!=null;
+        }
+
         public boolean isSet(final @Nullable T other) {
             return value==other;
         }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java
index 038c5af..c3c0f18 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactory.java
@@ -59,15 +59,36 @@ public interface ComponentFactory extends Serializable {
 
     public enum ApplicationAdvice {
         APPLIES,
+        /**
+         * Whether no other {@link ComponentFactory}s should apply (ie stop searching for other views).
+         * The widget author might want to "take control" and prevent other views.
+         */
+        APPLIES_EXCLUSIVELY,
         DOES_NOT_APPLY;
 
+        /**
+         * Whether applies in any way (no matter whether exclusively or not).
+         */
         public boolean applies() {
-            return this == APPLIES;
+            return this == APPLIES
+                    || this == APPLIES_EXCLUSIVELY;
+        }
+
+        /**
+         * @see #APPLIES_EXCLUSIVELY
+         */
+        public boolean appliesExclusively() {
+            return this == APPLIES_EXCLUSIVELY;
         }
 
         public static final ApplicationAdvice appliesIf(final boolean condition) {
             return condition ? ApplicationAdvice.APPLIES : ApplicationAdvice.DOES_NOT_APPLY;
         }
+
+        public static final ApplicationAdvice appliesExclusivelyIf(final boolean condition) {
+            return condition ? ApplicationAdvice.APPLIES_EXCLUSIVELY : ApplicationAdvice.DOES_NOT_APPLY;
+        }
+
     }
 
     /**
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java
index 659413a..e9fb908 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/ComponentFactoryAbstract.java
@@ -94,10 +94,20 @@ public abstract class ComponentFactoryAbstract implements ComponentFactory {
      */
     protected abstract ApplicationAdvice appliesTo(IModel<?> model);
 
+    /**
+     * Convenience for subclasses to call from {@link #appliesTo(IModel)}
+     */
     protected final ApplicationAdvice appliesIf(final boolean b) {
         return ApplicationAdvice.appliesIf(b);
     }
 
+    /**
+     * Convenience for subclasses to call from {@link #appliesTo(IModel)}
+     */
+    protected final ApplicationAdvice appliesExclusivelyIf(final boolean b) {
+        return ApplicationAdvice.appliesExclusivelyIf(b);
+    }
+
     @Override
     public final Component createComponent(final IModel<?> model) {
         log.debug("creating component {}", getComponentType()::toString);
diff --git a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
index 36ee05b..dc3cf59 100644
--- a/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
+++ b/viewers/wicket/viewer/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistryDefault.java
@@ -19,6 +19,7 @@
 package org.apache.isis.viewer.wicket.viewer.registries.components;
 
 import java.util.List;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import javax.annotation.PostConstruct;
@@ -36,6 +37,7 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.commons.internal.base._Refs;
 import org.apache.isis.commons.internal.base._Text;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.commons.internal.collections._Multimaps.ListMultimap;
@@ -152,8 +154,28 @@ implements ComponentFactoryRegistry {
     public Stream<ComponentFactory> streamComponentFactories(
             final ComponentType componentType,
             final @Nullable IModel<?> model) {
-        return componentFactoriesByType.streamElements(componentType)
-                .filter(componentFactory->componentFactory.appliesTo(componentType, model).applies())
+
+        // find all that apply, unless we find one that applies exclusively
+        // in the exclusive case, we just return the exclusive one
+
+        val exclusiveIfAny = _Refs.<ComponentFactory>objectRef(null);
+
+        val allThatApply = componentFactoriesByType.streamElements(componentType)
+                .filter(componentFactory->{
+                    val advide = componentFactory.appliesTo(componentType, model);
+                    if(advide.appliesExclusively()) {
+                        exclusiveIfAny.set(componentFactory);
+                    }
+                    return advide.applies();
+                })
+                // as an optimization, stop taking when we found an exclusive one
+                .takeWhile(__->exclusiveIfAny.isNull())
+                .collect(Collectors.toList());
+
+        return (exclusiveIfAny.isNotNull()
+                    ? Stream.of(exclusiveIfAny.getValueElseFail())
+                    : allThatApply.stream()
+                )
                 .peek(componentFactory->logComponentResolving(model, componentType, componentFactory));
     }