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/09/12 15:24:58 UTC

[isis] 04/05: ISIS-1976: Improve FacetHolder API

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

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 1dd0c8fcc42cec316e0fbf97160bf6c6b4987ca0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 12 16:27:55 2018 +0200

    ISIS-1976: Improve FacetHolder API
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../spec/feature/ObjectAssociationFilters.java     | 256 ---------------------
 .../isis/core/metamodel/facetapi/FacetHolder.java  |   5 +-
 .../core/metamodel/facetapi/FacetHolderImpl.java   |   5 +-
 .../isis/core/metamodel/facetapi/FacetUtil.java    |  31 +--
 .../core/metamodel/facets/ImperativeFacet.java     |  15 +-
 .../metamodel/interactions/InteractionUtils.java   |  21 +-
 .../metamodel/spec/feature/ObjectAssociation.java  |  20 +-
 .../specimpl/ObjectActionContributee.java          |   6 +-
 .../specimpl/ObjectActionParameterAbstract.java    |   6 +-
 .../specloader/specimpl/ObjectMemberAbstract.java  |   5 +-
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  20 +-
 ...jectAssociationPredicatesTest_visibleWhere.java |  18 +-
 ...FactoryDefaultTest_wrappedObject_transient.java |  12 +-
 ...FactoryDefaultTest_wrappedObject_transient.java |  12 +-
 .../PersistenceSessionServiceInternalDefault.java  |   4 +-
 .../CollectionContentsAsAjaxTablePanel.java        |  17 +-
 16 files changed, 93 insertions(+), 360 deletions(-)

