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 2018/10/01 10:53:34 UTC

[isis] branch v2 updated (4d98c3d -> eaeb0fe)

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

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


    from 4d98c3d  ISIS-1976: remove MutableProposedHolder
     new dbfc2b5  ISIS-1976: Improve the service lookup API (streams instead of collections)
     new eaeb0fe  ISIS-1976: cleanup ServiceUtil

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../metamodel/adapter/ObjectAdapterProvider.java   | 17 ++++--
 ...jectSpecIdFacetDerivedFromClassNameFactory.java |  2 +-
 .../isis/core/metamodel/services/ServiceUtil.java  | 62 +++++++++++---------
 .../core/metamodel/services/ServicesInjector.java  | 24 +++++---
 .../services/swagger/internal/Generation.java      |  9 +--
 .../core/metamodel/services/ServiceUtil_Test.java  | 24 ++++----
 .../homepage/HomePageProviderServiceDefault.java   | 25 +++++---
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    | 66 +++++++++++-----------
 .../menubars/bootstrap3/ServiceAndAction.java      |  6 +-
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 24 +++++---
 .../restfulobjects/rendering/ReprRenderer.java     |  1 -
 .../rendering/ReprRendererAbstract.java            |  7 ++-
 .../domainobjects/ActionResultReprRenderer.java    |  6 +-
 .../domainobjects/DomainObjectReprRenderer.java    |  2 +-
 .../domainobjects/DomainServiceLinkTo.java         |  2 +-
 .../rendering/domainobjects/ListReprRenderer.java  | 28 +++++----
 .../domainobjects/ObjectActionReprRenderer.java    | 14 ++---
 .../restfulobjects/server/ResourceContext.java     |  8 +--
 .../resources/DomainServiceResourceServerside.java | 23 ++------
 .../resources/DomainServicesListReprRenderer.java  |  2 +-
 .../server/resources/HomePageReprRenderer.java     |  6 +-
 .../server/resources/ResourceAbstract.java         | 12 +---
 .../wicket/model/models/ServiceActionsModel.java   | 11 ++--
 .../serviceactions/ServiceActionUtil.java          | 30 +++++-----
 .../isis/viewer/wicket/ui/pages/home/HomePage.java | 19 +++----
 25 files changed, 224 insertions(+), 206 deletions(-)


[isis] 01/02: ISIS-1976: Improve the service lookup API (streams instead of collections)

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

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

commit dbfc2b56d76d9f32c6c55af9831eea418c190903
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Oct 1 09:55:58 2018 +0200

    ISIS-1976: Improve the service lookup API (streams instead of
    collections)
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../metamodel/adapter/ObjectAdapterProvider.java   | 17 ++++--
 .../isis/core/metamodel/services/ServiceUtil.java  |  2 +
 .../homepage/HomePageProviderServiceDefault.java   | 25 +++++---
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    | 66 +++++++++++-----------
 .../menubars/bootstrap3/ServiceAndAction.java      |  6 +-
 ...ObjectAdapterContext_ObjectAdapterProvider.java | 24 +++++---
 .../restfulobjects/rendering/ReprRenderer.java     |  1 -
 .../rendering/ReprRendererAbstract.java            |  7 ++-
 .../domainobjects/ActionResultReprRenderer.java    |  6 +-
 .../rendering/domainobjects/ListReprRenderer.java  | 28 +++++----
 .../domainobjects/ObjectActionReprRenderer.java    | 14 ++---
 .../restfulobjects/server/ResourceContext.java     |  8 +--
 .../resources/DomainServiceResourceServerside.java | 23 ++------
 .../resources/DomainServicesListReprRenderer.java  |  2 +-
 .../server/resources/HomePageReprRenderer.java     |  6 +-
 .../server/resources/ResourceAbstract.java         | 12 +---
 .../wicket/model/models/ServiceActionsModel.java   | 11 ++--
 .../serviceactions/ServiceActionUtil.java          | 30 +++++-----
 .../isis/viewer/wicket/ui/pages/home/HomePage.java | 19 +++----
 19 files changed, 159 insertions(+), 148 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
index 452fd18..4d80ecb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterProvider.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.metamodel.adapter;
 
 import static org.apache.isis.commons.internal.base._With.mapIfPresentElse;
 
-import java.util.List;
+import java.util.stream.Stream;
 
 import javax.annotation.Nullable;
 
@@ -101,7 +101,8 @@ public interface ObjectAdapterProvider {
     
     // -- SERVICE LOOKUP 
     
-    List<ObjectAdapter> getServices();
+    Stream<ObjectAdapter> streamServices();
+    ObjectAdapter lookupService(String serviceId);
     
     
     // -- FOR THOSE THAT IMPLEMENT THROUGH DELEGATION
@@ -150,11 +151,19 @@ public interface ObjectAdapterProvider {
         }
         
         @Programmatic
-        default List<ObjectAdapter> getServices() {
-            return getObjectAdapterProvider().getServices();
+        default Stream<ObjectAdapter> streamServices() {
+            return getObjectAdapterProvider().streamServices();
+        }
+        
+        @Programmatic
+        default ObjectAdapter lookupService(String serviceId) {
+            return getObjectAdapterProvider().lookupService(serviceId);
         }
         
     }
+
+
+    
     
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
index 0f8f0ae..54a8745 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
@@ -58,6 +58,8 @@ public final class ServiceUtil {
             return fqcnOf(serviceClass);
         }
     }
