You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2017/10/25 15:40:27 UTC

[isis] branch master updated (0173c20 -> 19a47a8)

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

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


    from 0173c20  fixes comment in github-pr.sh
     new b6e96db  ISIS-1752: adds new 'menuBars' resource to RO viewer
     new 00ce18d  Merge remote-tracking branch 'origin/master'
     new b08d3c2  ISIS-1752: moves oid from MenuSection down into ActionLayout, so that could support custom menus in the future.
     new 19a47a8  Merge branch 'ISIS-1752-menu-layout-resource'

The 4 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:
 .../{component => menus}/ActionLayoutData.java     | 107 ++++++---------------
 .../ActionLayoutDataOwner.java                     |   4 +-
 .../isis/applib/layout/menus/HasCssClassFa.java    |  29 ------
 .../apache/isis/applib/layout/menus/HasNamed.java  |  29 ------
 .../apache/isis/applib/layout/menus/HasOid.java    |  29 ------
 .../org/apache/isis/applib/layout/menus/Menu.java  |   7 +-
 .../isis/applib/layout/menus/MenuSection.java      |  25 +----
 .../fixturespec/FixtureScriptsDefault.java         |   6 ++
 .../services/swagger/SwaggerServiceMenu.java       |  44 ++++++++-
 .../layout/menus/MenuBars_roundtrip_Test.java      |  15 ++-
 .../resources/MenuBarsResourceServerside.java      |   7 +-
 11 files changed, 97 insertions(+), 205 deletions(-)
 copy core/applib/src/main/java/org/apache/isis/applib/layout/{component => menus}/ActionLayoutData.java (68%)
 copy core/applib/src/main/java/org/apache/isis/applib/layout/{component => menus}/ActionLayoutDataOwner.java (90%)
 delete mode 100644 core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java
 delete mode 100644 core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java
 delete mode 100644 core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java

-- 
To stop receiving notification emails like this one, please contact
['"commits@isis.apache.org" <co...@isis.apache.org>'].

[isis] 03/04: ISIS-1752: moves oid from MenuSection down into ActionLayout, so that could support custom menus in the future.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b08d3c267477d08f559dded5875564ab457e297c
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Oct 25 16:38:12 2017 +0100

    ISIS-1752: moves oid from MenuSection down into ActionLayout, so that could support custom menus in the future.
---
 .../isis/applib/layout/menus/ActionLayoutData.java | 220 +++++++++++++++++++++
 ...sCssClassFa.java => ActionLayoutDataOwner.java} |  11 +-
 .../apache/isis/applib/layout/menus/HasNamed.java  |  29 ---
 .../apache/isis/applib/layout/menus/HasOid.java    |  29 ---
 .../org/apache/isis/applib/layout/menus/Menu.java  |   7 +-
 .../isis/applib/layout/menus/MenuSection.java      |  25 +--
 .../fixturespec/FixtureScriptsDefault.java         |   6 +
 .../services/swagger/SwaggerServiceMenu.java       |  44 ++++-
 .../layout/menus/MenuBars_roundtrip_Test.java      |  15 +-
 .../resources/MenuBarsResourceServerside.java      |   7 +-
 10 files changed, 288 insertions(+), 105 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutData.java
new file mode 100644
index 0000000..257705c
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutData.java
@@ -0,0 +1,220 @@
+/*
+ *  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.applib.layout.menus;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.isis.applib.annotation.BookmarkPolicy;
+
+/**
+ * Describes the layout of a single action, broadly corresponding to {@link org.apache.isis.applib.annotation.ActionLayout}.
+ *
+ * <p>
+ *  Note that {@link org.apache.isis.applib.annotation.ActionLayout#contributed()} is omitted because this only applies
+ *  to domain services.
+ * </p>
+ */
+@XmlRootElement(
+        name = "action"
+)
+@XmlType(
+    name = "action"
+    , propOrder = {
+        "oid"
+        , "id"
+        , "named"
+        , "namedEscaped"
+        , "bookmarking"
+        , "cssClass"
+        , "cssClassFa"
+        , "describedAs"
+        , "metadataError"
+    }
+)
+public class ActionLayoutData implements Serializable {
+
+
+    private static final long serialVersionUID = 1L;
+
+    public ActionLayoutData() {
+    }
+    public ActionLayoutData(final String oid, final String id) {
+        this.oid = oid;
+        this.id = id;
+    }
+
+
+    private String oid;
+
+    @XmlAttribute(required = true)
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(final String oid) {
+        this.oid = oid;
+    }
+
+
+
+    private String id;
+    /**
+     * Method name.
+     *
+     * <p>
+     *     Overloaded methods are not supported.
+     * </p>
+     */
+    @XmlAttribute(name="id", required = true)
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+
+
+    private BookmarkPolicy bookmarking;
+
+    @XmlAttribute(required = false)
+    public BookmarkPolicy getBookmarking() {
+        return bookmarking;
+    }
+
+    public void setBookmarking(BookmarkPolicy bookmarking) {
+        this.bookmarking = bookmarking;
+    }
+
+
+    private String cssClass;
+
+    @XmlAttribute(required = false)
+    public String getCssClass() {
+        return cssClass;
+    }
+
+    public void setCssClass(String cssClass) {
+        this.cssClass = cssClass;
+    }
+
+
+    private String cssClassFa;
+
+    @XmlAttribute(required = false)
+    public String getCssClassFa() {
+        return cssClassFa;
+    }
+
+    public void setCssClassFa(String cssClassFa) {
+        this.cssClassFa = cssClassFa;
+    }
+
+
+
+
+    private String describedAs;
+
+    @XmlElement(required = false)
+    public String getDescribedAs() {
+        return describedAs;
+    }
+
+    public void setDescribedAs(String describedAs) {
+        this.describedAs = describedAs;
+    }
+
+
+
+    private String named;
+
+    @XmlElement(required = false)
+    public String getNamed() {
+        return named;
+    }
+
+    public void setNamed(String named) {
+        this.named = named;
+    }
+
+
+
+    private Boolean namedEscaped;
+
+    @XmlAttribute(required = false)
+    public Boolean getNamedEscaped() {
+        return namedEscaped;
+    }
+
+    public void setNamedEscaped(Boolean namedEscaped) {
+        this.namedEscaped = namedEscaped;
+    }
+
+
+
+
+    private ActionLayoutDataOwner owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public ActionLayoutDataOwner getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final ActionLayoutDataOwner owner) {
+        this.owner = owner;
+    }
+
+
+    private String metadataError;
+
+    /**
+     * For diagnostics; populated by the framework if and only if a metadata error.
+     */
+    @XmlElement(required = false)
+    public String getMetadataError() {
+        return metadataError;
+    }
+
+    public void setMetadataError(final String metadataError) {
+        this.metadataError = metadataError;
+    }
+
+
+    @Override
+    public String toString() {
+        return "ActionLayoutData{" +
+                "oid='" + oid + '\'' +
+                ", id='" + id + '\'' +
+                '}';
+    }
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutDataOwner.java
similarity index 79%
rename from core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java
rename to core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutDataOwner.java
index 9cf9113..93c3700 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/ActionLayoutDataOwner.java
@@ -18,12 +18,11 @@
  */
 package org.apache.isis.applib.layout.menus;
 
