You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/04/07 08:15:30 UTC

[isis] branch master updated: ISIS-2994: further remove direct uses of facets in RO

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0bc7328f32 ISIS-2994: further remove direct uses of facets in RO
0bc7328f32 is described below

commit 0bc7328f32c66d19c7ee3f27256955b65622d901
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Apr 7 10:15:22 2022 +0200

    ISIS-2994: further remove direct uses of facets in RO
---
 .../facets/collections/CollectionFacet.java        |  3 +-
 .../metamodel/facets/object/grid/GridFacet.java    |  4 +-
 .../specloader/specimpl/ObjectActionDefault.java   |  6 +--
 .../apache/isis/core/metamodel/util/Facets.java    | 29 +++++++++++++-
 ...entNegotiationServiceForRestfulObjectsV1_0.java | 23 ++++-------
 .../service/swagger/internal/Generation.java       | 44 ++++++++--------------
 .../rendering/service/swagger/internal/_Util.java  | 15 +++-----
 .../resources/DomainObjectResourceServerside.java  | 20 ++++------
 .../resources/DomainTypeResourceServerside.java    |  5 +--
 9 files changed, 70 insertions(+), 79 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/CollectionFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/CollectionFacet.java
index 0610a1abb7..9229b33f5d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/CollectionFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/CollectionFacet.java
@@ -107,8 +107,7 @@ public interface CollectionFacet extends Facet {
         if(container==null) {
             return Optional.empty();
         }
-        val collectionSpec = container.getSpecification();
-        return Optional.ofNullable(collectionSpec.getFacet(CollectionFacet.class));
+        return container.getSpecification().lookupFacet(CollectionFacet.class);
     }
 
     public static int elementCount(@Nullable final ManagedObject container) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacet.java
index 1363babc27..9ad05c0b2e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/grid/GridFacet.java
@@ -18,6 +18,8 @@
  */
 package org.apache.isis.core.metamodel.facets.object.grid;
 
+import org.springframework.lang.Nullable;
+
 import org.apache.isis.applib.layout.grid.Grid;
 import org.apache.isis.applib.services.grid.GridSystemService;
 import org.apache.isis.applib.services.layout.LayoutService;
@@ -35,7 +37,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
  */
 public interface GridFacet extends Facet {
 
-    Grid getGrid(final ManagedObject objectAdapter);
+    Grid getGrid(@Nullable ManagedObject objectAdapter);
 
 
 }
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index e43bff05c1..b8b1a59094 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -41,7 +41,6 @@ import org.apache.isis.core.metamodel.consent.InteractionResultSet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facets.FacetedMethod;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacet;
 import org.apache.isis.core.metamodel.facets.actions.prototype.PrototypeFacet;
 import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFacet;
@@ -59,6 +58,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.util.Facets;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 
 import lombok.Getter;
@@ -112,9 +112,7 @@ implements ObjectAction {
             return;
         }
 
