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 2016/02/10 12:33:34 UTC

[1/5] isis git commit: ISIS-993: introducing the concept of minimal/normalized/complete grids (still WIP)

Repository: isis
Updated Branches:
  refs/heads/ISIS-993 f3e8bbfc0 -> 78943221c


http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
index 706db56..7b90b82 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/BS3GridTest.java
@@ -30,6 +30,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.applib.layout.bootstrap3.BS3Col;
 import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
 import org.apache.isis.applib.layout.bootstrap3.BS3Row;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/FCGridTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/FCGridTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/FCGridTest.java
index 5cb1ed6..d3fbd1a 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/FCGridTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/grid/FCGridTest.java
@@ -30,14 +30,15 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.applib.layout.common.ActionLayoutData;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCGrid;
-import org.apache.isis.applib.layout.fixedcols.FCTab;
-import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTabGroup;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.core.metamodel.services.grid.fixedcols.GridNormalizerServiceFC;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index d99b2a4..22866d4 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -29,7 +29,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
-import org.apache.isis.applib.layout.fixedcols.FCColumn.Hint;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn.Hint;
 import org.apache.isis.applib.services.memento.MementoService.Memento;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
index 8b2f322..6b7dfcc 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/selector/links/EntityLinksSelectorPanelFactory.java
@@ -24,7 +24,7 @@ import org.apache.wicket.model.IModel;
 
 import org.apache.isis.applib.layout.bootstrap3.BS3Grid;
 import org.apache.isis.applib.layout.common.Grid;
-import org.apache.isis.applib.layout.fixedcols.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
 import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/FCGridPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/FCGridPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/FCGridPanel.java
index 2db578d..4623028 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/FCGridPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/FCGridPanel.java
@@ -23,9 +23,9 @@ import java.util.List;
 
 import com.google.common.collect.FluentIterable;
 
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCGrid;
-import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTabGroup;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
 import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/PropUtil.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/PropUtil.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/PropUtil.java
index 0cafe36..9079391 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/PropUtil.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/PropUtil.java
@@ -26,7 +26,7 @@ import com.google.common.collect.FluentIterable;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/collections/EntityCollectionsPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/collections/EntityCollectionsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/collections/EntityCollectionsPanel.java
index 21c2ed0..b89009b 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/collections/EntityCollectionsPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/collections/EntityCollectionsPanel.java
@@ -32,7 +32,7 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/columns/EntityColumn.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/columns/EntityColumn.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/columns/EntityColumn.java
index cfb9bfa..aaacdef 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/columns/EntityColumn.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/columns/EntityColumn.java
@@ -33,7 +33,7 @@ import org.apache.wicket.markup.repeater.RepeatingView;
 
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/propsandcolls/EntityPropsAndCollsForm.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/propsandcolls/EntityPropsAndCollsForm.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/propsandcolls/EntityPropsAndCollsForm.java
index f1f2a78..0b1d7b7 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/propsandcolls/EntityPropsAndCollsForm.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/propsandcolls/EntityPropsAndCollsForm.java
@@ -44,9 +44,9 @@ import org.apache.isis.applib.annotation.MemberGroupLayout.ColumnSpans;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCColumn.Hint;
-import org.apache.isis.applib.layout.fixedcols.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn.Hint;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
 import org.apache.isis.core.commons.authentication.MessageBroker;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabgrouplist/TabGroupListPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabgrouplist/TabGroupListPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabgrouplist/TabGroupListPanel.java
index 0934f80..f95d8db 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabgrouplist/TabGroupListPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabgrouplist/TabGroupListPanel.java
@@ -24,7 +24,7 @@ import java.util.List;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 
-import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTabGroup;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.ui.components.layout.fixedcols.tabs.TabGroupPanel;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabGroupPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabGroupPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabGroupPanel.java
index 1e84474..77c90c1 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabGroupPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabGroupPanel.java
@@ -29,8 +29,8 @@ import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
 
-import org.apache.isis.applib.layout.fixedcols.FCTab;
-import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTabGroup;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabPanel.java
index 1dda0c6..d475fc8 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/fixedcols/tabs/TabPanel.java
@@ -1,6 +1,6 @@
 package org.apache.isis.viewer.wicket.ui.components.layout.fixedcols.tabs;
 
-import org.apache.isis.applib.layout.fixedcols.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;


[4/5] isis git commit: ISIS-993: hold the domainClass within the grid.

Posted by da...@apache.org.
ISIS-993: hold the domainClass within the grid.


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

Branch: refs/heads/ISIS-993
Commit: ecf6d1708be0a409cd8fb5d0257235b3b0de1f5b
Parents: 6053d1a
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Feb 10 10:37:18 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Feb 10 10:37:18 2016 +0000

----------------------------------------------------------------------
 .../layout/common/DomainObjectLayoutData.java   | 12 +++++
 .../apache/isis/applib/layout/common/Grid.java  | 20 ++++++--
 .../isis/applib/layout/common/GridAbstract.java | 17 +++++++
 .../layout/common/PropertyLayoutData.java       |  6 +--
 .../applib/services/layout/GridService.java     | 50 +++++++++++++++-----
 .../facets/object/grid/GridFacetDefault.java    |  2 +-
 .../services/grid/GridServiceDefault.java       | 32 +++++--------
 7 files changed, 98 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
index 702a3d6..d15d27b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
@@ -54,11 +54,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private BookmarkPolicy bookmarking;
 
+    @Override
     @XmlAttribute(required = false)
     public BookmarkPolicy getBookmarking() {
         return bookmarking;
     }
 
+    @Override
     public void setBookmarking(BookmarkPolicy bookmarking) {
         this.bookmarking = bookmarking;
     }
@@ -67,11 +69,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private String cssClass;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClass() {
         return cssClass;
     }
 
+    @Override
     public void setCssClass(String cssClass) {
         this.cssClass = cssClass;
     }
@@ -79,11 +83,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private String cssClassFa;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClassFa() {
         return cssClassFa;
     }
 
+    @Override
     public void setCssClassFa(String cssClassFa) {
         this.cssClassFa = cssClassFa;
     }
@@ -92,11 +98,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition cssClassFaPosition;
 
+    @Override
     @XmlAttribute(required = false)
     public org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition getCssClassFaPosition() {
         return cssClassFaPosition;
     }
 
+    @Override
     public void setCssClassFaPosition(org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition cssClassFaPosition) {
         this.cssClassFaPosition = cssClassFaPosition;
     }
@@ -104,11 +112,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private String describedAs;
 
+    @Override
     @XmlElement(required = false)
     public String getDescribedAs() {
         return describedAs;
     }
 
+    @Override
     public void setDescribedAs(String describedAs) {
         this.describedAs = describedAs;
     }
@@ -117,11 +127,13 @@ public class DomainObjectLayoutData implements Serializable,
 
     private String named;
 
+    @Override
     @XmlElement(required = false)
     public String getNamed() {
         return named;
     }
 
