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 05d7d4d93294dee591e233b6342133e5d68900dd
Author: Andi Huber <[email protected]>
AuthorDate: Fri Nov 4 11:28:56 2022 +0100

    ISIS-3272: support menu bars layout loading based on mime type (in
    principal)
    
    - yet only implementing XML (no changes here)
---
 .../applib/services/grid/GridLoaderService.java    |   4 +-
 .../services/menu/MenuBarsLoaderService.java       |  29 ++++--
 .../applib/services/menu/MenuBarsService.java      |   2 -
 .../causeway/applib/value/NamedWithMimeType.java   |  36 +++++++
 .../core/config/CausewayConfiguration.java         |  12 ++-
 .../services/layout/LayoutServiceDefault.java      |   5 +-
 .../runtimeservices/src/main/java/module-info.java |   1 -
 .../CausewayModuleCoreRuntimeServices.java         |   8 +-
 .../MenuBarsLoaderServiceBootstrap.java}           | 108 +++++++++++++--------
 ...erviceBS.java => MenuBarsServiceBootstrap.java} |  26 ++---
 .../RuntimeServicesTestAbstract.java               |  12 +--
 .../menubars/bootstrap/MenuBarsServiceBSTest.java  |   9 +-
 .../viewer/vaadin/ui/pages/main/TabUtil.java       |   4 +-
 .../testdomain/rest/MenuBarsResourceTest.java      |  42 ++++----
 .../services/menu/MenuUiServiceDefault.java        |   2 +
 15 files changed, 192 insertions(+), 108 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridLoaderService.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridLoaderService.java
