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 2014/11/13 18:12:46 UTC

[7/7] isis git commit: ISIS-951: introducing menu separators; also getting rid of the btn-warning for prototype, using subtler italics instead.

ISIS-951: introducing menu separators; also getting rid of the btn-warning for prototype, using subtler italics instead.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f436bcb1
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f436bcb1
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f436bcb1

Branch: refs/heads/master
Commit: f436bcb124830b3d94063ebdbb221c6ecb786d11
Parents: ad8e6b8
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Nov 13 16:25:23 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Nov 13 16:25:23 2014 +0000

----------------------------------------------------------------------
 .../cssmenu/AppActionsCssMenuFactory.java       | 11 ++-
 .../cssmenu/ApplicationActionsPanel.html        |  6 +-
 .../cssmenu/ApplicationActionsPanel.java        | 81 ++++++++++++++------
 .../widgets/cssmenu/CssMenuBuilder.java         |  2 +-
 .../components/widgets/cssmenu/CssMenuItem.java | 38 ++++++---
 .../widgets/cssmenu/CssMenuItemPanel.html       |  2 +-
 .../widgets/cssmenu/CssMenuPanel.java           | 19 +----
 .../widgets/cssmenu/CssSubMenuItemsPanel.html   |  2 +-
 .../wicket/ui/pages/bootstrap-overrides.css     | 17 ++++
 .../exceprecog/ExceptionRecognizer.java         |  5 +-
 .../exceprecog/ExceptionRecognizer2.java        |  3 +
 .../ExceptionRecognizerComposite.java           |  6 ++
 12 files changed, 133 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
index 12d544c..3d9e8ba 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/appactions/cssmenu/AppActionsCssMenuFactory.java
@@ -61,7 +61,8 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
         private final ObjectAdapter serviceAdapter;
         private final ObjectAdapterMemento serviceAdapterMemento;
         private final ObjectAction objectAction;
-        
+        public boolean separator;
+
         LogicalServiceAction(final String serviceName, final ObjectAdapter serviceAdapter, final ObjectAction objectAction) {
             this.serviceName = serviceName;
             this.serviceAdapter = serviceAdapter;
@@ -133,7 +134,8 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
                 }
                 final ObjectAdapterMemento serviceAdapterMemento = logicalServiceAction.serviceAdapterMemento;
                 final ObjectAction objectAction = logicalServiceAction.objectAction;
