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/01/13 10:01:38 UTC

[4/5] isis git commit: ISIS-993: simplifying and finetuning.

ISIS-993: simplifying and finetuning.

- layout.json disabled completely if a layout.xml is discovered
- got rid of the enable/disable dynamic reloading, went back to checking deployment category for isProduction mode or not
- ObjectLayoutMetadataService caches bad XML and also maintains xml -> metadata map (non-prod mode only)
- blacklisting only applies if in non-prod mode
- combined getMetadata() and reloadMetadata()
- ensure that members are sorted correctly when in property groups (within their col / tab)
- set up service specifications as being markAsService eagerly, rather than later on.
- removing EntityCombinedPanelFactory, now use EntityTabGroupsPanelFactory for both cases.


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

Branch: refs/heads/ISIS-993
Commit: aa720f384003df11ff8e5e4b9c46b0166b5b7e56
Parents: 021711e
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Jan 13 01:50:17 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Jan 13 01:50:17 2016 +0000

----------------------------------------------------------------------
 .../layout/v1_0/ObjectLayoutMetadata.java       | 13 ++++
 .../layout/ObjectLayoutMetadataService.java     | 13 ++--
 .../isis/core/commons/lang/ClassExtensions.java |  5 ++
 .../ObjectLayoutMetadataFacet.java              |  7 --
 .../ObjectLayoutMetadataFacetDefault.java       | 52 +++++++-------
 .../ObjectLayoutMetadataFacetFactory.java       |  2 +-
 .../layoutmetadata/LayoutMetadataReader2.java   |  2 +-
 .../json/LayoutMetadataReaderFromJson.java      | 30 +++++++-
 .../ObjectLayoutMetadataServiceDefault.java     | 76 +++++++++++++++-----
 .../services/metamodel/MetadataMenu.java        | 43 -----------
 .../spec/feature/ObjectAssociation.java         |  5 ++
 .../specloader/ObjectReflectorDefault.java      | 18 ++++-
 .../specimpl/FacetedMethodsBuilder.java         |  5 +-
 .../dflt/ObjectSpecificationDefault.java        | 11 ---
 .../ComponentFactoryRegistrarDefault.java       |  2 -
 .../combined/EntityCombinedPanelFactory.java    | 52 --------------
 .../entity/tabgroups/EntityTabGroupsPanel.java  | 14 ----
 .../tabgroups/EntityTabGroupsPanelFactory.java  | 10 +--
 .../wicket/ui/pages/entity/EntityPage.java      | 20 +++---
 19 files changed, 176 insertions(+), 204 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
index 4af327c..727bba2 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/layout/v1_0/ObjectLayoutMetadata.java
@@ -251,4 +251,17 @@ public class ObjectLayoutMetadata implements Dto, ActionHolder, Serializable {
     }
 
 
