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 21:42:43 UTC
[isis] branch master updated: ISIS-2340: wkt: simplify menu
building (use shared algorithm)
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 1ea4aa1 ISIS-2340: wkt: simplify menu building (use shared algorithm)
1ea4aa1 is described below
commit 1ea4aa1642d17f6fd052028e0709047724137b68
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jun 24 23:42:26 2020 +0200
ISIS-2340: wkt: simplify menu building (use shared algorithm)
---
.../viewer/javafx/model/menu/MenuItemFx.java | 47 ------
.../viewer/javafx/ui/main/MenuBuilderFx.java | 12 +-
.../action/link/ActionLinkUiModelFactory.java | 43 ------
.../isis/viewer/common/model/menu/MenuUiModel.java | 28 +---
.../model/menu/MenuUiModel_buildMenuItems.java | 116 +++++++++------
.../model/menu/MenuUiModel_buildMenuItems2.java | 161 ---------------------
.../isis/viewer/common/model/menu/MenuVisitor.java | 4 +-
.../common/model/menuitem/MenuItemUiModel.java | 121 ----------------
.../actionmenu/serviceactions/CssMenuItem.java | 84 +++++------
.../actionmenu/serviceactions/MenuActionPanel.java | 13 +-
.../serviceactions/ServiceActionUtil.java | 57 ++++++--
.../serviceactions/ServiceActionsPanel.java | 2 +-
12 files changed, 165 insertions(+), 523 deletions(-)
diff --git a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/menu/MenuItemFx.java b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/menu/MenuItemFx.java
deleted file mode 100644
index aacb1b8..0000000
--- a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/menu/MenuItemFx.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.isis.incubator.viewer.javafx.model.menu;
-
-import org.apache.isis.viewer.common.model.menuitem.MenuItemUiModel;
-
-import lombok.val;
-
-/**
- * @since 2.0.0
- */
-//@Log4j2
-public class MenuItemFx
-extends MenuItemUiModel<javafx.scene.Node, MenuItemFx> {
-
- public static MenuItemFx newMenuItem(final String label) {
- return new MenuItemFx(label);
- }
-
- private MenuItemFx(final String label) {
- super(label);
- }
-
- @Override
- protected MenuItemFx newSubMenuItem(final String label) {
- val subMenuItem = newMenuItem(label);
- subMenuItem.setParent(this);
- return subMenuItem;
- }
-
-}
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 2e8086d..32acbee 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
@@ -40,18 +40,18 @@ public class MenuBuilderFx implements MenuVisitor {
private ActionUiModelFactoryFx actionUiModelFactory = new ActionUiModelFactoryFx();
@Override
- public void addTopLevel(MenuItemDto menu) {
- log.info("top level menu {}", menu.getName());
+ public void addTopLevel(MenuItemDto menuDto) {
+ log.info("top level menu {}", menuDto.getName());
menuBar.getMenus()
- .add(currentTopLevelMenu = new Menu(menu.getName()));
+ .add(currentTopLevelMenu = new Menu(menuDto.getName()));
}
@Override
- public void addSubMenu(MenuItemDto menu) {
- val managedAction = menu.getManagedAction();
+ public void addSubMenu(MenuItemDto menuDto) {
+ val managedAction = menuDto.getManagedAction();
- log.info("sub menu {}", menu.getName());
+ log.info("sub menu {}", menuDto.getName());
val actionUiModel = actionUiModelFactory.newActionUiModel(managedAction);
currentTopLevelMenu.getItems().add(actionUiModel.createMenuUiComponent());
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/link/ActionLinkUiModelFactory.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/link/ActionLinkUiModelFactory.java
deleted file mode 100644
index 297cc21..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/action/link/ActionLinkUiModelFactory.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.isis.viewer.common.model.action.link;
-
-import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
-
-/**
- * Creates an {@link ActionLinkUiModel}, a holder of the <em>Action's</em> meta-model
- * and a click-able UI action component; eg. link, button, menu-items.
- *
- * @see ActionLinkUiModel
- *
- * @since 2.0.0
- * @param <T> - link component type, native to the viewer
- */
-public interface ActionLinkUiModelFactory<T> {
-
- /**
- * @param named - used when explicitly named (eg. menu bar layout file), otherwise {@code null}
- * @param managedAction
- */
- ActionLinkUiModel<T> newActionLink(
- String named,
- ManagedAction managedAction);
-
-
-}
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 001b826..4c19061 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,14 +21,10 @@ package org.apache.isis.viewer.common.model.menu;
import java.io.Serializable;
import java.util.List;
import java.util.Locale;
-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.runtime.context.IsisAppCommonContext;
-import org.apache.isis.viewer.common.model.action.link.ActionLinkUiModelFactory;
-import org.apache.isis.viewer.common.model.menuitem.MenuItemUiModel;
import lombok.Getter;
import lombok.NonNull;
@@ -49,28 +45,6 @@ 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,
- final ActionLinkUiModelFactory<T> menuActionFactory,
- final Function<String, M> menuItemFactory,
- final Consumer<M> onNewMenuItem) {
-
- val menuBars = commonContext.getMenuBarsService().menuBars();
-
- // TODO: remove hard-coded dependency on BS3
- final BS3MenuBar menuBar = (BS3MenuBar) menuBars.menuBarFor(getMenuBarSelect());
-
- MenuUiModel_buildMenuItems.buildMenuItems(
- commonContext,
- menuBar,
- menuActionFactory,
- menuItemFactory,
- onNewMenuItem);
-
- }
-
public void buildMenuItems(
final IsisAppCommonContext commonContext,
final MenuVisitor menuBuilder) {
@@ -78,7 +52,7 @@ public class MenuUiModel implements Serializable {
val menuBars = commonContext.getMenuBarsService().menuBars();
val menuBar = (BS3MenuBar) menuBars.menuBarFor(getMenuBarSelect());
- MenuUiModel_buildMenuItems2.buildMenuItems(
+ MenuUiModel_buildMenuItems.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 7d8ade4..f0b6d91 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
@@ -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.link.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 @Deprecated
+@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
-
+ 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;
-
- // Optionally creates a sub-menu item based on visibility and usability
- menuItemModel.addSubMenuItemFor(
- 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);
- });
+ val visibilityVeto = managedAction.checkVisibility(Where.EVERYWHERE);
+ if (visibilityVeto.isPresent()) {
+ continue;
+ }
+
+ val isFirstInSection = itemsPerSectionCounter.intValue()==0;
+
+ 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/MenuUiModel_buildMenuItems2.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems2.java
deleted file mode 100644
index 5799080..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuUiModel_buildMenuItems2.java
+++ /dev/null
@@ -1,161 +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.isis.viewer.common.model.menu;
-
-import java.util.concurrent.atomic.LongAdder;
-
-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.userprofile.UserProfileUiModelProvider;
-
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-@Log4j2
-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()) {
-
- menuVisitor.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 visibilityVeto = managedAction.checkVisibility(Where.EVERYWHERE);
- if (visibilityVeto.isPresent()) {
- continue;
- }
-
- val isFirstInSection = itemsPerSectionCounter.intValue()==0;
-
- menuVisitor.addSubMenu(managedAction, isFirstInSection, actionLayoutData);
- itemsPerSectionCounter.increment();
-
- }
- }
-
- }
- }
-
- // -- 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 MenuItemDto topLevelDto(
- final IsisAppCommonContext commonContext,
- final BS3Menu menu) {
-
- val menuItemIsUserProfile = _Strings.isNullOrEmpty(menu.getNamed()); // top level menu item name
-
- val menuItemName = menuItemIsUserProfile
- ? userProfileName(commonContext)
- : menu.getNamed();
-
- 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(
- final IsisAppCommonContext commonContext) {
- val userProfile = commonContext
- .lookupServiceElseFail(UserProfileUiModelProvider.class)
- .getUserProfile();
- return userProfile.getUserProfileName();
- }
-
-
-
-
-}
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
index 9cf198a..e2df4b4 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menu/MenuVisitor.java
@@ -20,8 +20,8 @@ package org.apache.isis.viewer.common.model.menu;
public interface MenuVisitor {
- void addTopLevel(MenuItemDto menu);
+ void addTopLevel(MenuItemDto menuDto);
void addSectionSpacer();
- void addSubMenu(MenuItemDto menu);
+ void addSubMenu(MenuItemDto menuDto);
}
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
deleted file mode 100644
index 9603f0d..0000000
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/menuitem/MenuItemUiModel.java
+++ /dev/null
@@ -1,121 +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.isis.viewer.common.model.menuitem;
-
-import java.util.Collections;
-import java.util.List;
-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.ActionUiMetaModel;
-import org.apache.isis.viewer.common.model.action.link.ActionLinkUiModel;
-
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import lombok.val;
-import lombok.experimental.Accessors;
-import lombok.extern.log4j.Log4j2;
-
-/**
- *
- * @since 2.0.0
- * @param <T> - link component type, native to the viewer
- * @param <U> - concrete type implementing this class
- */
-@Accessors(chain = true)
-@RequiredArgsConstructor
-@Log4j2
-public abstract class MenuItemUiModel<T, U extends MenuItemUiModel<T, U>> {
-
- @Getter private final String name;
-
- /**
- * To determine whether requires a separator before it.
- */
- @Getter @Setter private boolean isFirstInSection = false; // unless set otherwise
-
- @Getter @Setter private boolean isTertiaryRoot = false; // unless set otherwise
-
- @Getter @Setter private ActionLinkUiModel<T> menuActionUiModel;
-
- private final List<U> subMenuItems = _Lists.newArrayList();
- protected void addSubMenuItem(final U cssMenuItem) {
- subMenuItems.add(cssMenuItem);
- }
- public List<U> getSubMenuItems() {
- return Collections.unmodifiableList(subMenuItems);
- }
- /**
- * @param menuItems we assume these have the correct parent already set
- */
- public void replaceSubMenuItems(List<U> menuItems) {
- subMenuItems.clear();
- subMenuItems.addAll(menuItems);
- }
- public boolean hasSubMenuItems() {
- return subMenuItems.size() > 0;
- }
-
-
- @Getter private U parent;
- protected void setParent(U parent) {
- this.parent = parent;
- parent.addSubMenuItem(_Casts.uncheckedCast(this));
- }
- public boolean hasParent() {
- return parent != null;
- }
-
- // -- CONSTRUCTION
-
- /**
- * Optionally creates a sub-menu item invoking an action on the provided
- * {@link MenuActionWkt action model}, based on visibility and usability.
- */
- public void addSubMenuItemFor(
- @NonNull final ManagedAction managedAction,
- final boolean isFirstInSection,
- @Nullable final Consumer<U> onNewSubMenuItem) {
-
- 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);
-
- if(onNewSubMenuItem!=null) {
- onNewSubMenuItem.accept(_Casts.uncheckedCast(menutIem));
- }
- }
-
- protected abstract U newSubMenuItem(final String name);
-
-
-}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
index a55116f..11f8209 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/CssMenuItem.java
@@ -16,30 +16,29 @@
* under the License. */
package org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
import java.io.Serializable;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.model.Model;
-import org.apache.isis.viewer.common.model.menuitem.MenuItemUiModel;
+import org.apache.isis.core.commons.internal.base._Casts;
+import org.apache.isis.core.commons.internal.collections._Lists;
import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
import org.apache.isis.viewer.wicket.ui.util.Components;
import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
import org.apache.isis.viewer.wicket.ui.util.Decorators;
import org.apache.isis.viewer.wicket.ui.util.Tooltips;
+import lombok.Getter;
+import lombok.Setter;
import lombok.val;
class CssMenuItem
-extends MenuItemUiModel<AbstractLink, CssMenuItem>
implements Serializable {
private static final long serialVersionUID = 1L;
@@ -51,20 +50,37 @@ implements Serializable {
return new CssMenuItem(name);
}
+ @Getter private final String name;
+
+ @Getter @Setter private LinkAndLabel linkAndLabel;
+ @Getter @Setter private boolean needsSpacerBeforeSelf;
+
private CssMenuItem(final String name) {
- super(name);
+ this.name = name;
}
- @Override
protected CssMenuItem newSubMenuItem(final String name) {
val subMenuItem = newMenuItem(name);
subMenuItem.setParent(this);
return subMenuItem;
}
- @Override
- public LinkAndLabel getMenuActionUiModel() {
- return (LinkAndLabel) super.getMenuActionUiModel();
+ private final List<CssMenuItem> subMenuItems = _Lists.newArrayList();
+ protected void addSubMenuItem(final CssMenuItem cssMenuItem) {
+ subMenuItems.add(cssMenuItem);
+ }
+ public List<CssMenuItem> getSubMenuItems() {
+ return Collections.unmodifiableList(subMenuItems);
+ }
+ /**
+ * @param menuItems we assume these have the correct parent already set
+ */
+ public void replaceSubMenuItems(List<CssMenuItem> menuItems) {
+ subMenuItems.clear();
+ subMenuItems.addAll(menuItems);
+ }
+ public boolean hasSubMenuItems() {
+ return subMenuItems.size() > 0;
}
// //////////////////////////////////////////////////////////////
@@ -81,8 +97,8 @@ implements Serializable {
private Component addMenuItemComponentTo(final MarkupContainer markupContainer) {
- val actionMeta = super.getMenuActionUiModel().getActionUiMetaModel();
- val actionLink = super.getMenuActionUiModel().getUiComponent();
+ val actionMeta = getLinkAndLabel().getActionUiMetaModel();
+ val actionLink = getLinkAndLabel().getUiComponent();
val label = new Label(CssMenuItem.ID_MENU_LABEL, Model.of(this.getName()));
@@ -153,43 +169,19 @@ implements Serializable {
linkComponent.add(new CssClassAppender("top-parent"));
}
}
+
+ @Getter private CssMenuItem parent;
+ protected void setParent(CssMenuItem parent) {
+ this.parent = parent;
+ parent.addSubMenuItem(_Casts.uncheckedCast(this));
+ }
+ public boolean hasParent() {
+ return parent != null;
+ }
- // -- SERIALIZATION PROXY
- private Object writeReplace() {
- return new SerializationProxy(this);
- }
- private void readObject(ObjectInputStream stream) throws InvalidObjectException {
- throw new InvalidObjectException("Proxy required");
- }
- private static class SerializationProxy implements Serializable {
- private static final long serialVersionUID = 1L;
- private final String name;
- private final LinkAndLabel menuActionUiModel;
- private final boolean firstInSection;
- private final boolean tertiaryRoot;
- //private final CssMenuItem parent;
- private List<CssMenuItem> children;
-
- public SerializationProxy(CssMenuItem menuItem) {
- this.name = menuItem.getName();
- this.menuActionUiModel = menuItem.getMenuActionUiModel();
- this.firstInSection = menuItem.isFirstInSection();
- this.tertiaryRoot = menuItem.isTertiaryRoot();
- //this.parent = menuItem.getParent();
- this.children = new ArrayList<CssMenuItem>(menuItem.getSubMenuItems());
- }
- private Object readResolve() {
- val menuItem = new CssMenuItem(name);
- menuItem.setFirstInSection(firstInSection);
- menuItem.setTertiaryRoot(tertiaryRoot);
- menuItem.setMenuActionUiModel(menuActionUiModel);
- for (CssMenuItem child : children) menuItem.addSubMenuItem(child);
- return menuItem;
- }
- }
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/MenuActionPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/MenuActionPanel.java
index c7bd1a6..b42debd 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/MenuActionPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/MenuActionPanel.java
@@ -43,16 +43,14 @@ public abstract class MenuActionPanel extends PanelBase {
return new ListView<CssMenuItem>("subMenuItems", subMenuItems) {
private static final long serialVersionUID = 1L;
- private transient int populationCount = 0;
@Override
protected void populateItem(ListItem<CssMenuItem> listItem) {
val subMenuItem = listItem.getModelObject();
- if(subMenuItem.isFirstInSection()
- && populationCount>0) {
- addSeparatorBefore(subMenuItem, listItem);
- }
+ if(subMenuItem.isNeedsSpacerBeforeSelf()) {
+ listItem.add(new CssClassAppender("list-separator"));
+ }
if (subMenuItem.hasSubMenuItems()) {
addFolderItem(subMenuItem, listItem);
@@ -60,7 +58,6 @@ public abstract class MenuActionPanel extends PanelBase {
addLeafItem(subMenuItem, listItem);
}
- populationCount++;
}
};
}
@@ -76,10 +73,6 @@ public abstract class MenuActionPanel extends PanelBase {
// -- HELPER
- private void addSeparatorBefore(CssMenuItem menuItem, ListItem<CssMenuItem> listItem) {
- listItem.add(new CssClassAppender("list-separator"));
- }
-
private void addFolderItem(CssMenuItem menuItem, ListItem<CssMenuItem> listItem) {
final MarkupContainer parent = this;
ServiceActionUtil.addFolderItem(super.getCommonContext(), menuItem, listItem, parent);
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 357243f..8ff5986 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
@@ -24,15 +24,15 @@ import java.util.function.Consumer;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.AbstractLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
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.link.ActionLinkUiModelFactory;
+import org.apache.isis.viewer.common.model.menu.MenuItemDto;
import org.apache.isis.viewer.common.model.menu.MenuUiModel;
+import org.apache.isis.viewer.common.model.menu.MenuVisitor;
import org.apache.isis.viewer.wicket.model.common.CommonContextUtils;
import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
@@ -54,7 +54,7 @@ public final class ServiceActionUtil {
ListItem<CssMenuItem> listItem,
MarkupContainer parent) {
- val actionUiModel = menuItem.getMenuActionUiModel();
+ val actionUiModel = menuItem.getLinkAndLabel();
val menuItemActionLink = actionUiModel.getUiComponent();
val menuItemLabel = new Label("menuLinkLabel", menuItem.getName());
@@ -87,7 +87,7 @@ public final class ServiceActionUtil {
Fragment folderItem = new Fragment("content", "folderItem", parent);
listItem.add(folderItem);
- folderItem.add(new Label("folderName", subMenuItem.getMenuActionUiModel().getLabel()));
+ folderItem.add(new Label("folderName", subMenuItem.getLinkAndLabel().getLabel()));
final List<CssMenuItem> menuItems = subMenuItem.getSubMenuItems();
ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems",
menuItems) {
@@ -107,12 +107,11 @@ public final class ServiceActionUtil {
folderItem.add(subMenuItemsView);
}
- @RequiredArgsConstructor
- private static class MenuActionFactoryWkt implements ActionLinkUiModelFactory<AbstractLink> {
+ @RequiredArgsConstructor(staticName = "of")
+ private static class LinkAndLabelFactoryWkt {
private final IsisAppCommonContext commonContext;
- @Override
public LinkAndLabel newActionLink(
final String named,
final ManagedAction managedAction) {
@@ -135,17 +134,51 @@ public final class ServiceActionUtil {
}
+ @RequiredArgsConstructor(staticName = "of")
+ private static class MenuBuilderWkt implements MenuVisitor {
+
+ private final Consumer<CssMenuItem> onNewMenuItem;
+ private final LinkAndLabelFactoryWkt linkAndLabelFactory;
+
+ private CssMenuItem currentTopLevelMenu = null;
+ private boolean needsSpacerBeforeSelf = false;
+
+ @Override
+ public void addTopLevel(MenuItemDto menuDto) {
+ currentTopLevelMenu = CssMenuItem.newMenuItem(menuDto.getName());
+ onNewMenuItem.accept(currentTopLevelMenu);
+ }
+
+ @Override
+ public void addSectionSpacer() {
+ needsSpacerBeforeSelf = true;
+ }
+ @Override
+ public void addSubMenu(MenuItemDto menuDto) {
+ val managedAction = menuDto.getManagedAction();
+
+ val menuItem = CssMenuItem.newMenuItem(menuDto.getName());
+
+ currentTopLevelMenu.addSubMenuItem(menuItem);
+
+ menuItem.setLinkAndLabel(linkAndLabelFactory.newActionLink(menuDto.getName(), managedAction));
+ if(needsSpacerBeforeSelf) {
+ needsSpacerBeforeSelf = false;
+ menuItem.setNeedsSpacerBeforeSelf(true);
+ }
+ }
+
+ }
+
public static void buildMenu(
final IsisAppCommonContext commonContext,
final MenuUiModel menuUiModel,
final Consumer<CssMenuItem> onNewMenuItem) {
- menuUiModel.buildMenuItems(
- commonContext,
- new MenuActionFactoryWkt(commonContext),
- CssMenuItem::newMenuItem,
- onNewMenuItem);
+ menuUiModel.buildMenuItems(commonContext, MenuBuilderWkt.of(
+ onNewMenuItem,
+ LinkAndLabelFactoryWkt.of(commonContext)));
}
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
index 444f536..e97f244 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionsPanel.java
@@ -99,7 +99,7 @@ public class ServiceActionsPanel extends MenuActionPanel {
final List<CssMenuItem> childItems = menuItem.getSubMenuItems();
return _NullSafe.stream(childItems)
.map((final CssMenuItem input) -> {
- final String actionIdentifier = input.getMenuActionUiModel().getActionUiMetaModel().getActionIdentifier();
+ final String actionIdentifier = input.getLinkAndLabel().getActionUiMetaModel().getActionIdentifier();
if (actionIdentifier != null) {
// busrules-busrulesobjects-findbyname
final String actionId = CssClassAppender.asCssStyle(actionIdentifier);