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 2021/07/05 12:53:49 UTC

[isis] branch master updated: ISIS-2787: create menubars.layout base/fallback model from layout annotations only

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 e3658bc  ISIS-2787: create menubars.layout base/fallback model from layout annotations only
e3658bc is described below

commit e3658bccfbc99525eb48b583a4aea0bc8f4db602
Author: andi-huber <ah...@apache.org>
AuthorDate: Mon Jul 5 14:53:38 2021 +0200

    ISIS-2787: create menubars.layout base/fallback model from layout
    annotations only
---
 .../isis/core/metamodel/facetapi/FacetRanking.java | 31 +++++++++++++++++++++-
 .../specimpl/ObjectAssociationAbstract.java        |  9 +++----
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    | 20 +++++++++-----
 3 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
index f0eaf5c..f0c8e13 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
@@ -27,6 +27,7 @@ import java.util.function.BiConsumer;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Casts;
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.facetapi.Facet.Precedence;
@@ -143,6 +144,22 @@ public final class FacetRanking {
         return topRank.getLast();
     }
 
+    /**
+     * Optionally returns the winning facet, considering only the rank with selected precedence constraints,
+     * based on whether there was any added that has given facetType.
+     * @param facetType - for convenience, so the caller does not need to cast the result
+     * @param precedenceUpper - upper bound
+     */
+    public <F extends Facet> Optional<F> getWinnerNonEventLowerOrEqualTo(
+            final @NonNull Class<F> facetType,
+            final @NonNull Precedence precedenceUpper) {
+        val selectedRank = getHighestPrecedenceLowerOrEqualTo(precedenceUpper);
+        return selectedRank
+                .map(facetsByPrecedence::get)
+                .map(_Lists::lastElementIfAny) // only historically the last one wins
+                .map(_Casts::uncheckedCast);
+    }
+
 
     /**
      * Optionally returns the top ranking event facet, based on whether there was one added.
@@ -169,7 +186,7 @@ public final class FacetRanking {
      * @param facetType - for convenience, so the caller does not need to cast the result
      * @param precedenceUpper - upper bound
      */
-    public <F extends Facet> Can<F> getRankLowerOrEqualTo(final @NonNull Class<F> facetType, Precedence precedenceUpper) {
+    public <F extends Facet> Can<F> getRankLowerOrEqualTo(final @NonNull Class<F> facetType, final @NonNull Precedence precedenceUpper) {
         _Assert.assertEquals(this.facetType, facetType);
 
         val precedenceSelected = facetsByPrecedence
@@ -184,6 +201,18 @@ public final class FacetRanking {
         .orElseGet(Can::empty);
     }
 
+    /**
+     * Returns highest found precedence within ranks that conforms to given precedence constraint.
+     * @param precedenceUpper - upper bound
+     */
+    public Optional<Precedence> getHighestPrecedenceLowerOrEqualTo(final @NonNull Precedence precedenceUpper) {
+        return facetsByPrecedence
+        .keySet()
+        .stream()
+        .filter(precedence->precedence.ordinal()<=precedenceUpper.ordinal())
+        .max(Comparator.comparing(Precedence::ordinal));
+    }
+
     public Optional<Facet.Precedence> getTopPrecedence() {
         return Optional.ofNullable(topPrecedenceRef.get());
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
index 8cf581f..e31ed72 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
@@ -20,7 +20,6 @@
 package org.apache.isis.core.metamodel.specloader.specimpl;
 
 import org.apache.isis.applib.Identifier;
-import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facetapi.Facet.Precedence;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -97,13 +96,12 @@ implements ObjectAssociation {
     public final String getCanonicalFriendlyName() {
         return lookupFacet(MemberNamedFacet.class)
         .flatMap(MemberNamedFacet::getSharedFacetRanking)
-        .map(facetRanking->facetRanking.getRankLowerOrEqualTo(MemberNamedFacet.class, Precedence.HIGH))
-        .flatMap(Can::getLast) // TODO ranking implementation detail
+        .flatMap(facetRanking->facetRanking.getWinnerNonEventLowerOrEqualTo(MemberNamedFacet.class, Precedence.HIGH))
         .map(MemberNamedFacet::getSpecialization)
         .flatMap(specialization->specialization.left())
         .map(HasStaticText::translated)
         //we have a facet-post-processor to ensure following code path is unreachable,
-        // however, we keep it in support of JUnit testing
+        //however, we keep it in support of JUnit testing
         .orElseGet(()->getFeatureIdentifier().getMemberNaturalName());
     }
 
@@ -111,8 +109,7 @@ implements ObjectAssociation {
     public final String getCanonicalDescription() {
         return lookupFacet(MemberDescribedFacet.class)
         .flatMap(MemberDescribedFacet::getSharedFacetRanking)
-        .map(facetRanking->facetRanking.getRankLowerOrEqualTo(MemberDescribedFacet.class, Precedence.HIGH))
-        .flatMap(Can::getLast) // TODO ranking implementation detail
+        .flatMap(facetRanking->facetRanking.getWinnerNonEventLowerOrEqualTo(MemberDescribedFacet.class, Precedence.HIGH))
         .map(MemberDescribedFacet::getSpecialization)
         .flatMap(specialization->specialization.left())
         .map(HasStaticText::translated)
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
index 43158cb..48b8336 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/menubars/bootstrap3/MenuBarsServiceBS3.java
@@ -55,6 +55,7 @@ import org.apache.isis.core.config.environment.IsisSystemEnvironment;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.facetapi.Facet.Precedence;
 import org.apache.isis.core.metamodel.facets.actions.notinservicemenu.NotInServiceMenuFacet;
+import org.apache.isis.core.metamodel.facets.all.i8n.staatic.HasStaticText;
 import org.apache.isis.core.metamodel.facets.all.named.MemberNamedFacet;
 import org.apache.isis.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
 import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceFacet;
@@ -288,17 +289,22 @@ implements MenuBarsService {
                 }
 
                 val objectAction = serviceAndAction.getObjectAction();
-                val service = serviceAndAction.getServiceAdapter();
+                //val service = serviceAndAction.getServiceAdapter();
                 val logicalTypeName = serviceAndAction.getServiceAdapter().getSpecification().getLogicalTypeName();
                 val actionLayoutData = new ServiceActionLayoutData(logicalTypeName, objectAction.getId());
 
-                objectAction
+                val named = objectAction
                 .getFacetRanking(MemberNamedFacet.class)
-                .get()
-                .getRankLowerOrEqualTo(MemberNamedFacet.class, Precedence.DEFAULT)
-                .getLastOrFail();
-
-                actionLayoutData.setNamed(objectAction.getFriendlyName(service.asProvider()));
+                // assuming layout from annotations never installs higher than Precedence.DEFAULT
+                .flatMap(facetRanking->facetRanking.getWinnerNonEventLowerOrEqualTo(MemberNamedFacet.class, Precedence.DEFAULT))
+                .map(MemberNamedFacet::getSpecialization)
+                .flatMap(specialization->specialization.left())
+                .map(HasStaticText::translated)
+                //we have a facet-post-processor to ensure following code path is unreachable,
+                //however, we keep it in avoidance of fatal failure
+                .orElseGet(()->objectAction.getFeatureIdentifier().getMemberNaturalName());
+
+                actionLayoutData.setNamed(named); //that's for imperative naming ... objectAction.getFriendlyName(service.asProvider()));
                 menuSection.getServiceActions().add(actionLayoutData);
             }
             if(!menuSection.getServiceActions().isEmpty()) {