-import javax.xml.bind.annotation.XmlAttribute;
+import java.util.List;
 
-public interface HasCssClassFa {
-
-    @XmlAttribute(required = false)
-    String getCssClassFa();
-    void setCssClassFa(String cssClassFa);
+import org.apache.isis.applib.layout.component.Owner;
 
+public interface ActionLayoutDataOwner extends Owner {
+    List<ActionLayoutData> getActions();
+    void setActions(List<ActionLayoutData> actions);
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java
deleted file mode 100644
index a1fa344..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java
+++ /dev/null
@@ -1,29 +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.applib.layout.menus;
-
-import javax.xml.bind.annotation.XmlElement;
-
-public interface HasNamed {
-
-    @XmlElement(required = false)
-    String getNamed();
-    void setNamed(String named);
-
-}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java
deleted file mode 100644
index 72fecdf..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java
+++ /dev/null
@@ -1,29 +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.applib.layout.menus;
-
-import javax.xml.bind.annotation.XmlElement;
-
-public interface HasOid {
-
-    @XmlElement(required = true)
-    String getOid();
-    void setOid(String named);
-
-}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java
index 689cb1a..d17b3d6 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java
@@ -36,10 +36,11 @@ import org.apache.isis.applib.annotation.DomainServiceLayout;
         name = "menu"
         , propOrder = {
             "named",
+            "cssClassFa",
             "sections"
         }
 )
-public class Menu implements Serializable, HasNamed, HasCssClassFa {
+public class Menu implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
@@ -53,13 +54,11 @@ public class Menu implements Serializable, HasNamed, HasCssClassFa {
 
     private String named;
 
-    @Override
     @XmlElement(required = true)
     public String getNamed() {
         return named;
     }
 
-    @Override
     public void setNamed(String named) {
         this.named = named;
     }
@@ -68,13 +67,11 @@ public class Menu implements Serializable, HasNamed, HasCssClassFa {
 
     private String cssClassFa;
 
-    @Override
     @XmlAttribute(required = false)
     public String getCssClassFa() {
         return cssClassFa;
     }
 
-    @Override
     public void setCssClassFa(final String cssClassFa) {
         this.cssClassFa = cssClassFa;
     }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java
index 8fad97b..ae5b0e8 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java
@@ -21,14 +21,11 @@ package org.apache.isis.applib.layout.menus;
 import java.io.Serializable;
 import java.util.List;
 
-import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlType;
 
 import com.google.common.collect.Lists;
 
-import org.apache.isis.applib.layout.component.ActionLayoutData;
-import org.apache.isis.applib.layout.component.ActionLayoutDataOwner;
 
 /**
  * Corresponds to a domain service that contributes its actions under a particular {@link MenuBar}.
@@ -36,43 +33,27 @@ import org.apache.isis.applib.layout.component.ActionLayoutDataOwner;
 @XmlType(
         name = "section"
         , propOrder = {
-            "oid",
             "actions"
         }
 )
-public class MenuSection implements Serializable, HasOid, ActionLayoutDataOwner {
+public class MenuSection implements Serializable, ActionLayoutDataOwner {
 
     private static final long serialVersionUID = 1L;
 
     public MenuSection() {
     }
 
-    public MenuSection(String oid) {
-        this.oid = oid;
-    }
-
-    private String oid;
-
-    @Override
-    @XmlAttribute(required = true)
-    public String getOid() {
-        return oid;
-    }
-
-    @Override
-    public void setOid(final String oid) {
-        this.oid = oid;
-    }
-
 
     private List<ActionLayoutData> actions = Lists.newArrayList();
 
     // no wrapper
+    @Override
     @XmlElement(name = "action", required = false)
     public List<ActionLayoutData> getActions() {
         return actions;
     }
 
+    @Override
     public void setActions(List<ActionLayoutData> actionLayoutDatas) {
         this.actions = actionLayoutDatas;
     }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/fixturespec/FixtureScriptsDefault.java b/core/applib/src/main/java/org/apache/isis/applib/services/fixturespec/FixtureScriptsDefault.java
index 9137b62..83af55e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/fixturespec/FixtureScriptsDefault.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/fixturespec/FixtureScriptsDefault.java
@@ -24,9 +24,11 @@ import javax.annotation.PostConstruct;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.MinLength;
+import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Optionality;
 import org.apache.isis.applib.annotation.Parameter;
 import org.apache.isis.applib.annotation.ParameterLayout;
@@ -59,6 +61,10 @@ import org.apache.isis.applib.services.eventbus.EventBusService;
  *     automatically registered programmatically if no other instance of {@link FixtureScripts} is found.
  * </p>
  */
+@DomainService(
+        nature = NatureOfService.VIEW_MENU_ONLY,
+        objectType = "isisApplib.FixtureScriptsDefault"
+)
 @DomainServiceLayout(
         named="Prototyping",
         menuBar = DomainServiceLayout.MenuBar.SECONDARY,
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/swagger/SwaggerServiceMenu.java b/core/applib/src/main/java/org/apache/isis/applib/services/swagger/SwaggerServiceMenu.java
index a5f11d5..45b7664 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/swagger/SwaggerServiceMenu.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/swagger/SwaggerServiceMenu.java
@@ -16,6 +16,9 @@
  */
 package org.apache.isis.applib.services.swagger;
 
+import java.net.MalformedURLException;
+import java.net.URL;
+
 import org.apache.isis.applib.IsisApplibModule;
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
@@ -43,17 +46,52 @@ public class SwaggerServiceMenu {
     public static abstract class ActionDomainEvent extends IsisApplibModule.ActionDomainEvent<SwaggerServiceMenu> {
     }
 
-    public static class DownloadSwaggerSpecDomainEvent extends ActionDomainEvent {}
+
+    public static class OpenSwaggerUiDomainEvent extends ActionDomainEvent {}
 
     @Action(
             semantics = SemanticsOf.SAFE,
-            domainEvent = DownloadSwaggerSpecDomainEvent.class,
+            domainEvent = OpenSwaggerUiDomainEvent.class,
             restrictTo = RestrictTo.PROTOTYPING
     )
     @ActionLayout(
             cssClassFa = "fa-download"
     )
     @MemberOrder(sequence="500.600.1")
+    public URL openSwaggerUi() throws MalformedURLException {
+        return new java.net.URL("http:///swagger-ui/index.html");
+    }
+
+
+
+    public static class OpenRestApiDomainEvent extends ActionDomainEvent {}
+
+    @Action(
+            semantics = SemanticsOf.SAFE,
+            domainEvent = OpenSwaggerUiDomainEvent.class,
+            restrictTo = RestrictTo.PROTOTYPING
+    )
+    @ActionLayout(
+            cssClassFa = "fa-external-link"
+    )
+    @MemberOrder(sequence="500.600.2")
+    public URL openRestApi() throws MalformedURLException {
+        return new java.net.URL("http:///restful/");
+    }
+
+
+
+    public static class DownloadSwaggerSpecDomainEvent extends ActionDomainEvent {}
+
+    @Action(
+            semantics = SemanticsOf.SAFE,
+            domainEvent = DownloadSwaggerSpecDomainEvent.class,
+            restrictTo = RestrictTo.PROTOTYPING
+    )
+    @ActionLayout(
+            cssClassFa = "fa-external-link"
+    )
+    @MemberOrder(sequence="500.600.3")
     public Clob downloadSwaggerSchemaDefinition(
             @ParameterLayout(named = "Filename")
             final String fileNamePrefix,
@@ -74,6 +112,8 @@ public class SwaggerServiceMenu {
         return SwaggerService.Format.YAML;
     }
 
+
+
     @javax.inject.Inject
     SwaggerService swaggerService;
 }    
diff --git a/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java b/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java
index 012299f..9ffd97f 100644
--- a/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java
+++ b/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java
@@ -20,7 +20,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import org.apache.isis.applib.layout.component.ActionLayoutData;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -49,15 +48,15 @@ public class MenuBars_roundtrip_Test {
         Menu menu = new Menu();
         menu.setNamed("Parties");
 
-        MenuSection organisationMenu = new MenuSection("parties.OrganisationMenu:1");
-        organisationMenu.getActions().add(new ActionLayoutData("findByReference"));
-        organisationMenu.getActions().add(new ActionLayoutData("findByName"));
-        organisationMenu.getActions().add(new ActionLayoutData("create"));
+        MenuSection organisationMenu = new MenuSection();
+        organisationMenu.getActions().add(new ActionLayoutData("parties.OrganisationMenu:1", "findByReference"));
+        organisationMenu.getActions().add(new ActionLayoutData("parties.OrganisationMenu:1", "findByName"));
+        organisationMenu.getActions().add(new ActionLayoutData("parties.OrganisationMenu:1", "create"));
         menu.getSections().add(organisationMenu);
 
-        MenuSection personMenu = new MenuSection("parties.PersonMenu:1");
-        personMenu.getActions().add(new ActionLayoutData("findByUsername"));
-        personMenu.getActions().add(new ActionLayoutData("create"));
+        MenuSection personMenu = new MenuSection();
+        personMenu.getActions().add(new ActionLayoutData("parties.PersonMenu:1", "findByUsername"));
+        personMenu.getActions().add(new ActionLayoutData("parties.PersonMenu:1", "create"));
         menu.getSections().add(personMenu);
 
         menuBars.getPrimary().getMenus().add(menu);
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java
index 846e79a..f930875 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java
@@ -37,7 +37,7 @@ import org.apache.isis.applib.annotation.DomainServiceLayout;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filters;
-import org.apache.isis.applib.layout.component.ActionLayoutData;
+import org.apache.isis.applib.layout.menus.ActionLayoutData;
 import org.apache.isis.applib.layout.menus.Menu;
 import org.apache.isis.applib.layout.menus.MenuBar;
 import org.apache.isis.applib.layout.menus.MenuBars;
@@ -122,11 +122,10 @@ public class MenuBarsResourceServerside extends ResourceAbstract implements Menu
                     menu.getSections().add(menuSection);
                     menuSection = new MenuSection();
                 }
-                // populated lazily
-                menuSection.setOid(serviceAndAction.serviceAdapter.getOid().enString());
 
                 ObjectAction objectAction = serviceAndAction.objectAction;
-                ActionLayoutData action = new ActionLayoutData(objectAction.getId());
+                final String serviceOid = serviceAndAction.serviceAdapter.getOid().enString();
+                ActionLayoutData action = new ActionLayoutData(serviceOid, objectAction.getId());
                 action.setNamed(objectAction.getName());
                 menuSection.getActions().add(action);
             }

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.

[isis] 04/04: Merge branch 'ISIS-1752-menu-layout-resource'

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 19a47a8ad16f03a5eb5f69db12519a377882abdc
Merge: aed996d b08d3c2
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Oct 25 16:39:49 2017 +0100

    Merge branch 'ISIS-1752-menu-layout-resource'

 .../isis/applib/layout/menus/ActionLayoutData.java | 220 ++++++++++++++++
 .../applib/layout/menus/ActionLayoutDataOwner.java |  28 ++
 .../org/apache/isis/applib/layout/menus/Menu.java  |  93 +++++++
 .../apache/isis/applib/layout/menus/MenuBar.java   |  61 +++++
 .../apache/isis/applib/layout/menus/MenuBars.java  |  96 +++++++
 .../isis/applib/layout/menus/MenuSection.java      |  62 +++++
 .../isis/applib/layout/menus/package-info.java     |  38 +++
 .../fixturespec/FixtureScriptsDefault.java         |   6 +
 .../services/swagger/SwaggerServiceMenu.java       |  44 +++-
 .../layout/menus/MenuBars_roundtrip_Test.java      |  79 ++++++
 .../isis/viewer/restfulobjects/applib/Rel.java     |   1 +
 .../restfulobjects/applib/RepresentationType.java  |   4 +
 .../restfulobjects/applib/RestfulMediaType.java    |   2 +
 .../applib/menubars/MenuBarsResource.java          |  65 +++++
 .../server/RestfulObjectsApplication.java          |   2 +
 .../server/resources/HomePageReprRenderer.java     |   9 +-
 .../resources/HomePageResourceServerside.java      |   5 +
 .../resources/MenuBarsResourceServerside.java      | 283 +++++++++++++++++++++
 example/application/helloworld/pom.xml             |   2 +-
 github-pr.sh                                       |   2 +-
 20 files changed, 1097 insertions(+), 5 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.

[isis] 02/04: Merge remote-tracking branch 'origin/master'

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 00ce18d8981d2415da8d743ed2389eb5e16df563
Merge: b6e96db 0173c20
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Oct 25 16:01:23 2017 +0100

    Merge remote-tracking branch 'origin/master'

 github-pr.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.

[isis] 01/04: ISIS-1752: adds new 'menuBars' resource to RO viewer

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b6e96dbf1427b4b027fa1727b95bbd2bba038b98
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Oct 25 16:00:36 2017 +0100

    ISIS-1752: adds new 'menuBars' resource to RO viewer
---
 .../isis/applib/layout/menus/HasCssClassFa.java    |  29 +++
 .../apache/isis/applib/layout/menus/HasNamed.java  |  29 +++
 .../apache/isis/applib/layout/menus/HasOid.java    |  29 +++
 .../org/apache/isis/applib/layout/menus/Menu.java  |  96 +++++++
 .../apache/isis/applib/layout/menus/MenuBar.java   |  61 +++++
 .../apache/isis/applib/layout/menus/MenuBars.java  |  96 +++++++
 .../isis/applib/layout/menus/MenuSection.java      |  81 ++++++
 .../isis/applib/layout/menus/package-info.java     |  38 +++
 .../layout/menus/MenuBars_roundtrip_Test.java      |  80 ++++++
 .../isis/viewer/restfulobjects/applib/Rel.java     |   1 +
 .../restfulobjects/applib/RepresentationType.java  |   4 +
 .../restfulobjects/applib/RestfulMediaType.java    |   2 +
 .../applib/menubars/MenuBarsResource.java          |  65 +++++
 .../server/RestfulObjectsApplication.java          |   2 +
 .../server/resources/HomePageReprRenderer.java     |   9 +-
 .../resources/HomePageResourceServerside.java      |   5 +
 .../resources/MenuBarsResourceServerside.java      | 284 +++++++++++++++++++++
 example/application/helloworld/pom.xml             |   2 +-
 18 files changed, 911 insertions(+), 2 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java
new file mode 100644
index 0000000..9cf9113
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasCssClassFa.java
@@ -0,0 +1,29 @@
+/*
+ *  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.applib.layout.menus;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+public interface HasCssClassFa {
+
+    @XmlAttribute(required = false)
+    String getCssClassFa();
+    void setCssClassFa(String cssClassFa);
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java
new file mode 100644
index 0000000..a1fa344
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasNamed.java
@@ -0,0 +1,29 @@
+/*
+ *  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.applib.layout.menus;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public interface HasNamed {
+
+    @XmlElement(required = false)
+    String getNamed();
+    void setNamed(String named);
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java
new file mode 100644
index 0000000..72fecdf
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/HasOid.java
@@ -0,0 +1,29 @@
+/*
+ *  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.applib.layout.menus;
+
+import javax.xml.bind.annotation.XmlElement;
+
+public interface HasOid {
+
+    @XmlElement(required = true)
+    String getOid();
+    void setOid(String named);
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java
new file mode 100644
index 0000000..689cb1a
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/Menu.java
@@ -0,0 +1,96 @@
+/*
+ *  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.applib.layout.menus;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+
+/**
+ * Describes the collection of domain services into menubars, broadly corresponding to the aggregation of information of {@link DomainServiceLayout} that have the same value of {@link DomainServiceLayout#named()}.
+ */
+@XmlType(
+        name = "menu"
+        , propOrder = {
+            "named",
+            "sections"
+        }
+)
+public class Menu implements Serializable, HasNamed, HasCssClassFa {
+
+    private static final long serialVersionUID = 1L;
+
+    public Menu() {
+    }
+
+    public Menu(String named) {
+        this.named = named;
+    }
+
+
+    private String named;
+
+    @Override
+    @XmlElement(required = true)
+    public String getNamed() {
+        return named;
+    }
+
+    @Override
+    public void setNamed(String named) {
+        this.named = named;
+    }
+
+
+
+    private String cssClassFa;
+
+    @Override
+    @XmlAttribute(required = false)
+    public String getCssClassFa() {
+        return cssClassFa;
+    }
+
+    @Override
+    public void setCssClassFa(final String cssClassFa) {
+        this.cssClassFa = cssClassFa;
+    }
+
+
+
+    private List<MenuSection> sections = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElement(name = "section", required = false)
+    public List<MenuSection> getSections() {
+        return sections;
+    }
+
+    public void setSections(List<MenuSection> menuSections) {
+        this.sections = sections;
+    }
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBar.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBar.java
new file mode 100644
index 0000000..a349915
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBar.java
@@ -0,0 +1,61 @@
+/*
+ *  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.applib.layout.menus;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+
+/**
+ * Describes the collection of domain services into menubars, broadly corresponding to the aggregation of information of {@link org.apache.isis.applib.annotation.DomainServiceLayout} that have the same value of {@link DomainServiceLayout#named()}.
+ */
+@XmlType(
+        name = "menuBar"
+        , propOrder = {
+            "menus"
+        }
+)
+public class MenuBar implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public MenuBar() {
+    }
+
+
+    private List<Menu> menus = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElement(name = "menu", required = false)
+    public List<Menu> getMenus() {
+        return menus;
+    }
+
+    public void setMenus(List<Menu> menus) {
+        this.menus = menus;
+    }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBars.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBars.java
new file mode 100644
index 0000000..591fc44
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuBars.java
@@ -0,0 +1,96 @@
+/*
+ *  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.applib.layout.menus;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Describes the collection of domain services into menubars, broadly corresponding to the aggregation of information within {@link org.apache.isis.applib.annotation.DomainServiceLayout}.
+ */
+@XmlRootElement(
+        name = "menuBars"
+)
+@XmlType(
+        name = "menuBars"
+        , propOrder = {
+            "primary",
+            "secondary",
+            "tertiary",
+            "metadataError"
+        }
+)
+public class MenuBars implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public MenuBars() {
+    }
+
+    private MenuBar primary = new MenuBar();
+
+    public MenuBar getPrimary() {
+        return primary;
+    }
+
+    public void setPrimary(final MenuBar primary) {
+        this.primary = primary;
+    }
+
+    private MenuBar secondary = new MenuBar();
+
+    public MenuBar getSecondary() {
+        return secondary;
+    }
+
+    public void setSecondary(final MenuBar secondary) {
+        this.secondary = secondary;
+    }
+
+    private MenuBar tertiary = new MenuBar();
+
+    public MenuBar getTertiary() {
+        return tertiary;
+    }
+
+    public void setTertiary(final MenuBar tertiary) {
+        this.tertiary = tertiary;
+    }
+
+
+
+    private String metadataError;
+
+    /**
+     * For diagnostics; populated by the framework if and only if a metadata error.
+     */
+    @XmlElement(required = false)
+    public String getMetadataError() {
+        return metadataError;
+    }
+
+    public void setMetadataError(final String metadataError) {
+        this.metadataError = metadataError;
+    }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java
new file mode 100644
index 0000000..8fad97b
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/MenuSection.java
@@ -0,0 +1,81 @@
+/*
+ *  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.applib.layout.menus;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.layout.component.ActionLayoutData;
+import org.apache.isis.applib.layout.component.ActionLayoutDataOwner;
+
+/**
+ * Corresponds to a domain service that contributes its actions under a particular {@link MenuBar}.
+ */
+@XmlType(
+        name = "section"
+        , propOrder = {
+            "oid",
+            "actions"
+        }
+)
+public class MenuSection implements Serializable, HasOid, ActionLayoutDataOwner {
+
+    private static final long serialVersionUID = 1L;
+
+    public MenuSection() {
+    }
+
+    public MenuSection(String oid) {
+        this.oid = oid;
+    }
+
+    private String oid;
+
+    @Override
+    @XmlAttribute(required = true)
+    public String getOid() {
+        return oid;
+    }
+
+    @Override
+    public void setOid(final String oid) {
+        this.oid = oid;
+    }
+
+
+    private List<ActionLayoutData> actions = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElement(name = "action", required = false)
+    public List<ActionLayoutData> getActions() {
+        return actions;
+    }
+
+    public void setActions(List<ActionLayoutData> actionLayoutDatas) {
+        this.actions = actionLayoutDatas;
+    }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/menus/package-info.java b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/package-info.java
new file mode 100644
index 0000000..23e9b67
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/menus/package-info.java
@@ -0,0 +1,38 @@
+/*
+ *  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.
+ */
+
+/**
+ * The classes in this package provide layout metadata for a domain object's properties, collections and actions - the
+ * &quot;building blocks&quot; which then must be arranged into some sort of layout.
+ *
+ * <p>
+ *     The <code>bootstrap3</code> and <code>fixedcols</code> packages both provide different ways of doing the layout,
+ *     and both reference the classes in this package.
+ * </p>
+ *
+ */
+@javax.xml.bind.annotation.XmlSchema(
+        namespace = "http://isis.apache.org/applib/layout/menus",
+        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
+        xmlns = {
+                @javax.xml.bind.annotation.XmlNs(
+                        namespaceURI = "http://isis.apache.org/applib/layout/menus", prefix = "mnu")
+}
+)
+package org.apache.isis.applib.layout.menus;
\ No newline at end of file
diff --git a/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java b/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java
new file mode 100644
index 0000000..012299f
--- /dev/null
+++ b/core/applib/src/test/java/org/apache/isis/applib/layout/menus/MenuBars_roundtrip_Test.java
@@ -0,0 +1,80 @@
+/**
+ *  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.applib.layout.menus;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.isis.applib.layout.component.ActionLayoutData;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class MenuBars_roundtrip_Test {
+
+    private JaxbService jaxbService;
+
+    @Before
+    public void setUp() throws Exception {
+        jaxbService = new JaxbService.Simple();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+
+    @Test
+    public void happyCase() throws Exception {
+
+        // given
+        MenuBars menuBars = new MenuBars();
+        Menu menu = new Menu();
+        menu.setNamed("Parties");
+
+        MenuSection organisationMenu = new MenuSection("parties.OrganisationMenu:1");
+        organisationMenu.getActions().add(new ActionLayoutData("findByReference"));
+        organisationMenu.getActions().add(new ActionLayoutData("findByName"));
+        organisationMenu.getActions().add(new ActionLayoutData("create"));
+        menu.getSections().add(organisationMenu);
+
+        MenuSection personMenu = new MenuSection("parties.PersonMenu:1");
+        personMenu.getActions().add(new ActionLayoutData("findByUsername"));
+        personMenu.getActions().add(new ActionLayoutData("create"));
+        menu.getSections().add(personMenu);
+
+        menuBars.getPrimary().getMenus().add(menu);
+
+        // when
+        String xml = jaxbService.toXml(menuBars);
+        System.out.println(xml);
+
+        // when
+        MenuBars menuBars2 =
+                jaxbService.fromXml(MenuBars.class, xml);
+
+        // then
+        String xml2 = jaxbService.toXml(menuBars2);
+
+        assertThat(xml, is(equalTo(xml2)));
+
+    }
+
+}
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/Rel.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/Rel.java
index d8c0796..fdd1a2d 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/Rel.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/Rel.java
@@ -60,6 +60,7 @@ public enum Rel {
     // implementation specific
     CONTRIBUTED_BY(RelDefinition.IMPL, "contributed-by"),
     LAYOUT(RelDefinition.IMPL, "layout"),
+    MENUBARS(RelDefinition.IMPL, "menuBars"),
     LOGOUT(RelDefinition.IMPL, "logout");
 
     private final RelDefinition relDef;
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
index 1c2adc7..dd1ddf1 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RepresentationType.java
@@ -97,6 +97,10 @@ public enum RepresentationType {
             null,
             RestfulMediaType.APPLICATION_XML_LAYOUT_BS3,
             null),
+    MENUBARS(
+            null,
+            RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS,
+            null),
     PROPERTY_DESCRIPTION(
             RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION,
             null,
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RestfulMediaType.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RestfulMediaType.java
index b440b89..deb3dde 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RestfulMediaType.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/RestfulMediaType.java
@@ -58,6 +58,8 @@ public final class RestfulMediaType {
     private static final String XML_BASE = "application/xml" + ";profile=" + PROFILE_PARAM_PREFIX;
     public final static String APPLICATION_XML_LAYOUT_BS3 = XML_BASE + "layout-bs3";
 
+    public final static String APPLICATION_XML_LAYOUT_MENUBARS = XML_BASE + "layout-menubars";
+
 
     // currently only support a subset of representations in XML format
 
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/menubars/MenuBarsResource.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
new file mode 100644
index 0000000..941bcb4
--- /dev/null
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
@@ -0,0 +1,65 @@
+/*
+ *  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.restfulobjects.applib.menubars;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
+
+/**
+ * Not part of the Restful Objects spec.
+ */
+@Path("/menuBars")
+public interface MenuBarsResource {
+
+
+    /**
+     * Not part of the Restful Objects spec.
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS })
+    public Response menuBars();
+
+    /**
+     * Not part of the Restful Objects spec.
+     */
+    @DELETE
+    public Response deleteMenuBarsNotAllowed();
+
+    /**
+     * Not part of the Restful Objects spec.
+     */
+    @PUT
+    public Response putMenuBarsNotAllowed();
+
+    /**
+     * Not part of the Restful Objects spec.
+     */
+    @POST
+    public Response postMenuBarsNotAllowed();
+
+
+}
\ No newline at end of file
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplication.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplication.java
index ed75eee..bd6d3af 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplication.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplication.java
@@ -24,6 +24,7 @@ import org.apache.isis.viewer.restfulobjects.server.resources.DomainObjectResour
 import org.apache.isis.viewer.restfulobjects.server.resources.DomainServiceResourceServerside;
 import org.apache.isis.viewer.restfulobjects.server.resources.DomainTypeResourceServerside;
 import org.apache.isis.viewer.restfulobjects.server.resources.HomePageResourceServerside;
+import org.apache.isis.viewer.restfulobjects.server.resources.MenuBarsResourceServerside;
 import org.apache.isis.viewer.restfulobjects.server.resources.SwaggerSpecResource;
 import org.apache.isis.viewer.restfulobjects.server.resources.UserResourceServerside;
 import org.apache.isis.viewer.restfulobjects.server.resources.VersionResourceServerside;
@@ -36,6 +37,7 @@ public class RestfulObjectsApplication extends AbstractJaxRsApplication {
         addClass(HomePageResourceServerside.class);
         addClass(DomainTypeResourceServerside.class);
         addClass(UserResourceServerside.class);
+        addClass(MenuBarsResourceServerside.class);
         addClass(DomainObjectResourceServerside.class);
         addClass(DomainServiceResourceServerside.class);
         addClass(VersionResourceServerside.class);
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
index 855792a..099b121 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
@@ -56,7 +56,8 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
         }
 
         addLinkToUser(getRendererContext().getAuthenticationSession());
-        addLinkToServices(((ResourceContext)getRendererContext()).getPersistenceSession().getServices());
+        addLinkToMenuBars();
+        addLinkToServices(getRendererContext().getPersistenceSession().getServices());
         addLinkToVersion();
         addLinkToDomainTypes(((ResourceContext)getRendererContext()).getSpecificationLoader().allSpecifications());
 
@@ -118,6 +119,12 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
         getLinks().arrayAdd(link);
     }
 
+    private void addLinkToMenuBars() {
+        final JsonRepresentation link = LinkBuilder
+                .newBuilder(getRendererContext(), Rel.MENUBARS.getName(), RepresentationType.MENUBARS, "menuBars").build();
+        getLinks().arrayAdd(link);
+    }
+
     private void addLinkToDomainTypes(final Collection<ObjectSpecification> specifications) {
 
         final JsonRepresentation link = LinkBuilder.newBuilder(getRendererContext(), Rel.DOMAIN_TYPES.getName(), RepresentationType.TYPE_LIST, "domain-types").build();
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
index e0519b8..e335875 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
@@ -20,11 +20,15 @@ package org.apache.isis.viewer.restfulobjects.server.resources;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
@@ -64,6 +68,7 @@ public class HomePageResourceServerside extends ResourceAbstract implements Home
         throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to the home page resource is not allowed.");
     }
 
+
     @Override
     @GET
     @Path("/notAuthenticated")
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java
new file mode 100644
index 0000000..846e79a
--- /dev/null
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/MenuBarsResourceServerside.java
@@ -0,0 +1,284 @@
+/*
+ *  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.restfulobjects.server.resources;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.filter.Filters;
+import org.apache.isis.applib.layout.component.ActionLayoutData;
+import org.apache.isis.applib.layout.menus.Menu;
+import org.apache.isis.applib.layout.menus.MenuBar;
+import org.apache.isis.applib.layout.menus.MenuBars;
+import org.apache.isis.applib.layout.menus.MenuSection;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.actions.notinservicemenu.NotInServiceMenuFacet;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
+import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
+import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceFacet;
+import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.menubars.MenuBarsResource;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
+
+public class MenuBarsResourceServerside extends ResourceAbstract implements MenuBarsResource {
+
+    @Override
+    @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_USER })
+    public Response menuBars() {
+        init(RepresentationType.MENUBARS, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
+
+        final Response.ResponseBuilder builder;
+
+        MenuBars menuBars = new MenuBars();
+
+        List<ObjectAdapter> serviceAdapters = getResourceContext().getServiceAdapters();
+
+        append(serviceAdapters, menuBars.getPrimary(), DomainServiceLayout.MenuBar.PRIMARY);
+        append(serviceAdapters, menuBars.getSecondary(), DomainServiceLayout.MenuBar.SECONDARY);
+        append(serviceAdapters, menuBars.getTertiary(), DomainServiceLayout.MenuBar.TERTIARY);
+
+        builder = Response.status(Response.Status.OK).entity(menuBars).type(RepresentationType.MENUBARS.getXmlMediaType());
+
+        return builder.build();
+    }
+
+    private void append(
+            final List<ObjectAdapter> serviceAdapters,
+            final MenuBar menuBar,
+            final DomainServiceLayout.MenuBar menuBarPos) {
+
+        List<ServiceAndAction> serviceActions = Lists.newArrayList();
+
+        // cf ServiceActionsModel & ServiceActionUtil#buildMenu in Wicket viewer
+        for (final ObjectAdapter serviceAdapter : FluentIterable.from(serviceAdapters).filter(with(menuBarPos))) {
+            collateServiceActions(serviceAdapter, ActionType.USER, serviceActions);
+            collateServiceActions(serviceAdapter, ActionType.PROTOTYPE, serviceActions);
+        }
+
+        final Set<String> serviceNamesInOrder = serviceNamesInOrder(serviceAdapters, serviceActions);
+        final Map<String, List<ServiceAndAction>> serviceActionsByName = groupByServiceName(serviceActions);
+
+        // prune any service names that have no service actions
+        serviceNamesInOrder.retainAll(serviceActionsByName.keySet());
+
+        List<Menu> menus = buildMenuItems(serviceNamesInOrder, serviceActionsByName);
+        menuBar.getMenus().addAll(menus);
+    }
+
+    private static List<Menu> buildMenuItems(
+            final Set<String> serviceNamesInOrder,
+            final Map<String, List<ServiceAndAction>> serviceActionsByName) {
+
+        final List<Menu> menus = Lists.newArrayList();
+        for (String serviceName : serviceNamesInOrder) {
+
+            Menu menu = new Menu(serviceName);
+            menus.add(menu);
+
+            MenuSection menuSection = new MenuSection();
+            final List<ServiceAndAction> serviceActionsForName = serviceActionsByName.get(serviceName);
+            for (ServiceAndAction serviceAndAction : serviceActionsForName) {
+
+                if(serviceAndAction.separator && !menuSection.getActions().isEmpty()) {
+                    menu.getSections().add(menuSection);
+                    menuSection = new MenuSection();
+                }
+                // populated lazily
+                menuSection.setOid(serviceAndAction.serviceAdapter.getOid().enString());
+
+                ObjectAction objectAction = serviceAndAction.objectAction;
+                ActionLayoutData action = new ActionLayoutData(objectAction.getId());
+                action.setNamed(objectAction.getName());
+                menuSection.getActions().add(action);
+            }
+            if(!menuSection.getActions().isEmpty()) {
+                menu.getSections().add(menuSection);
+            }
+        }
+        return menus;
+    }
+
+
+    /**
+     * The unique service names, as they appear in order of the provided List of {@link ServiceAndAction}s.
+     *
+     * straight copy from Wicket UI
+     */
+    private static Set<String> serviceNamesInOrder(
+            final List<ObjectAdapter> serviceAdapters,
+            final List<ServiceAndAction> serviceActions) {
+        final Set<String> serviceNameOrder = Sets.newLinkedHashSet();
+
+        // first, order as defined in isis.properties
+        for (ObjectAdapter serviceAdapter : serviceAdapters) {
+            final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
+            String serviceName = serviceSpec.getFacet(NamedFacet.class).value();
+            serviceNameOrder.add(serviceName);
+        }
+        // then, any other services (eg due to misspellings, at the end)
+        for (ServiceAndAction serviceAction : serviceActions) {
+            if(!serviceNameOrder.contains(serviceAction.serviceName)) {
+                serviceNameOrder.add(serviceAction.serviceName);
+            }
+        }
+        return serviceNameOrder;
+    }
+
+    /**
+     * Group the provided {@link ServiceAndAction}s by their service name.
+     *
+     * straight copy from Wicket UI
+     */
+    private static Map<String, List<ServiceAndAction>> groupByServiceName(
+            final List<ServiceAndAction> serviceActions) {
+        final Map<String, List<ServiceAndAction>> serviceActionsByName = Maps.newTreeMap();
+
+        // map available services
+        ObjectAdapter lastServiceAdapter = null;
+
+        for (ServiceAndAction serviceAction : serviceActions) {
+            List<ServiceAndAction> serviceActionsForName = serviceActionsByName.get(serviceAction.serviceName);
+
+            final ObjectAdapter serviceAdapter = serviceAction.serviceAdapter;
+
+            if(serviceActionsForName == null) {
+                serviceActionsForName = Lists.newArrayList();
+                serviceActionsByName.put(serviceAction.serviceName, serviceActionsForName);
+            } else {
+                // capture whether this action is from a different service; if so, add a separator before it
+                serviceAction.separator = lastServiceAdapter != serviceAdapter;
+            }
+            serviceActionsForName.add(serviceAction);
+            lastServiceAdapter = serviceAdapter;
+        }
+
+        return serviceActionsByName;
+    }
+
+
+    private void collateServiceActions(
+            final ObjectAdapter serviceAdapter,
+            final ActionType actionType,
+            final List<ServiceAndAction> serviceActions) {
+        final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
+
+        // skip if annotated to not be included in repository menu using @DomainService
+        final DomainServiceFacet domainServiceFacet = serviceSpec.getFacet(DomainServiceFacet.class);
+        if (domainServiceFacet != null) {
+            final NatureOfService natureOfService = domainServiceFacet.getNatureOfService();
+            if (natureOfService == NatureOfService.VIEW_REST_ONLY ||
+                    natureOfService == NatureOfService.VIEW_CONTRIBUTIONS_ONLY ||
+                    natureOfService == NatureOfService.DOMAIN) {
+                return;
+            }
+        }
+
+        for (final ObjectAction objectAction : serviceSpec.getObjectActions(
+                actionType, Contributed.INCLUDED, Filters.<ObjectAction>any())) {
+
+            // skip if annotated to not be included in repository menu using legacy mechanism
+            if (objectAction.getFacet(NotInServiceMenuFacet.class) != null) {
+                continue;
+            }
+
+            final MemberOrderFacet memberOrderFacet = objectAction.getFacet(MemberOrderFacet.class);
+            String serviceName = memberOrderFacet != null? memberOrderFacet.name(): null;
+            if(Strings.isNullOrEmpty(serviceName)){
+                serviceName = serviceSpec.getFacet(NamedFacet.class).value();
+            }
+            serviceActions.add(new ServiceAndAction(serviceName, serviceAdapter, objectAction));
+        }
+    }
+
+    private static Predicate<ObjectAdapter> with(final DomainServiceLayout.MenuBar menuBar) {
+        return new Predicate<ObjectAdapter>() {
+            @Override
+            public boolean apply(ObjectAdapter input) {
+                final DomainServiceLayoutFacet facet =
+                        input.getSpecification().getFacet(DomainServiceLayoutFacet.class);
+                return facet != null && facet.getMenuBar() == menuBar;
+            }
+        };
+    }
+
+    @Override
+    public Response deleteMenuBarsNotAllowed() {
+        throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting the menuBars resource is not allowed.");
+
+    }
+
+    @Override
+    public Response putMenuBarsNotAllowed() {
+        throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Putting to the menuBars resource is not allowed.");
+
+    }
+
+    @Override
+    public Response postMenuBarsNotAllowed() {
+        throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to the menuBars resource is not allowed.");
+    }
+
+
+}
+
+class ServiceAndAction {
+    final String serviceName;
+    final ObjectAdapter serviceAdapter;
+    final ObjectAction objectAction;
+
+    public boolean separator;
+
+    ServiceAndAction(
+            final String serviceName,
+            final ObjectAdapter serviceAdapter,
+            final ObjectAction objectAction) {
+        this.serviceName = serviceName;
+        this.serviceAdapter = serviceAdapter;
+        this.objectAction = objectAction;
+    }
+
+    @Override
+    public String toString() {
+        return serviceName + " ~ " + objectAction.getIdentifier().toFullIdentityString();
+    }
+
+}
diff --git a/example/application/helloworld/pom.xml b/example/application/helloworld/pom.xml
index 646de10..ecbd029 100644
--- a/example/application/helloworld/pom.xml
+++ b/example/application/helloworld/pom.xml
@@ -36,7 +36,7 @@
     <packaging>war</packaging>
 
     <properties>
-        <isis.version>1.15.1</isis.version>
+        <isis.version>1.16.0-SNAPSHOT</isis.version>
 
         <lombok.version>1.16.18</lombok.version>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.