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 2020/06/24 14:33:14 UTC

[isis] branch master updated (2dfcd55 -> 8035599)

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

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


    from 2dfcd55  ISIS-2340: remove dependency exclusions (no longer required)
     new ace8369  ISIS-2340: simplify ActionLinkUiModelFactory
     new 8035599  ISIS-2340: simplify menu building

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../javafx/model/action/ActionLinkFactoryFx.java   |  32 +-----
 .../viewer/javafx/model/action/ActionLinkFx.java   |  31 +++++-
 .../viewer/javafx/ui/main/MenuBuilderFx.java       |  33 +++---
 .../viewer/javafx/ui/main/UiController.java        |   4 +-
 .../vaadin/model/action/ActionLinkFactoryVaa.java  |   6 +-
 .../viewer/vaadin/ui/pages/main/MainView.java      |  28 ++---
 .../ui/pages/main/MainView_createHeader.java       |  95 +++++------------
 .../vaadin/ui/pages/main/MenuBuilderVaa.java       |  58 +++++++++++
 .../viewer/common/model/UiComponentHolder.java     |  22 ++--
 .../common/model/action/ActionLinkUiModel.java     |   1 +
 .../model/action/ActionLinkUiModelFactory.java     |   7 +-
 .../common/model/action/ActionUiMetaModel.java     |   6 ++
 .../isis/viewer/common/model/menu/MenuBuilder.java |  30 ------
 .../isis/viewer/common/model/menu/MenuItemDto.java |  60 +++++++++++
 .../isis/viewer/common/model/menu/MenuUiModel.java |  69 ++-----------
 .../model/menu/MenuUiModel_buildMenuItems.java     |  13 ++-
 ...Items.java => MenuUiModel_buildMenuItems2.java} | 115 ++++++++++++---------
 .../isis/viewer/common/model/menu/MenuVisitor.java |   8 +-
 .../common/model/menuitem/MenuItemUiModel.java     |  19 ++--
 .../common/model/object/SimpleObjectUiModel.java   |   3 -
 .../serviceactions/ServiceActionUtil.java          |  10 +-
 21 files changed, 325 insertions(+), 325 deletions(-)
 create mode 100644 incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
 copy examples/demo/domain/src/main/java/demoapp/dom/mixins/MixinDemo_mixedInCollection.java => viewers/common/src/main/java/org/apache/isis/viewer/common/model/UiComponentHolder.java (71%)
 delete mode 100644 viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java
 create mode 100644 viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuItemDto.java
 copy viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/{MenuUiModel_buildMenuItems.java => MenuUiModel_buildMenuItems2.java} (58%)
 copy core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistryHolder.java => viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java (81%)


[isis] 02/02: ISIS-2340: simplify menu building

Posted by ah...@apache.org.
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

commit 803559910dd495254cce718519fc9696f15fcacc
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jun 24 15:58:09 2020 +0200

    ISIS-2340: simplify menu building
---
 .../viewer/javafx/ui/main/MenuBuilderFx.java       |  31 +++---
 .../viewer/vaadin/ui/pages/main/MainView.java      |  28 ++---
 .../ui/pages/main/MainView_createHeader.java       |  95 +++++------------
 .../vaadin/ui/pages/main/MenuBuilderVaa.java       |  58 +++++++++++
 .../MenuBuilder.java => UiComponentHolder.java}    |  20 ++--
 .../common/model/action/ActionLinkUiModel.java     |   1 +
 .../common/model/action/ActionUiMetaModel.java     |   6 ++
 .../isis/viewer/common/model/menu/MenuItemDto.java |  60 +++++++++++
 .../isis/viewer/common/model/menu/MenuUiModel.java |  69 ++-----------
 .../model/menu/MenuUiModel_buildMenuItems.java     |  12 +--
 ...Items.java => MenuUiModel_buildMenuItems2.java} | 114 ++++++++++++---------
 .../menu/{MenuBuilder.java => MenuVisitor.java}    |   9 +-
 .../common/model/menuitem/MenuItemUiModel.java     |  19 ++--
 13 files changed, 284 insertions(+), 238 deletions(-)

diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
index 7164126..dbefe50 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
@@ -18,10 +18,9 @@
  */
 package org.apache.isis.incubator.viewer.javafx.ui.main;
 
-import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.incubator.viewer.javafx.model.action.ActionLinkFactoryFx;
-import org.apache.isis.viewer.common.model.menu.MenuBuilder;
+import org.apache.isis.viewer.common.model.menu.MenuItemDto;
+import org.apache.isis.viewer.common.model.menu.MenuVisitor;
 
 import lombok.RequiredArgsConstructor;
 import lombok.val;
@@ -32,21 +31,29 @@ import javafx.scene.control.MenuBar;
 
 @RequiredArgsConstructor(staticName = "of")
 @Log4j2