+    
+    // -- HELPER
 
     private static String serviceTypeOf(final Class<?> serviceClass) {
         final String serviceType;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/homepage/HomePageProviderServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/homepage/HomePageProviderServiceDefault.java
index 082d03b..f2f0a2e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/homepage/HomePageProviderServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/homepage/HomePageProviderServiceDefault.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.core.runtime.services.homepage;
 
-import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -30,6 +29,7 @@ import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.homepage.HomePageProviderService;
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
@@ -53,8 +53,15 @@ public class HomePageProviderServiceDefault implements HomePageProviderService {
     @Programmatic
     @Override
     public Object homePage() {
-        final List<ObjectAdapter> serviceAdapters = getPersistenceSession().getServices();
-        for (final ObjectAdapter serviceAdapter : serviceAdapters) {
+        return homePage.get();
+    }
+    
+    private final _Lazy<Object> homePage = _Lazy.of(this::lookupHomePage);
+
+    private Object lookupHomePage() {
+        final Stream<ObjectAdapter> serviceAdapters = getPersistenceSession().streamServices();
+        
+        return serviceAdapters.map(serviceAdapter->{
             final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
             final Stream<ObjectAction> objectActions = serviceSpec.streamObjectActions(Contributed.EXCLUDED);
             
@@ -63,12 +70,12 @@ public class HomePageProviderServiceDefault implements HomePageProviderService {
             .filter(_NullSafe::isPresent)
             .findAny();
             
-            if(homePage.isPresent()) {
-                return homePage.get();
-            }
-            
-        }
-        return null;
+            return homePage;
+        })
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .findAny()
+        .orElse(null);
     }
 
     protected Object homePageIfUsable(ObjectAdapter serviceAdapter, ObjectAction objectAction) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/MenuBarsServiceBS3.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/MenuBarsServiceBS3.java
index 942c3b9..7f2962b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/MenuBarsServiceBS3.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/MenuBarsServiceBS3.java
@@ -57,6 +57,7 @@ import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceF
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 import org.apache.isis.core.metamodel.services.grid.GridServiceDefault;
 import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -179,31 +180,30 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
     private BS3MenuBars deriveMenuBarsFromMetaModelFacets() {
         final BS3MenuBars menuBars = new BS3MenuBars();
 
-        final List<ObjectAdapter> serviceAdapters =
-                isisSessionFactory.getCurrentSession().getPersistenceSession().getServices();
+        final Stream<ObjectAdapter> serviceAdapters =
+                isisSessionFactory.getCurrentSession().getPersistenceSession().streamServices();
 
-        final List<ObjectAdapter> visibleServiceAdapters =
-                _Lists.filter(serviceAdapters,
-                (final ObjectAdapter objectAdapter) -> {
-                        if (objectAdapter == null) {
-                            return false;
-                        }
-                        if (objectAdapter.getSpecification() == null) {
-                            return false;
-                        }
-                        final ObjectSpecification spec = objectAdapter.getSpecification();
-                        if (spec.isHidden()) {
-                            // however, this isn't the same as HiddenObjectFacet, so doesn't filter out
-                            // services that have an imperative hidden() method.
-                            return false;
-                        }
-                        final DomainServiceFacet facet = spec.getFacet(DomainServiceFacet.class);
-                        if (facet == null) {
-                            return true;
-                        }
-                        final NatureOfService natureOfService = facet.getNatureOfService();
-                        return natureOfService == null || natureOfService != NatureOfService.DOMAIN;
-                });
+        final List<ManagedObject> visibleServiceAdapters = serviceAdapters.filter(objectAdapter -> {
+            if (objectAdapter == null) {
+                return false;
+            }
+            if (objectAdapter.getSpecification() == null) {
+                return false;
+            }
+            final ObjectSpecification spec = objectAdapter.getSpecification();
+            if (spec.isHidden()) {
+                // however, this isn't the same as HiddenObjectFacet, so doesn't filter out
+                // services that have an imperative hidden() method.
+                return false;
+            }
+            final DomainServiceFacet facet = spec.getFacet(DomainServiceFacet.class);
+            if (facet == null) {
+                return true;
+            }
+            final NatureOfService natureOfService = facet.getNatureOfService();
+            return natureOfService == null || natureOfService != NatureOfService.DOMAIN;
+        })
+        .collect(Collectors.toList());
 
         append(visibleServiceAdapters, menuBars.getPrimary(), DomainServiceLayout.MenuBar.PRIMARY);
         append(visibleServiceAdapters, menuBars.getSecondary(), DomainServiceLayout.MenuBar.SECONDARY);
@@ -221,14 +221,14 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
 
 
     private void append(
-            final List<ObjectAdapter> serviceAdapters,
+            final List<ManagedObject> serviceAdapters,
             final BS3MenuBar menuBar,
             final DomainServiceLayout.MenuBar menuBarPos) {
 
         List<ServiceAndAction> serviceActions = _Lists.newArrayList();
 
         // cf ServiceActionsModel & ServiceActionUtil#buildMenu in Wicket viewer
-        for (final ObjectAdapter serviceAdapter : _Lists.filter(serviceAdapters, with(menuBarPos))) {
+        for (final ManagedObject serviceAdapter : _Lists.filter(serviceAdapters, with(menuBarPos))) {
             collateServiceActions(serviceAdapter, ActionType.USER, serviceActions);
             collateServiceActions(serviceAdapter, ActionType.PROTOTYPE, serviceActions);
         }
@@ -282,12 +282,12 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
      * straight copy from Wicket UI
      */
     private static Set<String> serviceNamesInOrder(
-            final List<ObjectAdapter> serviceAdapters,
+            final List<ManagedObject> serviceAdapters,
             final List<ServiceAndAction> serviceActions) {
         final Set<String> serviceNameOrder = _Sets.newLinkedHashSet();
 
         // first, order as defined in isis.properties
-        for (ObjectAdapter serviceAdapter : serviceAdapters) {
+        for (ManagedObject serviceAdapter : serviceAdapters) {
             final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
             String serviceName = serviceSpec.getFacet(NamedFacet.class).value();
             serviceNameOrder.add(serviceName);
@@ -311,12 +311,12 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
         final Map<String, List<ServiceAndAction>> serviceActionsByName = _Maps.newTreeMap();
 
         // map available services
-        ObjectAdapter lastServiceAdapter = null;
+        ManagedObject lastServiceAdapter = null;
 
         for (ServiceAndAction serviceAction : serviceActions) {
             List<ServiceAndAction> serviceActionsForName = serviceActionsByName.get(serviceAction.serviceName);
 
-            final ObjectAdapter serviceAdapter = serviceAction.serviceAdapter;
+            final ManagedObject serviceAdapter = serviceAction.serviceAdapter;
 
             if(serviceActionsForName == null) {
                 serviceActionsForName = _Lists.newArrayList();
@@ -334,7 +334,7 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
 
 
     private void collateServiceActions(
-            final ObjectAdapter serviceAdapter,
+            final ManagedObject serviceAdapter,
             final ActionType actionType,
             final List<ServiceAndAction> serviceActions) {
         final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
@@ -366,8 +366,8 @@ public class MenuBarsServiceBS3 implements MenuBarsService {
        
     }
 
-    private static Predicate<ObjectAdapter> with(final DomainServiceLayout.MenuBar menuBar) {
-        return (ObjectAdapter input) -> {
+    private static Predicate<ManagedObject> with(final DomainServiceLayout.MenuBar menuBar) {
+        return (ManagedObject input) -> {
                 final DomainServiceLayoutFacet facet =
                         input.getSpecification().getFacet(DomainServiceLayoutFacet.class);
                 return facet != null && facet.getMenuBar() == menuBar;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/ServiceAndAction.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/ServiceAndAction.java
index 4524da9..ffe37ea 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/ServiceAndAction.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/menubars/bootstrap3/ServiceAndAction.java
@@ -18,19 +18,19 @@
  */
 package org.apache.isis.core.runtime.services.menubars.bootstrap3;
 
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 
 class ServiceAndAction {
     final String serviceName;
-    final ObjectAdapter serviceAdapter;
+    final ManagedObject serviceAdapter;
     final ObjectAction objectAction;
 
     public boolean separator;
 
     ServiceAndAction(
             final String serviceName,
-            final ObjectAdapter serviceAdapter,
+            final ManagedObject serviceAdapter,
             final ObjectAction objectAction) {
         this.serviceName = serviceName;
         this.serviceAdapter = serviceAdapter;
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index 50505bf..a982773 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -20,8 +20,10 @@ package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
 import static org.apache.isis.commons.internal.base._With.requires;
 
-import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,6 +33,7 @@ import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.services.ServiceUtil;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -131,21 +134,28 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
     // -- SERVICE SUPPORT
     
     @Override
-    public List<ObjectAdapter> getServices() {
-        return serviceAdapters.get();
+    public Stream<ObjectAdapter> streamServices() {
+        return serviceAdapters.get().values().stream();
     }
     
+    @Override
+    public ObjectAdapter lookupService(final String serviceId) {
+        return serviceAdapters.get().get(serviceId);
+    }
+    
+    
     // -- HELPER
     
-    private final _Lazy<List<ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
+    private final _Lazy<Map<String, ObjectAdapter>> serviceAdapters = _Lazy.of(this::initServiceAdapters);
     
-    private List<ObjectAdapter> initServiceAdapters() {
+    private Map<String, ObjectAdapter> initServiceAdapters() {
+        
         return servicesInjector.streamRegisteredServiceInstances()
-        .map(this::adapterFor)
+        .map(this::adapterFor) 
         .peek(serviceAdapter->{
             Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
         })
-        .collect(Collectors.toList());
+        .collect(Collectors.toMap(a->ServiceUtil.id(a.getPojo()), v->v, (o,n)->n, LinkedHashMap::new));
     }
     
    
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
index d0633ad..b1685ad 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRenderer.java
@@ -21,7 +21,6 @@ package org.apache.isis.viewer.restfulobjects.rendering;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 
 public interface ReprRenderer<R extends ReprRenderer<R, T>, T> {
 
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
index 7438e7b..a07b021 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
@@ -20,12 +20,13 @@ package org.apache.isis.viewer.restfulobjects.rendering;
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import javax.ws.rs.core.MediaType;
 
-import org.apache.isis.commons.internal.collections._Lists;
 import com.google.common.collect.Maps;
 
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
@@ -223,8 +224,8 @@ public abstract class ReprRendererAbstract<R extends ReprRendererAbstract<R, T>,
         }
     }
 
-    protected List<ObjectAdapter> getServiceAdapters() {
-        return rendererContext.getPersistenceSession().getServices();
+    protected Stream<ObjectAdapter> streamServiceAdapters() {
+        return rendererContext.getPersistenceSession().streamServices();
     }
 
 }
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index 435c2cb..b34f15f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -16,8 +16,8 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
-import java.util.Collection;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import com.fasterxml.jackson.databind.node.NullNode;
 
@@ -135,8 +135,8 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
 
         case LIST:
 
-            final Collection<ObjectAdapter> collectionAdapters =
-                CollectionFacet.Utils.toAdapterList(returnedAdapter);
+            final Stream<ObjectAdapter> collectionAdapters =
+                CollectionFacet.Utils.streamAdapters(returnedAdapter);
             
             final ListReprRenderer listReprRenderer =
                     new ListReprRenderer(rendererContext, null, representation).withElementRel(Rel.ELEMENT);
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
index 272743b..83eba8f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
@@ -16,7 +16,9 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
-import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -27,10 +29,10 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Collection<ObjectAdapter>> {
+public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Stream<ObjectAdapter>> {
 
     private ObjectAdapterLinkTo linkTo;
-    private Collection<ObjectAdapter> objectAdapters;
+    private List<ObjectAdapter> objectAdapters;
     private ObjectSpecification elementType;
     private ObjectSpecification returnType;
     private Rel elementRel;
@@ -46,8 +48,12 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Col
     }
 
     @Override
-    public ListReprRenderer with(final Collection<ObjectAdapter> objectAdapters) {
-        this.objectAdapters = objectAdapters;
+    public ListReprRenderer with(final Stream<ObjectAdapter> objectAdapters) {
+        this.objectAdapters = objectAdapters!=null 
+                ? objectAdapters
+                .filter(adapter->!adapter.getSpecification().isHidden())
+                .collect(Collectors.toList())
+                    : null;
         return this;
     }
 
@@ -90,11 +96,8 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Col
 
         final JsonRepresentation values = JsonRepresentation.newArray();
 
-        for (final ObjectAdapter adapter : objectAdapters) {
-            final ObjectSpecification specification = adapter.getSpecification();
-            if (specification.isHidden()) {
-                continue;
-            }
+        objectAdapters
+        .forEach(adapter->{
             final JsonRepresentation linkToObject = linkTo.with(adapter).builder(elementRel).build();
             values.arrayAdd(linkToObject);
 
@@ -104,8 +107,9 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Col
                         );
                 final JsonRepresentation domainObject = renderer.with(adapter).render();
                 linkToObject.mapPut("value", domainObject);
-            }
-        }
+            }            
+        });
+        
         representation.mapPut("value", values);
     }
 
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
index 9b21a16..a4b7317 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
@@ -18,6 +18,7 @@ package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import com.fasterxml.jackson.databind.node.NullNode;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -108,14 +109,11 @@ public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<O
 
     private ObjectAdapter contributingServiceAdapter() {
         final ObjectSpecification serviceType = objectMember.getOnType();
-        final List<ObjectAdapter> serviceAdapters = getServiceAdapters();
-        for (final ObjectAdapter serviceAdapter : serviceAdapters) {
-            if (serviceAdapter.getSpecification() == serviceType) {
-                return serviceAdapter;
-            }
-        }
-        // fail fast
-        throw new IllegalStateException("Unable to locate contributing service");
+        final Stream<ObjectAdapter> serviceAdapters = streamServiceAdapters();
+        return serviceAdapters
+                .filter(serviceAdapter->serviceAdapter.getSpecification() == serviceType)
+                .findFirst()
+                .orElseThrow(()->new IllegalStateException("Unable to locate contributing service")); // fail fast
     }
 
     @Override
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
index a8e772b..3efb193 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -32,10 +33,9 @@ import javax.ws.rs.core.SecurityContext;
 import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.Providers;
 
+import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Sets;
-
-import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -277,8 +277,8 @@ public class ResourceContext implements RendererContext6 {
         return persistenceSession;
     }
 
-    public List<ObjectAdapter> getServiceAdapters() {
-        return persistenceSession.getServices();
+    public Stream<ObjectAdapter> streamServiceAdapters() {
+        return persistenceSession.streamServices();
     }
 
     @Override
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
index b770685..aa31ea3 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
@@ -17,7 +17,8 @@
 package org.apache.isis.viewer.restfulobjects.server.resources;
 
 import java.io.InputStream;
-import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
@@ -49,16 +50,10 @@ import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjec
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainServiceLinkTo;
 import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import org.apache.isis.commons.internal.collections._Lists;
-
 @Path("/services")
 public class DomainServiceResourceServerside extends ResourceAbstract implements DomainServiceResource {
 
-    private final static Predicate<ObjectAdapter> NATURE_OF_MENU = new Predicate<ObjectAdapter>() {
-        @Override
-        public boolean apply(final ObjectAdapter input) {
+    private final static Predicate<ObjectAdapter> NATURE_OF_MENU = (final ObjectAdapter input) -> {
             final ObjectSpecification specification = input.getSpecification();
             final DomainServiceFacet facet = specification.getFacet(DomainServiceFacet.class);
             if (facet == null) {
@@ -69,7 +64,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
             return  natureOfService == NatureOfService.VIEW ||
                     natureOfService == NatureOfService.VIEW_MENU_ONLY ||
                     natureOfService == NatureOfService.VIEW_REST_ONLY;
-        }
     };
 
     @Override
@@ -79,10 +73,8 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
     public Response services() {
         init(RepresentationType.LIST, Where.STANDALONE_TABLES, RepresentationService.Intent.NOT_APPLICABLE);
 
-        final List<ObjectAdapter> serviceAdapters =
-                _Lists.newArrayList(
-                        Iterables.filter(
-                                getResourceContext().getServiceAdapters(), NATURE_OF_MENU));
+        final Stream<ObjectAdapter> serviceAdapters = getResourceContext().streamServiceAdapters()
+                .filter(NATURE_OF_MENU);
 
         final DomainServicesListReprRenderer renderer = new DomainServicesListReprRenderer(getResourceContext(), null, JsonRepresentation.newMap());
         renderer.usingLinkToBuilder(new DomainServiceLinkTo())
@@ -118,7 +110,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
         MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
         MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
     })
-    //TODO proprietary @PrettyPrinting
     public Response service(@PathParam("serviceId") final String serviceId) {
         init(RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS, RepresentationService.Intent.ALREADY_PERSISTENT);
 
@@ -159,7 +150,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
         MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
         MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
     })
-    //TODO proprietary @PrettyPrinting
     public Response actionPrompt(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId) {
         init(RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS, RepresentationService.Intent.ALREADY_PERSISTENT);
 
@@ -195,7 +185,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
         MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
         MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
     })
-    //TODO proprietary @PrettyPrinting
     public Response invokeActionQueryOnly(
             final @PathParam("serviceId") String serviceId,
             final @PathParam("actionId") String actionId,
@@ -224,7 +213,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
         MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
         MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
     })
-    //TODO proprietary @PrettyPrinting
     public Response invokeActionIdempotent(
             final @PathParam("serviceId") String serviceId,
             final @PathParam("actionId") String actionId,
@@ -249,7 +237,6 @@ public class DomainServiceResourceServerside extends ResourceAbstract implements
         MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
         MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
     })
-    //TODO proprietary @PrettyPrinting
     public Response invokeAction(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream body) {
         init(RepresentationType.ACTION_RESULT, Where.STANDALONE_TABLES, RepresentationService.Intent.NOT_APPLICABLE, body);
 
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServicesListReprRenderer.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServicesListReprRenderer.java
index 97cade1..7f56432 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServicesListReprRenderer.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServicesListReprRenderer.java
@@ -49,7 +49,7 @@ public class DomainServicesListReprRenderer extends ListReprRenderer {
         final LinkFollowSpecs linkFollower = getLinkFollowSpecs().follow("links");
         if (linkFollower.matches(link)) {
             final DomainServicesListReprRenderer renderer = new DomainServicesListReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap());
-            renderer.with(getServiceAdapters());
+            renderer.with(streamServiceAdapters());
             link.mapPut("value", renderer.render());
         }
 
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
index 099b121..e8fc769 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageReprRenderer.java
@@ -19,7 +19,7 @@
 package org.apache.isis.viewer.restfulobjects.server.resources;
 
 import java.util.Collection;
-import java.util.List;
+import java.util.stream.Stream;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -57,7 +57,7 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
 
         addLinkToUser(getRendererContext().getAuthenticationSession());
         addLinkToMenuBars();
-        addLinkToServices(getRendererContext().getPersistenceSession().getServices());
+        addLinkToServices(getRendererContext().getPersistenceSession().streamServices());
         addLinkToVersion();
         addLinkToDomainTypes(((ResourceContext)getRendererContext()).getSpecificationLoader().allSpecifications());
 
@@ -90,7 +90,7 @@ public class HomePageReprRenderer extends ReprRendererAbstract<HomePageReprRende
         getLinks().arrayAdd(link);
     }
 
-    private void addLinkToServices(List<ObjectAdapter> serviceAdapters) {
+    private void addLinkToServices(Stream<ObjectAdapter> serviceAdapters) {
 
         final JsonRepresentation link = LinkBuilder.newBuilder(getRendererContext(), Rel.SERVICES.getName(), RepresentationType.LIST, "services").build();
 
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ResourceAbstract.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ResourceAbstract.java
index d651be5..39c84a6 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ResourceAbstract.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ResourceAbstract.java
@@ -19,7 +19,6 @@
 package org.apache.isis.viewer.restfulobjects.server.resources;
 
 import java.io.InputStream;
-import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -39,7 +38,6 @@ import org.apache.isis.core.commons.url.UrlDecoderUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
-import org.apache.isis.core.metamodel.services.ServiceUtil;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
@@ -153,13 +151,9 @@ public abstract class ResourceAbstract {
     }
 
     protected ObjectAdapter getServiceAdapter(final String serviceId) {
-        final List<ObjectAdapter> serviceAdapters = getPersistenceSession().getServices();
-        for (final ObjectAdapter serviceAdapter : serviceAdapters) {
-            final Object servicePojo = serviceAdapter.getPojo();
-            final String id = ServiceUtil.id(servicePojo);
-            if (serviceId.equals(id)) {
-                return serviceAdapter;
-            }
+        final ObjectAdapter serviceAdapter = getPersistenceSession().lookupService(serviceId);
+        if(serviceAdapter!=null) {
+            return serviceAdapter;
         }
         throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.NOT_FOUND, "Could not locate service '%s'", serviceId);
     }
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java
index d9b6d94..16a5ec4 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ServiceActionsModel.java
@@ -21,9 +21,10 @@ package org.apache.isis.viewer.wicket.model.models;
 
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facets.object.domainservicelayout.DomainServiceLayoutFacet;
 /**
@@ -52,7 +53,9 @@ public class ServiceActionsModel extends ModelAbstract<List<ObjectAdapter>> {
 
     @Override
     protected List<ObjectAdapter> load() {
-        return _Lists.filter(getServiceAdapters(), with(menuBar));
+        return streamServiceAdapters()
+                .filter(with(menuBar))
+                .collect(Collectors.toList());
     }
 
     private static Predicate<ObjectAdapter> with(final DomainServiceLayout.MenuBar menuBar) {
@@ -64,8 +67,8 @@ public class ServiceActionsModel extends ModelAbstract<List<ObjectAdapter>> {
         };
     }
 
-    protected List<ObjectAdapter> getServiceAdapters() {
-        return getPersistenceSession().getServices();
+    protected Stream<ObjectAdapter> streamServiceAdapters() {
+        return getPersistenceSession().streamServices();
     }
 
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
index 03fb219..39ff33c 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actionmenu/serviceactions/ServiceActionUtil.java
@@ -19,11 +19,11 @@
 
 package org.apache.isis.viewer.wicket.ui.components.actionmenu.serviceactions;
 
+import java.util.HashMap;
 import java.util.List;
-
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
@@ -40,7 +40,6 @@ import org.apache.isis.applib.layout.menubars.MenuBars;
 import org.apache.isis.applib.layout.menubars.MenuSection;
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3Menu;
 import org.apache.isis.applib.layout.menubars.bootstrap3.BS3MenuBar;
-import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -49,7 +48,6 @@ import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.runtime.system.SystemConstants;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.models.ServiceActionsModel;
@@ -212,11 +210,12 @@ public final class ServiceActionUtil {
 
         // we no longer use ServiceActionsModel#getObject() because the model only holds the services for the
         // menuBar in question, whereas the "Other" menu may reference a service which is defined for some other menubar
-        final List<ObjectAdapter> serviceAdapters = IsisContext.getSessionFactory().getCurrentSession().getPersistenceSession().getServices();
-        final ImmutableMap<ObjectAdapter, String> oidByServiceAdapter = FluentIterable.from(serviceAdapters)
-                .toMap((final ObjectAdapter objectAdapter) -> objectAdapter.getOid().enStringNoVersion());
-        final ImmutableBiMap<String, ObjectAdapter> serviceAdapterByOid = ImmutableBiMap
-                .copyOf(oidByServiceAdapter).inverse();
+        final Stream<ObjectAdapter> serviceAdapters = 
+                IsisContext.getSessionFactory().getCurrentSession().getPersistenceSession().streamServices();
+
+        final Map<String, ObjectAdapter> serviceAdapterBySpecId = 
+                serviceAdapters
+                .collect(Collectors.toMap(a->a.getSpecification().getSpecId().asString(), a->a, (o,n)->n, HashMap::new));
 
         final List<CssMenuItem> menuItems = _Lists.newArrayList();
         for (final BS3Menu menu : menuBar.getMenus()) {
@@ -228,12 +227,11 @@ public final class ServiceActionUtil {
                 boolean firstSection = true;
 
                 for (final ServiceActionLayoutData actionLayoutData : menuSection.getServiceActions()) {
-                    final String objectType = actionLayoutData.getObjectType();
-                    final Bookmark bookmark = new Bookmark(objectType, PersistenceSession.SERVICE_IDENTIFIER);
-                    final String oid = bookmark.toString();
-                    final ObjectAdapter serviceAdapter = serviceAdapterByOid.get(oid);
+                    final String objectTypeLiteral = actionLayoutData.getObjectType();
+                    
+                    final ObjectAdapter serviceAdapter = serviceAdapterBySpecId.get(objectTypeLiteral);
                     if(serviceAdapter == null) {
-                        // service not recognised, presumably the menu layout is out of sync with actual configured modules
+                        // service not recognized, presumably the menu layout is out of sync with actual configured modules
                         continue;
                     }
                     final EntityModel entityModel = new EntityModel(serviceAdapter);
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/home/HomePage.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/home/HomePage.java
index e0f2c70..0174087 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/home/HomePage.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/home/HomePage.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.viewer.wicket.ui.pages.home;
 
-import java.util.List;
 import java.util.Optional;
 import java.util.stream.Stream;
 
@@ -90,8 +89,8 @@ public class HomePage extends PageAbstract {
     }
 
     private ObjectAndAction lookupHomePageAction() {
-        final List<ObjectAdapter> serviceAdapters = getPersistenceSession().getServices();
-        for (final ObjectAdapter serviceAdapter : serviceAdapters) {
+        final Stream<ObjectAdapter> serviceAdapters = getPersistenceSession().streamServices();
+        return serviceAdapters.map(serviceAdapter->{
             final ObjectSpecification serviceSpec = serviceAdapter.getSpecification();
             final Stream<ObjectAction> objectActions = serviceSpec.streamObjectActions(Contributed.EXCLUDED);
             
@@ -99,13 +98,13 @@ public class HomePage extends PageAbstract {
             .map(objectAction->objectAndActionIfHomePageAndUsable(serviceAdapter, objectAction))
             .filter(_NullSafe::isPresent)
             .findAny();
-            
-            if(homePageAction.isPresent()) {
-                return homePageAction.get();
-            }
-
-        }
-        return null;
+            return homePageAction;
+        })
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .findAny()
+        .orElse(null)
+        ;
     }
 
     private ObjectAndAction objectAndActionIfHomePageAndUsable(ObjectAdapter serviceAdapter, ObjectAction objectAction) {


[isis] 02/02: ISIS-1976: cleanup ServiceUtil

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

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

commit eaeb0fe9178566299697b1aec56486aab7a72860
Author: Andi Huber <ah...@apache.org>
AuthorDate: Mon Oct 1 11:59:14 2018 +0200

    ISIS-1976: cleanup ServiceUtil
    
    improve ServiceInjector's service list validation for uniqueness to
    print all! duplicates
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 ...jectSpecIdFacetDerivedFromClassNameFactory.java |  2 +-
 .../isis/core/metamodel/services/ServiceUtil.java  | 60 ++++++++++++----------
 .../core/metamodel/services/ServicesInjector.java  | 24 ++++++---
 .../services/swagger/internal/Generation.java      |  9 +---
 .../core/metamodel/services/ServiceUtil_Test.java  | 24 ++++-----
 ...ObjectAdapterContext_ObjectAdapterProvider.java |  2 +-
 .../domainobjects/DomainObjectReprRenderer.java    |  2 +-
 .../domainobjects/DomainServiceLinkTo.java         |  2 +-
 8 files changed, 66 insertions(+), 59 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
index e02db27..59db0a7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
@@ -74,7 +74,7 @@ MetaModelValidatorRefiner {
     private static ObjectSpecIdFacet createObjectSpecIdFacet(final FacetHolder facetHolder, final Class<?> substitutedClass) {
         final boolean isService = isService(facetHolder);
         if (isService) {
-            final String id = ServiceUtil.id(substitutedClass);
+            final String id = ServiceUtil.idOfType(substitutedClass);
             if (id != null) {
                 return new ObjectSpecIdFacetDerivedFromDomainServiceAnnotationElseGetId(id, facetHolder);
             }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
index 54a8745..0bb7773 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServiceUtil.java
@@ -19,49 +19,51 @@
 
 package org.apache.isis.core.metamodel.services;
 
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.function.Supplier;
 
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.commons.internal.functions._Functions;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
 public final class ServiceUtil {
 
     private ServiceUtil() {
     }
 
-    public static String id(final Class<?> serviceClass) {
-        final String serviceType = serviceTypeOf(serviceClass);
+    public static String idOfType(final Class<?> serviceClass) {
+        
+        final String serviceType = serviceTypeUsingAnnotation(serviceClass);
         if (serviceType != null) {
             return serviceType;
         }
 
-        try {
-            Object object = serviceClass.newInstance();
-            return getIdOf(object);
-        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException e) {
-            return null;
-        }
+        return serviceTypeUsingIdGetterOrElseGet(serviceClass, ()->serviceClass.newInstance(), ()->null);
     }
 
-    public static String id(final Object object) {
-        final Class<?> serviceClass = object.getClass();
-        final String serviceType = serviceTypeOf(serviceClass);
+    public static String idOfPojo(final Object serviceObject) {
+        final Class<?> serviceClass = serviceObject.getClass();
+        final String serviceType = serviceTypeUsingAnnotation(serviceClass);
         if(serviceType != null) {
             return serviceType;
         }
 
-        try {
-            return getIdOf(object);
-        } catch (final NoSuchMethodException e) {
-            return fqcnOf(serviceClass);
-        }
+        return serviceTypeUsingIdGetterOrElseGet(serviceClass, ()->serviceObject, ()->normalize(serviceClass));
+    }
+    
+    public static String idOfSpec(final ObjectSpecification serviceSpec) {
+        return idOfType(serviceSpec.getCorrespondingClass());
+    }
+    
+    public static String idOfAdapter(final ManagedObject adapter) {
+        return idOfPojo(adapter.getPojo());
     }
     
     // -- HELPER
 
-    private static String serviceTypeOf(final Class<?> serviceClass) {
+    private static String serviceTypeUsingAnnotation(final Class<?> serviceClass) {
         final String serviceType;
         final DomainService domainService = serviceClass.getAnnotation(DomainService.class);
         if(domainService != null) {
@@ -73,17 +75,21 @@ public final class ServiceUtil {
         return null;
     }
 
-    private static String getIdOf(final Object object) throws NoSuchMethodException {
+    private static String serviceTypeUsingIdGetterOrElseGet(
+            final Class<?> serviceClass, 
+            final _Functions.CheckedSupplier<Object> objectSupplier,
+            final Supplier<String> orElse
+            ) {
+        
         try {
-            final Class<?> objectClass = object.getClass();
-            final Method m = objectClass.getMethod("getId");
-            return (String) m.invoke(object);
-        } catch (final SecurityException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
-            throw new IsisException(e);
+            final Method m = serviceClass.getMethod("getId");
+            return (String) m.invoke(objectSupplier.get());
+        } catch (Exception e) {
+            return orElse.get();
         }
     }
-
-    private static String fqcnOf(final Class<?> serviceClass) {
+    
+    private static String normalize(Class<?> serviceClass) {
         return serviceClass.getName();
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index c47bf50..8c6a927 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -35,6 +35,7 @@ import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -180,19 +181,26 @@ public class ServicesInjector implements ApplicationScopedComponent {
     }
 
     private static void validate(List<Object> serviceList) {
+        
         final ListMultimap<String, Object> servicesById = _Multimaps.newListMultimap();
         for (Object service : serviceList) {
-            String id = ServiceUtil.id(service);
+            String id = ServiceUtil.idOfPojo(service);
             servicesById.putElement(id, service);
         }
 
-        servicesById.forEach((serviceId, services)->{
-            if(services.size() > 1) {
-                throw new IllegalStateException(
-                        String.format("Service ids must be unique; serviceId '%s' is declared by domain services %s",
-                                serviceId, classNamesFor(services)));
-            }
-        });
+        final String errorMsg = servicesById.entrySet().stream()
+        .filter(entry->entry.getValue().size()>1) // filter for duplicates
+        .map(entry->{
+            String serviceId = entry.getKey();
+            List<Object> duplicateServiceEntries = entry.getValue();
+            return String.format("serviceId '%s' is declared by domain services %s",
+                    serviceId, classNamesFor(duplicateServiceEntries));
+        })
+        .collect(Collectors.joining(", "));
+         
+        if(_Strings.isNotEmpty(errorMsg)) {
+            throw new IllegalStateException("Service ids must be unique! "+errorMsg);
+        }
     }
 
     private static String classNamesFor(Collection<Object> services) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
index 5f82cac..83baf78 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/Generation.java
@@ -35,7 +35,6 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.services.swagger.SwaggerService;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.core.commons.factory.InstanceUtil;
 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.mixin.MixinFacet;
@@ -783,14 +782,8 @@ class Generation {
                 .required("extensions");
     }
 
-    // TODO: this is horrid, there ought to be a facet we can call instead...
     static String serviceIdFor(final ObjectSpecification serviceSpec) {
-        Object tempServiceInstance = InstanceUtil.createInstance(serviceSpec.getCorrespondingClass());
-        return serviceId(tempServiceInstance);
-    }
-
-    static String serviceId(final Object object) {
-        return ServiceUtil.id(object);
+        return ServiceUtil.idOfSpec(serviceSpec);
     }
 
     static String objectTypeFor(final ObjectSpecification objectSpec) {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/ServiceUtil_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/ServiceUtil_Test.java
index e36282e..4549312 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/ServiceUtil_Test.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/ServiceUtil_Test.java
@@ -18,15 +18,15 @@
  */
 package org.apache.isis.core.metamodel.services;
 
-import org.junit.Test;
-
-import org.apache.isis.applib.annotation.DomainService;
-
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertThat;
 
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.DomainService;
+
 public class ServiceUtil_Test {
 
     @DomainService(objectType = "foo.SomeServiceAnnotated")
@@ -59,11 +59,11 @@ public class ServiceUtil_Test {
     public void annotated() throws Exception {
 
         assertThat(
-                ServiceUtil.id(new SomeServiceAnnotated()),
+                ServiceUtil.idOfPojo(new SomeServiceAnnotated()),
                 is(equalTo("foo.SomeServiceAnnotated")));
 
         assertThat(
-                ServiceUtil.id(SomeServiceAnnotated.class),
+                ServiceUtil.idOfType(SomeServiceAnnotated.class),
                 is(equalTo("foo.SomeServiceAnnotated")));
     }
 
@@ -71,11 +71,11 @@ public class ServiceUtil_Test {
     public void id() throws Exception {
 
         assertThat(
-                ServiceUtil.id(new SomeServiceWithId()),
+                ServiceUtil.idOfPojo(new SomeServiceWithId()),
                 is(equalTo("bar.SomeServiceWithId")));
 
         assertThat(
-                ServiceUtil.id(SomeServiceWithId.class),
+                ServiceUtil.idOfType(SomeServiceWithId.class),
                 is(equalTo("bar.SomeServiceWithId")));
     }
 
@@ -83,21 +83,21 @@ public class ServiceUtil_Test {
     public void annotated_precedence_over_id() throws Exception {
 
         assertThat(
-                ServiceUtil.id(new SomeServiceAnnotatedAndWithId()),
+                ServiceUtil.idOfPojo(new SomeServiceAnnotatedAndWithId()),
                 is(equalTo("bop.SomeServiceAnnotated")));
 
         assertThat(
-                ServiceUtil.id(SomeServiceAnnotatedAndWithId.class),
+                ServiceUtil.idOfType(SomeServiceAnnotatedAndWithId.class),
                 is(equalTo("bop.SomeServiceAnnotated")));
     }
 
     @Test
     public void fallback_to_fqcn_for_obj_but_to_null_for_service() throws Exception {
         assertThat(
-                ServiceUtil.id(new SomeServiceWithoutAnnotationOrId()),
+                ServiceUtil.idOfPojo(new SomeServiceWithoutAnnotationOrId()),
                 is(equalTo("org.apache.isis.core.metamodel.services.ServiceUtil_Test$SomeServiceWithoutAnnotationOrId")));
         assertThat(
-                ServiceUtil.id(SomeServiceWithoutAnnotationOrId.class),
+                ServiceUtil.idOfType(SomeServiceWithoutAnnotationOrId.class),
                 is(nullValue()));
     }
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
index a982773..31aaeff 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterProvider.java
@@ -155,7 +155,7 @@ class ObjectAdapterContext_ObjectAdapterProvider implements ObjectAdapterProvide
         .peek(serviceAdapter->{
             Assert.assertFalse("expected to not be 'transient'", serviceAdapter.getOid().isTransient());
         })
-        .collect(Collectors.toMap(a->ServiceUtil.id(a.getPojo()), v->v, (o,n)->n, LinkedHashMap::new));
+        .collect(Collectors.toMap(ServiceUtil::idOfAdapter, v->v, (o,n)->n, LinkedHashMap::new));
     }
     
    
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 60b02d1..e6c32e2 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -163,7 +163,7 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
 
             // serviceId or instance Id
             if (isService) {
-                representation.mapPut("serviceId", ServiceUtil.id(objectAdapter.getPojo()));
+                representation.mapPut("serviceId", ServiceUtil.idOfAdapter(objectAdapter));
             } else {
                 final String domainType = getDomainType();
                 final String instanceId = getInstanceId();
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainServiceLinkTo.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainServiceLinkTo.java
index 58412c8..3602c06 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainServiceLinkTo.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainServiceLinkTo.java
@@ -27,7 +27,7 @@ public class DomainServiceLinkTo extends DomainObjectLinkTo {
 
     @Override
     public ObjectAdapterLinkTo with(final ObjectAdapter objectAdapter) {
-        serviceId = ServiceUtil.id(objectAdapter.getPojo());
+        serviceId = ServiceUtil.idOfAdapter(objectAdapter);
         return super.with(objectAdapter);
     }