+    private boolean normalized;
+
+    @Programmatic
+    @XmlTransient
+    public boolean isNormalized() {
+        return normalized;
+    }
+
+    @Programmatic
+    public void setNormalized(final boolean normalized) {
+        this.normalized = normalized;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java b/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
index e29ff47..1de0147 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/ObjectLayoutMetadataService.java
@@ -22,7 +22,13 @@ import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
 public interface ObjectLayoutMetadataService {
 
     /**
-     * Returns raw (unnormalized) metadata, per the <code>.layout.xml</code> file.
+     * Whether any metadata exists for this domain class, and if so then whether it is valid or invalid.
+     */
+    @Programmatic
+    boolean exists(Class<?> domainClass);
+
+    /**
+     * Returns raw (unnormalized) metadata, eg per the <code>.layout.xml</code> file.
      */
     @Programmatic
     ObjectLayoutMetadata fromXml(Class<?> domainClass);
@@ -39,10 +45,5 @@ public interface ObjectLayoutMetadataService {
     @Programmatic
     ObjectLayoutMetadata toMetadata(Class<?> domainClass);
 
-    @Programmatic
-    void toggleDynamicReloading();
-
-    @Programmatic
-    boolean isDynamicReloading();
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java
index 5f6983d..01ce5ca 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassExtensions.java
@@ -174,6 +174,11 @@ public final class ClassExtensions {
         return Resources.toString(url, Charset.defaultCharset());
     }
 
+    public static boolean exists(final Class<?> cls, final String resourceName) {
+        final URL url = Resources.getResource(cls, resourceName);
+        return url != null;
+    }
+
     public static Class<?> asWrapped(final Class<?> primitiveClassExtendee) {
         return ClassUtil.wrapperClasses.get(primitiveClassExtendee);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
index 2a63428..eb7efcd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacet.java
@@ -27,14 +27,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
  */
 public interface ObjectLayoutMetadataFacet extends Facet {
 
-    /**
-     * Will have been normalized by framework earlier.
-     */
     ObjectLayoutMetadata getMetadata();
 
-    /**
-     * (Re)load, in support of dynamic layout reloading.
-     */
-    void reloadMetadata();
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
index 9538e72..fdc12ef 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetDefault.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
@@ -42,6 +43,7 @@ import org.apache.isis.applib.layout.v1_0.Tab;
 import org.apache.isis.applib.layout.v1_0.TabGroup;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
+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;
@@ -93,59 +95,57 @@ public class ObjectLayoutMetadataFacetDefault
     public static ObjectLayoutMetadataFacet create(
             final FacetHolder facetHolder,
             final TranslationService translationService,
-            final ObjectLayoutMetadataService objectLayoutMetadataService) {
-        return new ObjectLayoutMetadataFacetDefault(facetHolder, translationService, objectLayoutMetadataService);
+            final ObjectLayoutMetadataService objectLayoutMetadataService,
+            final DeploymentCategory deploymentCategory) {
+        return new ObjectLayoutMetadataFacetDefault(facetHolder, translationService, objectLayoutMetadataService, deploymentCategory);
     }
 
     private final TranslationService translationService;
+    private final DeploymentCategory deploymentCategory;
     private final ObjectLayoutMetadataService objectLayoutMetadataService;
 
-    private boolean blacklisted;
     private ObjectLayoutMetadata metadata;
+    private boolean blacklisted;
 
     private ObjectLayoutMetadataFacetDefault(
             final FacetHolder facetHolder,
             final TranslationService translationService,
-            final ObjectLayoutMetadataService objectLayoutMetadataService) {
+            final ObjectLayoutMetadataService objectLayoutMetadataService,
+            final DeploymentCategory deploymentCategory) {
         super(ObjectLayoutMetadataFacetDefault.type(), facetHolder, Derivation.NOT_DERIVED);
         this.objectLayoutMetadataService = objectLayoutMetadataService;
         this.translationService = translationService;
+        this.deploymentCategory = deploymentCategory;
     }
 
-    @Override
-    public boolean isNoop() {
-        getMetadata();
-        return blacklisted;
-    }
-
+    /**
+     * Blacklisting only occurs if running in production mode.
+     */
     @Override
     public ObjectLayoutMetadata getMetadata() {
-        if(blacklisted) {
-            return null;
-        }
-        reloadMetadata();
-        return this.metadata;
-    }
-
-    @Override
-    public void reloadMetadata() {
-        if (metadata != null && !objectLayoutMetadataService.isDynamicReloading()) {
-            return;
+        if (deploymentCategory.isProduction() || blacklisted) {
+            return metadata;
         }
         final Class<?> domainClass = getSpecification().getCorrespondingClass();
         final ObjectLayoutMetadata metadata = objectLayoutMetadataService.fromXml(domainClass);
+        if(deploymentCategory.isProduction() && metadata == null) {
+            blacklisted = true;
+        }
         this.metadata = normalize(metadata);
-        blacklisted = this.metadata == null;
+        return this.metadata;
     }
 
     private ObjectLayoutMetadata normalize(final ObjectLayoutMetadata metadata) {
         if(metadata == null) {
             return null;
         }
-        if(LOG.isInfoEnabled()) {
-            LOG.info("Normalizing layout metadata for " + getSpecification().getCorrespondingClass().getName());
-        }
+        // if have .layout.json and then add a .layout.xml without restarting, then the normalizing is required
+        // in order to trample over the .layout.json's original facets.
+        // if(metadata.isNormalized()) {
+        //     return metadata;
+        // }
         doNormalize(metadata, getSpecification());
+        metadata.setNormalized(true);
         return metadata;
     }
 
@@ -424,7 +424,7 @@ public class ObjectLayoutMetadataFacetDefault
                 final ColumnHolder holder = column.getOwner();
                 if(holder instanceof Tab) {
                     final Tab tab = (Tab) holder;
-                    if(tab.getContents().size() == 1) {
+                    if(tab.getContents().size() == 1 && Strings.isNullOrEmpty(tab.getName()) ) {
                         final String collectionName = oneToManyAssociation.getName();
                         tab.setName(collectionName);
                     }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
index 479849c..28c69e6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/layoutmetadata/ObjectLayoutMetadataFacetFactory.java
@@ -44,7 +44,7 @@ public class ObjectLayoutMetadataFacetFactory extends FacetFactoryAbstract imple
         final ObjectLayoutMetadataService objectLayoutMetadataService = servicesInjector.lookupService(ObjectLayoutMetadataService.class);
         FacetUtil.addFacet(
                 ObjectLayoutMetadataFacetDefault.create(facetHolder,
-                        translationService, objectLayoutMetadataService));
+                        translationService, objectLayoutMetadataService, getDeploymentCategory()));
     }
 
     private ServicesInjector servicesInjector;

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java
index 533d13a..0df1fea 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/layoutmetadata/LayoutMetadataReader2.java
@@ -18,7 +18,7 @@ package org.apache.isis.core.metamodel.layoutmetadata;
 
 public interface LayoutMetadataReader2 extends LayoutMetadataReader {
 
-    public static class Support {
+    class Support {
 
         public static Support entitiesOnly() {
             return new Support(false,false,false,false,false,false,false);

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/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 0a29c6f..5c5c039 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
@@ -43,6 +43,7 @@ import org.apache.isis.applib.annotation.Render.Type;
 import org.apache.isis.applib.annotation.When;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
 import org.apache.isis.core.commons.lang.ClassExtensions;
 import org.apache.isis.core.metamodel.facets.all.describedas.DescribedAsFacet;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
@@ -78,6 +79,8 @@ import org.apache.isis.core.metamodel.layoutmetadata.PagedFacetRepr;
 import org.apache.isis.core.metamodel.layoutmetadata.PropertyLayoutFacetRepr;
 import org.apache.isis.core.metamodel.layoutmetadata.RenderFacetRepr;
 import org.apache.isis.core.metamodel.layoutmetadata.TypicalLengthFacetRepr;
+import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+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;
@@ -86,7 +89,7 @@ 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;
 
-public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 {
+public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2, ServicesInjectorAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(LayoutMetadataReaderFromJson.class);
 
@@ -411,6 +414,17 @@ public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 {
             return null;
         }
 
+        try {
+            final ObjectLayoutMetadataService objectLayoutMetadataService = getObjectLayoutMetadataService();
+            if(objectLayoutMetadataService.exists(domainClass)) {
+                blacklisted.add(domainClass);
+                return null;
+            }
+        } catch (IllegalArgumentException ex) {
+            // ignore
+        }
+
+
         final String resourceName = domainClass.getSimpleName() + ".layout.json";
         try {
             content = ClassExtensions.resourceContentOf(domainClass, resourceName);
@@ -683,4 +697,18 @@ public class LayoutMetadataReaderFromJson implements LayoutMetadataReader2 {
         return getClass().getName();
     }
 
+
+
+    private ObjectLayoutMetadataService getObjectLayoutMetadataService() {
+        return servicesInjector.lookupService(ObjectLayoutMetadataService.class);
+    }
+
+
+    private ServicesInjector servicesInjector;
+
+    @Override
+    public void setServicesInjector(final ServicesInjector servicesInjector) {
+        this.servicesInjector = servicesInjector;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
index 35010c2..f2861b8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/layout/ObjectLayoutMetadataServiceDefault.java
@@ -19,11 +19,12 @@ package org.apache.isis.core.metamodel.services.layout;
 import java.io.IOException;
 import java.net.URL;
 import java.nio.charset.Charset;
-import java.util.Set;
+import java.util.Map;
+import java.util.Objects;
 
 import javax.inject.Inject;
 
-import com.google.common.collect.Sets;
+import com.google.common.collect.Maps;
 import com.google.common.io.Resources;
 
 import org.slf4j.Logger;
@@ -35,6 +36,8 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
 import org.apache.isis.applib.services.jaxb.JaxbService;
 import org.apache.isis.applib.services.layout.ObjectLayoutMetadataService;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategoryAware;
 import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.SpecificationLoader;
@@ -42,15 +45,29 @@ import org.apache.isis.core.metamodel.spec.SpecificationLoaderAware;
 
 @DomainService(nature = NatureOfService.DOMAIN)
 public class ObjectLayoutMetadataServiceDefault
-        implements ObjectLayoutMetadataService, SpecificationLoaderAware {
+        implements ObjectLayoutMetadataService, SpecificationLoaderAware, DeploymentCategoryAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(ObjectLayoutMetadataServiceDefault.class);
 
+    // for better logging messages (used only in prototyping mode)
+    private final Map<Class<?>, String> badXmlByClass = Maps.newHashMap();
+
+    // cache (used only in prototyping mode)
+    private final Map<String, ObjectLayoutMetadata> metadataByXml = Maps.newHashMap();
+
+    @Override
+    @Programmatic
+    public boolean exists(final Class<?> domainClass) {
+        final URL resource = Resources.getResource(domainClass, resourceNameFor(domainClass));
+        return resource != null;
+    }
+
+    @Override
     @Programmatic
     public ObjectLayoutMetadata fromXml(Class<?> domainClass) {
 
+        final String resourceName = resourceNameFor(domainClass);
         final String xml;
-        final String resourceName = domainClass.getSimpleName() + ".layout.xml";
         try {
             xml = resourceContentOf(domainClass, resourceName);
         } catch (IOException | IllegalArgumentException ex) {
@@ -63,11 +80,39 @@ public class ObjectLayoutMetadataServiceDefault
             return null;
         }
 
+
+        if(!deploymentCategory.isProduction()) {
+            final ObjectLayoutMetadata objectLayoutMetadata = metadataByXml.get(xml);
+            if(objectLayoutMetadata != null) {
+                return objectLayoutMetadata;
+            }
+
+            final String badXml = badXmlByClass.get(domainClass);
+            if(badXml != null) {
+                if(Objects.equals(xml, badXml)) {
+                    // seen this before and already logged; just quit
+                    return null;
+                } else {
+                    // this different XML might be good
+                    badXmlByClass.remove(domainClass);
+                }
+            }
+
+        }
+
         try {
             final ObjectLayoutMetadata metadata = jaxbService.fromXml(ObjectLayoutMetadata.class, xml);
+            if(!deploymentCategory.isProduction()) {
+                metadataByXml.put(xml, metadata);
+            }
             return metadata;
         } catch(Exception ex) {
 
+            if(!deploymentCategory.isProduction()) {
+                // save fact that this was bad XML, so that we don't log again if called next time
+                badXmlByClass.put(domainClass, xml);
+            }
+
             // note that we don't blacklist if the file exists but couldn't be parsed;
             // the developer might fix so we will want to retry.
             final String message = "Failed to parse " + resourceName + " file (" + ex.getMessage() + ")";
@@ -82,9 +127,13 @@ public class ObjectLayoutMetadataServiceDefault
         return Resources.toString(url, Charset.defaultCharset());
     }
 
+    private String resourceNameFor(final Class<?> domainClass) {
+        return domainClass.getSimpleName() + ".layout.xml";
+    }
 
 
     @Override
+    @Programmatic
     public ObjectLayoutMetadata toMetadata(final Object domainObject) {
         return toMetadata(domainObject.getClass());
     }
@@ -98,17 +147,6 @@ public class ObjectLayoutMetadataServiceDefault
 
     ////////////////////////////////////////////////////////
 
-    private boolean dynamicReloading;
-
-    @Override
-    public void toggleDynamicReloading() {
-        this.dynamicReloading = !this.dynamicReloading;
-    }
-
-    @Override
-    public boolean isDynamicReloading() {
-        return this.dynamicReloading;
-    }
 
     //region > injected dependencies
 
@@ -119,10 +157,16 @@ public class ObjectLayoutMetadataServiceDefault
         this.specificationLookup = specificationLookup;
     }
 
+    private DeploymentCategory deploymentCategory;
+
+    @Override
+    public void setDeploymentCategory(final DeploymentCategory deploymentCategory) {
+        this.deploymentCategory = deploymentCategory;
+    }
+
     @Inject
     JaxbService jaxbService;
 
-
     //endregion
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/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 900ecc3..cc05eca 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
@@ -130,49 +130,6 @@ public class MetadataMenu implements SpecificationLoaderSpiAware {
     }
 
 
-    // //////////////////////////////////////
-
-    public static class SwitchOnDynamicReloadingOfLayoutsDomainEvent extends ActionDomainEvent {
-    }
-
-    @Action(
-            domainEvent = SwitchOnDynamicReloadingOfLayoutsDomainEvent.class,
-            semantics = SemanticsOf.SAFE,
-            restrictTo = RestrictTo.PROTOTYPING
-    )
-    @ActionLayout(
-            cssClassFa = "fa-check"
-    )
-    @MemberOrder(sequence="500.400.2")
-    public void switchOnDynamicReloadingOfLayouts() {
-        objectLayoutMetadataService.toggleDynamicReloading();
-    }
-    public boolean hideSwitchOnDynamicReloadingOfLayouts() {
-        return objectLayoutMetadataService.isDynamicReloading();
-    }
-
-    // //////////////////////////////////////
-
-    public static class SwitchOffDynamicReloadingOfLayoutsDomainEvent extends ActionDomainEvent {
-    }
-
-    @Action(
-            domainEvent = SwitchOffDynamicReloadingOfLayoutsDomainEvent.class,
-            semantics = SemanticsOf.SAFE,
-            restrictTo = RestrictTo.PROTOTYPING
-    )
-    @ActionLayout(
-            cssClassFa = "fa-times"
-    )
-    @MemberOrder(sequence="500.400.3")
-    public void switchOffDynamicReloadingOfLayouts() {
-        objectLayoutMetadataService.toggleDynamicReloading();
-    }
-    public boolean hideSwitchOffDynamicReloadingOfLayouts() {
-        return !objectLayoutMetadataService.isDynamicReloading();
-    }
-
-
 
     // //////////////////////////////////////
 

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
index 8837916..9c87476 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.metamodel.spec.feature;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -38,6 +39,7 @@ import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
 import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
 import org.apache.isis.core.metamodel.facets.object.membergroups.MemberGroupLayoutFacet;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
 import org.apache.isis.core.metamodel.specloader.specimpl.ContributeeMember;
 
 /**
@@ -405,6 +407,9 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
             for(ObjectAssociation association: associations) {
                 addAssociationIntoGroup(associationsByGroup, association);
             }
+            for (Map.Entry<String, List<ObjectAssociation>> objectAssociations : associationsByGroup.entrySet()) {
+                Collections.sort(objectAssociations.getValue(), new MemberOrderComparator(true));
+            }
             return associationsByGroup;
         }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
index 5f4c0d1..2957dd7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/ObjectReflectorDefault.java
@@ -245,6 +245,9 @@ public final class ObjectReflectorDefault
 
         // wire subcomponents into each other
         this.runtimeContext.injectInto(facetProcessor);
+        for (final LayoutMetadataReader layoutMetadataReader : layoutMetadataReaders) {
+            this.runtimeContext.injectInto(layoutMetadataReader);
+        }
 
         // initialize subcomponents
         facetDecoratorSet.init();
@@ -261,12 +264,13 @@ public final class ObjectReflectorDefault
             final DomainService domainService = serviceClass.getAnnotation(DomainService.class);
             if(domainService != null) {
                 if(domainService.nature() == NatureOfService.VIEW || domainService.nature() == NatureOfService.VIEW_CONTRIBUTIONS_ONLY) {
-                    internalLoadSpecification(serviceClass);
+                    internalLoadSpecification(serviceClass, domainService.nature());
                 }
             }
         }
     }
 
+
     private void loadSpecificationsForMixins() {
         final Set<Class<?>> mixinTypes = AppManifest.Registry.instance().getMixinTypes();
         if(mixinTypes == null) {
@@ -390,11 +394,16 @@ public final class ObjectReflectorDefault
     }
 
     private ObjectSpecification internalLoadSpecification(final Class<?> type) {
+        return internalLoadSpecification(type, null);
+    }
+
+    private ObjectSpecification internalLoadSpecification(final Class<?> type, final NatureOfService nature) {
         final Class<?> substitutedType = classSubstitutor.getClass(type);
-        return substitutedType != null ? loadSpecificationForSubstitutedClass(substitutedType) : null;
+        return substitutedType != null ? loadSpecificationForSubstitutedClass(substitutedType, nature) : null;
     }
 
-    private ObjectSpecification loadSpecificationForSubstitutedClass(final Class<?> type) {
+
+    private ObjectSpecification loadSpecificationForSubstitutedClass(final Class<?> type, final NatureOfService nature) {
         Assert.assertNotNull(type);
         final String typeName = type.getName();
 
@@ -405,6 +414,9 @@ public final class ObjectReflectorDefault
                 return spec;
             }
             final ObjectSpecification specification = createSpecification(type);
+            if(nature != null) {
+                specification.markAsService();
+            }
             if (specification == null) {
                 throw new IsisException("Failed to create specification for class " + typeName);
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index a6e71df..b5a1605 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@ -40,7 +40,6 @@ import org.apache.isis.core.commons.lang.ListExtensions;
 import org.apache.isis.core.commons.lang.MethodUtil;
 import org.apache.isis.core.commons.util.ToString;
 import org.apache.isis.core.metamodel.exceptions.MetaModelException;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facetapi.MethodRemover;
 import org.apache.isis.core.metamodel.facets.FacetFactory;
@@ -49,7 +48,6 @@ import org.apache.isis.core.metamodel.facets.FacetedMethod;
 import org.apache.isis.core.metamodel.facets.FacetedMethodParameter;
 import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.object.facets.FacetsFacet;
-import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet;
 import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
 import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader.ReaderException;
 import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader2;
@@ -116,7 +114,7 @@ public class FacetedMethodsBuilder {
         }
     }
 
-    private final FacetHolder spec;
+    private final ObjectSpecificationAbstract spec;
 
     private final Class<?> introspectedClass;
     private final List<Method> methods;
@@ -197,7 +195,6 @@ public class FacetedMethodsBuilder {
         // process facets at object level
         // this will also remove some methods, such as the superclass methods.
 
-        final ObjectLayoutMetadataFacet facet = spec.getFacet(ObjectLayoutMetadataFacet.class);
         final Properties metadataProperties = readMetadataProperties(introspectedClass);
 
         getFacetProcessor().process(introspectedClass, metadataProperties, methodRemover, spec);

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index afd556e..65448e9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -264,19 +264,8 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
         return isService;
     }
 
-    /**
-     * TODO: should ensure that service has at least one user action; fix when
-     * specification knows of its hidden methods.
-     * 
-     * <pre>
-     * if (objectActions != null &amp;&amp; objectActions.length == 0) {
-     *     throw new ObjectSpecificationException(&quot;Service object &quot; + getFullName() + &quot; should have at least one user action&quot;);
-     * }
-     * </pre>
-     */
     @Override
     public void markAsService() {
-        ensureServiceHasNoAssociations();
         isService = true;
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index befd252..3cf6308 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -40,7 +40,6 @@ import org.apache.isis.viewer.wicket.ui.components.collectioncontents.summary.Co
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.empty.EmptyCollectionPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.collections.EntityCollectionsPanelFactory;
-import org.apache.isis.viewer.wicket.ui.components.entity.combined.EntityCombinedPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.header.EntityHeaderPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconAndTitlePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.entity.icontitle.EntityIconTitleAndCopyLinkPanelFactory;
@@ -168,7 +167,6 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
 
         // top-level
         componentFactories.add(new EntityTabGroupsPanelFactory());
-        componentFactories.add(new EntityCombinedPanelFactory());
 
         // lower-level
         componentFactories.add(new EntityIconAndTitlePanelFactory());

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
deleted file mode 100644
index 004ba23..0000000
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/combined/EntityCombinedPanelFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.viewer.wicket.ui.components.entity.combined;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
-
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.ui.ComponentFactory;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.entity.EntityComponentFactoryAbstract;
-
-/**
- * {@link ComponentFactory} for {@link EntityCombinedPanel}.
- */
-public class EntityCombinedPanelFactory extends EntityComponentFactoryAbstract {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final String NAME = "combined";
-
-    public EntityCombinedPanelFactory() {
-        super(ComponentType.ENTITY, NAME, EntityCombinedPanel.class);
-    }
-
-    @Override
-    protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) {
-        return appliesIf(false); // TODO: remove
-    }
-
-    @Override
-    public Component createComponent(final String id, final IModel<?> model) {
-        throw new IllegalStateException("shouldn't be called"); // TODO: remove
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java
index 0889e1a..6b274a5 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanel.java
@@ -21,10 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.entity.tabgroups;
 
 import java.util.List;
 
-import javax.xml.bind.Marshaller;
-
 import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
@@ -37,8 +34,6 @@ import org.apache.wicket.model.Model;
 import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
 import org.apache.isis.applib.layout.v1_0.Tab;
 import org.apache.isis.applib.layout.v1_0.TabGroup;
-import org.apache.isis.applib.services.jaxb.JaxbService;
-import org.apache.isis.applib.services.layout.Object_downloadLayoutXml;
 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.layoutmetadata.ObjectLayoutMetadataFacet;
@@ -80,15 +75,6 @@ public class EntityTabGroupsPanel extends PanelAbstract<EntityModel> {
         final ObjectLayoutMetadata objectLayoutMetadata = objectLayoutMetadataFacet.getMetadata();
 
 
-        // TODO: debugging, remove
-        final JaxbService jaxbService = getServicesInjector().lookupService(JaxbService.class);
-        final String xml = jaxbService.toXml(objectLayoutMetadata,
-                ImmutableMap.<String,Object>of(
-                        Marshaller.JAXB_SCHEMA_LOCATION,
-                        Object_downloadLayoutXml.TNS + " " + Object_downloadLayoutXml.SCHEMA_LOCATION));
-        System.out.println(xml);
-
-
         addOrReplace(ComponentType.ENTITY_SUMMARY, model);
 
         final List<TabGroup> tabGroups = FluentIterable

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java
index d602730..722f98b 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/tabgroups/EntityTabGroupsPanelFactory.java
@@ -22,6 +22,7 @@ package org.apache.isis.viewer.wicket.ui.components.entity.tabgroups;
 import org.apache.wicket.Component;
 import org.apache.wicket.model.IModel;
 
+import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
 import org.apache.isis.core.metamodel.facets.object.layoutmetadata.ObjectLayoutMetadataFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
@@ -44,19 +45,14 @@ public class EntityTabGroupsPanelFactory extends EntityComponentFactoryAbstract
     }
 
     @Override
-    protected ApplicationAdvice doAppliesTo(final EntityModel entityModel) {
-        return super.doAppliesTo(entityModel); // TODO: remove this override
-    }
-
-    @Override
     public Component createComponent(final String id, final IModel<?> model) {
 
         final EntityModel entityModel = (EntityModel) model;
 
         final ObjectSpecification specification = entityModel.getTypeOfSpecification();
         final ObjectLayoutMetadataFacet facet = specification.getFacet(ObjectLayoutMetadataFacet.class);
-        facet.reloadMetadata();
-        final boolean hasLayout = !facet.isNoop();
+        final ObjectLayoutMetadata layoutMetadata = facet.getMetadata();
+        final boolean hasLayout = layoutMetadata != null;
         return hasLayout
                 ? new EntityTabGroupsPanel(id, entityModel)
                 : new EntityCombinedPanel(id, entityModel);

http://git-wip-us.apache.org/repos/asf/isis/blob/aa720f38/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
index 609be99..b104ac3 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/entity/EntityPage.java
@@ -29,6 +29,7 @@ import org.apache.wicket.model.AbstractReadOnlyModel;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.string.Strings;
 
+import org.apache.isis.applib.layout.v1_0.ObjectLayoutMetadata;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
@@ -138,16 +139,15 @@ public class EntityPage extends PageAbstract {
         final ObjectLayoutMetadataFacet facet = entityModel.getTypeOfSpecification()
                 .getFacet(ObjectLayoutMetadataFacet.class);
         if(facet != null) {
-            // the facet should always exist
-            //
-            // it's sufficient to simply call reloadMetadata().
-            // The facet checks the ObjectLayoutMetadataService to determine if dynamic reloading is enabled.
-            facet.reloadMetadata();
-            if(facet.getMetadata() == null) {
-                // fallback to invalidating entire cache
-                if(!getDeploymentType().isProduction()) {
-                    getSpecificationLoader().invalidateCacheFor(objectAdapter.getObject());
-                }
+            // the facet should always exist, in fact
+            // just enough to ask for the metadata.
+            // This will cause the current ObjectSpec to be updated as a side effect.
+            final ObjectLayoutMetadata metadata = facet.getMetadata();
+
+            // if none, then fallback to invalidating entire cache
+            // (this is the original LayoutMetadataFromJson behaviour)
+            if(metadata == null && !getDeploymentType().isProduction()) {
+                getSpecificationLoader().invalidateCacheFor(objectAdapter.getObject());
             }
         }