index 7e2adb12b8..37833c16ee 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridLoaderService.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/grid/GridLoaderService.java
@@ -63,12 +63,12 @@ public interface GridLoaderService {
      * Returns a new instance of a {@link Grid} for the specified domain 
class, eg from a
      * <code>layout.xml</code> file, else <code>null</code>.
      */
-    default Grid load(Class<?> domainClass) {
+    default Grid load(final Class<?> domainClass) {
         return load(domainClass, null);
     }
 
     /**
-     * Loads a specic alternative {@link Grid} layout for the specified domain
+     * Loads a specific alternative {@link Grid} layout for the specified 
domain
      * class.
      *
      * <p>
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsLoaderService.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsLoaderService.java
index d351c83b22..5e5986e269 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsLoaderService.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsLoaderService.java
@@ -18,14 +18,17 @@
  */
 package org.apache.causeway.applib.services.menu;
 
-import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBars;
+import java.util.EnumSet;
+import java.util.Optional;
+
+import org.apache.causeway.applib.layout.menubars.MenuBars;
+import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
 
 /**
- * Returns the {@link BSMenuBars} instance (bootstrap3-specific subtype of
- * {@link org.apache.causeway.applib.layout.menubars.MenuBars}, for the UI.
+ * Returns the {@link MenuBars} instance for the UI.
  *
  * <p>
- *     The default implementation deserializes the `menubars.layout.xml` file
+ *     The default implementation de-serializes the `menubars.layout...` file
  *     read from the classpath.
  * </p>
  *
@@ -34,9 +37,11 @@ import 
org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBars;
  *     {@link MenuBarsService}.
  * </p>
  *
- * @since 1.x {@index}
+ * @since 1.x - revised for 2.0 {@index}
  */
-public interface MenuBarsLoaderService {
+public interface MenuBarsLoaderService<T extends MenuBars> {
+
+    Class<T> implementedMenuBarsClass();
 
     /**
      * Whether dynamic reloading of layouts is enabled.
@@ -49,9 +54,15 @@ public interface MenuBarsLoaderService {
     boolean supportsReloading();
 
     /**
-     * Returns a new instance of a {@link BSMenuBars} if possible,
-     * else <tt>null</tt>.
+     * Supported format(s) for {@link #menuBars()}.
+     */
+    EnumSet<CommonMimeType> supportedFormats();
+
+    /**
+     * Returns a new instance of a {@link MenuBars} if possible,
+     * else <tt>Optional.empty()</tt>.
+     * @throws UnsupportedOperationException - when format is not supported
      */
-    BSMenuBars menuBars();
+    Optional<T> menuBars();
 
 }
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsService.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsService.java
index 654359f435..994e5f392b 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsService.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/menu/MenuBarsService.java
@@ -39,8 +39,6 @@ import 
org.apache.causeway.commons.internal.exceptions._Exceptions;
  */
 public interface MenuBarsService {
 
-    @Named(CausewayModuleApplib.NAMESPACE + 
".services.menu.MenuBarsService.Type")
-    @Value
     enum Type {
 
         /**
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/value/NamedWithMimeType.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/value/NamedWithMimeType.java
index 8917d43258..73a7df0e48 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/value/NamedWithMimeType.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/value/NamedWithMimeType.java
@@ -19,14 +19,19 @@
 package org.apache.causeway.applib.value;
 
 import java.io.Serializable;
+import java.util.Optional;
+import java.util.stream.Stream;
 
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
 
+import org.springframework.lang.Nullable;
+
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.internal.base._Strings;
 
 import lombok.Getter;
+import lombok.val;
 
 /**
  * @since 1.x {@index}
@@ -207,6 +212,37 @@ extends
             return mimeType.match(otherMimeType);
         }
 
+        /**
+         * Tries to match fileExt with any {@link CommonMimeType}.
+         */
+        public static Optional<CommonMimeType> valueOfFileExtension(final 
@Nullable String fileExt) {
+            if(_Strings.isNullOrEmpty(fileExt)) {
+                return Optional.empty();
+            }
+            val fileExtLower = fileExt.toLowerCase();
+            return Stream.of(CommonMimeType.values())
+                    
.filter(mime->mime.getProposedFileExtensions().contains(fileExtLower))
+                    .findFirst();
+        }
+
+        /**
+         * Parses fileName for its extension and tries to match with any 
{@link CommonMimeType}.
+         */
+        public static Optional<CommonMimeType> valueOfFileName(final @Nullable 
String fileName) {
+            if(_Strings.isNullOrEmpty(fileName)) {
+                return Optional.empty();
+            }
+            final int p = fileName.lastIndexOf('.');
+            if(p<0) {
+                return Optional.empty();
+            }
+            final int beginIndex = p + 1;
+            if ((fileName.length() - beginIndex) < 0) {
+                return Optional.empty();
+            }
+            return valueOfFileExtension(fileName.substring(beginIndex));
+        }
+
     }
 
 }
diff --git 
a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
 
b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
index 4fee76a0bc..0a0f08dcd8 100644
--- 
a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
+++ 
b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
@@ -42,7 +42,11 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import javax.activation.DataSource;
 import javax.inject.Named;
-import javax.validation.*;
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Payload;
+import javax.validation.Valid;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.NotEmpty;
@@ -2248,6 +2252,10 @@ public class CausewayConfiguration {
              */
             private boolean wicketSourcePlugin = false;
 
+            /**
+             * @deprecated common to all viewers - needs to be moved out of 
Wicket
+             */
+            @Deprecated
             private final Application application = new Application();
             @Data
             public static class Application {
@@ -2325,7 +2333,7 @@ public class CausewayConfiguration {
                  * </p>
                  */
                 @NotNull @NotEmpty
-                private String menubarsLayoutXml = "menubars.layout.xml";
+                private String menubarsLayoutFile = "menubars.layout.xml";
 
                 /**
                  * Identifies the application on the sign-in page
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
index d1db5d9c43..b6f46171c7 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/layout/LayoutServiceDefault.java
@@ -39,7 +39,6 @@ import org.apache.causeway.applib.services.jaxb.JaxbService;
 import org.apache.causeway.applib.services.layout.LayoutExportStyle;
 import org.apache.causeway.applib.services.layout.LayoutService;
 import org.apache.causeway.applib.services.menu.MenuBarsService;
-import org.apache.causeway.applib.services.menu.MenuBarsService.Type;
 import org.apache.causeway.applib.util.ZipWriter;
 import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
 import org.apache.causeway.commons.functional.Try;
@@ -104,7 +103,9 @@ public class LayoutServiceDefault implements LayoutService {
     }
 
     @Override
-    public String menuBarsLayout(final Type type, final CommonMimeType format) 
{
+    public String menuBarsLayout(
+            final MenuBarsService.Type type,
+            final CommonMimeType format) {
         switch(format) {
         case XML:{
             final MenuBars menuBars = menuBarsService.menuBars(type);
diff --git a/core/runtimeservices/src/main/java/module-info.java 
b/core/runtimeservices/src/main/java/module-info.java
index bc734ebd4e..69986102e3 100644
--- a/core/runtimeservices/src/main/java/module-info.java
+++ b/core/runtimeservices/src/main/java/module-info.java
@@ -30,7 +30,6 @@ module org.apache.causeway.core.runtimeservices {
     exports org.apache.causeway.core.runtimeservices.interaction;
     exports org.apache.causeway.core.runtimeservices.jaxb;
     exports org.apache.causeway.core.runtimeservices.locale;
-    exports org.apache.causeway.core.runtimeservices.menubars;
     exports org.apache.causeway.core.runtimeservices.menubars.bootstrap;
     exports org.apache.causeway.core.runtimeservices.message;
     exports org.apache.causeway.core.runtimeservices.placeholder;
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/CausewayModuleCoreRuntimeServices.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/CausewayModuleCoreRuntimeServices.java
index d47c144b99..526ac6c74b 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/CausewayModuleCoreRuntimeServices.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/CausewayModuleCoreRuntimeServices.java
@@ -44,8 +44,8 @@ import 
org.apache.causeway.core.runtimeservices.interaction.InteractionDtoFactor
 import org.apache.causeway.core.runtimeservices.jaxb.JaxbServiceDefault;
 import org.apache.causeway.core.runtimeservices.locale.LanguageProviderDefault;
 import 
org.apache.causeway.core.runtimeservices.locale.LocaleChoiceProviderDefault;
-import 
org.apache.causeway.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault;
-import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBS;
+import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsLoaderServiceBootstrap;
+import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBootstrap;
 import org.apache.causeway.core.runtimeservices.message.MessageServiceDefault;
 import 
org.apache.causeway.core.runtimeservices.placeholder.PlaceholderRenderServiceDefault;
 import 
org.apache.causeway.core.runtimeservices.publish.CommandPublisherDefault;
@@ -103,8 +103,8 @@ import 
org.apache.causeway.core.runtimeservices.xmlsnapshot.XmlSnapshotServiceDe
         LanguageProviderDefault.class,
         LocaleChoiceProviderDefault.class,
         MemberExecutorServiceDefault.class,
-        MenuBarsLoaderServiceDefault.class,
-        MenuBarsServiceBS.class,
+        MenuBarsLoaderServiceBootstrap.class,
+        MenuBarsServiceBootstrap.class,
         MessageServiceDefault.class,
         ObjectIconServiceDefault.class,
         ObjectLifecyclePublisherDefault.class,
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/MenuBarsLoaderServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsLoaderServiceBootstrap.java
similarity index 53%
rename from 
core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/MenuBarsLoaderServiceDefault.java
rename to 
core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsLoaderServiceBootstrap.java
index 74d43571bc..217c5390c5 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/MenuBarsLoaderServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsLoaderServiceBootstrap.java
@@ -16,11 +16,13 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.causeway.core.runtimeservices.menubars;
+package org.apache.causeway.core.runtimeservices.menubars.bootstrap;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.EnumSet;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.annotation.Priority;
@@ -36,54 +38,73 @@ import 
org.apache.causeway.applib.annotation.PriorityPrecedence;
 import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBars;
 import org.apache.causeway.applib.services.jaxb.JaxbService;
 import org.apache.causeway.applib.services.menu.MenuBarsLoaderService;
+import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType;
 import org.apache.causeway.commons.internal.base._Strings;
-import org.apache.causeway.core.config.CausewayConfiguration;
-import org.apache.causeway.core.config.environment.CausewaySystemEnvironment;
 import org.apache.causeway.core.config.viewer.web.WebAppContextPath;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
 import 
org.apache.causeway.core.runtimeservices.CausewayModuleCoreRuntimeServices;
 
+import lombok.Getter;
 import lombok.val;
+import lombok.experimental.Accessors;
 import lombok.extern.log4j.Log4j2;
 
 @Service
-@Named(CausewayModuleCoreRuntimeServices.NAMESPACE + 
".MenuBarsLoaderServiceDefault")
+@Named(CausewayModuleCoreRuntimeServices.NAMESPACE + 
".MenuBarsLoaderServiceBootstrap")
 @Priority(PriorityPrecedence.MIDPOINT)
 @Qualifier("Default")
 @Log4j2
-public class MenuBarsLoaderServiceDefault
-implements MenuBarsLoaderService {
+public class MenuBarsLoaderServiceBootstrap
+implements MenuBarsLoaderService<BSMenuBars> {
 
     private final JaxbService jaxbService;
     private final boolean supportsReloading;
-    private final AtomicReference<AbstractResource> 
menubarsLayoutXmlResourceRef;
+
+    @Getter(onMethod_={@Override}) @Accessors(fluent = true)
+    private final EnumSet<CommonMimeType> supportedFormats = 
EnumSet.of(CommonMimeType.XML);
+
+    private final AtomicReference<AbstractResource> menubarsLayoutResourceRef;
 
     @Inject
-    public MenuBarsLoaderServiceDefault(
-            final CausewaySystemEnvironment causewaySystemEnvironment,
-            final JaxbService jaxbService,
-            final CausewayConfiguration causewayConfiguration) {
+    public MenuBarsLoaderServiceBootstrap(
+            final MetaModelContext mmc,
+            final JaxbService jaxbService) {
         this.jaxbService = jaxbService;
-        this.supportsReloading = causewaySystemEnvironment.isPrototyping();
-
-        val menubarsLayoutXmlResource =
-                new 
ClassPathResource(causewayConfiguration.getViewer().getWicket().getApplication().getMenubarsLayoutXml());
-        this.menubarsLayoutXmlResourceRef = new 
AtomicReference<>(menubarsLayoutXmlResource);
+        this.supportsReloading = mmc.getSystemEnvironment().isPrototyping();
+
+        val menubarsLayoutFile = 
mmc.getConfiguration().getViewer().getWicket().getApplication()
+                .getMenubarsLayoutFile();
+        val menubarsLayoutResource = new ClassPathResource(menubarsLayoutFile);
+        if(!menubarsLayoutResource.exists()) {
+            log.warn("menubarsLayoutFile {} (as configured for Apache 
Causeway) not found",
+                    menubarsLayoutFile);
+        }
+        this.menubarsLayoutMimeType = 
CommonMimeType.valueOfFileName(menubarsLayoutFile)
+                .filter(supportedFormats::contains)
+                .orElse(CommonMimeType.XML); // fallback default
+        this.menubarsLayoutResourceRef = new 
AtomicReference<>(menubarsLayoutResource);
     }
 
     // JUnit support
-    public MenuBarsLoaderServiceDefault(
+    public MenuBarsLoaderServiceBootstrap(
             final JaxbService jaxbService,
-            final AtomicReference<AbstractResource> 
menubarsLayoutXmlResourceRef) {
+            final AtomicReference<AbstractResource> menubarsLayoutResourceRef) 
{
         this.jaxbService = jaxbService;
         this.supportsReloading = true;
 
-        menubarsLayoutXmlResourceRef.getAndUpdate(r->r!=null
+        menubarsLayoutResourceRef.getAndUpdate(r->r!=null
                 ? r
                 : new AbstractResource() {
                     @Override public String getDescription() { return "Empty 
Resource"; }
                     @Override public InputStream getInputStream() throws 
IOException { return null; }}
                 );
-        this.menubarsLayoutXmlResourceRef = menubarsLayoutXmlResourceRef;
+        this.menubarsLayoutResourceRef = menubarsLayoutResourceRef;
+        this.menubarsLayoutMimeType = CommonMimeType.XML;
+    }
+
+    @Override
+    public Class<BSMenuBars> implementedMenuBarsClass() {
+        return BSMenuBars.class;
     }
 
     @Override
@@ -92,16 +113,23 @@ implements MenuBarsLoaderService {
     }
 
     @Override
-    public BSMenuBars menuBars() {
-        return loadMenuBars(loadMenubarsLayoutResource());
+    public Optional<BSMenuBars> menuBars() {
+        return Optional.ofNullable(loadMenuBars(loadMenubarsLayoutResource()));
     }
 
     // public, in support of JUnit testing
-    public BSMenuBars loadMenuBars(String xmlString) {
-        try {
-            return jaxbService.fromXml(BSMenuBars.class, xmlString);
-        } catch (Exception e) {
-            severeCannotLoad(menubarsLayoutXmlResourceRef.get(), e);
+    public BSMenuBars loadMenuBars(final String layoutFileContent) {
+
+        switch(menubarsLayoutMimeType) {
+        case XML:{
+            try {
+                return jaxbService.fromXml(BSMenuBars.class, 
layoutFileContent);
+            } catch (Exception e) {
+                severeCannotLoad(menubarsLayoutResourceRef.get(), e);
+                return null;
+            }
+        }
+        default:
             return null;
         }
     }
@@ -110,31 +138,32 @@ implements MenuBarsLoaderService {
 
     private String loadMenubarsLayoutResource() {
 
-        val menubarsLayoutXmlResource = menubarsLayoutXmlResourceRef.get();
+        val menubarsLayoutResource = menubarsLayoutResourceRef.get();
         try {
 
-            if(!menubarsLayoutXmlResource.exists()) {
+            if(!menubarsLayoutResource.exists()) {
                 return null;
             }
 
-            val source = menubarsLayoutXmlResource.getInputStream(); // throws 
if not found
-            final String xml =
+            val source = menubarsLayoutResource.getInputStream(); // throws if 
not found
+            final String layoutFileContent =
                     _Strings.read(source, StandardCharsets.UTF_8);
 
-            if(xml == null) {
-                warnNotFound(menubarsLayoutXmlResource);
+            if(layoutFileContent == null) {
+                warnNotFound(menubarsLayoutResource);
             }
-            return xml;
+            return layoutFileContent;
         } catch (Exception e) {
-            severeCannotLoad(menubarsLayoutXmlResource, e);
+            severeCannotLoad(menubarsLayoutResource, e);
             return null;
         }
 
     }
 
     private boolean warnedOnce = false;
+    private CommonMimeType menubarsLayoutMimeType;
 
-    private void warnNotFound(AbstractResource menubarsLayoutXmlResource) {
+    private void warnNotFound(final AbstractResource menubarsLayoutResource) {
         if(warnedOnce) {
             return;
         }
@@ -142,16 +171,17 @@ implements MenuBarsLoaderService {
         log.warn(
                 "{}: could not find readable resource {} for the 
Menubars-Layout.",
                         WebAppContextPath.class.getName(),
-                        menubarsLayoutXmlResource);
+                        menubarsLayoutResource);
         warnedOnce = true;
     }
 
-    private void severeCannotLoad(AbstractResource menubarsLayoutXmlResource, 
Exception cause) {
+    private void severeCannotLoad(final AbstractResource 
menubarsLayoutResource, final Exception cause) {
 
         log.error("{}: could not find readable resource {} for the 
Menubars-Layout.",
                         WebAppContextPath.class.getName(),
-                        menubarsLayoutXmlResource,
+                        menubarsLayoutResource,
                 cause);
     }
+
 }
 
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBS.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBootstrap.java
similarity index 96%
rename from 
core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBS.java
rename to 
core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBootstrap.java
index bbdcec8e01..0b426692d5 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBS.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBootstrap.java
@@ -20,7 +20,6 @@ package 
org.apache.causeway.core.runtimeservices.menubars.bootstrap;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
@@ -37,6 +36,7 @@ import 
org.apache.causeway.applib.annotation.DomainServiceLayout;
 import org.apache.causeway.applib.annotation.NatureOfService;
 import org.apache.causeway.applib.annotation.PriorityPrecedence;
 import org.apache.causeway.applib.layout.component.ServiceActionLayoutData;
+import org.apache.causeway.applib.layout.menubars.MenuBars;
 import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenu;
 import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBar;
 import org.apache.causeway.applib.layout.menubars.bootstrap.BSMenuBars;
@@ -51,7 +51,6 @@ import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.collections._Lists;
 import org.apache.causeway.commons.internal.collections._Maps;
 import org.apache.causeway.commons.internal.collections._Sets;
-import org.apache.causeway.core.config.environment.CausewaySystemEnvironment;
 import org.apache.causeway.core.metamodel.context.MetaModelContext;
 import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence;
 import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
@@ -81,12 +80,12 @@ import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 @Service
-@Named(CausewayModuleCoreRuntimeServices.NAMESPACE + ".MenuBarsServiceBS")
+@Named(CausewayModuleCoreRuntimeServices.NAMESPACE + 
".MenuBarsServiceBootstrap")
 @Priority(PriorityPrecedence.MIDPOINT)
 @Qualifier("BS")
 @RequiredArgsConstructor(onConstructor_ = {@Inject})
 @Log4j2
-public class MenuBarsServiceBS
+public class MenuBarsServiceBootstrap
 implements MenuBarsService {
 
     public static final String MB3_TNS = 
"http://causeway.apache.org/applib/layout/menubars/bootstrap3";;
@@ -98,18 +97,18 @@ implements MenuBarsService {
     public static final String LINKS_TNS = GridServiceDefault.LINKS_TNS;
     public static final String LINKS_SCHEMA_LOCATION = 
GridServiceDefault.LINKS_SCHEMA_LOCATION;
 
-    private final MenuBarsLoaderService menuBarsLoaderService;
+    private final MenuBarsLoaderService<BSMenuBars> loader;
     private final MessageService messageService;
     private final JaxbService jaxbService;
-    private final CausewaySystemEnvironment causewaySystemEnvironment;
     private final MetaModelContext metaModelContext;
 
-    private final _Lazy<BSMenuBars> menuBarsFromAnnotationsOnly = 
_Lazy.threadSafe(this::menuBarsFromAnnotationsOnly);
+    private final _Lazy<BSMenuBars> menuBarsFromAnnotationsOnly =
+            _Lazy.threadSafe(this::menuBarsFromAnnotationsOnly);
 
     BSMenuBars menuBars;
 
     @Override
-    public BSMenuBars menuBars(final Type type) {
+    public MenuBars menuBars(final Type type) {
 
         val menuBarsFromAnnotationsOnly = 
this.menuBarsFromAnnotationsOnly.get();
 
@@ -127,16 +126,17 @@ implements MenuBarsService {
         val menuBarsFromAnnotationsOnly = 
this.menuBarsFromAnnotationsOnly.get();
 
         // load (and only fallback if nothing could be loaded)...
-        if(menuBars == null || menuBarsLoaderService.supportsReloading()) {
+        if(menuBars == null || loader.supportsReloading()) {
             this.menuBars = loadOrElse(menuBarsFromAnnotationsOnly);
         }
 
         return menuBars;
     }
 
-    private BSMenuBars loadOrElse(final BSMenuBars 
menuBarsFromAnnotationsOnly) {
+    private BSMenuBars loadOrElse(
+            final BSMenuBars menuBarsFromAnnotationsOnly) {
 
-        val menuBars = Optional.ofNullable(menuBarsLoaderService.menuBars())
+        val menuBars = loader.menuBars()
                 .map(this::updateFacetsFromActionLayoutXml)
                 .map(this::addTnsAndSchemaLocation)
                 .orElse(menuBarsFromAnnotationsOnly);
@@ -271,7 +271,7 @@ implements MenuBarsService {
 
         menuBars.setMetadataError(
                 "Exactly one menu must have 'unreferencedActions' flag set; 
found " + size + " such menus");
-        if(causewaySystemEnvironment.isPrototyping()) {
+        if(metaModelContext.getSystemEnvironment().isPrototyping()) {
             messageService.warnUser("Menubars metadata errors; check the error 
log");
         }
         log.error("Menubar layout metadata errors:\n\n{}\n\n", 
jaxbService.toXml(menuBars));
@@ -502,5 +502,7 @@ implements MenuBarsService {
     }
 
 
+
+
 }
 
diff --git 
a/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/RuntimeServicesTestAbstract.java
 
b/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/RuntimeServicesTestAbstract.java
index 1b02c498b3..3565b936b8 100644
--- 
a/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/RuntimeServicesTestAbstract.java
+++ 
b/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/RuntimeServicesTestAbstract.java
@@ -33,8 +33,8 @@ import 
org.apache.causeway.core.metamodel._testing.MetaModelContext_forTesting;
 import 
org.apache.causeway.core.metamodel._testing.MetaModelContext_forTesting.MetaModelContext_forTestingBuilder;
 import org.apache.causeway.core.metamodel.context.HasMetaModelContext;
 import org.apache.causeway.core.metamodel.context.MetaModelContext;
-import 
org.apache.causeway.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault;
-import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBS;
+import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsLoaderServiceBootstrap;
+import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBootstrap;
 
 import lombok.Getter;
 import lombok.val;
@@ -68,7 +68,7 @@ implements HasMetaModelContext {
                 .forTestingLazy(MenuBarsLoaderService.class, ()->{
 
                     val jaxbService = 
getServiceRegistry().lookupServiceElseFail(JaxbService.class);
-                    return new MenuBarsLoaderServiceDefault(
+                    return new MenuBarsLoaderServiceBootstrap(
                             jaxbService,
                             menubarsLayoutXmlResourceRef);
                 }));
@@ -81,13 +81,11 @@ implements HasMetaModelContext {
                     val messageService = 
getServiceRegistry().lookupServiceElseFail(MessageService.class);
                     val jaxbService = 
getServiceRegistry().lookupServiceElseFail(JaxbService.class);
                     val menuBarsLoaderService = 
getServiceRegistry().lookupServiceElseFail(MenuBarsLoaderService.class);
-                    return new MenuBarsServiceBS(
+                    return new MenuBarsServiceBootstrap(
                             menuBarsLoaderService,
                             messageService,
                             jaxbService,
-                            getSystemEnvironment(),
                             metaModelContext);
-
                     }));
 
 
@@ -105,7 +103,7 @@ implements HasMetaModelContext {
         metaModelContext = null;
     }
 
-    protected void onSetUp(MetaModelContext_forTestingBuilder mmcBuilder) {
+    protected void onSetUp(final MetaModelContext_forTestingBuilder 
mmcBuilder) {
     }
 
     protected void afterSetUp() {
diff --git 
a/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBSTest.java
 
b/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBSTest.java
index 4b1a1cc995..1590ac3e4b 100644
--- 
a/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBSTest.java
+++ 
b/core/runtimeservices/src/test/java/org/apache/causeway/core/runtimeservices/menubars/bootstrap/MenuBarsServiceBSTest.java
@@ -39,15 +39,14 @@ import 
org.apache.causeway.core.metamodel._testing.MetaModelContext_forTesting.M
 import org.apache.causeway.core.metamodel.facetapi.Facet.Precedence;
 import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet;
 import org.apache.causeway.core.runtimeservices.RuntimeServicesTestAbstract;
-import 
org.apache.causeway.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault;
 
 import lombok.val;
 
 class MenuBarsServiceBSTest
 extends RuntimeServicesTestAbstract {
 
-    private MenuBarsServiceBS menuBarsService;
-    private MenuBarsLoaderServiceDefault menuBarsLoaderService;
+    private MenuBarsServiceBootstrap menuBarsService;
+    private MenuBarsLoaderServiceBootstrap menuBarsLoaderService;
     private LayoutService layoutService;
 
     @Override
@@ -61,8 +60,8 @@ extends RuntimeServicesTestAbstract {
         
getConfiguration().getCore().getMetaModel().getIntrospector().setValidateIncrementally(false);
 
         layoutService = 
getServiceRegistry().lookupServiceElseFail(LayoutService.class);
-        menuBarsService = (MenuBarsServiceBS) 
getServiceRegistry().lookupServiceElseFail(MenuBarsService.class);
-        menuBarsLoaderService = (MenuBarsLoaderServiceDefault) 
getServiceRegistry().lookupServiceElseFail(MenuBarsLoaderService.class);
+        menuBarsService = (MenuBarsServiceBootstrap) 
getServiceRegistry().lookupServiceElseFail(MenuBarsService.class);
+        menuBarsLoaderService = (MenuBarsLoaderServiceBootstrap) 
getServiceRegistry().lookupServiceElseFail(MenuBarsLoaderService.class);
 
         // double check, we are all set
         assertNotNull(getSpecificationLoader().loadSpecification(Bar.class));
diff --git 
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/TabUtil.java
 
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/TabUtil.java
index e6f81b1898..b498bb85ab 100644
--- 
a/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/TabUtil.java
+++ 
b/incubator/viewers/vaadin/ui/src/main/java/org/apache/causeway/incubator/viewer/vaadin/ui/pages/main/TabUtil.java
@@ -28,7 +28,7 @@ import com.vaadin.flow.component.tabs.Tabs;
 import com.vaadin.flow.router.RouteConfiguration;
 import com.vaadin.flow.router.RouterLink;
 
-import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBS;
+import 
org.apache.causeway.core.runtimeservices.menubars.bootstrap.MenuBarsServiceBootstrap;
 
 import lombok.experimental.UtilityClass;
 
@@ -36,7 +36,7 @@ import lombok.experimental.UtilityClass;
 @UtilityClass
 final class TabUtil {
 
-    static void createMenuTabs(final MenuBarsServiceBS menuBarsService, final 
Consumer<Tab> onTabCreated) {
+    static void createMenuTabs(final MenuBarsServiceBootstrap menuBarsService, 
final Consumer<Tab> onTabCreated) {
         // onTabCreated.accept(TabUtil.createTab("Dashboard", 
DashboardView.class));
     }
 
diff --git 
a/regressiontests/incubating/src/test/java/org/apache/causeway/testdomain/rest/MenuBarsResourceTest.java
 
b/regressiontests/incubating/src/test/java/org/apache/causeway/testdomain/rest/MenuBarsResourceTest.java
index 17bbc652df..4c50440991 100644
--- 
a/regressiontests/incubating/src/test/java/org/apache/causeway/testdomain/rest/MenuBarsResourceTest.java
+++ 
b/regressiontests/incubating/src/test/java/org/apache/causeway/testdomain/rest/MenuBarsResourceTest.java
@@ -46,11 +46,11 @@ import 
org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization.
 import lombok.val;
 
 @SpringBootTest(
-        classes = { 
+        classes = {
                 Configuration_headless.class,
                 Configuration_usingActionSemantics.class,
                 MenuBarsResourceTest.TestSetup.class
-        }, 
+        },
         properties = {
                 "causeway.core.meta-model.introspector.mode=FULL",
                 "causeway.applib.annotation.domain-object.editing=TRUE",
@@ -62,7 +62,7 @@ import lombok.val;
     CausewayPresets.SilenceProgrammingModel
 })
 class MenuBarsResourceTest {
-    
+
     @Inject private MenuBarsResourceServerside menuBarsResourceServerside;
     @Inject private MenuBarsService menuBarsService;
 
@@ -71,50 +71,50 @@ class MenuBarsResourceTest {
         MenuBarsResourceServerside.class
     })
     static class TestSetup {
-        
+
     }
-    
+
     @Test
     void blobDemoMenu_fromMenuBarsResourceServerside_shouldBe_GET() {
-        
+
         assertNotNull(menuBarsResourceServerside);
-        
-        val layoutResourceDescriptor = 
+
+        val layoutResourceDescriptor =
                 ResourceDescriptor
                 .of(RepresentationType.MENUBARS, Where.ANYWHERE, 
RepresentationService.Intent.NOT_APPLICABLE);
-        
+
         val resourceContext = 
menuBarsResourceServerside.resourceContextForTesting(layoutResourceDescriptor, 
/*params*/null);
         val linksForServiceActionsAddingVisitor = 
MenuBarsResourceServerside.linksForServiceActionsAddingVisitor(resourceContext);
-        
+
         val menuBars = menuBarsService.menuBars();
-        
+
         menuBars.visit(linksForServiceActionsAddingVisitor);
-        
+
         assertNotNull(menuBars);
-        
+
         val blobDemoMenuRef = _Refs.<ServiceActionLayoutData>objectRef(null);
-        
+
         // find service action by object-type
         menuBars.visit(actionLayoutData->{
             
if("regressiontests.BlobDemoMenu".equals(actionLayoutData.getObjectType())) {
                 blobDemoMenuRef.setValue(actionLayoutData);
             }
         });
-        
+
         val blobDemoMenu = blobDemoMenuRef.getValue().orElse(null);
-        
+
         assertNotNull(blobDemoMenu);
-        
+
         val jaxbEntity = 
SerializationStrategy.JSON_INDENTED.entity(blobDemoMenu);
-        
+
         assertNotNull(jaxbEntity);
-        
+
         final long methodCount = _Strings.grep(jaxbEntity.toString(), 
"\"method\"")
         .filter(line->line.contains("GET"))
         .count();
-        
+
         assertEquals(1L, methodCount);
-        
+
     }
 
 }
diff --git 
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
 
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
index 5950776583..7b34e4499c 100644
--- 
a/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
+++ 
b/viewers/commons/services/src/main/java/org/apache/causeway/viewer/commons/services/menu/MenuUiServiceDefault.java
@@ -56,10 +56,12 @@ implements MenuUiService {
     private final MetaModelContext metaModelContext;
     private final MenuBarsService menuBarsService;
 
+    @Override
     public MenuUiModel getMenu(final DomainServiceLayout.MenuBar 
menuBarSelect) {
         return MenuUiModel.of(menuBarSelect, select(menuBarSelect));
     }
 
+    @Override
     public void buildMenuItems(
             final MenuUiModel menuUiModel,
             final MenuVisitor menuBuilder) {


Reply via email to