-        elementType = getFacetedMethod()
-                .lookupFacet(TypeOfFacet.class)
-                .map(TypeOfFacet::valueSpec)
+        elementType = Facets.typeOf(getFacetedMethod())
                 .orElseGet(()->{
                     val returnType = getReturnType();
                     if(!returnType.isScalar()) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
index 8ea2391a69..ecbe6668a6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
@@ -35,14 +35,17 @@ import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
 import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
 import org.apache.isis.core.metamodel.facets.collections.collection.defaultview.DefaultViewFacet;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
 import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import org.apache.isis.core.metamodel.facets.object.bookmarkpolicy.BookmarkPolicyFacet;
+import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceFacet;
 import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.facets.object.icon.IconFacet;
+import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacet;
 import org.apache.isis.core.metamodel.facets.object.projection.ProjectionFacet;
 import org.apache.isis.core.metamodel.facets.object.promptStyle.PromptStyleFacet;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
@@ -97,17 +100,29 @@ public final class Facets {
     }
 
     public Optional<BSGrid> bootstrapGrid(
-            final ObjectSpecification objectSpec, final ManagedObject objectAdapter) {
+            final ObjectSpecification objectSpec, final @Nullable ManagedObject objectAdapter) {
         return objectSpec.lookupFacet(GridFacet.class)
         .map(gridFacet->gridFacet.getGrid(objectAdapter))
         .flatMap(grid->_Casts.castTo(BSGrid.class, grid));
     }
 
+    public Optional<BSGrid> bootstrapGrid(final ObjectSpecification objectSpec) {
+        return bootstrapGrid(objectSpec, null);
+    }
+
     //XXX could be moved to ManagedObject directly, there be an utility already under a different name
     public Stream<ManagedObject> collectionStream(final @Nullable ManagedObject collection) {
         return CollectionFacet.streamAdapters(collection);
     }
 
+    // used for non-scalar action return
+    public Stream<ManagedObject> collectionStream(
+            final ObjectSpecification objectSpec, final @Nullable ManagedObject collection) {
+        return objectSpec.lookupFacet(CollectionFacet.class)
+        .map(collectionFacet->collectionFacet.stream(collection))
+        .orElseGet(Stream::empty);
+    }
+
     public Optional<String> cssClassFor(
             final FacetHolder objectSpec, final ManagedObject objectAdapter) {
         return objectSpec.lookupFacet(CssClassFacet.class)
@@ -228,6 +243,11 @@ public final class Facets {
         .orElse(fallback);
     }
 
+    public Optional<ObjectSpecification> typeOf(final FacetHolder facetHolder) {
+        return facetHolder.lookupFacet(TypeOfFacet.class)
+        .map(TypeOfFacet::valueSpec);
+    }
+
     public OptionalInt typicalLength(
             final ObjectSpecification objectSpec, final OptionalInt maxLength) {
         val typicalLength = objectSpec
@@ -249,6 +269,13 @@ public final class Facets {
         return objectSpec.containsFacet(ValueFacet.class);
     }
 
+    public boolean domainServiceIsPresent(final ObjectSpecification objectSpec) {
+        return objectSpec.containsFacet(DomainServiceFacet.class);
+    }
+
+    public boolean mixinIsPresent(final ObjectSpecification objectSpec) {
+        return objectSpec.containsFacet(MixinFacet.class);
+    }
 
 
 }
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 34bfb123a8..b2353bcd66 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -36,14 +36,13 @@ import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.domain.DomainObjectList;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
-import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedCollection;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.metamodel.util.Facets;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse;
@@ -208,7 +207,8 @@ implements ContentNegotiationService {
             final Collection<ManagedObject> collectionAdapters = objectAdaptersFrom(objectAndActionInvocation);
 
             if(collectionAdapters != null) {
-                final ObjectSpecification elementSpec = elementSpecFrom(objectAndActionInvocation);
+                final ObjectSpecification elementSpec =
+                        objectAndActionInvocation.getAction().getElementType();
                 final ObjectSpecification actionOwnerSpec = actionOwnerSpecFrom(objectAndActionInvocation);
                 final String actionId = actionIdFrom(objectAndActionInvocation);
                 final String actionArguments = actionArgumentsFrom(objectAndActionInvocation);
@@ -334,21 +334,12 @@ implements ContentNegotiationService {
         return title;
     }
 
-    private ObjectSpecification elementSpecFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
-        final TypeOfFacet typeOfFacet = objectAndActionInvocation.getAction().getFacet(TypeOfFacet.class);
-        return typeOfFacet != null
-                ? typeOfFacet.valueSpec()
-                : specificationLoader.specForType(Object.class).orElse(null);
-    }
-
     private Collection<ManagedObject> objectAdaptersFrom(final ObjectAndActionInvocation objectAndActionInvocation) {
-        final ManagedObject returnedAdapter = objectAndActionInvocation.getReturnedAdapter();
-        final ObjectSpecification returnType = objectAndActionInvocation.getAction().getReturnType();
+        val returnedAdapter = objectAndActionInvocation.getReturnedAdapter();
+        val returnTypeSpec = objectAndActionInvocation.getAction().getReturnType();
 
-        final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
-        return collectionFacet != null
-                ? collectionFacet.stream(returnedAdapter).collect(Collectors.toList())
-                : null;
+        return Facets.collectionStream(returnTypeSpec, returnedAdapter)
+                .collect(Collectors.toList());
     }
 
     /**
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
index dcb5716263..56f28b4974 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/Generation.java
@@ -33,10 +33,7 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.swagger.Visibility;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceFacet;
-import org.apache.isis.core.metamodel.facets.object.logicaltype.LogicalTypeFacet;
-import org.apache.isis.core.metamodel.facets.object.mixin.MixinFacet;
 import org.apache.isis.core.metamodel.services.ServiceUtil;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
@@ -45,6 +42,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.metamodel.util.Facets;
 
 import lombok.val;
 
@@ -184,15 +182,12 @@ class Generation {
         // but this is now done by SpecificationLoader itself)
         for (final ObjectSpecification objectSpec : specificationLoader.snapshotSpecifications()) {
 
-            final DomainServiceFacet domainServiceFacet = objectSpec.getFacet(DomainServiceFacet.class);
-            if (domainServiceFacet != null) {
+            if(Facets.domainServiceIsPresent(objectSpec)
+                    || Facets.mixinIsPresent(objectSpec)) {
                 continue;
             }
-            final MixinFacet mixinFacet = objectSpec.getFacet(MixinFacet.class);
-            if (mixinFacet != null) {
-                continue;
-            }
-            if(visibility.isPublic() && !_Util.isVisibleForPublic(objectSpec)) {
+            if(visibility.isPublic()
+                    && !_Util.isVisibleForPublic(objectSpec)) {
                 continue;
             }
             if(objectSpec.isAbstract()) {
@@ -210,7 +205,8 @@ class Generation {
             final List<OneToManyAssociation> objectCollections = _Util.collectionsOf(objectSpec, visibility);
             final List<ObjectAction> objectActions = _Util.actionsOf(objectSpec, visibility, classExcluder);
 
-            if(objectProperties.isEmpty() && objectCollections.isEmpty()) {
+            if(objectProperties.isEmpty()
+                    && objectCollections.isEmpty()) {
                 continue;
             }
             final ModelImpl isisModel = appendObjectPathAndModelDefinitions(objectSpec);
@@ -638,16 +634,9 @@ class Generation {
     }
 
     Property actionReturnTypeFor(final ObjectAction objectAction) {
-
-        final ObjectSpecification specification = objectAction.getReturnType();
-        TypeOfFacet typeOfFacet = objectAction.getFacet(TypeOfFacet.class);
-        if(typeOfFacet != null) {
-            ObjectSpecification elementSpec = typeOfFacet.valueSpec();
-            if(elementSpec != null) {
-                return arrayPropertyOf(elementSpec);
-            }
-        }
-        return modelFor(specification);
+        return objectAction.getReturnType().isNonScalar()
+                ? arrayPropertyOf(objectAction.getElementType())
+                : modelFor(objectAction.getReturnType());
     }
 
     private Property modelFor(final OneToManyAssociation collection) {
@@ -685,12 +674,9 @@ class Generation {
         }
 
         if(specification.isNonScalar()) {
-            TypeOfFacet typeOfFacet = specification.getFacet(TypeOfFacet.class);
-            if(typeOfFacet != null) {
-                ObjectSpecification elementSpec = typeOfFacet.valueSpec();
-                if(elementSpec != null) {
-                    return arrayPropertyOf(elementSpec);
-                }
+            val elementSpec = Facets.typeOf(specification).orElse(null);
+            if(elementSpec != null) {
+                return arrayPropertyOf(elementSpec);
             }
         }
 
@@ -773,7 +759,7 @@ class Generation {
     }
 
     static String logicalTypeNameFor(final ObjectSpecification objectSpec) {
-        return objectSpec.getFacet(LogicalTypeFacet.class).value();
+        return objectSpec.getLogicalTypeName();
     }
 
     static StringProperty stringProperty() {
@@ -781,7 +767,7 @@ class Generation {
     }
 
     static StringProperty stringPropertyEnum(final String... enumValues) {
-        StringProperty stringProperty = stringProperty();
+        final StringProperty stringProperty = stringProperty();
         stringProperty._enum(Arrays.asList(enumValues));
         if(enumValues.length >= 1) {
             stringProperty._default(enumValues[0]);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/_Util.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/_Util.java
index 1a89c58fc9..4f03ff3065 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/_Util.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/swagger/internal/_Util.java
@@ -28,7 +28,6 @@ import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
 import org.apache.isis.core.metamodel.spec.ActionScope;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MixedIn;
@@ -36,6 +35,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.util.Facets;
 
 import lombok.val;
 import lombok.experimental.UtilityClass;
@@ -53,11 +53,7 @@ final class _Util {
     }
 
     private boolean isTypeOfVisibleForPublic(final ObjectAction objectAction) {
-        final TypeOfFacet typeOfFacet = objectAction.getFacet(TypeOfFacet.class);
-        if (typeOfFacet == null) {
-            return false;
-        }
-        return isVisibleForPublic(typeOfFacet.valueSpec());
+        return isVisibleForPublic(objectAction.getElementType());
     }
 
     private boolean isVisibleForPublic(final Can<ObjectSpecification> parameterTypes) {
@@ -91,15 +87,14 @@ final class _Util {
             return true;
         }
         if(specification.isNonScalar()) {
-            TypeOfFacet typeOfFacet = specification.getFacet(TypeOfFacet.class);
-            if(typeOfFacet != null) {
-                ObjectSpecification elementSpec = typeOfFacet.valueSpec();
+            val elementSpec = Facets.typeOf(specification).orElse(null);
+            if(elementSpec != null) {
                 return isVisibleForPublic(elementSpec);
             }
         }
 
         final Class<?> correspondingClass = specification.getCorrespondingClass();
-        return  Collection.class.isAssignableFrom(correspondingClass) ||
+        return Collection.class.isAssignableFrom(correspondingClass) ||
                 correspondingClass.isArray() ||
                 correspondingClass == void.class ||
                 correspondingClass == Void.class;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 788e1f9054..c337f0363a 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -50,13 +50,13 @@ import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
 import org.apache.isis.core.metamodel.interactions.managed.ManagedMember;
 import org.apache.isis.core.metamodel.interactions.managed.MemberInteraction.AccessIntent;
 import org.apache.isis.core.metamodel.interactions.managed.PropertyInteraction;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
+import org.apache.isis.core.metamodel.util.Facets;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.Rel;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
@@ -336,20 +336,14 @@ implements DomainObjectResource {
             final String domainType,
             final String instanceId) {
 
-        val gridFacet = getSpecificationLoader().specForLogicalTypeName(domainType)
-        .map(spec->spec.getFacet(GridFacet.class))
-        .orElse(null);
-
-        if(gridFacet == null) {
-            return Optional.empty();
-        }
-        val objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId,
-                roEx->_EndpointLogging.error(log, "GET /objects/{}/{}/object-layout", domainType, instanceId, roEx));
-        val grid = gridFacet.getGrid(objectAdapter);
-        return Optional.of(grid);
+        return getSpecificationLoader().specForLogicalTypeName(domainType)
+            .flatMap(spec->Facets.bootstrapGrid(
+                    spec,
+                    getObjectAdapterElseThrowNotFound(domainType, instanceId,
+                            roEx->_EndpointLogging
+                                .error(log, "GET /objects/{}/{}/object-layout", domainType, instanceId, roEx))));
     }
 
-
     // public ... for testing
     public static void addLinks(
             final ResourceContext resourceContext,
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
index dbb1287bbb..3c40601d91 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
@@ -36,10 +36,10 @@ import org.apache.isis.applib.services.iactnlayer.InteractionLayerTracker;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.grid.GridFacet;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.util.Facets;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.Rel;
 import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
@@ -154,8 +154,7 @@ implements DomainTypeResource {
         val serializationStrategy = resourceContext.getSerializationStrategy();
 
         val responseBuilder = getSpecificationLoader().specForLogicalTypeName(domainType)
-                .map(spec -> spec.getFacet(GridFacet.class))
-                .map(gridFacet -> gridFacet.getGrid(null))
+                .map(Facets::bootstrapGrid)
                 .map(grid ->
                         Response.status(Response.Status.OK)
                                 .entity(serializationStrategy.entity(grid))