diff --git a/core/legacy/transition-1-2/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java b/core/legacy/transition-1-2/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
deleted file mode 100644
index 0a8e419..0000000
--- a/core/legacy/transition-1-2/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociationFilters.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.metamodel.spec.feature;
-
-import java.util.List;
-
-import org.apache.isis.applib.annotation.Where;
-import org.apache.isis.applib.filter.Filter;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.consent.Consent;
-import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.WhereValueFacet;
-import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-//import org.apache.isis.core.metamodel.facets.WhenAndWhereValueFacet;
-
-/** @deprecated */
-@Deprecated
-public class ObjectAssociationFilters {
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> PROPERTIES;
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> REFERENCE_PROPERTIES;
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> WHERE_VISIBLE_IN_COLLECTION_TABLE;
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> WHERE_VISIBLE_IN_STANDALONE_TABLE;
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> ALL;
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> COLLECTIONS;
-    /** @deprecated */
-//    @Deprecated
-//    public static final Filter<ObjectAssociation> VISIBLE_AT_LEAST_SOMETIMES;
-
-    public ObjectAssociationFilters() {
-    }
-
-    /** @deprecated */
-    @Deprecated
-    public static final Filter<ObjectAssociation> staticallyVisible(Where context) {
-        return Filters.staticallyVisible(context);
-    }
-
-    /** @deprecated */
-    @Deprecated
-    public static Filter<ObjectAssociation> dynamicallyVisible(
-            AuthenticationSession session, ObjectAdapter target, Where where) {
-        return Filters.dynamicallyVisible(target, InteractionInitiatedBy.USER, where);
-    }
-
-    /** @deprecated */
-    @Deprecated
-    public static Filter<ObjectAssociation> enabled(AuthenticationSession session, ObjectAdapter adapter, Where where) {
-        return Filters.enabled(adapter, InteractionInitiatedBy.USER, where);
-    }
-
-    static {
-        PROPERTIES = Filters.PROPERTIES;
-        REFERENCE_PROPERTIES = Filters.REFERENCE_PROPERTIES;
-        WHERE_VISIBLE_IN_COLLECTION_TABLE = Filters.WHERE_VISIBLE_IN_COLLECTION_TABLE;
-        WHERE_VISIBLE_IN_STANDALONE_TABLE = Filters.WHERE_VISIBLE_IN_STANDALONE_TABLE;
-        ALL = Filters.ALL;
-        COLLECTIONS = Filters.COLLECTIONS;
-//        VISIBLE_AT_LEAST_SOMETIMES = Filters.VISIBLE_AT_LEAST_SOMETIMES;
-    }
-    
-    public static class Filters {
-
-        private Filters() {
-        }
-
-        /**
-         * Filters only fields that are for properties (ie 1:1 associations)
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> PROPERTIES = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation association) {
-                return association.isOneToOneAssociation();
-            }
-        };
-
-        /**
-         * Filters only fields that are for reference properties (ie 1:1 associations)
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> REFERENCE_PROPERTIES = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation association) {
-                return association.isOneToOneAssociation() && 
-                       !association.getSpecification().containsDoOpFacet(ValueFacet.class);
-            }
-        };
-        
-        /**
-         * Filters only fields that are for properties (ie 1:1 associations)
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> WHERE_VISIBLE_IN_COLLECTION_TABLE = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation association) {
-                final HiddenFacet hiddenFacet = association.getFacet(HiddenFacet.class);
-                return hiddenFacet == null || !hiddenFacet.where().inParentedTable();
-            }
-        };
-
-        /**
-         * Filters only fields that are for properties (ie 1:1 associations)
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> WHERE_VISIBLE_IN_STANDALONE_TABLE = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation association) {
-                final HiddenFacet hiddenFacet = association.getFacet(HiddenFacet.class);
-                return hiddenFacet == null || !hiddenFacet.where().inStandaloneTable();
-            }
-        };
-
-        /**
-         * Returns all fields (that is, filters out nothing).
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> ALL = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation property) {
-                return true;
-            }
-        };
-
-        /**
-         * Filters only fields that are for collections (ie 1:m associations)
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public final static Filter<ObjectAssociation> COLLECTIONS = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation property) {
-                return property.isOneToManyAssociation();
-            }
-        };
-
-        /**
-         * 
-         * [ahuber] not 100% equivalent to legacy code -> possible source of errors
-         * 
-         * Filters only properties that are visible statically, ie have not been
-         * unconditionally hidden at compile time.
-         *
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public static final Filter<ObjectAssociation> VISIBLE_AT_LEAST_SOMETIMES = new Filter<ObjectAssociation>() {
-            @Override
-            public boolean accept(final ObjectAssociation property) {
-                final HiddenFacet hiddenFacet = property.getFacet(HiddenFacet.class);
-                return hiddenFacet == null || hiddenFacet.where() != Where.EVERYWHERE;
-            }
-        };
-
-        /**
-         * [ahuber] not 100% equivalent to legacy code -> possible source of errors 
-         * 
-        * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-        */
-        @Deprecated
-        public static final Filter<ObjectAssociation> staticallyVisible(final Where context) {
-            return new Filter<ObjectAssociation>() {
-                @Override
-                public boolean accept(final ObjectAssociation association) {
-                    final List<Facet> facets = association.getFacets((Facet facet)->
-                             facet instanceof WhereValueFacet && facet instanceof HiddenFacet);
-                    for (Facet facet : facets) {
-                        final WhereValueFacet wawF = (WhereValueFacet) facet;
-                        if (wawF.where().includes(context) && wawF.where() == Where.EVERYWHERE) {
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-            };
-        }
-
-        /**
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public static Filter<ObjectAssociation> dynamicallyVisible(
-                final ObjectAdapter target,
-                final InteractionInitiatedBy interactionInitiatedBy,
-                final Where where) {
-            return new Filter<ObjectAssociation>() {
-                @Override
-                public boolean accept(final ObjectAssociation objectAssociation) {
-                    final Consent visible = objectAssociation.isVisible(target, interactionInitiatedBy, where);
-                    return visible.isAllowed();
-                }
-            };
-        }
-
-        /**
-         * @deprecated -use {@link com.google.common.base.Predicate equivalent}
-         */
-        @Deprecated
-        public static Filter<ObjectAssociation> enabled(
-                final ObjectAdapter adapter,
-                final InteractionInitiatedBy interactionInitiatedBy,
-                final Where where) {
-            return new Filter<ObjectAssociation>() {
-                @Override
-                public boolean accept(final ObjectAssociation objectAssociation) {
-                    final Consent usable = objectAssociation.isUsable(adapter, interactionInitiatedBy, where);
-                    return usable.isAllowed();
-                }
-            };
-        }
-
-    }
-    
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
index 9726bb1..400ae23 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
@@ -19,9 +19,8 @@
 
 package org.apache.isis.core.metamodel.facetapi;
 
-import java.util.List;
-
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 /**
  * Anything in the metamodel (which also includes peers in the reflector) that
@@ -68,7 +67,7 @@ public interface FacetHolder {
      * @param predicate
      * @return
      */
-    List<Facet> getFacets(Predicate<Facet> predicate);
+    Stream<Facet> streamFacets();
 
     /**
      * Adds the facet, extracting its {@link Facet#facetType() type} as the key.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderImpl.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderImpl.java
index 1f9523f..f711c26 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderImpl.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderImpl.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 /**
  * For base subclasses or, more likely, to help write tests.
@@ -99,8 +100,8 @@ public class FacetHolderImpl implements FacetHolder {
     }
 
     @Override
-    public List<Facet> getFacets(final Predicate<Facet> predicate) {
-        return FacetUtil.getFacets(facetsByClass, predicate);
+    public Stream<Facet> streamFacets() {
+        return FacetUtil.streamFacets(facetsByClass);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
index 4f86764..2fd21d0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
@@ -19,15 +19,14 @@
 
 package org.apache.isis.core.metamodel.facetapi;
 
-import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.isis.commons.internal._Constants;
 import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.collections._Lists;
 
 
 public final class FacetUtil {
@@ -40,8 +39,10 @@ public final class FacetUtil {
             return;
         }
         final FacetHolder facetHolder = facet.getFacetHolder();
-        final List<Facet> facets = facetHolder.getFacets(
-                each->facet.facetType() == each.facetType() && facet.getClass() == each.getClass() );
+        final List<Facet> facets = facetHolder.streamFacets()
+                .filter( each->facet.facetType() == each.facetType() && facet.getClass() == each.getClass() )
+                .collect(Collectors.toList());
+        
         if(facets.size() == 1) {
             final Facet existingFacet = facets.get(0);
             final Facet underlyingFacet = existingFacet.getUnderlyingFacet();
@@ -115,16 +116,10 @@ public final class FacetUtil {
      * Bit nasty, for use only by {@link FacetHolder}s that index their
      * {@link Facet}s in a Map.
      */
-    public static List<Facet> getFacets(final Map<Class<? extends Facet>, Facet> facetsByClass, final Predicate<Facet> predicate) {
-        final List<Facet> filteredFacets = _Lists.newArrayList();
-        final List<Facet> allFacets = new ArrayList<>(facetsByClass.values());
-        for (final Facet facet : allFacets) {
-            // facets that implement MultiTypedFacet will be held more than once.  The 'contains' check ensures they are only returned once, however.
-            if (predicate.test(facet) && !filteredFacets.contains(facet)) {
-                filteredFacets.add(facet);
-            }
-        }
-        return filteredFacets;
+    public static Stream<Facet> streamFacets(final Map<Class<? extends Facet>, Facet> facetsByClass) {
+        return facetsByClass.values()
+        .stream()
+        .distinct();
     }
 
     public static void removeFacet(final Map<Class<? extends Facet>, Facet> facetsByClass, final Facet facet) {
@@ -169,10 +164,8 @@ public final class FacetUtil {
             final Facet facet = source.getFacet(facetType);
 
         }
-        List<Facet> facets = source.getFacets(__->true);
-        for (Facet facet : facets) {
-            target.addFacet(facet);
-        }
+        source.streamFacets()
+        .forEach(target::addFacet);
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ImperativeFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ImperativeFacet.java
index 8a43f63..8e95bd0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ImperativeFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ImperativeFacet.java
@@ -19,15 +19,13 @@
 
 package org.apache.isis.core.metamodel.facets;
 
-import static org.apache.isis.commons.internal.functions._Predicates.alwaysTrue;
-
 import java.lang.reflect.Method;
 import java.util.List;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.functions._Predicates;
 import org.apache.isis.core.commons.lang.ObjectExtensions;
 import org.apache.isis.core.metamodel.facetapi.DecoratingFacet;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -134,19 +132,20 @@ public interface ImperativeFacet extends Facet {
         }
 
         public static Intent getIntent(final ObjectMember member, final Method method) {
-            final List<Facet> allFacets = member.getFacets(alwaysTrue());
             final List<ImperativeFacet> imperativeFacets = _Lists.newArrayList();
-            for (final Facet facet : allFacets) {
+            final Stream<Facet> allFacets = member.streamFacets();
+            allFacets.forEach(facet->{
                 final ImperativeFacet imperativeFacet = ImperativeFacet.Util.getImperativeFacet(facet);
                 if (imperativeFacet == null) {
-                    continue;
+                    return;
                 }
                 final List<Method> methods = imperativeFacet.getMethods();
                 if (!methods.contains(method)) {
-                    continue;
+                    return;
                 }
                 imperativeFacets.add(imperativeFacet);
-            }
+            });
+            
             switch(imperativeFacets.size()) {
             case 0:
                 break;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionUtils.java
index f64d2f7..0f0f0e7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/InteractionUtils.java
@@ -19,9 +19,8 @@
 
 package org.apache.isis.core.metamodel.interactions;
 
-import java.util.List;
-
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.isis.core.metamodel.consent.InteractionResult;
 import org.apache.isis.core.metamodel.consent.InteractionResultSet;
@@ -36,32 +35,32 @@ public final class InteractionUtils {
 
     public static InteractionResult isVisibleResult(final FacetHolder facetHolder, final VisibilityContext<?> context) {
         final InteractionResult result = new InteractionResult(context.createInteractionEvent());
-        final List<Facet> facets = facetHolder.getFacets(isA(HidingInteractionAdvisor.class));
-        for (final Facet facet : facets) {
+        final Stream<Facet> facets = facetHolder.streamFacets().filter(isA(HidingInteractionAdvisor.class));
+        facets.forEach(facet->{
             final HidingInteractionAdvisor advisor = (HidingInteractionAdvisor) facet;
             result.advise(advisor.hides(context), advisor);
-        }
+        });
         return result;
     }
 
     public static InteractionResult isUsableResult(final FacetHolder facetHolder, final UsabilityContext<?> context) {
         final InteractionResult result = new InteractionResult(context.createInteractionEvent());
-        final List<Facet> facets = facetHolder.getFacets(isA(DisablingInteractionAdvisor.class));
-        for (final Facet facet : facets) {
+        final Stream<Facet> facets = facetHolder.streamFacets().filter(isA(DisablingInteractionAdvisor.class));
+        facets.forEach(facet->{
             final DisablingInteractionAdvisor advisor = (DisablingInteractionAdvisor) facet;
             final String disables = advisor.disables(context);
             result.advise(disables, advisor);
-        }
+        });
         return result;
     }
 
     public static InteractionResult isValidResult(final FacetHolder facetHolder, final ValidityContext<?> context) {
         final InteractionResult result = new InteractionResult(context.createInteractionEvent());
-        final List<Facet> facets = facetHolder.getFacets(isA(ValidatingInteractionAdvisor.class));
-        for (final Facet facet : facets) {
+        final Stream<Facet> facets = facetHolder.streamFacets().filter(isA(ValidatingInteractionAdvisor.class));
+        facets.forEach(facet->{
             final ValidatingInteractionAdvisor advisor = (ValidatingInteractionAdvisor) facet;
             result.advise(advisor.invalidates(context), advisor);
-        }
+        });
         return result;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
index 6f7f1d8..eb529e7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.internal.base._Strings;
@@ -170,18 +171,13 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
             return new Predicate<ObjectAssociation>() {
                 @Override
                 public boolean test(final ObjectAssociation association) {
-                    final List<Facet> facets = association.getFacets(new Predicate<Facet>() {
-                        @Override public boolean test(final Facet facet) {
-                            return facet instanceof WhereValueFacet && facet instanceof HiddenFacet;
-                        }
-                    });
-                    for (Facet facet : facets) {
-                        final WhereValueFacet wawF = (WhereValueFacet) facet;
-                        if (wawF.where().includes(where)) {
-                            return false;
-                        }
-                    }
-                    return true;
+                    final Stream<Facet> facets = association.streamFacets()
+                            .filter((final Facet facet)->
+                                facet instanceof WhereValueFacet && facet instanceof HiddenFacet);
+                    
+                    return !facets
+                    .map(facet->(WhereValueFacet) facet)
+                    .anyMatch(wawF->wawF.where().includes(where));
                 }
             };
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
index 1eb5afd..169d144 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
@@ -24,6 +24,8 @@ import com.google.common.collect.Lists;
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
+
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -236,8 +238,8 @@ public class ObjectActionContributee extends ObjectActionDefault implements Cont
     }
 
     @Override
-    public List<Facet> getFacets(Predicate<Facet> predicate) {
-        return facetHolder.getFacets(predicate);
+    public Stream<Facet> streamFacets() {
+        return facetHolder.streamFacets();
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
index c901970..bf9be16 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
@@ -22,6 +22,8 @@ package org.apache.isis.core.metamodel.specloader.specimpl;
 import java.util.List;
 
 import java.util.function.Predicate;
+import java.util.stream.Stream;
+
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.Identifier;
@@ -241,9 +243,9 @@ public abstract class ObjectActionParameterAbstract implements ObjectActionParam
     }
 
     @Override
-    public List<Facet> getFacets(final Predicate<Facet> predicate) {
+    public Stream<Facet> streamFacets() {
         final FacetHolder facetHolder = getFacetHolder();
-        return facetHolder != null ? facetHolder.getFacets(predicate) : Lists.<Facet> newArrayList();
+        return facetHolder != null ? facetHolder.streamFacets() : Stream.of();
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index e180376..6794534 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Objects;
 
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Where;
@@ -152,8 +153,8 @@ public abstract class ObjectMemberAbstract implements ObjectMember {
     }
 
     @Override
-    public List<Facet> getFacets(final Predicate<Facet> predicate) {
-        return getFacetHolder().getFacets(predicate);
+    public Stream<Facet> streamFacets() {
+        return getFacetHolder().streamFacets();
     }
 
     @Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index 7065f39..8deffdd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -23,6 +23,8 @@ import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -32,12 +34,6 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.commons.internal.functions._Predicates;
-
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 import org.apache.isis.core.commons.lang.StringExtensions;
 import org.apache.isis.core.commons.util.ToString;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -377,26 +373,26 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
     private void cataloguePropertiesAndCollections(final Map<Method, ObjectMember> membersByMethod) {
         final Stream<ObjectAssociation> fields = streamAssociations(Contributed.EXCLUDED);
         fields.forEach(field->{
-            final List<Facet> facets = field.getFacets(ImperativeFacet.PREDICATE);
-            for (final Facet facet : facets) {
+            final Stream<Facet> facets = field.streamFacets().filter(ImperativeFacet.PREDICATE);
+            facets.forEach(facet->{
                 final ImperativeFacet imperativeFacet = ImperativeFacet.Util.getImperativeFacet(facet);
                 for (final Method imperativeFacetMethod : imperativeFacet.getMethods()) {
                     membersByMethod.put(imperativeFacetMethod, field);
                 }
-            }
+            });
         });
     }
 
     private void catalogueActions(final Map<Method, ObjectMember> membersByMethod) {
         final Stream<ObjectAction> userActions = streamObjectActions(Contributed.INCLUDED);
         userActions.forEach(userAction->{
-            final List<Facet> facets = userAction.getFacets(ImperativeFacet.PREDICATE);
-            for (final Facet facet : facets) {
+            final Stream<Facet> facets = userAction.streamFacets().filter(ImperativeFacet.PREDICATE);
+            facets.forEach(facet->{
                 final ImperativeFacet imperativeFacet = ImperativeFacet.Util.getImperativeFacet(facet);
                 for (final Method imperativeFacetMethod : imperativeFacet.getMethods()) {
                     membersByMethod.put(imperativeFacetMethod, userAction);
                 }
-            }
+            });
         });
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java
index 80b7906..4352f14 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/feature/ObjectAssociationPredicatesTest_visibleWhere.java
@@ -38,6 +38,8 @@ import org.junit.runners.Parameterized.Parameters;
 
 import org.apache.isis.applib.annotation.Where;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facets.WhereValueFacet;
 import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
@@ -107,8 +109,8 @@ public class ObjectAssociationPredicatesTest_visibleWhere {
             allowing(mockHiddenFacet).where();
             will(returnValue(where));
 
-            allowing(mockObjectAssociation).getFacets(with(any(Predicate.class)));
-            will(returnValue(Lists.newArrayList(mockHiddenFacet)));
+            allowing(mockObjectAssociation).streamFacets();
+            will(returnValue(Lists.newArrayList(mockHiddenFacet).stream()));
         }});
     }
 
@@ -131,11 +133,13 @@ public class ObjectAssociationPredicatesTest_visibleWhere {
         final Predicate<ObjectAssociation> predicate = new Predicate<ObjectAssociation>() {
             @Override
             public boolean test(final ObjectAssociation association) {
-                final List<Facet> facets = association.getFacets(new Predicate<Facet>() {
-                    @Override public boolean test(final Facet facet) {
-                        return facet instanceof WhereValueFacet && facet instanceof HiddenFacet;
-                    }
-                });
+                final List<Facet> facets = association.streamFacets()
+                        .filter(new Predicate<Facet>() {
+                            @Override public boolean test(final Facet facet) {
+                                return facet instanceof WhereValueFacet && facet instanceof HiddenFacet;
+                            }
+                        })
+                        .collect(Collectors.toList());
                 for (Facet facet : facets) {
                     final WhereValueFacet wawF = (WhereValueFacet) facet;
                     if (wawF.where().includes(whereContext)) {
diff --git a/core/plugins/jdo-datanucleus-4/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java b/core/plugins/jdo-datanucleus-4/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
index 9dba6f4..040e878 100644
--- a/core/plugins/jdo-datanucleus-4/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
+++ b/core/plugins/jdo-datanucleus-4/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
@@ -230,8 +230,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
 
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
                 
                 allowing(mockPasswordMember).isVisible(mockEmployeeAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE);
                 will(returnValue(visibilityConsent));
@@ -275,8 +275,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
         facets = Arrays.asList((Facet)new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
 
                 oneOf(mockPasswordMember).set(mockEmployeeAdapter, mockPasswordAdapter, InteractionInitiatedBy.USER);
             }
@@ -293,8 +293,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
         ));
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
                 
                 oneOf(mockPasswordMember).get(mockEmployeeAdapter, InteractionInitiatedBy.USER);
                 will(returnValue(mockPasswordAdapter));
diff --git a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
index a4127c0..b370b5f 100644
--- a/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
+++ b/core/plugins/jdo-datanucleus-5/src/test/java/org/apache/isis/core/wrapper/WrapperFactoryDefaultTest_wrappedObject_transient.java
@@ -230,8 +230,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
 
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
                 
                 allowing(mockPasswordMember).isVisible(mockEmployeeAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE);
                 will(returnValue(visibilityConsent));
@@ -275,8 +275,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
         facets = Arrays.asList((Facet)new PropertySetterFacetViaSetterMethod(setPasswordMethod, mockPasswordMember));
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
 
                 oneOf(mockPasswordMember).set(mockEmployeeAdapter, mockPasswordAdapter, InteractionInitiatedBy.USER);
             }
@@ -293,8 +293,8 @@ public class WrapperFactoryDefaultTest_wrappedObject_transient {
         ));
         context.checking(new Expectations() {
             {
-                allowing(mockPasswordMember).getFacets(with(any(Predicate.class)));
-                will(returnValue(facets));
+                allowing(mockPasswordMember).streamFacets();
+                will(returnValue(facets.stream()));
                 
                 oneOf(mockPasswordMember).get(mockEmployeeAdapter, InteractionInitiatedBy.USER);
                 will(returnValue(mockPasswordAdapter));
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
index f8efe43..ea5b3af 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
@@ -91,10 +91,10 @@ public class PersistenceSessionServiceInternalDefault implements PersistenceSess
         final boolean denyRefresh = fieldResetPolicy == BookmarkService.FieldResetPolicy.DONT_REFRESH; 
                         
         if(rootOid.isViewModel()) {
-            //FIXME[ISIS-1976] if code is reachable requires separate view model handler
             //throw _Exceptions.unexpectedCodeReach();
+            //FIXME[ISIS-1976] if code is reachable requires separate view model handler
             
-            return getPersistenceSession().adapterForViewModel(rootOid, __->rootOid); // reuse rootOid
+            return getPersistenceSession().adapterForViewModel(rootOid, __->rootOid).getObject(); // reuse rootOid
             
         } else if(denyRefresh) {
             return ps.fetchPersistentPojoInTransaction(rootOid);
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
index a09b3d4..1b3099e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/ajaxtable/CollectionContentsAsAjaxTablePanel.java
@@ -185,16 +185,13 @@ extends PanelAbstract<EntityCollectionModel> implements CollectionCountProvider
 
                         final Predicate<ObjectAssociation> predicate = ObjectAssociation.Predicates.PROPERTIES
                                 .and((final ObjectAssociation association)->{
-                                    final List<Facet> facets = association.getFacets((final Facet facet)->{
-                                        return facet instanceof WhereValueFacet && facet instanceof HiddenFacet;
-                                    });
-                                    for (Facet facet : facets) {
-                                        final WhereValueFacet wawF = (WhereValueFacet) facet;
-                                        if (wawF.where().includes(whereContext)) {
-                                            return false;
-                                        }
-                                    }
-                                    return true;
+                                    final Stream<Facet> facets = association.streamFacets()
+                                            .filter((final Facet facet)->
+                                                facet instanceof WhereValueFacet && facet instanceof HiddenFacet);
+                                    return !facets
+                                    .map(facet->(WhereValueFacet) facet)
+                                    .anyMatch(wawF->wawF.where().includes(whereContext));
+                                    
                                 })
                                 .and(associationDoesNotReferenceParent(parentSpecIfAny));