+    @Override
     public void setNamed(String named) {
         this.named = named;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
index 7380a3a..fd7b067 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/Grid.java
@@ -19,10 +19,8 @@
 package org.apache.isis.applib.layout.common;
 
 import java.util.LinkedHashMap;
-import java.util.List;
 
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.layout.bootstrap3.BS3Col;
 import org.apache.isis.applib.services.layout.GridService;
 
 /**
@@ -34,15 +32,26 @@ import org.apache.isis.applib.services.layout.GridService;
  */
 public interface Grid {
 
+    @Programmatic
+    Class<?> getDomainClass();
+
+    @Programmatic
+    void setDomainClass(final Class<?> domainClass);
+
+    @Programmatic
     boolean isNormalized();
 
+    @Programmatic
     void setNormalized(final boolean normalized);
 
-    @Programmatic LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById();
+    @Programmatic
+    LinkedHashMap<String, PropertyLayoutData> getAllPropertiesById();
 
-    @Programmatic LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById();
+    @Programmatic
+    LinkedHashMap<String, CollectionLayoutData> getAllCollectionsById();
 
-    @Programmatic LinkedHashMap<String, ActionLayoutData> getAllActionsById();
+    @Programmatic
+    LinkedHashMap<String, ActionLayoutData> getAllActionsById();
 
     interface Visitor {
         void visit(final DomainObjectLayoutData domainObjectLayoutData);
@@ -69,6 +78,7 @@ public interface Grid {
         }
     }
 
+    @Programmatic
     void visit(final Grid.Visitor visitor);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
index 2efb85c..d320dff 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
@@ -39,6 +39,23 @@ import org.apache.isis.applib.services.layout.GridService;
 @XmlTransient // ignore this class
 public abstract class GridAbstract implements Grid {
 
+
+    private Class<?> domainClass;
+
+    @Programmatic
+    @XmlTransient
+    public Class<?> getDomainClass() {
+        return domainClass;
+    }
+
+    @Programmatic
+    @XmlTransient
+    public void setDomainClass(final Class<?> domainClass) {
+        this.domainClass = domainClass;
+    }
+
+
+
     private boolean normalized;
 
     @Programmatic

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
index 9bbec66..923833a 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
@@ -242,13 +242,11 @@ public class PropertyLayoutData
     }
 
 
-
-
-    @Override public String toString() {
+    @Override
+    public String toString() {
         return "PropertyLayoutData{" +
                 "id='" + id + '\'' +
                 '}';
     }
 
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
index ec2d699..fc33df4 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
@@ -18,6 +18,8 @@ package org.apache.isis.applib.services.layout;
 
 import java.util.List;
 
+import org.apache.isis.applib.annotation.MemberGroupLayout;
+import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.layout.common.Grid;
 
@@ -26,12 +28,14 @@ public interface GridService {
     /**
      * Whether any metadata exists for this domain class, and if so then whether it is valid or invalid.
      */
-    @Programmatic boolean exists(Class<?> domainClass);
+    @Programmatic
+    boolean exists(Class<?> domainClass);
 
     /**
      * Returns (raw unnormalized) metadata, eg per the <code>.layout.xml</code> file.
      */
-    @Programmatic Grid fromXml(Class<?> domainClass);
+    @Programmatic
+    Grid fromXml(Class<?> domainClass);
 
     /**
      * Normalize the grid with respect to the specified domain class.
@@ -40,27 +44,48 @@ public interface GridService {
      *     This will (often) modify the grid graph in order to add in any unreferenced actions and so forth.
      * </p>
      */
-    Grid normalize(Grid grid, final Class<?> domainClass);
+    Grid normalize(Grid grid);
 
-    Grid complete(Grid grid, final Class<?> domainClass);
+    Grid complete(Grid grid);
 
-    Grid minimal(Grid grid, final Class<?> domainClass);
+    Grid minimal(Grid grid);
 
     enum Style {
 
+        /**
+         * As per {@link #NORMALIZED}, but also with all (non-null) facets for all
+         * properties/collections/actions also included included in the grid.
+         *
+         * <p>
+         *     The intention here is that any layout metadata annotations can be removed from the code.
+         * </p>
+         */
         COMPLETE,
         /**
-         * Default, corresponding to raw state along with any additional regions added
-         * as a result of normalization process.
+         * Default, whereby missing properties/collections/actions are added to regions,
+         * and unused/empty regions are removed/trimmed.
+         *
+         * <p>
+         *     It should be possible to remove any {@link MemberOrder} and {@link MemberGroupLayout} annotations but
+         *     any layout annotations would need to be retained.
+         * </p>
          */
         NORMALIZED,
+        /**
+         * As per {@link #NORMALIZED}, but with no properties/collections/actions.
+         *
+         * <p>
+         *     The intention here is for layout annotations that &quot;bind&quot; the properties/collections/actions
+         *     to the regions to be retained.
+         * </p>
+         */
         MINIMAL
     }
 
     /**
-     * Obtains the (normalized) layout metadata, if any, for the (domain class of the) specified domain object.
+     * Obtains the layout metadata, if any, for the (domain class of the) specified domain object.
      *
-     * @param style - whether the returned grid should be complete (having been normalized), or should be as
+     * @param style - whether the returned grid should be complete, normalized, or as
      *              minimal as possible.
      */
     @Programmatic Grid toGrid(Object domainObject, final Style style);
@@ -78,12 +103,13 @@ public interface GridService {
     /**
      * For all of the available {@link GridNormalizerService}s available, return only the first one for any that
      * are for the same grid implementation.
-     * <p/>
+     * 
      * <p>
-     * This allows default implementations (eg for bootstrap3) to be overridden while also allowing for the more
-     * general idea of multiple implementations.
+     *   This allows default implementations (eg for bootstrap3) to be overridden while also allowing for the more
+     *   general idea of multiple implementations.
      * </p>
      */
     @Programmatic
     List<GridNormalizerService<?>> gridNormalizerServices();
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
index 4f5f0ae..fc9ee46 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
@@ -85,7 +85,7 @@ public class GridFacetDefault
         }
         final Class<?> domainClass = getSpecification().getCorrespondingClass();
 
-        return gridService.normalize(grid, domainClass);
+        return gridService.normalize(grid);
     }
 
     private ObjectSpecification getSpecification() {

http://git-wip-us.apache.org/repos/asf/isis/blob/ecf6d170/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
index 1d078f5..97588b9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
@@ -127,11 +127,12 @@ public class GridServiceDefault
                     .toList();
             final JAXBContext context = JAXBContext.newInstance(pageImplementations.toArray(new Class[0]));
 
-            final Grid metadata = (Grid) jaxbService.fromXml(context, xml);
+            final Grid grid = (Grid) jaxbService.fromXml(context, xml);
+            grid.setDomainClass(domainClass);
             if(!deploymentCategory.isProduction()) {
-                pageByXml.put(xml, metadata);
+                pageByXml.put(xml, grid);
             }
-            return metadata;
+            return grid;
         } catch(Exception ex) {
 
             if(!deploymentCategory.isProduction()) {
@@ -150,7 +151,7 @@ public class GridServiceDefault
 
     @Override
     @Programmatic
-    public Grid normalize(final Grid grid, final Class<?> domainClass) {
+    public Grid normalize(final Grid grid) {
 
         // if have .layout.json and then add a .layout.xml without restarting, then note that
         // the changes won't be picked up.  Normalizing would be required
@@ -159,6 +160,8 @@ public class GridServiceDefault
             return grid;
         }
 
+        final Class<?> domainClass = grid.getDomainClass();
+
         for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
             gridNormalizerService.normalize(grid, domainClass);
         }
@@ -170,8 +173,9 @@ public class GridServiceDefault
 
     @Override
     @Programmatic
-    public Grid complete(final Grid grid, final Class<?> domainClass) {
+    public Grid complete(final Grid grid) {
 
+        final Class<?> domainClass = grid.getDomainClass();
         for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
             gridNormalizerService.complete(grid, domainClass);
         }
@@ -181,8 +185,9 @@ public class GridServiceDefault
 
     @Override
     @Programmatic
-    public Grid minimal(final Grid grid, final Class<?> domainClass) {
+    public Grid minimal(final Grid grid) {
 
+        final Class<?> domainClass = grid.getDomainClass();
         for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
             gridNormalizerService.minimal(grid, domainClass);
         }
@@ -217,25 +222,14 @@ public class GridServiceDefault
             final GridFacet facet = objectSpec.getFacet(GridFacet.class);
             return facet != null? facet.getGrid(): null;
         case COMPLETE:
-            return completeGridFor(domainClass);
+            return complete(fromXml(domainClass));
         case MINIMAL:
-            return minimalGridFor(domainClass);
+            return minimal(fromXml(domainClass));
         default:
             throw new IllegalArgumentException("unsupported style");
         }
     }
 
-    protected Grid minimalGridFor(final Class<?> domainClass) {
-        Grid grid = fromXml(domainClass);
-        return grid;
-    }
-
-    protected Grid completeGridFor(final Class<?> domainClass) {
-        Grid grid = fromXml(domainClass);
-        grid = normalize(grid, domainClass);
-        return grid;
-    }
-
     @Override
     public String tnsAndSchemaLocation(final Grid grid) {
         final List<String> parts = Lists.newArrayList();


[2/5] isis git commit: ISIS-993: introducing the concept of minimal/normalized/complete grids (still WIP)

Posted by da...@apache.org.
ISIS-993: introducing the concept of minimal/normalized/complete grids (still WIP)

Also:
- moved responsibility for determining the available set of gridNormalizerServices to GridService (ensure only one such per grid implementation)
- moved the FC applib classes into the metamodel, so no longer public API.


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

Branch: refs/heads/ISIS-993
Commit: 5c831757d34919ab7b36f84a6e6579a4061a97e3
Parents: f3e8bbf
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Feb 9 08:02:44 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Feb 9 08:02:44 2016 +0000

----------------------------------------------------------------------
 .../isis/applib/layout/fixedcols/FCColumn.java  | 161 ---------------
 .../applib/layout/fixedcols/FCColumnOwner.java  |  25 ---
 .../isis/applib/layout/fixedcols/FCGrid.java    | 204 -------------------
 .../isis/applib/layout/fixedcols/FCTab.java     | 159 ---------------
 .../applib/layout/fixedcols/FCTabGroup.java     |  94 ---------
 .../layout/fixedcols/FCTabGroupOwner.java       |  25 ---
 .../applib/layout/fixedcols/package-info.java   |  35 ----
 .../services/layout/GridNormalizerService.java  |  48 +++++
 .../applib/services/layout/GridService.java     |  53 ++++-
 .../layout/Object_downloadLayoutXml.java        |  15 +-
 .../services/layout/Object_viewLayout.java      |   8 +-
 .../facets/object/grid/GridFacetDefault.java    |  29 +--
 .../facets/object/grid/GridFacetFactory.java    |  11 +-
 .../json/LayoutMetadataReaderFromJson.java      |   2 +-
 .../services/grid/GridNormalizerService.java    |  38 ----
 .../grid/GridNormalizerServiceAbstract.java     |  26 ++-
 .../services/grid/GridServiceDefault.java       | 110 +++++++++-
 .../grid/fixedcols/GridNormalizerServiceFC.java |   8 +-
 .../grid/fixedcols/applib/FCColumn.java         | 161 +++++++++++++++
 .../grid/fixedcols/applib/FCColumnOwner.java    |  25 +++
 .../services/grid/fixedcols/applib/FCGrid.java  | 204 +++++++++++++++++++
 .../services/grid/fixedcols/applib/FCTab.java   | 159 +++++++++++++++
 .../grid/fixedcols/applib/FCTabGroup.java       |  94 +++++++++
 .../grid/fixedcols/applib/FCTabGroupOwner.java  |  25 +++
 .../grid/fixedcols/applib/package-info.java     |  44 ++++
 .../services/metamodel/MetadataMenu.java        |   2 +-
 .../metamodel/spec/ObjectSpecifications.java    |   2 +-
 .../metamodel/services/grid/BS3GridTest.java    |   1 +
 .../metamodel/services/grid/FCGridTest.java     |   9 +-
 .../viewer/wicket/model/models/EntityModel.java |   2 +-
 .../links/EntityLinksSelectorPanelFactory.java  |   2 +-
 .../layout/fixedcols/FCGridPanel.java           |   6 +-
 .../components/layout/fixedcols/PropUtil.java   |   2 +-
 .../collections/EntityCollectionsPanel.java     |   2 +-
 .../layout/fixedcols/columns/EntityColumn.java  |   2 +-
 .../propsandcolls/EntityPropsAndCollsForm.java  |   6 +-
 .../tabgrouplist/TabGroupListPanel.java         |   2 +-
 .../layout/fixedcols/tabs/TabGroupPanel.java    |   4 +-
 .../layout/fixedcols/tabs/TabPanel.java         |   2 +-
 39 files changed, 983 insertions(+), 824 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
deleted file mode 100644
index 79d94b4..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumn.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.applib.layout.fixedcols;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlTransient;
-import javax.xml.bind.annotation.XmlType;
-
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.annotation.MemberGroupLayout;
-import org.apache.isis.applib.layout.common.CollectionLayoutData;
-import org.apache.isis.applib.layout.common.CollectionLayoutDataOwner;
-import org.apache.isis.applib.layout.common.FieldSet;
-import org.apache.isis.applib.layout.common.FieldSetOwner;
-import org.apache.isis.applib.layout.common.Owned;
-import org.apache.isis.applib.layout.common.PropertyLayoutData;
-
-/**
- * The column contains a mixture of {@link FieldSet}s (of {@link PropertyLayoutData properties}) and also
- * {@link CollectionLayoutData collection}s.
- *
- * <p>
- * A column generally is used within a {@link FCTab}; there can be up to three such (left, middle and right).  It is
- * also possible for their to be a column far-left on the top-level {@link FCGrid page}, and another far-right.
- * </p>
- *
- */
-@XmlType(
-        propOrder = {
-                "fieldSets"
-                , "collections"
-        }
-)
-public class FCColumn implements Serializable, FieldSetOwner, CollectionLayoutDataOwner, Owned<FCColumnOwner> {
-
-    private static final long serialVersionUID = 1L;
-
-    public FCColumn() {
-    }
-
-    public FCColumn(final int span) {
-        setSpan(span);
-    }
-
-    private int span = 4;
-
-    @XmlAttribute(required = true)
-    public int getSpan() {
-        return span;
-    }
-
-    public void setSpan(final int span) {
-        this.span = span;
-    }
-
-
-
-    private List<FieldSet> fieldSets = Lists.newArrayList();
-
-    // no wrapper
-    @XmlElementRef(type = FieldSet.class, name = "fieldSet", required = false)
-    public List<FieldSet> getFieldSets() {
-        return fieldSets;
-    }
-
-    public void setFieldSets(final List<FieldSet> fieldSets) {
-        this.fieldSets = fieldSets;
-    }
-
-
-    private List<CollectionLayoutData> collections = Lists.newArrayList();
-
-    // no wrapper
-    @XmlElementRef(type = CollectionLayoutData.class, name = "collection", required = false)
-    public List<CollectionLayoutData> getCollections() {
-        return collections;
-    }
-
-    public void setCollections(final List<CollectionLayoutData> collections) {
-        this.collections = collections;
-    }
-
-
-    private FCColumnOwner owner;
-    /**
-     * Owner.
-     *
-     * <p>
-     *     Set programmatically by framework after reading in from XML.
-     * </p>
-     */
-    @XmlTransient
-    public FCColumnOwner getOwner() {
-        return owner;
-    }
-
-    public void setOwner(final FCColumnOwner owner) {
-        this.owner = owner;
-    }
-
-
-
-
-    private Hint hint;
-
-    @XmlTransient
-    public Hint getHint() {
-        return hint;
-    }
-
-    public void setHint(final Hint hint) {
-        this.hint = hint;
-    }
-
-
-
-    public enum Hint {
-        LEFT,
-        MIDDLE,
-        RIGHT;
-
-        public int from(MemberGroupLayout.ColumnSpans columnSpans) {
-            if(this == LEFT) return columnSpans.getLeft();
-            if(this == MIDDLE) return columnSpans.getMiddle();
-            if(this == RIGHT) return columnSpans.getRight();
-            throw new IllegalStateException();
-        }
-
-        public FCColumn from(final FCTab fcTab) {
-            if(fcTab == null) {
-                return null;
-            }
-            if(this == LEFT) return fcTab.getLeft();
-            if(this == MIDDLE) return fcTab.getMiddle();
-            if(this == RIGHT) return fcTab.getRight();
-            throw new IllegalStateException();
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumnOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumnOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumnOwner.java
deleted file mode 100644
index fe2ea76..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCColumnOwner.java
+++ /dev/null
@@ -1,25 +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.fixedcols;
-
-import org.apache.isis.applib.layout.common.Owner;
-
-public interface FCColumnOwner extends Owner {
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
deleted file mode 100644
index 01626dd..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCGrid.java
+++ /dev/null
@@ -1,204 +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.fixedcols;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementRef;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
-import org.apache.isis.applib.layout.common.ActionLayoutData;
-import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
-import org.apache.isis.applib.layout.common.CollectionLayoutData;
-import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
-import org.apache.isis.applib.layout.common.FieldSet;
-import org.apache.isis.applib.layout.common.Grid;
-import org.apache.isis.applib.layout.common.GridAbstract;
-import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.services.dto.Dto;
-
-/**
- * Top-level page, consisting of an optional {@link FCColumn column} on the far left and another (also optional) on the
- * far right, with the middle consisting of a number of {@link FCTabGroup tabgroup}s, stacked vertically.
- */
-@XmlRootElement(
-        name = "grid"
-)
-@XmlType(
-        name = "grid"
-        , propOrder = {
-                "actions"
-                , "left"
-                , "tabGroups"
-                , "right"
-        }
-)
-public class FCGrid extends GridAbstract implements Dto, ActionLayoutDataOwner, Serializable, FCColumnOwner, FCTabGroupOwner {
-
-    private static final long serialVersionUID = 1L;
-
-    private List<ActionLayoutData> actions;
-
-    // no wrapper
-    @XmlElementRef(type = ActionLayoutData.class, name="action", required = false)
-    public List<ActionLayoutData> getActions() {
-        return actions;
-    }
-
-    public void setActions(List<ActionLayoutData> actionLayoutDatas) {
-        this.actions = actionLayoutDatas;
-    }
-
-
-
-    private FCColumn left;
-
-    @XmlElement(required = false)
-    public FCColumn getLeft() {
-        return left;
-    }
-
-    public void setLeft(final FCColumn left) {
-        this.left = left;
-        left.setHint(FCColumn.Hint.LEFT);
-    }
-
-
-
-    private List<FCTabGroup> tabGroups;
-
-    // no wrapper
-    @XmlElement(name = "tabGroup", required = true)
-    public List<FCTabGroup> getTabGroups() {
-        return tabGroups;
-    }
-
-    public void setTabGroups(List<FCTabGroup> tabGroups) {
-        this.tabGroups = tabGroups;
-    }
-
-
-
-    private FCColumn right;
-
-    @XmlElement(required = false)
-    public FCColumn getRight() {
-        return right;
-    }
-
-    public void setRight(final FCColumn right) {
-        this.right = right;
-        right.setHint(FCColumn.Hint.RIGHT);
-    }
-
-
-
-    interface Visitor extends Grid.Visitor {
-        void visit(final FCGrid fcPage);
-        void visit(final FCTabGroup fcTabGroup);
-        void visit(final FCTab fcTab);
-        void visit(final FCColumn fcColumn);
-    }
-
-    public static class VisitorAdapter extends Grid.VisitorAdapter implements Visitor {
-        @Override
-        public void visit(final FCGrid fcPage) { }
-        @Override
-        public void visit(final FCTabGroup fcTabGroup) { }
-        @Override
-        public void visit(final FCTab fcTab) { }
-        @Override
-        public void visit(final FCColumn fcColumn) { }
-        @Override
-        public void visit(final PropertyLayoutData propertyLayoutData) {}
-        @Override
-        public void visit(final CollectionLayoutData collectionLayoutData) {}
-        @Override
-        public void visit(final ActionLayoutData actionLayoutData) { }
-    }
-
-
-    /**
-     * Visits all elements of the graph.  The {@link Visitor} implementation
-     * can assume that all "owner" references are populated.
-     */
-    public void visit(final Grid.Visitor visitor) {
-        FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
-        fcVisitor.visit(this);
-        traverseActions(this, visitor);
-        traverseColumn(getLeft(), this, visitor);
-        final List<FCTabGroup> tabGroups = getTabGroups();
-        for (final FCTabGroup fcTabGroup : tabGroups) {
-            fcTabGroup.setOwner(this);
-            fcVisitor.visit(fcTabGroup);
-            final List<FCTab> tabs = fcTabGroup.getTabs();
-            for (final FCTab fcTab : tabs) {
-                fcTab.setOwner(fcTabGroup);
-                fcVisitor.visit(fcTab);
-                traverseColumn(fcTab.getLeft(), fcTab, visitor);
-                traverseColumn(fcTab.getMiddle(), fcTab, visitor);
-                traverseColumn(fcTab.getRight(), fcTab, visitor);
-            }
-        }
-        traverseColumn(getRight(), this, visitor);
-    }
-
-    private void traverseColumn(
-            final FCColumn fcColumn,
-            final FCColumnOwner fcColumnOwner,
-            final Grid.Visitor visitor) {
-        if(fcColumn == null) {
-            return;
-        }
-        FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
-        fcColumn.setOwner(fcColumnOwner);
-        fcVisitor.visit(fcColumn);
-        traverseFieldSets(fcColumn, visitor);
-        traverseCollections(fcColumn, visitor);
-    }
-
-    private static Visitor asFcVisitor(final Grid.Visitor visitor) {
-        return visitor instanceof Visitor? (Visitor) visitor : new VisitorAdapter() {
-            @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
-                visitor.visit(domainObjectLayoutData);
-            }
-
-            @Override public void visit(final ActionLayoutData actionLayoutData) {
-                visitor.visit(actionLayoutData);
-            }
-
-            @Override public void visit(final PropertyLayoutData propertyLayoutData) {
-                visitor.visit(propertyLayoutData);
-            }
-
-            @Override public void visit(final CollectionLayoutData collectionLayoutData) {
-                visitor.visit(collectionLayoutData);
-            }
-
-            @Override public void visit(final FieldSet fieldSet) {
-                visitor.visit(fieldSet);
-            }
-        };
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTab.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTab.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTab.java
deleted file mode 100644
index f7b7100..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTab.java
+++ /dev/null
@@ -1,159 +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.fixedcols;
-
-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.XmlTransient;
-import javax.xml.bind.annotation.XmlType;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.layout.common.CollectionLayoutData;
-import org.apache.isis.applib.layout.common.MemberRegion;
-import org.apache.isis.applib.layout.common.Owned;
-import org.apache.isis.applib.layout.common.FieldSet;
-
-@XmlType(
-        name="tab"
-        , propOrder = {
-                "name"
-                , "left"
-                , "middle"
-                , "right"
-        }
-)
-public class FCTab implements FCColumnOwner, Serializable, Owned<FCTabGroup> {
-
-    private static final long serialVersionUID = 1L;
-
-    private String name;
-
-    @XmlAttribute(required = true)
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-
-
-    private FCColumn left = new FCColumn();
-
-    @XmlElement(required = true)
-    public FCColumn getLeft() {
-        return left;
-    }
-
-    public void setLeft(final FCColumn left) {
-        this.left = left;
-        left.setHint(FCColumn.Hint.LEFT);
-    }
-
-
-    private FCColumn middle;
-
-    @XmlElement(required = false)
-    public FCColumn getMiddle() {
-        return middle;
-    }
-
-    public void setMiddle(final FCColumn middle) {
-        this.middle = middle;
-        middle.setHint(FCColumn.Hint.MIDDLE);
-    }
-
-
-    private FCColumn right;
-
-    @XmlElement(required = false)
-    public FCColumn getRight() {
-        return right;
-    }
-
-    public void setRight(final FCColumn right) {
-        this.right = right;
-        right.setHint(FCColumn.Hint.RIGHT);
-    }
-
-
-
-    private FCTabGroup owner;
-    /**
-     * Owner.
-     *
-     * <p>
-     *     Set programmatically by framework after reading in from XML.
-     * </p>
-     */
-    @XmlTransient
-    public FCTabGroup getOwner() {
-        return owner;
-    }
-
-    public void setOwner(final FCTabGroup owner) {
-        this.owner = owner;
-    }
-
-    /**
-     * Aggregates the contents of all collections on this tab.
-     */
-    @Programmatic
-    public List<MemberRegion> getContents() {
-        final List<MemberRegion> contents = Lists.newArrayList();
-        appendContent(contents, getLeft());
-        appendContent(contents, getMiddle());
-        appendContent(contents, getRight());
-        return contents;
-    }
-
-
-
-    private static void appendContent(final List<MemberRegion> contents, final FCColumn FCColumn) {
-        if(FCColumn == null) {
-            return;
-        }
-        final List<FieldSet> fieldSets = FCColumn.getFieldSets();
-        if(fieldSets != null) {
-            contents.addAll(fieldSets);
-        }
-        final List<CollectionLayoutData> collectionLayoutDatas = FCColumn.getCollections();
-        if(collectionLayoutDatas != null) {
-            contents.addAll(collectionLayoutDatas);
-        }
-    }
-
-    public static class Predicates {
-        public static Predicate<FCTab> notEmpty() {
-            return new Predicate<FCTab>() {
-                @Override
-                public boolean apply(final FCTab FCTab) {
-                    return !FCTab.getContents().isEmpty();
-                }
-            };
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
deleted file mode 100644
index 93c88970..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroup.java
+++ /dev/null
@@ -1,94 +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.fixedcols;
-
-import java.io.Serializable;
-import java.util.List;
-
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlTransient;
-import javax.xml.bind.annotation.XmlType;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.layout.common.Owned;
-
-@XmlType(
-        propOrder = {
-                "tabs"
-        }
-
-)
-public class FCTabGroup implements FCColumnOwner, Serializable, Owned<FCTabGroupOwner> {
-
-    private static final long serialVersionUID = 1L;
-
-    private List<FCTab> tabs = Lists.newArrayList();
-
-    // no wrapper
-    @XmlElement(name = "tab", required = false)
-    public List<FCTab> getTabs() {
-        return tabs;
-    }
-
-    public void setTabs(List<FCTab> tabs) {
-        this.tabs = tabs;
-    }
-
-
-
-    private FCTabGroupOwner owner;
-
-    /**
-     * Owner.
-     *
-     * <p>
-     *     Set programmatically by framework after reading in from XML.
-     * </p>
-     */
-    @XmlTransient
-    public FCTabGroupOwner getOwner() {
-        return owner;
-    }
-
-    public void setOwner(final FCTabGroupOwner owner) {
-        this.owner = owner;
-    }
-
-
-
-
-
-
-    public static class Predicates {
-        public static Predicate<FCTabGroup> notEmpty() {
-            return new Predicate<FCTabGroup>() {
-                @Override
-                public boolean apply(final FCTabGroup tabGroup) {
-                    return FluentIterable
-                            .from(tabGroup.getTabs())
-                            .anyMatch(FCTab.Predicates.notEmpty());
-                }
-            };
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroupOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroupOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroupOwner.java
deleted file mode 100644
index 2b37c0f..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/FCTabGroupOwner.java
+++ /dev/null
@@ -1,25 +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.fixedcols;
-
-import org.apache.isis.applib.layout.common.Owner;
-
-public interface FCTabGroupOwner extends Owner {
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/package-info.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/package-info.java b/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/package-info.java
deleted file mode 100644
index af1fb85..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/fixedcols/package-info.java
+++ /dev/null
@@ -1,35 +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.
- */
-
-/**
- * The classes in this package define how to layout the properties, collections and actions of a domain object - the
- * building blocks - as defined in the <code>members.v1</code> package.
- *
- * <p>
- *     The layout is reasonably flexible, being a half-way house between the annotation/JSON style layouts (pre 1.12.0)
- *     vs the fully flexible layouts provided by the <code>bootstrap3</code> layouts.  In particular, they allow
- *     property fieldsets and collections to be grouped into tabs, with collections being laid out in any column.
- *     However, tab groups only appear in the central area of the page, and may only have a maximum of three columns.
- * </p>
- */
-@javax.xml.bind.annotation.XmlSchema(
-        namespace = "http://isis.apache.org/schema/applib/layout/fixedcols",
-        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
-)
-package org.apache.isis.applib.layout.fixedcols;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridNormalizerService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridNormalizerService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridNormalizerService.java
new file mode 100644
index 0000000..ced93eb
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridNormalizerService.java
@@ -0,0 +1,48 @@
+/**
+ *  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.services.layout;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.common.Grid;
+
+/**
+ * Provides implementation of {@link Grid}.
+ * @param <G>
+ */
+public interface GridNormalizerService<G extends Grid> {
+
+    /**
+     * Which grid implementation is understood by this.
+     */
+    @Programmatic
+    Class<? extends Grid> gridImplementation();
+
+    @Programmatic
+    String tns();
+
+    @Programmatic
+    String schemaLocation();
+
+    @Programmatic
+    void normalize(G grid, Class<?> domainClass);
+
+    @Programmatic
+    void complete(G grid, Class<?> domainClass);
+
+    @Programmatic
+    void minimal(G grid, Class<?> domainClass);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
index a641889..ec2d699 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
@@ -16,6 +16,8 @@
  */
 package org.apache.isis.applib.services.layout;
 
+import java.util.List;
+
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.layout.common.Grid;
 
@@ -24,8 +26,7 @@ public interface GridService {
     /**
      * Whether any metadata exists for this domain class, and if so then whether it is valid or invalid.
      */
-    @Programmatic
-    boolean exists(Class<?> domainClass);
+    @Programmatic boolean exists(Class<?> domainClass);
 
     /**
      * Returns (raw unnormalized) metadata, eg per the <code>.layout.xml</code> file.
@@ -33,14 +34,56 @@ public interface GridService {
     @Programmatic Grid fromXml(Class<?> domainClass);
 
     /**
+     * Normalize the grid with respect to the specified domain class.
+     *
+     * <p>
+     *     This will (often) modify the grid graph in order to add in any unreferenced actions and so forth.
+     * </p>
+     */
+    Grid normalize(Grid grid, final Class<?> domainClass);
+
+    Grid complete(Grid grid, final Class<?> domainClass);
+
+    Grid minimal(Grid grid, final Class<?> domainClass);
+
+    enum Style {
+
+        COMPLETE,
+        /**
+         * Default, corresponding to raw state along with any additional regions added
+         * as a result of normalization process.
+         */
+        NORMALIZED,
+        MINIMAL
+    }
+
+    /**
      * Obtains the (normalized) layout metadata, if any, for the (domain class of the) specified domain object.
+     *
+     * @param style - whether the returned grid should be complete (having been normalized), or should be as
+     *              minimal as possible.
      */
-    @Programmatic Grid toGrid(Object domainObject);
+    @Programmatic Grid toGrid(Object domainObject, final Style style);
 
     /**
      * Obtains the (normalized) layout metadata, if any, for the specified domain class.
+     *
+     * @param style - whether the returned grid should be complete (having been normalized), or should be as
+     *              minimal as possible.
      */
-    @Programmatic Grid toGrid(Class<?> domainClass);
+    @Programmatic Grid toGrid(Class<?> domainClass, final Style style);
 
     String tnsAndSchemaLocation(final Grid grid);
-}
\ No newline at end of file
+
+    /**
+     * For all of the available {@link GridNormalizerService}s available, return only the first one for any that
+     * are for the same grid implementation.
+     * <p/>
+     * <p>
+     * This allows default implementations (eg for bootstrap3) to be overridden while also allowing for the more
+     * general idea of multiple implementations.
+     * </p>
+     */
+    @Programmatic
+    List<GridNormalizerService<?>> gridNormalizerServices();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
index 01beb41..10fee16 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
@@ -54,8 +54,9 @@ public class Object_downloadLayoutXml {
     @MemberOrder(sequence = "550.1")
     public Object $$(
             @ParameterLayout(named = "File name")
-            final String fileName) {
-        final Grid grid = getPage();
+            final String fileName,
+            final GridService.Style style) {
+        final Grid grid = getGrid(style);
         final String xml = jaxbService.toXml(grid,
                 ImmutableMap.<String,Object>of(
                         Marshaller.JAXB_SCHEMA_LOCATION,
@@ -66,14 +67,18 @@ public class Object_downloadLayoutXml {
     }
 
     public boolean hide$$() {
-        return getPage() == null;
+        // can use either style to determine whether this action should be hidden
+        return getGrid(GridService.Style.COMPLETE) == null;
     }
     public String default0$$() {
         return Util.withSuffix(object.getClass().getSimpleName(), "layout.xml");
     }
+    public GridService.Style default1$$() {
+        return GridService.Style.NORMALIZED;
+    }
 
-    protected Grid getPage() {
-        return gridService.toGrid(object);
+    protected Grid getGrid(final GridService.Style style) {
+        return gridService.toGrid(object, style);
     }
 
     @Inject

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_viewLayout.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_viewLayout.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_viewLayout.java
index df38db2..6d2e3a7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_viewLayout.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_viewLayout.java
@@ -51,16 +51,16 @@ public class Object_viewLayout {
     )
     @MemberOrder(sequence = "550.2")
     public Grid $$() {
-        return getPage();
+        return getGrid(GridService.Style.NORMALIZED);
     }
 
     @Programmatic // TODO ... excluded for now (getting an Isis framework exception in the view model rendering).
     public boolean hide$$() {
-        return getPage() == null;
+        return getGrid(GridService.Style.NORMALIZED) == null;
     }
 
-    protected Grid getPage() {
-        return gridService.toGrid(object);
+    protected Grid getGrid(final GridService.Style style) {
+        return gridService.toGrid(object, style);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
index 596829d..4f5f0ae 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetDefault.java
@@ -22,13 +22,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.layout.common.Grid;
-import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.layout.GridService;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.services.grid.GridNormalizerService;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 public class GridFacetDefault
@@ -45,15 +43,11 @@ public class GridFacetDefault
 
     public static GridFacet create(
             final FacetHolder facetHolder,
-            final TranslationService translationService,
             final GridService gridService,
-            final GridNormalizerService gridNormalizerService, final DeploymentCategory deploymentCategory) {
-        return new GridFacetDefault(facetHolder, translationService, gridService, gridNormalizerService,
-                deploymentCategory);
+            final DeploymentCategory deploymentCategory) {
+        return new GridFacetDefault(facetHolder, gridService, deploymentCategory);
     }
 
-    private final TranslationService translationService;
-    private final GridNormalizerService gridNormalizerService;
     private final DeploymentCategory deploymentCategory;
     private final GridService gridService;
 
@@ -62,14 +56,10 @@ public class GridFacetDefault
 
     private GridFacetDefault(
             final FacetHolder facetHolder,
-            final TranslationService translationService,
             final GridService gridService,
-            final GridNormalizerService gridNormalizerService,
             final DeploymentCategory deploymentCategory) {
         super(GridFacetDefault.type(), facetHolder, Derivation.NOT_DERIVED);
         this.gridService = gridService;
-        this.translationService = translationService;
-        this.gridNormalizerService = gridNormalizerService;
         this.deploymentCategory = deploymentCategory;
     }
 
@@ -93,21 +83,9 @@ public class GridFacetDefault
         if(grid == null) {
             return null;
         }
-
-        // if have .layout.json and then add a .layout.xml without restarting, then note that
-        // the changes won't be picked up.  Normalizing would be required
-        // in order to trample over the .layout.json's original facets
-        if(grid.isNormalized()) {
-            return grid;
-        }
-
         final Class<?> domainClass = getSpecification().getCorrespondingClass();
 
-        gridNormalizerService.normalize(grid, domainClass);
-
-        grid.setNormalized(true);
-
-        return grid;
+        return gridService.normalize(grid, domainClass);
     }
 
     private ObjectSpecification getSpecification() {
@@ -115,5 +93,4 @@ public class GridFacetDefault
     }
 
 
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetFactory.java
index 9c4f9cd..1cfcd04 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacetFactory.java
@@ -16,10 +16,12 @@
  * under the License. */
 package org.apache.isis.core.metamodel.facets.object.grid;
 
+import java.util.List;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.applib.services.i18n.TranslationService;
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.applib.services.layout.GridService;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -27,7 +29,6 @@ import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
 import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
-import org.apache.isis.core.metamodel.services.grid.GridNormalizerService;
 
 public class GridFacetFactory extends FacetFactoryAbstract implements ServicesInjectorAware {
 
@@ -41,16 +42,12 @@ public class GridFacetFactory extends FacetFactoryAbstract implements ServicesIn
     public void process(final ProcessClassContext processClassContext) {
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
 
-        final TranslationService translationService =
-                servicesInjector.lookupService(TranslationService.class);
         final GridService gridService =
                 servicesInjector.lookupService(GridService.class);
-        final GridNormalizerService gridNormalizerService =
-                servicesInjector.lookupService(GridNormalizerService.class);
 
         FacetUtil.addFacet(
                 GridFacetDefault.create(facetHolder,
-                        translationService, gridService, gridNormalizerService, getDeploymentCategory()));
+                        gridService, getDeploymentCategory()));
     }
 
     private ServicesInjector servicesInjector;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
index 779cf66..05b84fc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/json/LayoutMetadataReaderFromJson.java
@@ -84,7 +84,7 @@ import org.apache.isis.core.metamodel.runtimecontext.ServicesInjectorAware;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.ObjectSpecifications;
-import org.apache.isis.applib.layout.fixedcols.FCColumn.Hint;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn.Hint;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
deleted file mode 100644
index 844168b..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerService.java
+++ /dev/null
@@ -1,38 +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.core.metamodel.services.grid;
-
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.layout.common.Grid;
-
-public interface GridNormalizerService<G extends Grid> {
-
-    @Programmatic
-    Class<? extends Grid> gridImplementation();
-
-    @Programmatic
-    String tns();
-
-    @Programmatic
-    String schemaLocation();
-
-    @Programmatic
-    void normalize(G grid, Class<?> domainClass);
-
-
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
index 91d8aba..79d3548 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.applib.layout.common.ActionLayoutData;
 import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
@@ -38,10 +39,10 @@ import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.Grid;
 import org.apache.isis.applib.layout.common.MemberRegionOwner;
 import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCColumnOwner;
-import org.apache.isis.applib.layout.fixedcols.FCGrid;
-import org.apache.isis.applib.layout.fixedcols.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumnOwner;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -119,6 +120,10 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
     @Override
     public void normalize(final G grid, final Class<?> domainClass) {
 
+        if(!gridImplementation.isAssignableFrom(grid.getClass())) {
+            // ignore any other grid implementations
+            return;
+        }
         final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
 
         final Map<String, OneToOneAssociation> oneToOneAssociationById =
@@ -142,6 +147,19 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
         }
     }
 
+    @Programmatic
+    @Override
+    public void complete(final G grid, final Class<?> domainClass) {
+        // TODO: do some different logic here...
+        normalize(grid, domainClass);
+    }
+
+    @Programmatic
+    @Override
+    public void minimal(final G grid, final Class<?> domainClass) {
+        // TODO: do some different logic here...
+        normalize(grid, domainClass);
+    }
     /**
      * Ensures that all object members (properties, collections and actions) are in the metadata.
      */

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
index 66d4f9e..1d078f5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
@@ -29,6 +29,7 @@ import javax.xml.bind.JAXBContext;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -40,6 +41,7 @@ import org.slf4j.LoggerFactory;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.applib.layout.common.Grid;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.layout.GridService;
@@ -146,6 +148,48 @@ public class GridServiceDefault
         }
     }
 
+    @Override
+    @Programmatic
+    public Grid normalize(final Grid grid, final Class<?> domainClass) {
+
+        // if have .layout.json and then add a .layout.xml without restarting, then note that
+        // the changes won't be picked up.  Normalizing would be required
+        // in order to trample over the .layout.json's original facets
+        if(grid.isNormalized()) {
+            return grid;
+        }
+
+        for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
+            gridNormalizerService.normalize(grid, domainClass);
+        }
+
+        grid.setNormalized(true);
+
+        return grid;
+    }
+
+    @Override
+    @Programmatic
+    public Grid complete(final Grid grid, final Class<?> domainClass) {
+
+        for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
+            gridNormalizerService.complete(grid, domainClass);
+        }
+
+        return grid;
+    }
+
+    @Override
+    @Programmatic
+    public Grid minimal(final Grid grid, final Class<?> domainClass) {
+
+        for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
+            gridNormalizerService.minimal(grid, domainClass);
+        }
+
+        return grid;
+    }
+
     private static String resourceContentOf(final Class<?> cls, final String resourceName) throws IOException {
         final URL url = Resources.getResource(cls, resourceName);
         return Resources.toString(url, Charset.defaultCharset());
@@ -158,17 +202,39 @@ public class GridServiceDefault
 
     @Override
     @Programmatic
-    public Grid toGrid(final Object domainObject) {
-        return toGrid(domainObject.getClass());
+    public Grid toGrid(final Object domainObject, final Style style) {
+        return toGrid(domainObject.getClass(), style);
     }
 
     @Override
-    public Grid toGrid(final Class<?> domainClass) {
-        final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
-        final GridFacet facet = objectSpec.getFacet(GridFacet.class);
-        return facet != null? facet.getGrid(): null;
+    public Grid toGrid(final Class<?> domainClass, final Style style) {
+        switch (style) {
+        case NORMALIZED:
+            // obtain the already normalized grid, if available.
+            // (if there is none, then the facet will delegate back to this service to do the normalization,
+            // but then will cache it for any subsequent requests).
+            final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
+            final GridFacet facet = objectSpec.getFacet(GridFacet.class);
+            return facet != null? facet.getGrid(): null;
+        case COMPLETE:
+            return completeGridFor(domainClass);
+        case MINIMAL:
+            return minimalGridFor(domainClass);
+        default:
+            throw new IllegalArgumentException("unsupported style");
+        }
     }
 
+    protected Grid minimalGridFor(final Class<?> domainClass) {
+        Grid grid = fromXml(domainClass);
+        return grid;
+    }
+
+    protected Grid completeGridFor(final Class<?> domainClass) {
+        Grid grid = fromXml(domainClass);
+        grid = normalize(grid, domainClass);
+        return grid;
+    }
 
     @Override
     public String tnsAndSchemaLocation(final Grid grid) {
@@ -189,6 +255,38 @@ public class GridServiceDefault
 
     ////////////////////////////////////////////////////////
 
+    private List<GridNormalizerService<?>> filteredGridNormalizerServices;
+
+    /**
+     * For all of the available {@link GridNormalizerService}s available, return only the first one for any that
+     * are for the same grid implementation.
+     */
+    @Programmatic
+    public List<GridNormalizerService<?>> gridNormalizerServices() {
+
+        if (filteredGridNormalizerServices == null) {
+            List<GridNormalizerService<?>> services = Lists.newArrayList();
+
+            for (GridNormalizerService gridNormalizerService : this.gridNormalizerServices) {
+                final Class gridImplementation = gridNormalizerService.gridImplementation();
+                final boolean notSeenBefore = FluentIterable.from(services).filter(new Predicate<GridNormalizerService<?>>() {
+                    @Override public boolean apply(@Nullable final GridNormalizerService<?> gridNormalizerService) {
+                        return gridNormalizerService.gridImplementation() == gridImplementation;
+                    }
+                }).isEmpty();
+                if(notSeenBefore) {
+                    services.add(gridNormalizerService);
+                }
+            }
+
+            filteredGridNormalizerServices = services;
+
+        }
+        return filteredGridNormalizerServices;
+    }
+
+    ////////////////////////////////////////////////////////
+
 
     //region > injected dependencies
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
index c617c73..d48fddb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/GridNormalizerServiceFC.java
@@ -30,10 +30,10 @@ import org.apache.isis.applib.layout.common.CollectionLayoutData;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.Grid;
 import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
-import org.apache.isis.applib.layout.fixedcols.FCGrid;
-import org.apache.isis.applib.layout.fixedcols.FCTab;
-import org.apache.isis.applib.layout.fixedcols.FCTabGroup;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTabGroup;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.services.grid.GridNormalizerServiceAbstract;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumn.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumn.java
new file mode 100644
index 0000000..157428a
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumn.java
@@ -0,0 +1,161 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.MemberGroupLayout;
+import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.CollectionLayoutDataOwner;
+import org.apache.isis.applib.layout.common.FieldSet;
+import org.apache.isis.applib.layout.common.FieldSetOwner;
+import org.apache.isis.applib.layout.common.Owned;
+import org.apache.isis.applib.layout.common.PropertyLayoutData;
+
+/**
+ * The column contains a mixture of {@link FieldSet}s (of {@link PropertyLayoutData properties}) and also
+ * {@link CollectionLayoutData collection}s.
+ *
+ * <p>
+ * A column generally is used within a {@link FCTab}; there can be up to three such (left, middle and right).  It is
+ * also possible for their to be a column far-left on the top-level {@link FCGrid page}, and another far-right.
+ * </p>
+ *
+ */
+@XmlType(
+        propOrder = {
+                "fieldSets"
+                , "collections"
+        }
+)
+public class FCColumn implements Serializable, FieldSetOwner, CollectionLayoutDataOwner, Owned<FCColumnOwner> {
+
+    private static final long serialVersionUID = 1L;
+
+    public FCColumn() {
+    }
+
+    public FCColumn(final int span) {
+        setSpan(span);
+    }
+
+    private int span = 4;
+
+    @XmlAttribute(required = true)
+    public int getSpan() {
+        return span;
+    }
+
+    public void setSpan(final int span) {
+        this.span = span;
+    }
+
+
+
+    private List<FieldSet> fieldSets = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElementRef(type = FieldSet.class, name = "fieldSet", required = false)
+    public List<FieldSet> getFieldSets() {
+        return fieldSets;
+    }
+
+    public void setFieldSets(final List<FieldSet> fieldSets) {
+        this.fieldSets = fieldSets;
+    }
+
+
+    private List<CollectionLayoutData> collections = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElementRef(type = CollectionLayoutData.class, name = "collection", required = false)
+    public List<CollectionLayoutData> getCollections() {
+        return collections;
+    }
+
+    public void setCollections(final List<CollectionLayoutData> collections) {
+        this.collections = collections;
+    }
+
+
+    private FCColumnOwner owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public FCColumnOwner getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final FCColumnOwner owner) {
+        this.owner = owner;
+    }
+
+
+
+
+    private Hint hint;
+
+    @XmlTransient
+    public Hint getHint() {
+        return hint;
+    }
+
+    public void setHint(final Hint hint) {
+        this.hint = hint;
+    }
+
+
+
+    public enum Hint {
+        LEFT,
+        MIDDLE,
+        RIGHT;
+
+        public int from(MemberGroupLayout.ColumnSpans columnSpans) {
+            if(this == LEFT) return columnSpans.getLeft();
+            if(this == MIDDLE) return columnSpans.getMiddle();
+            if(this == RIGHT) return columnSpans.getRight();
+            throw new IllegalStateException();
+        }
+
+        public FCColumn from(final FCTab fcTab) {
+            if(fcTab == null) {
+                return null;
+            }
+            if(this == LEFT) return fcTab.getLeft();
+            if(this == MIDDLE) return fcTab.getMiddle();
+            if(this == RIGHT) return fcTab.getRight();
+            throw new IllegalStateException();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumnOwner.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumnOwner.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumnOwner.java
new file mode 100644
index 0000000..9bc073c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCColumnOwner.java
@@ -0,0 +1,25 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+import org.apache.isis.applib.layout.common.Owner;
+
+public interface FCColumnOwner extends Owner {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCGrid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCGrid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCGrid.java
new file mode 100644
index 0000000..b7625af
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCGrid.java
@@ -0,0 +1,204 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.isis.applib.layout.common.ActionLayoutData;
+import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
+import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
+import org.apache.isis.applib.layout.common.FieldSet;
+import org.apache.isis.applib.layout.common.Grid;
+import org.apache.isis.applib.layout.common.GridAbstract;
+import org.apache.isis.applib.layout.common.PropertyLayoutData;
+import org.apache.isis.applib.services.dto.Dto;
+
+/**
+ * Top-level page, consisting of an optional {@link FCColumn column} on the far left and another (also optional) on the
+ * far right, with the middle consisting of a number of {@link FCTabGroup tabgroup}s, stacked vertically.
+ */
+@XmlRootElement(
+        name = "grid"
+)
+@XmlType(
+        name = "grid"
+        , propOrder = {
+                "actions"
+                , "left"
+                , "tabGroups"
+                , "right"
+        }
+)
+public class FCGrid extends GridAbstract implements Dto, ActionLayoutDataOwner, Serializable, FCColumnOwner, FCTabGroupOwner {
+
+    private static final long serialVersionUID = 1L;
+
+    private List<ActionLayoutData> actions;
+
+    // no wrapper
+    @XmlElementRef(type = ActionLayoutData.class, name="action", required = false)
+    public List<ActionLayoutData> getActions() {
+        return actions;
+    }
+
+    public void setActions(List<ActionLayoutData> actionLayoutDatas) {
+        this.actions = actionLayoutDatas;
+    }
+
+
+
+    private FCColumn left;
+
+    @XmlElement(required = false)
+    public FCColumn getLeft() {
+        return left;
+    }
+
+    public void setLeft(final FCColumn left) {
+        this.left = left;
+        left.setHint(FCColumn.Hint.LEFT);
+    }
+
+
+
+    private List<FCTabGroup> tabGroups;
+
+    // no wrapper
+    @XmlElement(name = "tabGroup", required = true)
+    public List<FCTabGroup> getTabGroups() {
+        return tabGroups;
+    }
+
+    public void setTabGroups(List<FCTabGroup> tabGroups) {
+        this.tabGroups = tabGroups;
+    }
+
+
+
+    private FCColumn right;
+
+    @XmlElement(required = false)
+    public FCColumn getRight() {
+        return right;
+    }
+
+    public void setRight(final FCColumn right) {
+        this.right = right;
+        right.setHint(FCColumn.Hint.RIGHT);
+    }
+
+
+
+    interface Visitor extends Grid.Visitor {
+        void visit(final FCGrid fcPage);
+        void visit(final FCTabGroup fcTabGroup);
+        void visit(final FCTab fcTab);
+        void visit(final FCColumn fcColumn);
+    }
+
+    public static class VisitorAdapter extends Grid.VisitorAdapter implements Visitor {
+        @Override
+        public void visit(final FCGrid fcPage) { }
+        @Override
+        public void visit(final FCTabGroup fcTabGroup) { }
+        @Override
+        public void visit(final FCTab fcTab) { }
+        @Override
+        public void visit(final FCColumn fcColumn) { }
+        @Override
+        public void visit(final PropertyLayoutData propertyLayoutData) {}
+        @Override
+        public void visit(final CollectionLayoutData collectionLayoutData) {}
+        @Override
+        public void visit(final ActionLayoutData actionLayoutData) { }
+    }
+
+
+    /**
+     * Visits all elements of the graph.  The {@link Visitor} implementation
+     * can assume that all "owner" references are populated.
+     */
+    public void visit(final Grid.Visitor visitor) {
+        FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
+        fcVisitor.visit(this);
+        traverseActions(this, visitor);
+        traverseColumn(getLeft(), this, visitor);
+        final List<FCTabGroup> tabGroups = getTabGroups();
+        for (final FCTabGroup fcTabGroup : tabGroups) {
+            fcTabGroup.setOwner(this);
+            fcVisitor.visit(fcTabGroup);
+            final List<FCTab> tabs = fcTabGroup.getTabs();
+            for (final FCTab fcTab : tabs) {
+                fcTab.setOwner(fcTabGroup);
+                fcVisitor.visit(fcTab);
+                traverseColumn(fcTab.getLeft(), fcTab, visitor);
+                traverseColumn(fcTab.getMiddle(), fcTab, visitor);
+                traverseColumn(fcTab.getRight(), fcTab, visitor);
+            }
+        }
+        traverseColumn(getRight(), this, visitor);
+    }
+
+    private void traverseColumn(
+            final FCColumn fcColumn,
+            final FCColumnOwner fcColumnOwner,
+            final Grid.Visitor visitor) {
+        if(fcColumn == null) {
+            return;
+        }
+        FCGrid.Visitor fcVisitor = asFcVisitor(visitor);
+        fcColumn.setOwner(fcColumnOwner);
+        fcVisitor.visit(fcColumn);
+        traverseFieldSets(fcColumn, visitor);
+        traverseCollections(fcColumn, visitor);
+    }
+
+    private static Visitor asFcVisitor(final Grid.Visitor visitor) {
+        return visitor instanceof Visitor? (Visitor) visitor : new VisitorAdapter() {
+            @Override public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+                visitor.visit(domainObjectLayoutData);
+            }
+
+            @Override public void visit(final ActionLayoutData actionLayoutData) {
+                visitor.visit(actionLayoutData);
+            }
+
+            @Override public void visit(final PropertyLayoutData propertyLayoutData) {
+                visitor.visit(propertyLayoutData);
+            }
+
+            @Override public void visit(final CollectionLayoutData collectionLayoutData) {
+                visitor.visit(collectionLayoutData);
+            }
+
+            @Override public void visit(final FieldSet fieldSet) {
+                visitor.visit(fieldSet);
+            }
+        };
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTab.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTab.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTab.java
new file mode 100644
index 0000000..3ce6df8
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTab.java
@@ -0,0 +1,159 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+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.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.MemberRegion;
+import org.apache.isis.applib.layout.common.Owned;
+import org.apache.isis.applib.layout.common.FieldSet;
+
+@XmlType(
+        name="tab"
+        , propOrder = {
+                "name"
+                , "left"
+                , "middle"
+                , "right"
+        }
+)
+public class FCTab implements FCColumnOwner, Serializable, Owned<FCTabGroup> {
+
+    private static final long serialVersionUID = 1L;
+
+    private String name;
+
+    @XmlAttribute(required = true)
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+
+    private FCColumn left = new FCColumn();
+
+    @XmlElement(required = true)
+    public FCColumn getLeft() {
+        return left;
+    }
+
+    public void setLeft(final FCColumn left) {
+        this.left = left;
+        left.setHint(FCColumn.Hint.LEFT);
+    }
+
+
+    private FCColumn middle;
+
+    @XmlElement(required = false)
+    public FCColumn getMiddle() {
+        return middle;
+    }
+
+    public void setMiddle(final FCColumn middle) {
+        this.middle = middle;
+        middle.setHint(FCColumn.Hint.MIDDLE);
+    }
+
+
+    private FCColumn right;
+
+    @XmlElement(required = false)
+    public FCColumn getRight() {
+        return right;
+    }
+
+    public void setRight(final FCColumn right) {
+        this.right = right;
+        right.setHint(FCColumn.Hint.RIGHT);
+    }
+
+
+
+    private FCTabGroup owner;
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public FCTabGroup getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final FCTabGroup owner) {
+        this.owner = owner;
+    }
+
+    /**
+     * Aggregates the contents of all collections on this tab.
+     */
+    @Programmatic
+    public List<MemberRegion> getContents() {
+        final List<MemberRegion> contents = Lists.newArrayList();
+        appendContent(contents, getLeft());
+        appendContent(contents, getMiddle());
+        appendContent(contents, getRight());
+        return contents;
+    }
+
+
+
+    private static void appendContent(final List<MemberRegion> contents, final FCColumn FCColumn) {
+        if(FCColumn == null) {
+            return;
+        }
+        final List<FieldSet> fieldSets = FCColumn.getFieldSets();
+        if(fieldSets != null) {
+            contents.addAll(fieldSets);
+        }
+        final List<CollectionLayoutData> collectionLayoutDatas = FCColumn.getCollections();
+        if(collectionLayoutDatas != null) {
+            contents.addAll(collectionLayoutDatas);
+        }
+    }
+
+    public static class Predicates {
+        public static Predicate<FCTab> notEmpty() {
+            return new Predicate<FCTab>() {
+                @Override
+                public boolean apply(final FCTab FCTab) {
+                    return !FCTab.getContents().isEmpty();
+                }
+            };
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroup.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroup.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroup.java
new file mode 100644
index 0000000..d27eae8
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroup.java
@@ -0,0 +1,94 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.layout.common.Owned;
+
+@XmlType(
+        propOrder = {
+                "tabs"
+        }
+
+)
+public class FCTabGroup implements FCColumnOwner, Serializable, Owned<FCTabGroupOwner> {
+
+    private static final long serialVersionUID = 1L;
+
+    private List<FCTab> tabs = Lists.newArrayList();
+
+    // no wrapper
+    @XmlElement(name = "tab", required = false)
+    public List<FCTab> getTabs() {
+        return tabs;
+    }
+
+    public void setTabs(List<FCTab> tabs) {
+        this.tabs = tabs;
+    }
+
+
+
+    private FCTabGroupOwner owner;
+
+    /**
+     * Owner.
+     *
+     * <p>
+     *     Set programmatically by framework after reading in from XML.
+     * </p>
+     */
+    @XmlTransient
+    public FCTabGroupOwner getOwner() {
+        return owner;
+    }
+
+    public void setOwner(final FCTabGroupOwner owner) {
+        this.owner = owner;
+    }
+
+
+
+
+
+
+    public static class Predicates {
+        public static Predicate<FCTabGroup> notEmpty() {
+            return new Predicate<FCTabGroup>() {
+                @Override
+                public boolean apply(final FCTabGroup tabGroup) {
+                    return FluentIterable
+                            .from(tabGroup.getTabs())
+                            .anyMatch(FCTab.Predicates.notEmpty());
+                }
+            };
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroupOwner.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroupOwner.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroupOwner.java
new file mode 100644
index 0000000..f6f59d5
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/FCTabGroupOwner.java
@@ -0,0 +1,25 @@
+/*
+ *  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.core.metamodel.services.grid.fixedcols.applib;
+
+import org.apache.isis.applib.layout.common.Owner;
+
+public interface FCTabGroupOwner extends Owner {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/package-info.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/package-info.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/package-info.java
new file mode 100644
index 0000000..3cdd1f1
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/fixedcols/applib/package-info.java
@@ -0,0 +1,44 @@
+/*
+ *  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.
+ */
+
+/**
+ * THIS STUFF ALL WORKS, BUT REMOVED FROM PUBLIC APPLIB BECAUSE IT LOOKS
+ * LIKE THE BOOTSTRAP3 GRID WILL BE SUFFICIENT.
+ *
+ * The benefit of keeping this stuff around is that it reinforces where
+ * separation of responsibilities are for grid components (tab etc)
+ * vs common components (fieldset, action, property, collection, domainobject).
+ *
+ * --------------------
+ *
+ * The classes in this package define how to layout the properties, collections and actions of a domain object - the
+ * building blocks - as defined in the <code>members.v1</code> package.
+ *
+ * <p>
+ *     The layout is reasonably flexible, being a half-way house between the annotation/JSON style layouts (pre 1.12.0)
+ *     vs the fully flexible layouts provided by the <code>bootstrap3</code> layouts.  In particular, they allow
+ *     property fieldsets and collections to be grouped into tabs, with collections being laid out in any column.
+ *     However, tab groups only appear in the central area of the page, and may only have a maximum of three columns.
+ * </p>
+ */
+@javax.xml.bind.annotation.XmlSchema(
+        namespace = "http://isis.apache.org/schema/applib/layout/fixedcols",
+        elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
+)
+package org.apache.isis.core.metamodel.services.grid.fixedcols.applib;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
index c017adf..76a436e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
@@ -108,7 +108,7 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
             final OutputStreamWriter writer = new OutputStreamWriter(zos);
             for (final ObjectSpecification objectSpec : domainObjectSpecs) {
                 final Class<?> domainClass = objectSpec.getCorrespondingClass();
-                final Grid grid = gridService.toGrid(domainClass);
+                final Grid grid = gridService.toGrid(domainClass, GridService.Style.NORMALIZED);
                 if(grid != null) {
                     zos.putNextEntry(new ZipEntry(zipEntryNameFor(objectSpec)));
                     String xml = jaxbService.toXml(grid);

http://git-wip-us.apache.org/repos/asf/isis/blob/5c831757/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
index 686ab7c..a47e9c5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecifications.java
@@ -25,7 +25,7 @@ import java.util.Set;
 
 import com.google.common.collect.Lists;
 
-import org.apache.isis.applib.layout.fixedcols.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 
 


[5/5] isis git commit: ISIS-993: can now download normalized, complete or minimal layouts.

Posted by da...@apache.org.
ISIS-993: can now download normalized, complete or minimal layouts.


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

Branch: refs/heads/ISIS-993
Commit: 78943221cc6eccc0afed292910bb84a62b8a37bf
Parents: ecf6d17
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Feb 10 11:33:06 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Feb 10 11:33:06 2016 +0000

----------------------------------------------------------------------
 .../isis/applib/layout/bootstrap3/BS3Col.java   |  3 ++-
 .../isis/applib/layout/bootstrap3/BS3Grid.java  |  9 ++++----
 .../applib/layout/common/ActionLayoutData.java  |  2 +-
 .../layout/common/DomainObjectLayoutData.java   |  8 +++----
 .../common/DomainObjectLayoutDataOwner.java     |  2 ++
 .../isis/applib/layout/common/GridAbstract.java | 10 ++++----
 .../applib/services/layout/GridService.java     |  2 +-
 .../layout/Object_downloadLayoutXml.java        |  6 ++---
 .../grid/GridNormalizerServiceAbstract.java     | 24 ++++++++++++++++----
 .../services/grid/GridServiceDefault.java       | 12 ++++++++++
 .../services/metamodel/MetadataMenu.java        |  7 +++---
 .../dom/simple/SimpleObject.layout.xml          |  2 ++
 12 files changed, 60 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
index 1a5bec7..d568f05 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Col.java
@@ -33,6 +33,7 @@ import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
 import org.apache.isis.applib.layout.common.CollectionLayoutDataOwner;
 import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
+import org.apache.isis.applib.layout.common.DomainObjectLayoutDataOwner;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.FieldSetOwner;
 
@@ -66,7 +67,7 @@ import org.apache.isis.applib.layout.common.FieldSetOwner;
 )
 public class BS3Col extends BS3RowContent
         implements ActionLayoutDataOwner, BS3TabGroupOwner, BS3RowOwner, FieldSetOwner, HasCssId,
-        CollectionLayoutDataOwner {
+        CollectionLayoutDataOwner, DomainObjectLayoutDataOwner {
 
     private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
index 5d0cb47..7ec9665 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
@@ -166,7 +166,8 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
 
     protected void traverseRows(final BS3RowOwner rowOwner, final Grid.Visitor visitor) {
         final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
-        for (BS3Row bs3Row : rowOwner.getRows()) {
+        final List<BS3Row> rows = rowOwner.getRows();
+        for (BS3Row bs3Row : Lists.newArrayList(rows)) {
             bs3Row.setOwner(this);
             bs3Visitor.preVisit(bs3Row);
             bs3Visitor.visit(bs3Row);
@@ -178,7 +179,7 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
     private void traverseCols(final Grid.Visitor visitor, final BS3Row bs3Row) {
         final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
         final List<BS3RowContent> cols = bs3Row.getCols();
-        for (BS3RowContent rowContent : cols) {
+        for (BS3RowContent rowContent : Lists.newArrayList(cols)) {
             rowContent.setOwner(bs3Row);
             if(rowContent instanceof BS3Col) {
                 final BS3Col bs3Col = (BS3Col) rowContent;
@@ -215,7 +216,7 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
             final Grid.Visitor visitor) {
         final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
         final List<BS3TabGroup> tabGroups = bs3TabGroupOwner.getTabGroups();
-        for (BS3TabGroup bs3TabGroup : tabGroups) {
+        for (BS3TabGroup bs3TabGroup : Lists.newArrayList(tabGroups)) {
             bs3TabGroup.setOwner(bs3TabGroupOwner);
             bs3Visitor.preVisit(bs3TabGroup);
             bs3Visitor.visit(bs3TabGroup);
@@ -229,7 +230,7 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
             final Grid.Visitor visitor) {
         final BS3Grid.Visitor bs3Visitor = asBs3Visitor(visitor);
         final List<BS3Tab> tabs = bs3TabOwner.getTabs();
-        for (BS3Tab tab : tabs) {
+        for (BS3Tab tab : Lists.newArrayList(tabs)) {
             tab.setOwner(bs3TabOwner);
             bs3Visitor.preVisit(tab);
             bs3Visitor.visit(tab);

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
index 5097349..6bd4113 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
@@ -48,7 +48,7 @@ import org.apache.isis.applib.annotation.Where;
         , "metadataError"
     }
 )
-public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwner>,HasCssClass, HasCssClassFa,
+public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwner>, HasCssClass, HasCssClassFa,
         HasDescribedAs, HasHidden, HasNamed, HasBookmarking {
 
     private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
index d15d27b..a0502e3 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
@@ -43,7 +43,7 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
             , "metadataError"
         }
 )
-public class DomainObjectLayoutData implements Serializable,
+public class DomainObjectLayoutData implements Serializable, Owned<DomainObjectLayoutDataOwner>,
         HasBookmarking, HasCssClass, HasCssClassFa, HasDescribedAs, HasNamed {
 
     private static final long serialVersionUID = 1L;
@@ -185,7 +185,7 @@ public class DomainObjectLayoutData implements Serializable,
 
 
 
-    private MemberRegionOwner owner;
+    private DomainObjectLayoutDataOwner owner;
     /**
      * Owner.
      *
@@ -194,11 +194,11 @@ public class DomainObjectLayoutData implements Serializable,
      * </p>
      */
     @XmlTransient
-    public MemberRegionOwner getOwner() {
+    public DomainObjectLayoutDataOwner getOwner() {
         return owner;
     }
 
-    public void setOwner(final MemberRegionOwner owner) {
+    public void setOwner(final DomainObjectLayoutDataOwner owner) {
         this.owner = owner;
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutDataOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutDataOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutDataOwner.java
index 2b719e9..77e9e8c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutDataOwner.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutDataOwner.java
@@ -20,4 +20,6 @@ package org.apache.isis.applib.layout.common;
 
 public interface DomainObjectLayoutDataOwner extends Owner {
 
+    DomainObjectLayoutData getDomainObject();
+    void setDomainObject(DomainObjectLayoutData domainObjectLayoutData);
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
index d320dff..eac1588 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/GridAbstract.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import javax.xml.bind.annotation.XmlTransient;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 import org.apache.isis.applib.annotation.Programmatic;
@@ -49,7 +50,6 @@ public abstract class GridAbstract implements Grid {
     }
 
     @Programmatic
-    @XmlTransient
     public void setDomainClass(final Class<?> domainClass) {
         this.domainClass = domainClass;
     }
@@ -80,7 +80,7 @@ public abstract class GridAbstract implements Grid {
         if(actionLayoutDatas == null) {
             return;
         }
-        for (final ActionLayoutData actionLayoutData : actionLayoutDatas) {
+        for (final ActionLayoutData actionLayoutData : Lists.newArrayList(actionLayoutDatas)) {
             actionLayoutData.setOwner(actionLayoutDataOwner);
             visitor.visit(actionLayoutData);
         }
@@ -92,12 +92,12 @@ public abstract class GridAbstract implements Grid {
      */
     protected void traverseFieldSets(final FieldSetOwner fieldSetOwner, final GridAbstract.Visitor visitor) {
         final List<FieldSet> fieldSets = fieldSetOwner.getFieldSets();
-        for (FieldSet fieldSet : fieldSets) {
+        for (FieldSet fieldSet : Lists.newArrayList(fieldSets)) {
             fieldSet.setOwner(fieldSetOwner);
             visitor.visit(fieldSet);
             traverseActions(fieldSet, visitor);
             final List<PropertyLayoutData> properties = fieldSet.getProperties();
-            for (final PropertyLayoutData property : properties) {
+            for (final PropertyLayoutData property : Lists.newArrayList(properties)) {
                 property.setOwner(fieldSet);
                 visitor.visit(property);
                 traverseActions(property, visitor);
@@ -112,7 +112,7 @@ public abstract class GridAbstract implements Grid {
     protected void traverseCollections(
             final CollectionLayoutDataOwner owner, final GridAbstract.Visitor visitor) {
         final List<CollectionLayoutData> collections = owner.getCollections();
-        for (CollectionLayoutData collection : collections) {
+        for (CollectionLayoutData collection : Lists.newArrayList(collections)) {
             collection.setOwner(owner);
             visitor.visit(collection);
             traverseActions(collection, visitor);

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
index fc33df4..8a671a1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/GridService.java
@@ -103,7 +103,7 @@ public interface GridService {
     /**
      * For all of the available {@link GridNormalizerService}s available, return only the first one for any that
      * are for the same grid implementation.
-     * 
+     *
      * <p>
      *   This allows default implementations (eg for bootstrap3) to be overridden while also allowing for the more
      *   general idea of multiple implementations.

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
index 10fee16..d3a5128 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_downloadLayoutXml.java
@@ -63,15 +63,15 @@ public class Object_downloadLayoutXml {
                         gridService.tnsAndSchemaLocation(grid)
                 ));
 
-        return new Clob(Util.withSuffix(fileName, "xml"), "text/xml", xml);
+        return new Clob(Util.withSuffix(fileName, style.name().toLowerCase() + ".xml"), "text/xml", xml);
     }
 
     public boolean hide$$() {
         // can use either style to determine whether this action should be hidden
-        return getGrid(GridService.Style.COMPLETE) == null;
+        return getGrid(GridService.Style.NORMALIZED) == null;
     }
     public String default0$$() {
-        return Util.withSuffix(object.getClass().getSimpleName(), "layout.xml");
+        return Util.withSuffix(object.getClass().getSimpleName(), "layout");
     }
     public GridService.Style default1$$() {
         return GridService.Style.NORMALIZED;

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
index 3c38356..279086c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
@@ -40,6 +40,7 @@ import org.apache.isis.applib.layout.common.ActionLayoutData;
 import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
 import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
+import org.apache.isis.applib.layout.common.DomainObjectLayoutDataOwner;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.Grid;
 import org.apache.isis.applib.layout.common.HasBookmarking;
@@ -180,6 +181,8 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
     @Override
     public void complete(final G grid, final Class<?> domainClass) {
         normalize(grid, domainClass);
+        if(true) {
+
         final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
 
         grid.visit(new FCGrid.VisitorAdapter() {
@@ -233,6 +236,7 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
                 setPluralIfAny(domainObjectLayoutData, objectSpec);
             }
         });
+        }
     }
 
     private static boolean isDoOp(final Facet facet) {
@@ -348,9 +352,11 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
         final NamedFacet namedFacet = facetHolder.getFacet(NamedFacet.class);
         if(isDoOp(namedFacet)) {
             final String named = namedFacet.value();
-            final boolean escaped = namedFacet.escaped();
             if(!Strings.isNullOrEmpty(named)){
                 hasNamed.setNamed(named);
+            }
+            final boolean escaped = namedFacet.escaped();
+            if(!escaped) {
                 hasNamed.setNamedEscaped(escaped);
             }
         }
@@ -438,12 +444,20 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
                 actionLayoutData.getOwner().getActions().remove(actionLayoutData);
             }
 
-            @Override public void visit(final CollectionLayoutData collectionLayoutData) {
-                collectionLayoutData.getOwner().getCollections().remove(this);
+            @Override
+            public void visit(final CollectionLayoutData collectionLayoutData) {
+                collectionLayoutData.getOwner().getCollections().remove(collectionLayoutData);
             }
 
-            @Override public void visit(final PropertyLayoutData propertyLayoutData) {
-                propertyLayoutData.getOwner().getProperties().remove(this);
+            @Override
+            public void visit(final PropertyLayoutData propertyLayoutData) {
+                propertyLayoutData.getOwner().getProperties().remove(propertyLayoutData);
+            }
+
+            @Override
+            public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+                final DomainObjectLayoutDataOwner owner = domainObjectLayoutData.getOwner();
+                owner.setDomainObject(new DomainObjectLayoutData());
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
index 97588b9..f99b84d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridServiceDefault.java
@@ -153,6 +153,10 @@ public class GridServiceDefault
     @Programmatic
     public Grid normalize(final Grid grid) {
 
+        if(grid == null) {
+            return null;
+        }
+
         // if have .layout.json and then add a .layout.xml without restarting, then note that
         // the changes won't be picked up.  Normalizing would be required
         // in order to trample over the .layout.json's original facets
@@ -175,6 +179,10 @@ public class GridServiceDefault
     @Programmatic
     public Grid complete(final Grid grid) {
 
+        if(grid == null) {
+            return null;
+        }
+
         final Class<?> domainClass = grid.getDomainClass();
         for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
             gridNormalizerService.complete(grid, domainClass);
@@ -187,6 +195,10 @@ public class GridServiceDefault
     @Programmatic
     public Grid minimal(final Grid grid) {
 
+        if(grid == null) {
+            return null;
+        }
+
         final Class<?> domainClass = grid.getDomainClass();
         for (GridNormalizerService gridNormalizerService : gridNormalizerServices()) {
             gridNormalizerService.minimal(grid, domainClass);

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
index 76a436e..73a3fab 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetadataMenu.java
@@ -91,7 +91,7 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
             cssClassFa = "fa-download"
     )
     @MemberOrder(sequence="500.400.1")
-    public Blob downloadLayouts() {
+    public Blob downloadLayouts(final GridService.Style style) {
         final Collection<ObjectSpecification> allSpecs = specificationLoader.allSpecifications();
         final Collection<ObjectSpecification> domainObjectSpecs = Collections2
                 .filter(allSpecs, new Predicate<ObjectSpecification>(){
@@ -108,7 +108,7 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
             final OutputStreamWriter writer = new OutputStreamWriter(zos);
             for (final ObjectSpecification objectSpec : domainObjectSpecs) {
                 final Class<?> domainClass = objectSpec.getCorrespondingClass();
-                final Grid grid = gridService.toGrid(domainClass, GridService.Style.NORMALIZED);
+                final Grid grid = gridService.toGrid(domainClass, style);
                 if(grid != null) {
                     zos.putNextEntry(new ZipEntry(zipEntryNameFor(objectSpec)));
                     String xml = jaxbService.toXml(grid);
@@ -118,7 +118,8 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
                 }
             }
             writer.close();
-            return new Blob("layouts.zip", mimeTypeApplicationZip, baos.toByteArray());
+            final String fileName = "layouts." + style.name().toLowerCase() + ".zip";
+            return new Blob(fileName, mimeTypeApplicationZip, baos.toByteArray());
         } catch (final IOException ex) {
             throw new FatalException("Unable to create zip of layouts", ex);
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/78943221/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
index b076822..9652100 100644
--- a/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
+++ b/example/application/simpleapp/dom/src/main/java/domainapp/dom/simple/SimpleObject.layout.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <bs3:grid xsi:schemaLocation="http://isis.apache.org/schema/applib/layout/common http://isis.apache.org/schema/applib/layout/common/common.xsd http://isis.apache.org/schema/applib/layout/bootstrap3 http://isis.apache.org/schema/applib/layout/bootstrap3/bootstrap3.xsd" xmlns:c="http://isis.apache.org/schema/applib/layout/common" xmlns:bs3="http://isis.apache.org/schema/applib/layout/bootstrap3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 
+
 <!--
     <bs3:row>
         <bs3:col span="8" unreferencedActions="false">
@@ -34,6 +35,7 @@
         </bs3:col>
     </bs3:row>
 -->
+
     <bs3:row>
         <bs3:col span="12" unreferencedActions="false">
             <c:domainObject/>


[3/5] isis git commit: ISIS-993: fleshing out the GridNormalizerServiceAbstract for the "complete" and "minimal" updating of Grid graphs (prior to conversion to XML).

Posted by da...@apache.org.
ISIS-993: fleshing out the GridNormalizerServiceAbstract for the "complete" and "minimal" updating of Grid graphs (prior to conversion to XML).


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

Branch: refs/heads/ISIS-993
Commit: 6053d1a8efed2d5cae9cbbc8b0497796397686cd
Parents: 5c83175
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Feb 10 10:21:00 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Feb 10 10:21:00 2016 +0000

----------------------------------------------------------------------
 .../isis/applib/layout/bootstrap3/BS3Grid.java  |   2 +-
 .../applib/layout/common/ActionLayoutData.java  |  19 +-
 .../layout/common/CollectionLayoutData.java     |  22 +-
 .../common/CollectionLayoutDataOwner.java       |   1 +
 .../layout/common/DomainObjectLayoutData.java   |  16 +-
 .../isis/applib/layout/common/FieldSet.java     |  11 +-
 .../applib/layout/common/HasBookmarking.java    |  14 +
 .../isis/applib/layout/common/HasCssClass.java  |  12 +
 .../applib/layout/common/HasCssClassFa.java     |  16 +
 .../applib/layout/common/HasDescribedAs.java    |  12 +
 .../isis/applib/layout/common/HasHidden.java    |  14 +
 .../isis/applib/layout/common/HasNamed.java     |  17 ++
 .../isis/applib/layout/common/MemberRegion.java |   2 +-
 .../layout/common/PropertyLayoutData.java       |  16 +-
 .../members/cssclassfa/CssClassFaPosition.java  |  24 ++
 .../grid/GridNormalizerServiceAbstract.java     | 301 ++++++++++++++++++-
 16 files changed, 479 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
index a893cfb..5d0cb47 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/bootstrap3/BS3Grid.java
@@ -113,7 +113,7 @@ public class BS3Grid extends GridAbstract implements BS3Element, Dto, BS3RowOwne
 
 
 
-    interface Visitor extends Grid.Visitor {
+    public interface Visitor extends Grid.Visitor {
         void preVisit(final BS3Grid bs3Grid);
         void visit(final BS3Grid bs3Grid);
         void postVisit(final BS3Grid bs3Grid);

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
index f1aa540..5097349 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/ActionLayoutData.java
@@ -48,7 +48,8 @@ import org.apache.isis.applib.annotation.Where;
         , "metadataError"
     }
 )
-public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwner> {
+public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwner>,HasCssClass, HasCssClassFa,
+        HasDescribedAs, HasHidden, HasNamed, HasBookmarking {
 
     private static final long serialVersionUID = 1L;
 
@@ -79,11 +80,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private BookmarkPolicy bookmarking;
 
+    @Override
     @XmlAttribute(required = false)
     public BookmarkPolicy getBookmarking() {
         return bookmarking;
     }
 
+    @Override
     public void setBookmarking(BookmarkPolicy bookmarking) {
         this.bookmarking = bookmarking;
     }
@@ -91,11 +94,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private String cssClass;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClass() {
         return cssClass;
     }
 
+    @Override
     public void setCssClass(String cssClass) {
         this.cssClass = cssClass;
     }
@@ -103,11 +108,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private String cssClassFa;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClassFa() {
         return cssClassFa;
     }
 
+    @Override
     public void setCssClassFa(String cssClassFa) {
         this.cssClassFa = cssClassFa;
     }
@@ -116,11 +123,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition cssClassFaPosition;
 
+    @Override
     @XmlAttribute(required = false)
     public org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition getCssClassFaPosition() {
         return cssClassFaPosition;
     }
 
+    @Override
     public void setCssClassFaPosition(org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition cssClassFaPosition) {
         this.cssClassFaPosition = cssClassFaPosition;
     }
@@ -128,11 +137,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private String describedAs;
 
+    @Override
     @XmlElement(required = false)
     public String getDescribedAs() {
         return describedAs;
     }
 
+    @Override
     public void setDescribedAs(String describedAs) {
         this.describedAs = describedAs;
     }
@@ -141,11 +152,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private Where hidden;
 
+    @Override
     @XmlAttribute(required = false)
     public Where getHidden() {
         return hidden;
     }
 
+    @Override
     public void setHidden(Where hidden) {
         this.hidden = hidden;
     }
@@ -154,11 +167,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private String named;
 
+    @Override
     @XmlElement(required = false)
     public String getNamed() {
         return named;
     }
 
+    @Override
     public void setNamed(String named) {
         this.named = named;
     }
@@ -167,11 +182,13 @@ public class ActionLayoutData implements Serializable, Owned<ActionLayoutDataOwn
 
     private Boolean namedEscaped;
 
+    @Override
     @XmlAttribute(required = false)
     public Boolean getNamedEscaped() {
         return namedEscaped;
     }
 
+    @Override
     public void setNamedEscaped(Boolean namedEscaped) {
         this.namedEscaped = namedEscaped;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutData.java
index 19758d6..05a331f 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutData.java
@@ -52,7 +52,11 @@ import org.apache.isis.applib.annotation.Where;
                 , "metadataError"
         }
 )
-public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner, Serializable {
+public class CollectionLayoutData
+        implements MemberRegion<CollectionLayoutDataOwner>,
+                   ActionLayoutDataOwner,
+                   Serializable,
+                   HasCssClass, HasDescribedAs, HasHidden, HasNamed {
 
     private static final long serialVersionUID = 1L;
 
@@ -81,11 +85,13 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
     private String cssClass;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClass() {
         return cssClass;
     }
 
+    @Override
     public void setCssClass(String cssClass) {
         this.cssClass = cssClass;
     }
@@ -94,11 +100,13 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
     private String describedAs;
 
+    @Override
     @XmlElement(required = false)
     public String getDescribedAs() {
         return describedAs;
     }
 
+    @Override
     public void setDescribedAs(String describedAs) {
         this.describedAs = describedAs;
     }
@@ -123,11 +131,13 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
     private Where hidden;
 
+    @Override
     @XmlAttribute(required = false)
     public Where getHidden() {
         return hidden;
     }
 
+    @Override
     public void setHidden(Where hidden) {
         this.hidden = hidden;
     }
@@ -135,11 +145,13 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
     private String named;
 
+    @Override
     @XmlElement(required = false)
     public String getNamed() {
         return named;
     }
 
+    @Override
     public void setNamed(String named) {
         this.named = named;
     }
@@ -147,11 +159,13 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
     private Boolean namedEscaped;
 
+    @Override
     @XmlAttribute(required = false)
     public Boolean getNamedEscaped() {
         return namedEscaped;
     }
 
+    @Override
     public void setNamedEscaped(Boolean namedEscaped) {
         this.namedEscaped = namedEscaped;
     }
@@ -197,7 +211,7 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
 
 
 
-    private MemberRegionOwner owner;
+    private CollectionLayoutDataOwner owner;
     /**
      * Owner.
      *
@@ -206,11 +220,11 @@ public class CollectionLayoutData implements MemberRegion, ActionLayoutDataOwner
      * </p>
      */
     @XmlTransient
-    public MemberRegionOwner getOwner() {
+    public CollectionLayoutDataOwner getOwner() {
         return owner;
     }
 
-    public void setOwner(final MemberRegionOwner owner) {
+    public void setOwner(final CollectionLayoutDataOwner owner) {
         this.owner = owner;
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
index 438ae56..0eae2c7 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/CollectionLayoutDataOwner.java
@@ -21,5 +21,6 @@ package org.apache.isis.applib.layout.common;
 import java.util.List;
 
 public interface CollectionLayoutDataOwner extends MemberRegionOwner {
+
     List<CollectionLayoutData> getCollections();
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
index 0db726a..702a3d6 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/DomainObjectLayoutData.java
@@ -43,7 +43,8 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
             , "metadataError"
         }
 )
-public class DomainObjectLayoutData implements Serializable {
+public class DomainObjectLayoutData implements Serializable,
+        HasBookmarking, HasCssClass, HasCssClassFa, HasDescribedAs, HasNamed {
 
     private static final long serialVersionUID = 1L;
 
@@ -126,6 +127,19 @@ public class DomainObjectLayoutData implements Serializable {
     }
 
 
+    private Boolean namedEscaped;
+
+    @Override
+    @XmlAttribute(required = false)
+    public Boolean getNamedEscaped() {
+        return namedEscaped;
+    }
+
+    @Override
+    public void setNamedEscaped(Boolean namedEscaped) {
+        this.namedEscaped = namedEscaped;
+    }
+
 
 
     private String plural;

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
index 262796b..7037135 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/FieldSet.java
@@ -51,7 +51,10 @@ import org.apache.isis.applib.layout.bootstrap3.BS3Col;
                 , "metadataError"
         }
 )
-public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializable {
+public class FieldSet
+        implements MemberRegion<FieldSetOwner>,
+                   ActionLayoutDataOwner,
+                   Serializable {
 
     private static final long serialVersionUID = 1L;
 
@@ -162,7 +165,7 @@ public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializab
     }
 
 
-    private MemberRegionOwner owner;
+    private FieldSetOwner owner;
     /**
      * Owner.
      *
@@ -171,11 +174,11 @@ public class FieldSet implements MemberRegion, ActionLayoutDataOwner, Serializab
      * </p>
      */
     @XmlTransient
-    public MemberRegionOwner getOwner() {
+    public FieldSetOwner getOwner() {
         return owner;
     }
 
-    public void setOwner(final MemberRegionOwner owner) {
+    public void setOwner(final FieldSetOwner owner) {
         this.owner = owner;
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasBookmarking.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasBookmarking.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasBookmarking.java
new file mode 100644
index 0000000..ad841a2
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasBookmarking.java
@@ -0,0 +1,14 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+import org.apache.isis.applib.annotation.BookmarkPolicy;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasBookmarking {
+    @XmlAttribute(required = false) BookmarkPolicy getBookmarking();
+
+    void setBookmarking(BookmarkPolicy bookmarking);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClass.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClass.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClass.java
new file mode 100644
index 0000000..e42dc09
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClass.java
@@ -0,0 +1,12 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasCssClass {
+    @XmlAttribute(required = false) String getCssClass();
+
+    void setCssClass(String cssClass);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClassFa.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClassFa.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClassFa.java
new file mode 100644
index 0000000..763b8dd
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasCssClassFa.java
@@ -0,0 +1,16 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasCssClassFa {
+    @XmlAttribute(required = false) String getCssClassFa();
+
+    void setCssClassFa(String cssClassFa);
+
+    @XmlAttribute(required = false) org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition getCssClassFaPosition();
+
+    void setCssClassFaPosition(org.apache.isis.applib.annotation.ActionLayout.CssClassFaPosition cssClassFaPosition);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasDescribedAs.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasDescribedAs.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasDescribedAs.java
new file mode 100644
index 0000000..f19c95a
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasDescribedAs.java
@@ -0,0 +1,12 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasDescribedAs {
+    @XmlElement(required = false) String getDescribedAs();
+
+    void setDescribedAs(String describedAs);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasHidden.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasHidden.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasHidden.java
new file mode 100644
index 0000000..7953141
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasHidden.java
@@ -0,0 +1,14 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+import org.apache.isis.applib.annotation.Where;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasHidden {
+    @XmlAttribute(required = false) Where getHidden();
+
+    void setHidden(Where hidden);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasNamed.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasNamed.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasNamed.java
new file mode 100644
index 0000000..4a29ee9
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/HasNamed.java
@@ -0,0 +1,17 @@
+package org.apache.isis.applib.layout.common;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Created by Dan on 10/02/2016.
+ */
+public interface HasNamed {
+    @XmlElement(required = false) String getNamed();
+
+    void setNamed(String named);
+
+    @XmlAttribute(required = false) Boolean getNamedEscaped();
+
+    void setNamedEscaped(Boolean namedEscaped);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/MemberRegion.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/MemberRegion.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/MemberRegion.java
index daf4aed4..f335cde 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/MemberRegion.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/MemberRegion.java
@@ -27,7 +27,7 @@ package org.apache.isis.applib.layout.common;
  *     (containing a single collection and associated actions)
  * </p>
  */
-public interface MemberRegion extends Owned<MemberRegionOwner> {
+public interface MemberRegion<T extends MemberRegionOwner> extends Owned<T> {
 
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java b/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
index 91e7ee0..9bbec66 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/common/PropertyLayoutData.java
@@ -45,7 +45,11 @@ import org.apache.isis.applib.annotation.Where;
                 , "metadataError"
         }
 )
-public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable, Owned<FieldSet> {
+public class PropertyLayoutData
+        implements ActionLayoutDataOwner,
+                   Serializable,
+                   Owned<FieldSet>,
+                   HasCssClass, HasDescribedAs, HasHidden, HasNamed {
 
     private static final long serialVersionUID = 1L;
 
@@ -74,11 +78,13 @@ public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable,
 
     private String cssClass;
 
+    @Override
     @XmlAttribute(required = false)
     public String getCssClass() {
         return cssClass;
     }
 
+    @Override
     public void setCssClass(String cssClass) {
         this.cssClass = cssClass;
     }
@@ -86,11 +92,13 @@ public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable,
 
     private String describedAs;
 
+    @Override
     @XmlElement(required = false)
     public String getDescribedAs() {
         return describedAs;
     }
 
+    @Override
     public void setDescribedAs(String describedAs) {
         this.describedAs = describedAs;
     }
@@ -98,11 +106,13 @@ public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable,
 
     private Where hidden;
 
+    @Override
     @XmlAttribute(required = false)
     public Where getHidden() {
         return hidden;
     }
 
+    @Override
     public void setHidden(Where hidden) {
         this.hidden = hidden;
     }
@@ -134,11 +144,13 @@ public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable,
 
     private String named;
 
+    @Override
     @XmlElement(required = false)
     public String getNamed() {
         return named;
     }
 
+    @Override
     public void setNamed(String named) {
         this.named = named;
     }
@@ -146,11 +158,13 @@ public class PropertyLayoutData implements ActionLayoutDataOwner, Serializable,
 
     private Boolean namedEscaped;
 
+    @Override
     @XmlAttribute(required = false)
     public Boolean getNamedEscaped() {
         return namedEscaped;
     }
 
+    @Override
     public void setNamedEscaped(Boolean namedEscaped) {
         this.namedEscaped = namedEscaped;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaPosition.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaPosition.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaPosition.java
index 4692f6a..a08e4af 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaPosition.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/cssclassfa/CssClassFaPosition.java
@@ -72,4 +72,28 @@ public enum CssClassFaPosition {
         }
         throw new IllegalArgumentException("not recognized: " + cssClassFaPosition);
     }
+    @Deprecated
+    public DomainObjectLayout.CssClassFaPosition toDomainObjectLayoutPosition() {
+        if (this == CssClassFaPosition.LEFT) {
+            return DomainObjectLayout.CssClassFaPosition.LEFT;
+        } else {
+            return DomainObjectLayout.CssClassFaPosition.RIGHT;
+        }
+    }
+    @Deprecated
+    public ViewModelLayout.CssClassFaPosition toViewModelLayoutPosition() {
+        if (this == CssClassFaPosition.LEFT) {
+            return ViewModelLayout.CssClassFaPosition.LEFT;
+        } else {
+            return ViewModelLayout.CssClassFaPosition.RIGHT;
+        }
+    }
+    @Deprecated
+    public ActionLayout.CssClassFaPosition toActionLayoutPosition() {
+        if (this == CssClassFaPosition.LEFT) {
+            return ActionLayout.CssClassFaPosition.LEFT;
+        } else {
+            return ActionLayout.CssClassFaPosition.RIGHT;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6053d1a8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
index 79d3548..3c38356 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/grid/GridNormalizerServiceAbstract.java
@@ -17,6 +17,7 @@
 package org.apache.isis.core.metamodel.services.grid;
 
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -30,22 +31,30 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.BookmarkPolicy;
+import org.apache.isis.applib.annotation.LabelPosition;
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.layout.GridNormalizerService;
+import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.layout.common.ActionLayoutData;
 import org.apache.isis.applib.layout.common.ActionLayoutDataOwner;
 import org.apache.isis.applib.layout.common.CollectionLayoutData;
+import org.apache.isis.applib.layout.common.DomainObjectLayoutData;
 import org.apache.isis.applib.layout.common.FieldSet;
 import org.apache.isis.applib.layout.common.Grid;
+import org.apache.isis.applib.layout.common.HasBookmarking;
+import org.apache.isis.applib.layout.common.HasCssClass;
+import org.apache.isis.applib.layout.common.HasCssClassFa;
+import org.apache.isis.applib.layout.common.HasDescribedAs;
+import org.apache.isis.applib.layout.common.HasHidden;
+import org.apache.isis.applib.layout.common.HasNamed;
 import org.apache.isis.applib.layout.common.MemberRegionOwner;
 import org.apache.isis.applib.layout.common.PropertyLayoutData;
-import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
-import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumnOwner;
-import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
-import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.applib.services.layout.GridNormalizerService;
 import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
 import org.apache.isis.core.metamodel.facets.actions.layout.ActionPositionFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.BookmarkPolicyFacetForActionXml;
@@ -54,6 +63,11 @@ import org.apache.isis.core.metamodel.facets.actions.layout.CssClassFacetForActi
 import org.apache.isis.core.metamodel.facets.actions.layout.DescribedAsFacetForActionXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.HiddenFacetForActionLayoutXml;
 import org.apache.isis.core.metamodel.facets.actions.layout.NamedFacetForActionXml;
+import org.apache.isis.core.metamodel.facets.actions.position.ActionPositionFacet;
+import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
+import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
+import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
+import org.apache.isis.core.metamodel.facets.collections.collection.defaultview.DefaultViewFacet;
 import org.apache.isis.core.metamodel.facets.collections.layout.CssClassFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.DefaultViewFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.DescribedAsFacetForCollectionXml;
@@ -61,7 +75,18 @@ import org.apache.isis.core.metamodel.facets.collections.layout.HiddenFacetForCo
 import org.apache.isis.core.metamodel.facets.collections.layout.NamedFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.PagedFacetForCollectionXml;
 import org.apache.isis.core.metamodel.facets.collections.layout.SortedByFacetForCollectionXml;
+import org.apache.isis.core.metamodel.facets.collections.sortedby.SortedByFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaFacet;
+import org.apache.isis.core.metamodel.facets.members.cssclassfa.CssClassFaPosition;
 import org.apache.isis.core.metamodel.facets.members.order.annotprop.MemberOrderFacetXml;
+import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolicyFacet;
+import org.apache.isis.core.metamodel.facets.object.paged.PagedFacet;
+import org.apache.isis.core.metamodel.facets.object.plural.PluralFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.multiline.MultiLineFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.renderedadjusted.RenderedAdjustedFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.typicallen.TypicalLengthFacet;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.CssClassFacetForPropertyXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.DescribedAsFacetForPropertyXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.HiddenFacetForPropertyXml;
@@ -70,6 +95,10 @@ import org.apache.isis.core.metamodel.facets.properties.propertylayout.MultiLine
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.NamedFacetForPropertyXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.RenderedAdjustedFacetForPropertyXml;
 import org.apache.isis.core.metamodel.facets.properties.propertylayout.TypicalLengthFacetForPropertyXml;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumn;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCColumnOwner;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCGrid;
+import org.apache.isis.core.metamodel.services.grid.fixedcols.applib.FCTab;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.SpecificationLoader;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
@@ -150,15 +179,273 @@ public abstract class GridNormalizerServiceAbstract<G extends Grid>
     @Programmatic
     @Override
     public void complete(final G grid, final Class<?> domainClass) {
-        // TODO: do some different logic here...
         normalize(grid, domainClass);
+        final ObjectSpecification objectSpec = specificationLookup.loadSpecification(domainClass);
+
+        grid.visit(new FCGrid.VisitorAdapter() {
+            @Override
+            public void visit(final ActionLayoutData actionLayoutData) {
+                final ObjectAction objectAction = objectSpec.getObjectAction(actionLayoutData.getId());
+
+                setBookmarkingIfAny(actionLayoutData, objectAction);
+                setCssClassIfAny(actionLayoutData, objectAction);
+                setCssClassFaIfAny(actionLayoutData, objectAction);
+                setDescribedAsIfAny(actionLayoutData, objectAction);
+                setHiddenIfAny(actionLayoutData, objectAction);
+                setNamedIfAny(actionLayoutData, objectAction);
+                setActionPositionIfAny(actionLayoutData, objectAction);
+            }
+
+            @Override
+            public void visit(final CollectionLayoutData collectionLayoutData) {
+                final ObjectAssociation collection = objectSpec.getAssociation(collectionLayoutData.getId());
+
+                setCssClassIfAny(collectionLayoutData, collection);
+                setDefaultViewIfAny(collectionLayoutData, collection);
+                setDescribedAsIfAny(collectionLayoutData, collection);
+                setHiddenIfAny(collectionLayoutData, collection);
+                setNamedIfAny(collectionLayoutData, collection);
+                setPagedIfAny(collectionLayoutData, collection);
+                setSortedByIfAny(collectionLayoutData, collection);
+            }
+
+            @Override
+            public void visit(final PropertyLayoutData propertyLayoutData) {
+                final ObjectAssociation property = objectSpec.getAssociation(propertyLayoutData.getId());
+
+                setCssClassIfAny(propertyLayoutData, property);
+                setDescribedAsIfAny(propertyLayoutData, property);
+                setHiddenIfAny(propertyLayoutData, property);
+                setNamedIfAny(propertyLayoutData, property);
+                setLabelPositionIfAny(propertyLayoutData, property);
+                setMultiLineIfAny(propertyLayoutData, property);
+                setRenderedAsDayBeforeIfAny(propertyLayoutData, property);
+                setTypicalLengthIfAny(propertyLayoutData, property);
+            }
+
+            @Override
+            public void visit(final DomainObjectLayoutData domainObjectLayoutData) {
+                setBookmarkingIfAny(domainObjectLayoutData, objectSpec);
+                setCssClassIfAny(domainObjectLayoutData, objectSpec);
+                setCssClassFaIfAny(domainObjectLayoutData, objectSpec);
+                setDescribedAsIfAny(domainObjectLayoutData, objectSpec);
+                setNamedIfAny(domainObjectLayoutData, objectSpec);
+                setPluralIfAny(domainObjectLayoutData, objectSpec);
+            }
+        });
+    }
+
+    private static boolean isDoOp(final Facet facet) {
+        return facet != null && !facet.isNoop();
+    }
+
+    protected void setBookmarkingIfAny(
+            final HasBookmarking hasBookmarking,
+            final FacetHolder facetHolder) {
+        final BookmarkPolicyFacet bookmarkPolicyFacet = facetHolder.getFacet(BookmarkPolicyFacet.class);
+        if(isDoOp(bookmarkPolicyFacet)) {
+            final BookmarkPolicy bookmarking = bookmarkPolicyFacet.value();
+            if(bookmarking != null) {
+                hasBookmarking.setBookmarking(bookmarking);
+            }
+        }
+    }
+
+    protected void setCssClassIfAny(
+            final HasCssClass hasCssClass,
+            final FacetHolder facetHolder) {
+        final CssClassFacet cssClassFacet = facetHolder.getFacet(CssClassFacet.class);
+        if(isDoOp(cssClassFacet)) {
+            try {
+                // try...finally because CSS class may vary by object, and we pass in only null
+                final String cssClass = cssClassFacet.cssClass(null);
+                if(!Strings.isNullOrEmpty(cssClass)) {
+                    hasCssClass.setCssClass(cssClass);
+                }
+            } catch(Exception ignore) {
+                // ignore
+            }
+        }
+    }
+
+    protected void setCssClassFaIfAny(
+            final HasCssClassFa hasCssClassFa,
+            final FacetHolder facetHolder) {
+        final CssClassFaFacet cssClassFaFacet = facetHolder.getFacet(CssClassFaFacet.class);
+        if (isDoOp(cssClassFaFacet)) {
+            final String cssClassFa = cssClassFaFacet.value();
+            final CssClassFaPosition position = cssClassFaFacet.getPosition();
+            if(!Strings.isNullOrEmpty(cssClassFa)) {
+                hasCssClassFa.setCssClassFa(cssClassFa);
+                hasCssClassFa.setCssClassFaPosition(position.toActionLayoutPosition());
+            }
+        }
+    }
+
+    protected void setDefaultViewIfAny(
+            final CollectionLayoutData collectionLayoutData,
+            final FacetHolder facetHolder) {
+        final DefaultViewFacet defaultViewFacet = facetHolder.getFacet(DefaultViewFacet.class);
+        if(isDoOp(defaultViewFacet)) {
+            final String defaultView = defaultViewFacet.value();
+            if(!Strings.isNullOrEmpty(defaultView)) {
+                collectionLayoutData.setDefaultView(defaultView);
+            }
+        }
+    }
+
+    protected void setDescribedAsIfAny(
+            final HasDescribedAs hasDescribedAs,
+            final FacetHolder facetHolder) {
+        final DescribedAsFacet describedAsFacet = facetHolder.getFacet(DescribedAsFacet.class);
+        if(isDoOp(describedAsFacet)) {
+            final String describedAs = describedAsFacet.value();
+            if(!Strings.isNullOrEmpty(describedAs)) {
+                hasDescribedAs.setDescribedAs(describedAs);
+            }
+        }
     }
 
+    protected void setHiddenIfAny(
+            final HasHidden hasHidden,
+            final FacetHolder facetHolder) {
+        final HiddenFacet hiddenFacet = facetHolder.getFacet(HiddenFacet.class);
+        if (isDoOp(hiddenFacet)) {
+            final Where where = hiddenFacet.where();
+            if(where != null) {
+                hasHidden.setHidden(where);
+            }
+        }
+    }
+
+    protected void setLabelPositionIfAny(
+            final PropertyLayoutData propertyLayoutData,
+            final FacetHolder facetHolder) {
+        final LabelAtFacet labelAtFacet = facetHolder.getFacet(LabelAtFacet.class);
+        if(isDoOp(labelAtFacet)) {
+            final LabelPosition labelPosition = labelAtFacet.label();
+            if(labelPosition != null) {
+                propertyLayoutData.setLabelPosition(labelPosition);
+            }
+        }
+    }
+
+    protected void setMultiLineIfAny(
+            final PropertyLayoutData propertyLayoutData,
+            final FacetHolder facetHolder) {
+        final MultiLineFacet multiLineFacet = facetHolder.getFacet(MultiLineFacet.class);
+        if(isDoOp(multiLineFacet)) {
+            final int numberOfLines = multiLineFacet.numberOfLines();
+            if(numberOfLines > 0) {
+                propertyLayoutData.setMultiLine(numberOfLines);
+            }
+        }
+    }
+
+    protected void setNamedIfAny(
+            final HasNamed hasNamed,
+            final FacetHolder facetHolder) {
+        final NamedFacet namedFacet = facetHolder.getFacet(NamedFacet.class);
+        if(isDoOp(namedFacet)) {
+            final String named = namedFacet.value();
+            final boolean escaped = namedFacet.escaped();
+            if(!Strings.isNullOrEmpty(named)){
+                hasNamed.setNamed(named);
+                hasNamed.setNamedEscaped(escaped);
+            }
+        }
+    }
+
+    protected void setPagedIfAny(
+            final CollectionLayoutData collectionLayoutData,
+            final FacetHolder facetHolder) {
+        final PagedFacet pagedFacet = facetHolder.getFacet(PagedFacet.class);
+        if(isDoOp(pagedFacet)) {
+            final int value = pagedFacet.value();
+            if(value > 0) {
+                collectionLayoutData.setPaged(value);
+            }
+        }
+    }
+
+    protected void setPluralIfAny(
+            final DomainObjectLayoutData domainObjectLayoutData,
+            final FacetHolder facetHolder) {
+        final PluralFacet pluralFacet = facetHolder.getFacet(PluralFacet.class);
+        if(isDoOp(pluralFacet)) {
+            final String plural = pluralFacet.value();
+            if(!Strings.isNullOrEmpty(plural)) {
+                domainObjectLayoutData.setPlural(plural);
+            }
+        }
+    }
+
+
+    protected void setActionPositionIfAny(
+            final ActionLayoutData actionLayoutData,
+            final FacetHolder facetHolder) {
+        final ActionPositionFacet actionPositionFacet = facetHolder.getFacet(ActionPositionFacet.class);
+        if(isDoOp(actionPositionFacet)) {
+            final ActionLayout.Position position = actionPositionFacet.position();
+            if(position != null) {
+                actionLayoutData.setPosition(position);
+            }
+        }
+    }
+
+    protected void setRenderedAsDayBeforeIfAny(
+            final PropertyLayoutData propertyLayoutData,
+            final FacetHolder facetHolder) {
+        final RenderedAdjustedFacet renderedAdjustedFacet = facetHolder.getFacet(RenderedAdjustedFacet.class);
+        if(isDoOp(renderedAdjustedFacet)) {
+            final int adjusted = renderedAdjustedFacet.value();
+            propertyLayoutData.setRenderedAsDayBefore(adjusted != 0);
+        }
+    }
+
+    protected void setSortedByIfAny(
+            final CollectionLayoutData collectionLayoutData,
+            final FacetHolder facetHolder) {
+        final SortedByFacet sortedByFacet = facetHolder.getFacet(SortedByFacet.class);
+        if(isDoOp(sortedByFacet)) {
+            final Class<? extends Comparator<?>> className = sortedByFacet.value();
+            if(className != null) {
+                collectionLayoutData.setSortedBy(className.getCanonicalName());
+            }
+        }
+    }
+
+    protected void setTypicalLengthIfAny(
+            final PropertyLayoutData propertyLayoutData,
+            final FacetHolder facetHolder) {
+        final TypicalLengthFacet typicalLengthFacet = facetHolder.getFacet(TypicalLengthFacet.class);
+        if(isDoOp(typicalLengthFacet)) {
+            final int typicalLength = typicalLengthFacet.value();
+            if(typicalLength > 0) {
+                propertyLayoutData.setTypicalLength(typicalLength);
+            }
+        }
+    }
+
+
     @Programmatic
     @Override
     public void minimal(final G grid, final Class<?> domainClass) {
-        // TODO: do some different logic here...
         normalize(grid, domainClass);
+        grid.visit(new FCGrid.VisitorAdapter() {
+            @Override
+            public void visit(final ActionLayoutData actionLayoutData) {
+                actionLayoutData.getOwner().getActions().remove(actionLayoutData);
+            }
+
+            @Override public void visit(final CollectionLayoutData collectionLayoutData) {
+                collectionLayoutData.getOwner().getCollections().remove(this);
+            }
+
+            @Override public void visit(final PropertyLayoutData propertyLayoutData) {
+                propertyLayoutData.getOwner().getProperties().remove(this);
+            }
+        });
     }
     /**
      * Ensures that all object members (properties, collections and actions) are in the metadata.