-                final Builder subMenuItemBuilder = serviceMenuItem.newSubMenuItem(serviceAdapterMemento, objectAction, cssMenuContext);
+                final boolean separator = logicalServiceAction.separator;
+                final Builder subMenuItemBuilder = serviceMenuItem.newSubMenuItem(serviceAdapterMemento, objectAction, separator, cssMenuContext);
                 if (subMenuItemBuilder == null) {
                     // not visible
                     continue;
@@ -201,13 +203,18 @@ public class AppActionsCssMenuFactory extends ComponentFactoryAbstract {
         final Map<String, List<LogicalServiceAction>> serviceActionsByName = Maps.newTreeMap();
         
         // map available services
+        ObjectAdapter lastServiceAdapter = null;
         for (LogicalServiceAction serviceAction : serviceActions) {
             List<LogicalServiceAction> serviceActionsForName = serviceActionsByName.get(serviceAction.serviceName);
             if(serviceActionsForName == null) {
                 serviceActionsForName = Lists.newArrayList();
                 serviceActionsByName.put(serviceAction.serviceName, serviceActionsForName);
+            } else {
+                // capture whether this action is from a different service
+                serviceAction.separator = lastServiceAdapter != serviceAction.serviceAdapter;
             }
             serviceActionsForName.add(serviceAction);
+            lastServiceAdapter = serviceAction.serviceAdapter;
         }
         
         return serviceActionsByName;

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
index 0a37c74..0562067 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.html
@@ -13,7 +13,7 @@
 
             <wicket:fragment wicket:id="leafItem">
                 <a class="menuLink" wicket:id="menuLink">
-                    <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span> <span wicket:id="menuLinkLabel"></span>
+                    <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span> <span class="menuLinkLabel" wicket:id="menuLinkLabel"></span>
                 </a>
             </wicket:fragment>
 
@@ -26,6 +26,10 @@
                 </ul>
             </wicket:fragment>
 
+            <wicket:fragment wicket:id="empty">
+            </wicket:fragment>
+
+
         </wicket:panel>
     </body>
 </html>

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
index fa6f4be..48b34d4 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/ApplicationActionsPanel.java
@@ -6,6 +6,7 @@ import de.agilecoders.wicket.extensions.markup.html.bootstrap.button.DropdownAut
 
 import java.util.List;
 import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
 import org.apache.wicket.markup.head.CssHeaderItem;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.JavaScriptHeaderItem;
@@ -49,7 +50,7 @@ public class ApplicationActionsPanel extends Panel {
                 CssMenuItem menuItem = listItem.getModelObject();
                 listItem.add(new Label("name", menuItem.getName()));
 
-                List<CssMenuItem> subMenuItems = menuItem.getSubMenuItems();
+                List<CssMenuItem> subMenuItems = withSeparators(menuItem);
 
 // fake data to test multi-level menus
 
@@ -88,7 +89,9 @@ public class ApplicationActionsPanel extends Panel {
         listItem.add(folderItem);
 
         folderItem.add(new Label("folderName", subMenuItem.getName()));
-        ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems", subMenuItem.getSubMenuItems()) {
+        final List<CssMenuItem> menuItems = withSeparators(subMenuItem);
+        ListView<CssMenuItem> subMenuItemsView = new ListView<CssMenuItem>("subMenuItems",
+                menuItems) {
             @Override
             protected void populateItem(ListItem<CssMenuItem> listItem) {
                 CssMenuItem subMenuItem = listItem.getModelObject();
@@ -103,35 +106,63 @@ public class ApplicationActionsPanel extends Panel {
         folderItem.add(subMenuItemsView);
     }
 
-    private void addLeafItem(CssMenuItem menuItem, ListItem<CssMenuItem> listItem) {
-        Fragment leafItem = new Fragment("content", "leafItem", ApplicationActionsPanel.this);
+    private List<CssMenuItem> withSeparators(CssMenuItem subMenuItem) {
+        final List<CssMenuItem> subMenuItems = subMenuItem.getSubMenuItems();
+        final List<CssMenuItem> itemsWithSeparators = Lists.newArrayList();
+        for (CssMenuItem menuItem : subMenuItems) {
+            if(menuItem.isSeparator()) {
+                // nasty...
+                // ... we add it twice, but mutate it along the way
+                itemsWithSeparators.add(
+                        CssMenuItem.newMenuItem(menuItem.getName() + "-separator")
+                                .separator(menuItem.isSeparator())
+                                .prototyping(menuItem.isPrototyping())
+                                .build());
+                menuItem.setSeparator(false);
+            }
+            itemsWithSeparators.add(menuItem);
+        }
+        return itemsWithSeparators;
+    }
 
-        AbstractLink subMenuItemLink = menuItem.getLink();
+    private void addLeafItem(
+            final CssMenuItem menuItem,
+            final ListItem<CssMenuItem> listItem) {
 
-        Label menuItemLabel = new Label("menuLinkLabel", menuItem.getName());
-        subMenuItemLink.addOrReplace(menuItemLabel);
+        Fragment leafItem;
+        if (!menuItem.isSeparator()) {
+            leafItem = new Fragment("content", "leafItem", ApplicationActionsPanel.this);
 
-        if (!menuItem.isEnabled()) {
-            listItem.add(new CssClassNameAppender("disabled"));
-            subMenuItemLink.setEnabled(false);
-            TooltipBehavior tooltipBehavior = new TooltipBehavior(Model.of(menuItem.getDisabledReason()));
-            listItem.add(tooltipBehavior);
-        }
-        if (menuItem.isPrototyping()) {
-            subMenuItemLink.add(new CssClassNameAppender("btn btn-warning"));
-        }
-        leafItem.add(subMenuItemLink);
-        listItem.add(leafItem);
+            AbstractLink subMenuItemLink = menuItem.getLink();
 
-        String cssClassFa = menuItem.getCssClassFa();
-        if (Strings.isNullOrEmpty(cssClassFa)) {
-            Components.permanentlyHide(subMenuItemLink, "menuLinkFontAwesome");
-            subMenuItemLink.add(new CssClassAppender("menuLinkSpacer"));
+            Label menuItemLabel = new Label("menuLinkLabel", menuItem.getName());
+            subMenuItemLink.addOrReplace(menuItemLabel);
+
+            if (!menuItem.isEnabled()) {
+                listItem.add(new CssClassNameAppender("disabled"));
+                subMenuItemLink.setEnabled(false);
+                TooltipBehavior tooltipBehavior = new TooltipBehavior(Model.of(menuItem.getDisabledReason()));
+                listItem.add(tooltipBehavior);
+            }
+            if (menuItem.isPrototyping()) {
+                subMenuItemLink.add(new CssClassNameAppender("prototype"));
+            }
+            leafItem.add(subMenuItemLink);
+
+            String cssClassFa = menuItem.getCssClassFa();
+            if (Strings.isNullOrEmpty(cssClassFa)) {
+                Components.permanentlyHide(subMenuItemLink, "menuLinkFontAwesome");
+                subMenuItemLink.add(new CssClassAppender("menuLinkSpacer"));
+            } else {
+                Label dummy = new Label("menuLinkFontAwesome", "");
+                dummy.add(new CssClassAppender(cssClassFa));
+                subMenuItemLink.addOrReplace(dummy);
+            }
         } else {
-            Label dummy = new Label("menuLinkFontAwesome", "");
-            dummy.add(new CssClassAppender(cssClassFa));
-            subMenuItemLink.addOrReplace(dummy);
+            leafItem = new Fragment("content", "empty", ApplicationActionsPanel.this);
+            listItem.add(new CssClassNameAppender("divider"));
         }
+        listItem.add(leafItem);
 
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
index 6b9189f..0b12d23 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuBuilder.java
@@ -160,7 +160,7 @@ public class CssMenuBuilder {
         final ObjectAdapterMemento targetAdapterMemento = adapterMemento; // determineAdapterFor(action);
         if(targetAdapterMemento != null) {
             // against an entity or a service (if a contributed action)
-            subMenuItemBuilder = parent.newSubMenuItem(targetAdapterMemento, action, cssMenuContext);
+            subMenuItemBuilder = parent.newSubMenuItem(targetAdapterMemento, action, false, cssMenuContext);
         } else {
             if (action.containsDoOpFacet(BulkFacet.class)) {
                 // ignore fact have no target action; 

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
index bfbb539..05b0184 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItem.java
@@ -104,20 +104,16 @@ public class CssMenuItem implements Serializable {
             return this;
         }
 
-        /**
-         * Access the {@link CssMenuItem} before it is attached to its parent.
-         * 
-         * @see #build()
-         */
-        public CssMenuItem itemBeingBuilt() {
-            return cssMenuItem;
-        }
-
         public Builder prototyping(boolean prototype) {
             cssMenuItem.setPrototyping(prototype);
             return this;
         }
 
+        public Builder separator(boolean separator) {
+            cssMenuItem.setSeparator(separator);
+            return this;
+        }
+
         public Builder withActionIdentifier(String actionIdentifier) {
             cssMenuItem.setActionIdentifier(actionIdentifier);
             return this;
@@ -169,6 +165,7 @@ public class CssMenuItem implements Serializable {
     private String disabledReason;
     private boolean blobOrClob = false; // unless set otherwise
     private boolean prototype = false; // unless set otherwise
+    private boolean separator = false; // unless set otherwise
 
     static final String ID_MENU_LABEL = "menuLabel";
 
@@ -202,6 +199,18 @@ public class CssMenuItem implements Serializable {
         return prototype;
     }
 
+    public void setSeparator(boolean separator) {
+        this.separator = separator;
+    }
+
+    /**
+     * Requires a separator before it
+     * @return
+     */
+    public boolean isSeparator() {
+        return separator;
+    }
+
     private CssMenuItem(final String name) {
         this.name = name;
     }
@@ -292,6 +301,7 @@ public class CssMenuItem implements Serializable {
     public Builder newSubMenuItem(
             final ObjectAdapterMemento targetAdapterMemento,
             final ObjectAction objectAction,
+            final boolean separator,
             final CssMenuBuilder.CssMenuContext cssMenuContext) {
 
         // check visibility
@@ -325,6 +335,7 @@ public class CssMenuItem implements Serializable {
                 .enabled(reasonDisabledIfAny)
                 .returnsBlobOrClob(returnsBlobOrClob(objectAction))
                 .prototyping(isExplorationOrPrototype(objectAction))
+                .separator(separator)
                 .withActionIdentifier(actionIdentifierFor(objectAction))
                 .withCssClass(cssClassFor(objectAction))
                 .withCssClassFa(cssClassFaFor(objectAction));
@@ -388,8 +399,8 @@ public class CssMenuItem implements Serializable {
         final String actionLabel = linkAndLabel.getLabel();
         Builder builder = this.newSubMenuItem(actionLabel)
                               .link(link)
-                              .prototyping(linkAndLabel.isPrototype())
-                              .returnsBlobOrClob(linkAndLabel.isBlobOrClob())
+                .prototyping(linkAndLabel.isPrototype())
+                .returnsBlobOrClob(linkAndLabel.isBlobOrClob())
                               .withFacet(objectAction.getFacet(CssClassFacet.class))
                               .withFacet(objectAction.getFacet(CssClassFaFacet.class));
         return builder;
@@ -423,10 +434,13 @@ public class CssMenuItem implements Serializable {
                 link.add(new CssClassAppender("noVeil"));
             }
             if(this.prototype) {
-                link.add(new CssClassAppender("btn-warning"));
+                link.add(new CssClassAppender("prototype"));
+                link.add(new CssClassAppender("btn-default"));
             } else {
                 link.add(new CssClassAppender("btn-default"));
             }
+
+
             if(this.cssClass != null) {
                 link.add(new CssClassAppender(this.cssClass));
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
index 1d65257..7d80c8e 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuItemPanel.html
@@ -23,7 +23,7 @@
             <li class="cssMenuItemPanel">
                 <a wicket:id="menuLink" class="btn">
                     <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span>
-                    <span wicket:id="menuLabel">[menu label]</span>
+                    <span class="menuLabel" wicket:id="menuLabel">[menu label]</span>
                 </a>
 
                 <p wicket:id="menuLabel">[menu label]</p>

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
index 9181e76..ad0c75a 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssMenuPanel.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.viewer.wicket.ui.components.widgets.cssmenu;
 
-import java.util.Arrays;
 import java.util.List;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.html.WebMarkupContainer;
@@ -27,7 +26,6 @@ import org.apache.wicket.markup.repeater.RepeatingView;
 import org.apache.wicket.model.util.ListModel;
 import org.apache.isis.core.commons.lang.StringExtensions;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
@@ -39,7 +37,7 @@ import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
  * <p>
  * The {@link Style} enum allows the presentation to be altered.
  */
-public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
+public class CssMenuPanel extends PanelAbstract<CssMenuPanel.ListOfCssMenuItemsModel> {
 
     private static final long serialVersionUID = 1L;
 
@@ -66,26 +64,21 @@ public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
         }
     }
 
-    static class MyModel extends ListModel<CssMenuItem> {
+    static class ListOfCssMenuItemsModel extends ListModel<CssMenuItem> {
 
         private static final long serialVersionUID = 1L;
 
-        public MyModel(final List<CssMenuItem> cssMenuItems) {
+        public ListOfCssMenuItemsModel(final List<CssMenuItem> cssMenuItems) {
             super(cssMenuItems);
         }
     }
 
-    public static CssMenuItem.Builder newMenuItem(final String name) {
-        return CssMenuItem.newMenuItem(name);
-    }
-
     private final StyleAppender styleAppender;
     static final String ID_MENU_ITEMS = "menuItems";
-    static final String ID_MENU_ITEM_FONT_AWESOME = "menuItemFontAwesome";
     static final String ID_MENU_ITEM = "menuItem";
 
     public CssMenuPanel(final String id, final Style style, final List<CssMenuItem> topLevelMenuItems) {
-        super(id, new MyModel(topLevelMenuItems));
+        super(id, new ListOfCssMenuItemsModel(topLevelMenuItems));
         this.styleAppender = new StyleAppender(style);
 
         add(styleAppender);
@@ -102,10 +95,6 @@ public class CssMenuPanel extends PanelAbstract<CssMenuPanel.MyModel> {
 
     }
 
-    public CssMenuPanel(final ComponentType componentType, final Style style, final CssMenuItem... topLevelMenuItems) {
-        this(componentType.getWicketId(), style, Arrays.asList(topLevelMenuItems));
-    }
-
     static final class StyleAppender extends CssClassAppender {
 
         private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
index f4e5fdf..4b4d00d 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/cssmenu/CssSubMenuItemsPanel.html
@@ -24,7 +24,7 @@
         <li wicket:id="subMenuItems" class="cssSubMenuItem">
             <a wicket:id="menuLink" class="btn">
                 <span class="fontAwesomeIcon" wicket:id="menuLinkFontAwesome"></span>
-                <span wicket:id="menuLabel">[menu label]</span>
+                <span class="menuLabel" wicket:id="menuLabel">[menu label]</span>
             </a>
             <p wicket:id="menuLabel">[menu label]</p>
             <span wicket:id="subMenuItems">[subMenuItems]</span>

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
index 51c53d3..9e3e23d 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/bootstrap-overrides.css
@@ -172,3 +172,20 @@ div.label-left .choicesPlaceholder {
     width: 20px;
     height: 20px;
 }
+
+.prototype {
+    font-style: italic;
+}
+
+/*
+not sure if this also needed, but it works...
+a.prototype span.menuLabel::before,
+a.prototype span.menuLinkLabel::before {
+    content: "[";
+}
+
+a.prototype span.menuLabel::after,
+a.prototype span.menuLinkLabel::after {
+    content: "]";
+}
+*/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
index 1b66626..258fa0e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
-
+import org.apache.isis.applib.annotation.Programmatic;
 
 
 /**
@@ -60,11 +60,14 @@ public interface ExceptionRecognizer {
      * 
      * @return user-friendly message to render, or <tt>null</tt> otherwise.
      */
+    @Programmatic
     public String recognize(Throwable ex);
 
+    @Programmatic
     @PostConstruct
     public void init(Map<String, String> properties);
 
+    @Programmatic
     @PreDestroy
     public void shutdown();
 

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
index d69f9d3..89b2ae1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.applib.services.exceprecog;
 
+import org.apache.isis.applib.annotation.Programmatic;
+
 /**
  * An extension of the {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer} interface that
  * allows recognized exceptions to be {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category categorize}d.
@@ -77,6 +79,7 @@ public interface ExceptionRecognizer2 extends ExceptionRecognizer {
         }
     }
 
+    @Programmatic
     public Recognition recognize2(final Throwable ex);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/f436bcb1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
index 390e797..f3b6a63 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
@@ -28,6 +28,7 @@ import javax.annotation.PreDestroy;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.annotation.Programmatic;
 
 /**
  * Convenience implementation of {@link ExceptionRecognizer} that loops through a list of
@@ -66,6 +67,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
      * before the more general ones.  See the <i>JDO object store</i> applib for
      * an example.
      */
+    @Programmatic
     public final void add(ExceptionRecognizer ers) {
         services.add(ers);
     }
@@ -74,6 +76,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
      * Returns the non-<tt>null</tt> message of the first {@link #add(ExceptionRecognizer) add}ed 
      * {@link ExceptionRecognizer service} that recognizes the exception. 
      */
+    @Programmatic
     public final  String recognize(Throwable ex) {
         for (ExceptionRecognizer ers : services) {
             String message = ers.recognize(ex);
@@ -95,6 +98,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
      *     category of {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category#CLIENT_ERROR}.
      * </p>
      */
+    @Programmatic
     public final Recognition recognize2(Throwable ex) {
         for (ExceptionRecognizer ers : services) {
             if(ers instanceof ExceptionRecognizer2) {
@@ -111,6 +115,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
 
     @PostConstruct
     @Override
+    @Programmatic
     public final void init(Map<String, String> properties) {
         for (ExceptionRecognizer ers : services) {
             ers.init(properties);
@@ -119,6 +124,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
 
     @PreDestroy
     @Override
+    @Programmatic
     public final void shutdown() {
         for (ExceptionRecognizer ers : services) {
             ers.shutdown();