-public class MenuBuilderFx implements MenuBuilder {
+public class MenuBuilderFx implements MenuVisitor {
     
     private final MenuBar menuBar;
     
     private Menu currentTopLevelMenu = null;
     private ActionLinkFactoryFx actionLinkFactory = new ActionLinkFactoryFx();
 
-    
     @Override
-    public void addTopLevel(BS3Menu menu) {
-        log.info("top level menu {}", menu.getNamed());
+    public void addTopLevel(MenuItemDto menu) {
+        log.info("top level menu {}", menu.getName());
         
         menuBar.getMenus()
-        .add(currentTopLevelMenu = new Menu(menu.getNamed()));
+        .add(currentTopLevelMenu = new Menu(menu.getName()));
+    }
+
+    @Override
+    public void addSubMenu(MenuItemDto menu) {
+        val managedAction = menu.getManagedAction();
+        
+        log.info("sub menu {}", menu.getName());
         
+        val actionLink = actionLinkFactory.newActionLink(menu.getName(), managedAction);
+        currentTopLevelMenu.getItems().add(actionLink.getUiMenuItem());
     }
     
     @Override
@@ -55,12 +62,4 @@ public class MenuBuilderFx implements MenuBuilder {
         log.info("spacer");
     }
     
-    @Override
-    public void addSubMenu(String named, ManagedAction managedAction) {
-        log.info("top level menu {}", managedAction.getName());
-        
-        val actionLink = actionLinkFactory.newActionLink(named, managedAction);
-        currentTopLevelMenu.getItems().add(actionLink.getUiMenuItem());
-    }
-    
 }
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
index a854901..1076100 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView.java
@@ -32,11 +32,9 @@ import com.vaadin.flow.theme.Theme;
 import com.vaadin.flow.theme.lumo.Lumo;
 
 import org.apache.isis.core.commons.collections.Can;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.interactions.InteractionHead;
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.incubator.viewer.vaadin.model.action.ActionLinkVaa;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentFactoryVaa;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.collection.TableView;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.object.ObjectFormView;
@@ -97,19 +95,23 @@ implements BeforeEnterObserver {
         setDrawerOpened(false);
     }
 
-    private void onMenuAction(ActionLinkVaa menuActionModel) {
+    private void onMenuAction(ManagedAction managedAction) {
         
         pageContent.removeAll();
 
-        val objectAction = menuActionModel.getObjectAction();
-        val actionOwner = menuActionModel.getActionHolder().getManagedObject();
-
-        val result = objectAction
-                .execute(
-                        InteractionHead.simple(actionOwner),
-                        Can.empty(),
-                        InteractionInitiatedBy.USER
-                        );
+        val resultOrVeto = managedAction.invoke(Can.empty());
+        
+        val result = resultOrVeto.leftIfAny(); 
+        
+//        val objectAction = menuActionModel.getObjectAction();
+//        val actionOwner = menuActionModel.getActionHolder().getManagedObject();
+//
+//        val result = objectAction
+//                .execute(
+//                        InteractionHead.simple(actionOwner),
+//                        Can.empty(),
+//                        InteractionInitiatedBy.USER
+//                        );
 
         if (result.getSpecification().isParentedOrFreeCollection()) {
             pageContent.add(TableView.fromCollection(result));
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
index bee44ca..79db90b 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MainView_createHeader.java
@@ -18,27 +18,20 @@
  */
 package org.apache.isis.incubator.viewer.vaadin.ui.pages.main;
 
-import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 
 import com.vaadin.flow.component.Component;
 import com.vaadin.flow.component.Text;
 import com.vaadin.flow.component.html.Div;
-import com.vaadin.flow.component.html.Hr;
 import com.vaadin.flow.component.html.Image;
-import com.vaadin.flow.component.html.Label;
 import com.vaadin.flow.component.menubar.MenuBar;
 import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
 import com.vaadin.flow.component.orderedlayout.FlexLayout;
 
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.incubator.viewer.vaadin.model.action.ActionLinkFactoryVaa;
-import org.apache.isis.incubator.viewer.vaadin.model.action.ActionLinkVaa;
-import org.apache.isis.incubator.viewer.vaadin.model.decorator.Decorators;
-import org.apache.isis.incubator.viewer.vaadin.model.menu.MenuItemVaa;
 import org.apache.isis.viewer.common.model.branding.BrandingUiModel;
 import org.apache.isis.viewer.common.model.header.HeaderUiModel;
-import org.apache.isis.viewer.common.model.menu.MenuUiModel;
 
 import lombok.val;
 
@@ -48,17 +41,17 @@ final class MainView_createHeader {
     static Component createHeader(
             final IsisAppCommonContext commonContext, 
             final HeaderUiModel headerUiModel,
-            final Consumer<ActionLinkVaa> subMenuEventHandler) {
-        
+            final Consumer<ManagedAction> subMenuEventHandler) {
+
         val titleOrLogo = createTitleOrLogo(commonContext, headerUiModel.getBranding());
         val leftMenuBar = new MenuBar();
         val horizontalSpacer = new Div();
-//        horizontalSpacer.setWidthFull();
+        //        horizontalSpacer.setWidthFull();
         val rightMenuBar = new MenuBar();
-        
+
         leftMenuBar.setOpenOnHover(true);
         rightMenuBar.setOpenOnHover(true);
-        
+
         // holds the top level left and right aligned menu parts
         // TODO does not honor small displays yet, overflow is just not visible
         val menuBarContainer = new FlexLayout(titleOrLogo, leftMenuBar, horizontalSpacer, rightMenuBar);
@@ -68,60 +61,30 @@ final class MainView_createHeader {
 
         // right align using css
         rightMenuBar.getStyle().set("margin-left", "auto");
-        
+
         menuBarContainer.setWidthFull();
-        
-        // menu section handler, that creates and adds sub-menus to their parent top level menu   
-        final BiConsumer<MenuBar, MenuItemVaa> menuSectionBuilder = (menuBar, menuSectionUiModel) -> {
-            val menuItem = menuSectionUiModel.isTertiaryRoot() 
-                    ? menuBar.addItem(Decorators.getUser()
-                            .decorateWithAvatar(new Label(), commonContext))
-                    : menuBar.addItem(Decorators.getMenu()
-                            .decorateTopLevel(new Label(menuSectionUiModel.getName())));
-            val subMenu = menuItem.getSubMenu();
-            menuSectionUiModel.getSubMenuItems().forEach(menuItemModel -> {
-                val menuActionModel = (ActionLinkVaa)menuItemModel.getMenuActionUiModel();
-                
-                if(menuItemModel.isFirstInSection() 
-                        && subMenu.getItems().size()>0) {
-                    val spacer = new Hr();
-                    //spacer.addClassName("spacer"); TODO vertical margin or padding is currently a bit too large 
-                    subMenu.addItem(spacer);
-                }
-                
-                subMenu.addItem(
-                        (Component)menuActionModel.getUiComponent(), 
-                        e->subMenuEventHandler.accept(menuActionModel));
-            });
-                    
-        };
-        
-        // top level left aligned ...
-        buildMenuModel(commonContext, headerUiModel.getPrimary(), newMenuItem->
-            menuSectionBuilder.accept(leftMenuBar, newMenuItem));
-        
-        // top level right aligned ...
-        buildMenuModel(commonContext, headerUiModel.getSecondary(), newMenuItem->
-            menuSectionBuilder.accept(rightMenuBar, newMenuItem));
-        
-        // tertiary menu items get collected under a top level menu labeled with the current user's name 
-        buildMenuModel(commonContext, headerUiModel.getTertiary(), newMenuItem->
-            menuSectionBuilder.accept(rightMenuBar, newMenuItem));
-        
+
+        val leftMenuBuilder = MenuBuilderVaa.of(commonContext, subMenuEventHandler, leftMenuBar);
+        val rightMenuBuilder = MenuBuilderVaa.of(commonContext, subMenuEventHandler, rightMenuBar);
+
+        headerUiModel.getPrimary().buildMenuItems(commonContext, leftMenuBuilder);
+        headerUiModel.getSecondary().buildMenuItems(commonContext, rightMenuBuilder);
+        headerUiModel.getTertiary().buildMenuItems(commonContext, rightMenuBuilder);
+
         return menuBarContainer;
-        
+
     }
-    
+
     // -- HELPER
 
     private static Component createTitleOrLogo(
             final IsisAppCommonContext commonContext, 
             final BrandingUiModel brandingUiModel) {
-        
-        
+
+
         val brandingName = brandingUiModel.getName();
         val brandingLogo = brandingUiModel.getLogoHref();
-        
+
         if(brandingLogo.isPresent()) {
             val webAppContextPath = commonContext.getWebAppContextPath();
             val logo = new Image(
@@ -132,20 +95,8 @@ final class MainView_createHeader {
             return logo;
         }
         return new Text(brandingName.orElse("App"));
-        
-    }
-    
-    private static void buildMenuModel(
-            final IsisAppCommonContext commonContext,
-            final MenuUiModel menuUiModel,
-            final Consumer<MenuItemVaa> onNewMenuItem) {
-        
-        menuUiModel.buildMenuItems(
-                commonContext, 
-                new ActionLinkFactoryVaa(),
-                MenuItemVaa::newMenuItem,
-                onNewMenuItem);
+
     }
-    
-    
+
+
 }
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
new file mode 100644
index 0000000..01d4ee8
--- /dev/null
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/pages/main/MenuBuilderVaa.java
@@ -0,0 +1,58 @@
+package org.apache.isis.incubator.viewer.vaadin.ui.pages.main;
+
+import java.util.function.Consumer;
+
+import com.vaadin.flow.component.contextmenu.MenuItem;
+import com.vaadin.flow.component.html.Hr;
+import com.vaadin.flow.component.html.Label;
+import com.vaadin.flow.component.menubar.MenuBar;
+
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
+import org.apache.isis.core.runtime.context.IsisAppCommonContext;
+import org.apache.isis.incubator.viewer.vaadin.model.action.ActionLinkFactoryVaa;
+import org.apache.isis.incubator.viewer.vaadin.model.decorator.Decorators;
+import org.apache.isis.viewer.common.model.menu.MenuItemDto;
+import org.apache.isis.viewer.common.model.menu.MenuVisitor;
+
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(staticName = "of") 
+class MenuBuilderVaa implements MenuVisitor {
+
+    private final IsisAppCommonContext commonContext; 
+    private final Consumer<ManagedAction> subMenuEventHandler;
+    private final MenuBar menuBar;
+
+    private MenuItem currentTopLevelMenu = null;
+    private ActionLinkFactoryVaa actionLinkFactory = new ActionLinkFactoryVaa();
+
+    @Override
+    public void addTopLevel(MenuItemDto menuDto) {
+
+        if(menuDto.isTertiaryRoot()) {
+            currentTopLevelMenu = menuBar.addItem(Decorators.getUser()
+                    .decorateWithAvatar(new Label(), commonContext));
+        } else {
+            currentTopLevelMenu = menuBar.addItem(Decorators.getMenu()
+                    .decorateTopLevel(new Label(menuDto.getName())));
+        }
+    }
+
+    @Override
+    public void addSubMenu(MenuItemDto menu) {
+        val managedAction = menu.getManagedAction();
+        val actionLink = actionLinkFactory.newActionLink(menu.getName(), managedAction);
+        currentTopLevelMenu.getSubMenu()
+        .addItem(actionLink.getUiComponent(), e->subMenuEventHandler.accept(managedAction));
+    }
+
+    @Override
+    public void addSectionSpacer() {
+        val spacer = new Hr();
+        //spacer.addClassName("spacer"); TODO vertical margin or padding is currently a bit too large 
+        currentTopLevelMenu.getSubMenu()
+        .addItem(spacer);
+    }
+
+}
\ No newline at end of file
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/UiComponentHolder.java
similarity index 65%
copy from viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java
copy to viewers/common/src/main/java/org/apache/isis/viewer/common/model/UiComponentHolder.java
index f120d89..b8de704 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/UiComponentHolder.java
@@ -16,15 +16,21 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.viewer.common.model.menu;
+package org.apache.isis.viewer.common.model;
 
-import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
+import java.util.function.Supplier;
 
-public interface MenuBuilder {
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 
-    void addTopLevel(BS3Menu menu);
-    void addSectionSpacer();
-    void addSubMenu(String named, ManagedAction managedAction);
+@RequiredArgsConstructor
+public class UiComponentHolder<T> implements HasUiComponent<T> {
     
+    protected final Supplier<T> componentFactory;
+
+    // implements HasUiComponent<T>
+    @Getter(onMethod = @__(@Override), lazy = true) 
+    private final T uiComponent = componentFactory.get();
+    
+
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModel.java
index 82c8b2a..03de318 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModel.java
@@ -41,6 +41,7 @@ import lombok.RequiredArgsConstructor;
  * @param <T> - link component type, native to the viewer
  */
 @RequiredArgsConstructor
+@Deprecated// instead use the ActionUiMetaModel directly
 public abstract class ActionLinkUiModel<T> implements HasUiComponent<T> {
 
     protected final ActionLinkUiComponentFactory<T> uiComponentFactory;
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
index 1cec22a..1b8a694 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionUiMetaModel.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.common.model.decorator.disable.DisableUiModel;
@@ -65,6 +66,11 @@ public class ActionUiMetaModel implements Serializable {
     @Getter private final boolean requiresImmediateConfirmation;
 
     public static <T> ActionUiMetaModel of(
+            final ManagedAction managedAction) {
+        return new ActionUiMetaModel(managedAction.getOwner(), managedAction.getAction());
+    }
+    
+    public static <T> ActionUiMetaModel of(
             final ManagedObject actionHolder,
             final ObjectAction objectAction) {
         return new ActionUiMetaModel(actionHolder, objectAction);
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuItemDto.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuItemDto.java
new file mode 100644
index 0000000..6e11b44
--- /dev/null
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuItemDto.java
@@ -0,0 +1,60 @@
+/*
+ *  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.isis.viewer.common.model.menu;
+
+import javax.annotation.Nullable;
+
+import org.apache.isis.core.commons.internal.base._Strings;
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
+import org.apache.isis.viewer.common.model.action.ActionUiMetaModel;
+
+import lombok.NonNull;
+import lombok.Value;
+import lombok.val;
+
+@Value(staticConstructor = "of")
+public class MenuItemDto {
+
+    @NonNull
+    private final String name;
+    
+    @Nullable
+    private final String cssClassFa;
+    
+    @Nullable // eg. topLevel
+    private final ManagedAction managedAction;
+    
+    private final boolean isTertiaryRoot;
+    
+    public static MenuItemDto topLevel(String name, String cssClassFa) {
+        return of(name, cssClassFa, null, false);
+    }
+
+    public static MenuItemDto tertiaryRoot(String name, String cssClassFa) {
+        return of(name, cssClassFa, null, true);
+    }
+    
+    public static MenuItemDto subMenu(@NonNull ManagedAction managedAction, String named, String cssClassFa) {
+        val name = _Strings.isNotEmpty(named)
+                ? named
+                : ActionUiMetaModel.of(managedAction).getLabel();
+        return of(name, cssClassFa, managedAction, false);
+    }
+    
+}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel.java
index a5c0b42..91bd397 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel.java
@@ -21,13 +21,11 @@ package org.apache.isis.viewer.common.model.menu;
 import java.io.Serializable;
 import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3MenuBar;
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModelFactory;
 import org.apache.isis.viewer.common.model.menuitem.MenuItemUiModel;
@@ -36,11 +34,10 @@ import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
-import lombok.extern.log4j.Log4j2;
 
 @Getter
 @RequiredArgsConstructor(staticName = "of")
-@Log4j2
+//@Log4j2
 public class MenuUiModel implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -52,6 +49,7 @@ public class MenuUiModel implements Serializable {
         return menuBarSelect.name().toLowerCase(Locale.ENGLISH);
     }
     
+    @Deprecated//use MenuVisitor instead
     public <T, M extends MenuItemUiModel<T, M>> 
     void buildMenuItems(
             final IsisAppCommonContext commonContext,
@@ -75,67 +73,16 @@ public class MenuUiModel implements Serializable {
     
     public void buildMenuItems(
             final IsisAppCommonContext commonContext,
-            final MenuBuilder menuBuilder) {
+            final MenuVisitor menuBuilder) {
         
         val menuBars = commonContext.getMenuBarsService().menuBars();
-
-        // TODO: remove hard-coded dependency on BS3
-        final BS3MenuBar menuBar = (BS3MenuBar) menuBars.menuBarFor(getMenuBarSelect());
+        val menuBar = (BS3MenuBar) menuBars.menuBarFor(getMenuBarSelect());
         
-        val itemsPerSectionCounter = new LongAdder();
-        
-        for (val menu : menuBar.getMenus()) {
-            
-            menuBuilder.addTopLevel(menu);
-
-            for (val menuSection : menu.getSections()) {
-
-                itemsPerSectionCounter.reset();
-                
-                for (val actionLayoutData : menuSection.getServiceActions()) {
-                    val serviceSpecId = actionLayoutData.getObjectType();
-
-                    val serviceAdapter = commonContext.lookupServiceAdapterById(serviceSpecId);
-                    if(serviceAdapter == null) {
-                        // service not recognized, presumably the menu layout is out of sync with actual configured modules
-                        continue;
-                    }
-
-                    val managedAction = ManagedAction.lookupAction(serviceAdapter, actionLayoutData.getId())
-                            .orElse(null);
-                    if (managedAction == null) {
-                        log.warn("No such action {}", actionLayoutData.getId());
-                        continue;
-                    }
-                    
-                    val isFirstInSection = itemsPerSectionCounter.intValue()==0; 
-                    
-                    //TODO call this only, if visible and usable 
-                    menuBuilder.addSubMenu(actionLayoutData.getNamed(), managedAction);
-                    
-//                    val menuActionUiModel = menuActionFactory.newAction(
-//                            commonContext,
-//                            actionLayoutData.getNamed(),
-//                            managedAction);
-
-                    // Optionally creates a sub-menu item based on visibility and usability
-//                    menuItemModel.addSubMenuItemFor(
-//                            menuActionUiModel, 
-//                            isFirstInSection,
-//                            newSubMenuItem->{
-//                                // increment counter only when a sub item was actually added
-//                                itemsPerSectionCounter.increment();
-//                                newSubMenuItem.setMenuActionUiModel(menuActionUiModel);
-//                    });
-                    
-                }
-            }
-//            if (menuItemModel.hasSubMenuItems()) {
-//                onNewMenuItem.accept(menuItemModel);
-//            }
-        }
+        MenuUiModel_buildMenuItems2.buildMenuItems(
+                commonContext, 
+                menuBar,
+                menuBuilder);
         
     }
-    
 
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
index 40d5220..e7e3dd1 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
@@ -34,7 +34,7 @@ import org.apache.isis.viewer.common.model.userprofile.UserProfileUiModelProvide
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
-@Log4j2
+@Log4j2 @Deprecated
 final class MenuUiModel_buildMenuItems {
 
     public static <T, M extends MenuItemUiModel<T, M>> 
@@ -75,18 +75,18 @@ final class MenuUiModel_buildMenuItems {
                     }
                     
                     val isFirstInSection = itemsPerSectionCounter.intValue()==0; 
-                    
-                    val menuActionUiModel = menuActionFactory.newActionLink(
-                            actionLayoutData.getNamed(),
-                            managedAction);
 
                     // Optionally creates a sub-menu item based on visibility and usability
                     menuItemModel.addSubMenuItemFor(
-                            menuActionUiModel, 
+                            managedAction, 
                             isFirstInSection,
                             newSubMenuItem->{
                                 // increment counter only when a sub item was actually added
                                 itemsPerSectionCounter.increment();
+                                
+                                val menuActionUiModel = menuActionFactory.newActionLink(
+                                        actionLayoutData.getNamed(),
+                                        managedAction);
                                 newSubMenuItem.setMenuActionUiModel(menuActionUiModel);
                     });
                     
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems2.java
similarity index 58%
copy from viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
copy to viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems2.java
index 40d5220..5799080 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems2.java
@@ -19,40 +19,36 @@
 package org.apache.isis.viewer.common.model.menu;
 
 import java.util.concurrent.atomic.LongAdder;
-import java.util.function.Consumer;
-import java.util.function.Function;
 
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.layout.component.ServiceActionLayoutData;
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3MenuBar;
 import org.apache.isis.core.commons.internal.base._Strings;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.viewer.common.model.action.ActionLinkUiModelFactory;
-import org.apache.isis.viewer.common.model.menuitem.MenuItemUiModel;
 import org.apache.isis.viewer.common.model.userprofile.UserProfileUiModelProvider;
 
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 @Log4j2
-final class MenuUiModel_buildMenuItems {
-
-    public static <T, M extends MenuItemUiModel<T, M>> 
-    void buildMenuItems(
-            final IsisAppCommonContext commonContext,
-            final BS3MenuBar menuBar,
-            final ActionLinkUiModelFactory<T> menuActionFactory,
-            final Function<String, M> menuItemFactory,
-            final Consumer<M> onNewMenuItem) {
-
-        // we no longer use ServiceActionsModel#getObject() because the model only holds the services for the
-        // menuBar in question, whereas the "Other" menu may reference a service which is defined for some other menubar
+final class MenuUiModel_buildMenuItems2 {
 
+    public static void buildMenuItems(
+            IsisAppCommonContext commonContext, 
+            BS3MenuBar menuBar, 
+            MenuVisitor menuBuilder) {
+        
         val itemsPerSectionCounter = new LongAdder();
         
+        val menuVisitor = MenuProcessor.of(commonContext, menuBuilder); 
+        
         for (val menu : menuBar.getMenus()) {
             
-            val menuItemModel = processTopLevel(commonContext, menuItemFactory, menu);
+            menuVisitor.addTopLevel(menu);
 
             for (val menuSection : menu.getSections()) {
 
@@ -74,41 +70,69 @@ final class MenuUiModel_buildMenuItems {
                         continue;
                     }
                     
-                    val isFirstInSection = itemsPerSectionCounter.intValue()==0; 
+                    val visibilityVeto = managedAction.checkVisibility(Where.EVERYWHERE);
+                    if (visibilityVeto.isPresent()) {
+                        continue;
+                    }
+                    
+                    val isFirstInSection = itemsPerSectionCounter.intValue()==0;
                     
-                    val menuActionUiModel = menuActionFactory.newActionLink(
-                            actionLayoutData.getNamed(),
-                            managedAction);
-
-                    // Optionally creates a sub-menu item based on visibility and usability
-                    menuItemModel.addSubMenuItemFor(
-                            menuActionUiModel, 
-                            isFirstInSection,
-                            newSubMenuItem->{
-                                // increment counter only when a sub item was actually added
-                                itemsPerSectionCounter.increment();
-                                newSubMenuItem.setMenuActionUiModel(menuActionUiModel);
-                    });
+                    menuVisitor.addSubMenu(managedAction, isFirstInSection, actionLayoutData);
+                    itemsPerSectionCounter.increment();
                     
                 }
             }
-            if (menuItemModel.hasSubMenuItems()) {
-                onNewMenuItem.accept(menuItemModel);
-            }
+
         }
-        
     }
     
     // -- HELPER
+    
+    @RequiredArgsConstructor(staticName = "of")
+    private static class MenuProcessor {
+
+        private final IsisAppCommonContext commonContext;
+        private final MenuVisitor menuVisitor;
+        
+        private BS3Menu currentTopLevel;
+        private boolean pushedCurrentTopLevel = false;
+        
+        public void addTopLevel(BS3Menu menu) {
+            currentTopLevel = menu;
+            pushedCurrentTopLevel = false;
+        }
+
+        public void addSubMenu(
+                @NonNull ManagedAction managedAction,
+                boolean isFirstInSection, 
+                ServiceActionLayoutData actionLayoutData) {
+            
+            if(!pushedCurrentTopLevel) {
+                val topLevelDto = topLevelDto(commonContext, currentTopLevel); 
+                
+                menuVisitor.addTopLevel(topLevelDto);
+                pushedCurrentTopLevel = true;
+            } else {
+                if(isFirstInSection) {
+                    menuVisitor.addSectionSpacer();
+                }
+            }
+            val menuDto = MenuItemDto.subMenu(
+                    managedAction,
+                    actionLayoutData.getNamed(), 
+                    actionLayoutData.getCssClassFa());
+            
+            menuVisitor.addSubMenu(menuDto);
+        }
+        
+    }
 
     /**
      * @implNote when ever the top level MenuItem name is empty or {@code null} we set the name
      * to the current user's profile name 
      */
-    private static <T, M extends MenuItemUiModel<T, M>>  
-    M processTopLevel(
+    private static MenuItemDto topLevelDto(
             final IsisAppCommonContext commonContext,
-            final Function<String, M> menuItemFactory, 
             final BS3Menu menu) {
         
         val menuItemIsUserProfile = _Strings.isNullOrEmpty(menu.getNamed()); // top level menu item name
@@ -117,14 +141,10 @@ final class MenuUiModel_buildMenuItems {
                 ? userProfileName(commonContext)
                 : menu.getNamed();
         
-        val menuItemModel = menuItemFactory.apply(menuItemName); 
-        
-        if(menuItemIsUserProfile) {
-            // under the assumption that this can only be the case when we have discovered the empty named top level menu
-            menuItemModel.setTertiaryRoot(true);  
-        }
-        
-        return menuItemModel;
+        return menuItemIsUserProfile
+                // under the assumption that this can only be the case when we have discovered the empty named top level menu
+                ? MenuItemDto.tertiaryRoot(menuItemName, menu.getCssClassFa())
+                : MenuItemDto.topLevel(menuItemName, menu.getCssClassFa());
     }
 
     private static String userProfileName(
@@ -134,6 +154,8 @@ final class MenuUiModel_buildMenuItems {
                 .getUserProfile();
         return userProfile.getUserProfileName();
     }
+
+
     
     
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
similarity index 77%
rename from viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java
rename to viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
index f120d89..9cf198a 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuBuilder.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
@@ -18,13 +18,10 @@
  */
 package org.apache.isis.viewer.common.model.menu;
 
-import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
+public interface MenuVisitor {
 
-public interface MenuBuilder {
-
-    void addTopLevel(BS3Menu menu);
+    void addTopLevel(MenuItemDto menu);
     void addSectionSpacer();
-    void addSubMenu(String named, ManagedAction managedAction);
+    void addSubMenu(MenuItemDto menu);
     
 }
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menuitem/MenuItemUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menuitem/MenuItemUiModel.java
index 89e6fe0..7d0166f 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menuitem/MenuItemUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menuitem/MenuItemUiModel.java
@@ -24,9 +24,12 @@ import java.util.function.Consumer;
 
 import javax.annotation.Nullable;
 
+import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.commons.internal.base._Casts;
 import org.apache.isis.core.commons.internal.collections._Lists;
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModel;
+import org.apache.isis.viewer.common.model.action.ActionUiMetaModel;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -93,22 +96,16 @@ public abstract class MenuItemUiModel<T, U extends MenuItemUiModel<T, U>> {
      * {@link MenuActionWkt action model}, based on visibility and usability.
      */
     public void addSubMenuItemFor(
-            @NonNull final ActionLinkUiModel<T> actionModel,
+            @NonNull final ManagedAction managedAction,
             final boolean isFirstInSection,
             @Nullable final Consumer<U> onNewSubMenuItem) {
 
-        val objectAction = actionModel.getObjectAction();
-        if(!actionModel.isVisible()) {
-            log.debug("not visible {}", objectAction.getName());
-            return;
-        }
-
-        // build the link
-        val actionMeta = actionModel.getActionUiMetaModel();
-        if (actionMeta == null) {
-            // can only get a null if invisible, so this should not happen given the visibility guard above
+        if(managedAction.checkUsability(Where.EVERYWHERE).isPresent()) {
+            log.debug("not visible {}", managedAction.getName());
             return;
         }
+        
+        val actionMeta = ActionUiMetaModel.of(managedAction);
 
         val menutIem = newSubMenuItem(actionMeta.getLabel())
                 .setFirstInSection(isFirstInSection);


[isis] 01/02: ISIS-2340: simplify ActionLinkUiModelFactory

Posted by ah...@apache.org.
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

commit ace8369d556861c8ff1390528b6328f1aac634e0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jun 24 13:10:16 2020 +0200

    ISIS-2340: simplify ActionLinkUiModelFactory
---
 .../javafx/model/action/ActionLinkFactoryFx.java   | 32 ++--------------------
 .../viewer/javafx/model/action/ActionLinkFx.java   | 31 +++++++++++++++++++--
 .../viewer/javafx/ui/main/MenuBuilderFx.java       |  4 +--
 .../viewer/javafx/ui/main/UiController.java        |  4 +--
 .../vaadin/model/action/ActionLinkFactoryVaa.java  |  6 ++--
 .../model/action/ActionLinkUiModelFactory.java     |  7 +----
 .../model/menu/MenuUiModel_buildMenuItems.java     |  3 +-
 .../common/model/object/SimpleObjectUiModel.java   |  3 --
 .../serviceactions/ServiceActionUtil.java          | 10 ++++---
 9 files changed, 44 insertions(+), 56 deletions(-)

diff --git a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFactoryFx.java b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFactoryFx.java
index 315fed0..3715198 100644
--- a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFactoryFx.java
+++ b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFactoryFx.java
@@ -20,50 +20,22 @@ package org.apache.isis.incubator.viewer.javafx.model.action;
 
 
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.viewer.common.model.action.ActionLinkUiModel;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModelFactory;
-import org.apache.isis.viewer.common.model.object.SimpleObjectUiModel;
 
 import lombok.RequiredArgsConstructor;
-import lombok.val;
 
 import javafx.scene.Node;
-import javafx.scene.control.Label;
 
 @RequiredArgsConstructor
 public class ActionLinkFactoryFx implements ActionLinkUiModelFactory<Node> {
 
     @Override
-    public ActionLinkFx newAction(
-            IsisAppCommonContext commonContext, 
+    public ActionLinkFx newActionLink(
             String named,
             ManagedAction managedAction) {
         
-        val actionOwnerModel = new SimpleObjectUiModel(commonContext, managedAction.getOwner());
-        
-        val actionUiModel = new ActionLinkFx(
-                this::createUiComponent,
-                named,
-                actionOwnerModel, 
-                managedAction.getAction());
-        
-        return actionUiModel;
-    }
-    
-    // -- HELPER
-    
-    private Node createUiComponent(
-            final ActionLinkUiModel<Node> actionUiModel) {
-        
-        val actionMeta = actionUiModel.getActionUiMetaModel();
-        val uiLabel = new Label(actionMeta.getLabel());
-        
-        return uiLabel;
-        //return Decorators.getIcon().decorate(uiLabel, actionMeta.getFontAwesomeUiModel());
-                
+        return ActionLinkFx.of(named, managedAction);
     }
 
-
     
 }
\ No newline at end of file
diff --git a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFx.java b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFx.java
index 330a76c..ad586cf 100644
--- a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFx.java
+++ b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/action/ActionLinkFx.java
@@ -18,18 +18,33 @@
  */
 package org.apache.isis.incubator.viewer.javafx.model.action;
 
+import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.common.model.HasUiMenuItem;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiComponentFactory;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModel;
 import org.apache.isis.viewer.common.model.object.ObjectUiModel;
+import org.apache.isis.viewer.common.model.object.SimpleObjectUiModel;
+
+import lombok.val;
 
 import javafx.scene.Node;
+import javafx.scene.control.Label;
 import javafx.scene.control.Menu;
 
-public class ActionLinkFx extends ActionLinkUiModel<Node> implements HasUiMenuItem<Menu>{
+public class ActionLinkFx 
+extends ActionLinkUiModel<Node> 
+implements HasUiMenuItem<Menu>{
 
-    public ActionLinkFx(
+    public static ActionLinkFx of(
+            final String named,
+            final ManagedAction managedAction) {
+        
+        val actionOwnerModel = new SimpleObjectUiModel(managedAction.getOwner());
+        return new ActionLinkFx(ActionLinkFx::createUiComponent, named, actionOwnerModel, managedAction.getAction());
+    }
+    
+    protected ActionLinkFx(
             final ActionLinkUiComponentFactory<Node> uiComponentFactory,
             final String named,
             final ObjectUiModel actionHolder,
@@ -38,6 +53,18 @@ public class ActionLinkFx extends ActionLinkUiModel<Node> implements HasUiMenuIt
         super(uiComponentFactory, named, actionHolder, objectAction);
     }
 
+
+    private static Node createUiComponent(
+            final ActionLinkUiModel<Node> actionUiModel) {
+        
+        val actionMeta = actionUiModel.getActionUiMetaModel();
+        val uiLabel = new Label(actionMeta.getLabel());
+        
+        return uiLabel;
+        //return Decorators.getIcon().decorate(uiLabel, actionMeta.getFontAwesomeUiModel());
+                
+    }
+    
     @Override
     public Menu getUiMenuItem() {
         return new Menu(super.getLabel());
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
index 492de92..7164126 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/MenuBuilderFx.java
@@ -20,7 +20,6 @@ package org.apache.isis.incubator.viewer.javafx.ui.main;
 
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.incubator.viewer.javafx.model.action.ActionLinkFactoryFx;
 import org.apache.isis.viewer.common.model.menu.MenuBuilder;
 
@@ -35,7 +34,6 @@ import javafx.scene.control.MenuBar;
 @Log4j2
 public class MenuBuilderFx implements MenuBuilder {
     
-    private final IsisAppCommonContext commonContext;
     private final MenuBar menuBar;
     
     private Menu currentTopLevelMenu = null;
@@ -61,7 +59,7 @@ public class MenuBuilderFx implements MenuBuilder {
     public void addSubMenu(String named, ManagedAction managedAction) {
         log.info("top level menu {}", managedAction.getName());
         
-        val actionLink = actionLinkFactory.newAction(commonContext, named, managedAction);
+        val actionLink = actionLinkFactory.newActionLink(named, managedAction);
         currentTopLevelMenu.getItems().add(actionLink.getUiMenuItem());
     }
     
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiController.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiController.java
index 2fc80f9..7ebd01e 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiController.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/main/UiController.java
@@ -57,8 +57,8 @@ public class UiController {
         
         val commonContext = IsisAppCommonContext.of(metaModelContext);
         
-        val leftMenuBuilder = MenuBuilderFx.of(commonContext, menuBarLeft);
-        val rightMenuBuilder = MenuBuilderFx.of(commonContext, menuBarRight);
+        val leftMenuBuilder = MenuBuilderFx.of(menuBarLeft);
+        val rightMenuBuilder = MenuBuilderFx.of(menuBarRight);
         
         header.getPrimary().buildMenuItems(commonContext, leftMenuBuilder);
         header.getSecondary().buildMenuItems(commonContext, rightMenuBuilder);
diff --git a/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/action/ActionLinkFactoryVaa.java b/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/action/ActionLinkFactoryVaa.java
index 7438d2c..5faba5c 100644
--- a/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/action/ActionLinkFactoryVaa.java
+++ b/incubator/viewers/vaadin/model/src/main/java/org/apache/isis/incubator/viewer/vaadin/model/action/ActionLinkFactoryVaa.java
@@ -22,7 +22,6 @@ import com.vaadin.flow.component.Component;
 import com.vaadin.flow.component.html.Label;
 
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 import org.apache.isis.incubator.viewer.vaadin.model.decorator.Decorators;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModel;
 import org.apache.isis.viewer.common.model.action.ActionLinkUiModelFactory;
@@ -35,12 +34,11 @@ import lombok.val;
 public class ActionLinkFactoryVaa implements ActionLinkUiModelFactory<Component> {
 
     @Override
-    public ActionLinkUiModel<Component> newAction(
-            IsisAppCommonContext commonContext, 
+    public ActionLinkUiModel<Component> newActionLink(
             String named,
             ManagedAction managedAction) {
         
-        val actionOwnerModel = new SimpleObjectUiModel(commonContext, managedAction.getOwner());
+        val actionOwnerModel = new SimpleObjectUiModel(managedAction.getOwner());
         
         val actionUiModel = new ActionLinkVaa(
                 this::createUiComponent,
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModelFactory.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModelFactory.java
index c6c711f..ae602d4 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModelFactory.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/ActionLinkUiModelFactory.java
@@ -19,7 +19,6 @@
 package org.apache.isis.viewer.common.model.action;
 
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 
 /**
  * Creates an {@link ActionLinkUiModel}, a holder of the <em>Action's</em> meta-model 
@@ -33,14 +32,10 @@ import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 public interface ActionLinkUiModelFactory<T> {
     
     /**
-     * 
-     * @param commonContext
      * @param named - used when explicitly named (eg. menu bar layout file), otherwise {@code null}
      * @param managedAction
-     * @return
      */
-    ActionLinkUiModel<T> newAction(
-            IsisAppCommonContext commonContext, 
+    ActionLinkUiModel<T> newActionLink(
             String named,
             ManagedAction managedAction);
     
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
index 6ad1b97..40d5220 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems.java
@@ -76,8 +76,7 @@ final class MenuUiModel_buildMenuItems {
                     
                     val isFirstInSection = itemsPerSectionCounter.intValue()==0; 
                     
-                    val menuActionUiModel = menuActionFactory.newAction(
-                            commonContext,
+                    val menuActionUiModel = menuActionFactory.newActionLink(
                             actionLayoutData.getNamed(),
                             managedAction);
 
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/object/SimpleObjectUiModel.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/object/SimpleObjectUiModel.java
index 6503a73..5bc0a59 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/object/SimpleObjectUiModel.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/object/SimpleObjectUiModel.java
@@ -19,7 +19,6 @@
 package org.apache.isis.viewer.common.model.object;
 
 import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.runtime.context.IsisAppCommonContext;
 
 import lombok.Getter;
 import lombok.NonNull;
@@ -28,8 +27,6 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class SimpleObjectUiModel implements ObjectUiModel {
 
-    private final IsisAppCommonContext commonContext;
-    
     @NonNull @Getter(onMethod = @__(@Override))
     private final ManagedObject managedObject;
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
index 4ed5660..a09ff5c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
@@ -39,6 +39,7 @@ import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 import org.apache.isis.viewer.wicket.ui.util.Decorators;
 
+import lombok.RequiredArgsConstructor;
 import lombok.val;
 import lombok.experimental.UtilityClass;
 
@@ -105,12 +106,13 @@ public final class ServiceActionUtil {
         folderItem.add(subMenuItemsView);
     }
 
-
+    @RequiredArgsConstructor
     private static class MenuActionFactoryWkt implements ActionLinkUiModelFactory<AbstractLink> {
 
+        private final IsisAppCommonContext commonContext;
+        
         @Override
-        public LinkAndLabel newAction(
-                IsisAppCommonContext commonContext, 
+        public LinkAndLabel newActionLink(
                 String named, 
                 ManagedAction managedAction) {
         
@@ -137,7 +139,7 @@ public final class ServiceActionUtil {
         
         menuUiModel.buildMenuItems(
                 commonContext, 
-                new MenuActionFactoryWkt(),
+                new MenuActionFactoryWkt(commonContext),
                 CssMenuItem::newMenuItem,
                 onNewMenuItem);
     }