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 2021/03/03 18:39:13 UTC

[isis] 08/09: ISIS-2553: memoization for ApplicationFeatureId#getPathIds

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

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

commit 099e65acb9e74acaedbd1cd4f667e82e88398ce0
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Mar 3 19:06:14 2021 +0100

    ISIS-2553: memoization for ApplicationFeatureId#getPathIds
---
 .../services/appfeat/ApplicationFeatureId.java     | 121 +++++++++++----------
 .../ApplicationFeatureRepositoryDefault.java       |   4 +-
 .../metamodel/services/appfeat/_Predicates.java    |  19 ++--
 .../services/appfeat/ApplicationFeatureIdTest.java |  39 ++++---
 .../ApplicationFeatureRepositoryDefaultTest.java   |   2 +-
 .../api/permission/ApplicationPermissionValue.java |   3 +-
 .../permission/ApplicationPermissionValueSet.java  |   4 +-
 .../app/feature/ApplicationFeatureViewModel.java   |   6 +-
 .../user/ApplicationUser_filterPermissions.java    |  10 +-
 9 files changed, 110 insertions(+), 98 deletions(-)

diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
index c29f7e7..a0e6886 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/appfeat/ApplicationFeatureId.java
@@ -19,9 +19,8 @@
 package org.apache.isis.applib.services.appfeat;
 
 import java.io.Serializable;
-import java.util.Collections;
 import java.util.Comparator;
-import java.util.List;
+import java.util.function.Consumer;
 
 import static java.util.Comparator.comparing;
 import static java.util.Comparator.naturalOrder;
@@ -37,6 +36,7 @@ import org.apache.isis.applib.util.Hashing;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.applib.util.ToString;
+import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
@@ -44,7 +44,7 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
 
 import lombok.Getter;
 import lombok.NonNull;
-import lombok.Setter;
+import lombok.Synchronized;
 import lombok.val;
 
 /**
@@ -102,6 +102,7 @@ implements
             final @NonNull  String namespace, 
             final @Nullable String logicalTypeSimpleName,
             final @Nullable String memberName) {
+        
         if(logicalTypeSimpleName == null) {
             return newNamespace(namespace);
         }
@@ -113,55 +114,51 @@ implements
     }
 
     public static ApplicationFeatureId newNamespace(final String namespace) {
-        val feature = new ApplicationFeatureId(ApplicationFeatureSort.NAMESPACE);
-        feature.setNamespace(namespace);
-        feature.setTypeSimpleName(null);
-        feature.setMemberName(null);
-        return feature;
+        val featureId = new ApplicationFeatureId(ApplicationFeatureSort.NAMESPACE);
+        featureId.namespace = namespace;
+        featureId.typeSimpleName = null;
+        featureId.memberName = null;
+        return featureId;
     }
 
     public static ApplicationFeatureId newType(final String logicalTypeName) {
-        val feat = new ApplicationFeatureId(ApplicationFeatureSort.TYPE);
-        initType(feat, logicalTypeName);
-        return feat;
+        val featureId = new ApplicationFeatureId(ApplicationFeatureSort.TYPE);
+        initType(featureId, logicalTypeName);
+        return featureId;
     }
 
     public static ApplicationFeatureId newMember(final String logicalTypeName, final String memberName) {
-        final ApplicationFeatureId featureId = new ApplicationFeatureId(ApplicationFeatureSort.MEMBER);
+        val featureId = new ApplicationFeatureId(ApplicationFeatureSort.MEMBER);
         initType(featureId, logicalTypeName);
-        featureId.setMemberName(memberName);
+        featureId.memberName = memberName;
         return featureId;
     }
 
-    public static ApplicationFeatureId newMember(String fqn) {
-        val feat = new ApplicationFeatureId(ApplicationFeatureSort.MEMBER);
-        initMember(feat, fqn);
-        return feat;
+    public static ApplicationFeatureId newMember(String fullyQualifiedName) {
+        val featureId = new ApplicationFeatureId(ApplicationFeatureSort.MEMBER);
+        final int i = fullyQualifiedName.lastIndexOf("#");
+        if(i == -1) {
+            throw new IllegalArgumentException("Malformed, expected a '#': " + fullyQualifiedName);
+        }
+        val logicalTypeName = fullyQualifiedName.substring(0, i);
+        val memberName = fullyQualifiedName.substring(i + 1);
+        initType(featureId, logicalTypeName);
+        featureId.memberName = memberName;
+        return featureId;
     }
     
     // -- FACTORY HELPERS
     
-    private static void initType(final ApplicationFeatureId feature, final String fullyQualifiedName) {
+    private static void initType(final ApplicationFeatureId featureId, final String fullyQualifiedName) {
         final int i = fullyQualifiedName.lastIndexOf(".");
         if(i != -1) {
-            feature.setNamespace(fullyQualifiedName.substring(0, i));
-            feature.setTypeSimpleName(fullyQualifiedName.substring(i+1));
+            featureId.namespace = fullyQualifiedName.substring(0, i);
+            featureId.typeSimpleName = fullyQualifiedName.substring(i+1);
         } else {
-            feature.setNamespace("");
-            feature.setTypeSimpleName(fullyQualifiedName);
+            featureId.namespace = "";
+            featureId.typeSimpleName = fullyQualifiedName;
         }
-        feature.setMemberName(null);
-    }
-    
-    private static void initMember(final ApplicationFeatureId feature, final String fullyQualifiedName) {
-        final int i = fullyQualifiedName.lastIndexOf("#");
-        if(i == -1) {
-            throw new IllegalArgumentException("Malformed, expected a '#': " + fullyQualifiedName);
-        }
-        final String className = fullyQualifiedName.substring(0, i);
-        final String memberName = fullyQualifiedName.substring(i+1);
-        initType(feature, className);
-        feature.setMemberName(memberName);
+        featureId.memberName = null;
     }
     
     // -- CONSTRUCTOR
@@ -187,9 +184,9 @@ implements
     @Getter final @NonNull ApplicationFeatureSort sort;
     
     /**
-     * The {@link ApplicationFeatureId id} of the member's class.
+     * The {@link ApplicationFeatureId id} of the member's logical type.
      */
-    public ApplicationFeatureId getParentClassId() {
+    public ApplicationFeatureId getParentTypeFeatureId() {
         _Assert.assertTrue(sort.isMember());
         final String logicalTypeName = this.getNamespace() + "." + getTypeSimpleName();
         return newType(logicalTypeName);
@@ -198,13 +195,13 @@ implements
     // -- PROPERTIES - NON UI
     
     @Programmatic 
-    @Getter @Setter private String namespace;
+    @Getter private String namespace;
 
     @Programmatic 
-    @Getter @Setter private String typeSimpleName;
+    @Getter private String typeSimpleName;
 
     @Programmatic 
-    @Getter @Setter private String memberName;
+    @Getter private String memberName;
 
     @Programmatic
     public String getFullyQualifiedName() {
@@ -239,7 +236,7 @@ implements
      * class or package.
      */
     @Programmatic
-    public ApplicationFeatureId getParentPackageId() {
+    public ApplicationFeatureId getParentNamespaceFeatureId() {
         
         _Assert.assertFalse(sort.isMember());
 
@@ -286,35 +283,43 @@ implements
 
     // -- pathIds, parentIds
 
-    @Programmatic
-    public List<ApplicationFeatureId> getPathIds() {
-        //TODO[2533] add memoization
-        return pathIds(this);
+    private transient Can<ApplicationFeatureId> pathIds;
+    
+    @Programmatic @Synchronized
+    public Can<ApplicationFeatureId> getPathIds() {
+        if(pathIds==null) {
+            pathIds = pathIds(this);
+        }
+        return pathIds;
     }
 
     @Programmatic
-    public List<ApplicationFeatureId> getParentIds() {
-        //TODO[2533] add memoization
-        return pathIds(getParentId());
+    public Can<ApplicationFeatureId> getParentFeatureIds() {
+        val parent = getParentFeatureId();
+        return parent!=null
+                ? getParentFeatureId().getPathIds()
+                : Can.empty();
     }
 
-    private ApplicationFeatureId getParentId() {
-        return sort == ApplicationFeatureSort.MEMBER
-                ? getParentClassId()
-                : getParentPackageId();
+    private ApplicationFeatureId getParentFeatureId() {
+        return sort.isMember()
+                ? getParentTypeFeatureId()
+                : getParentNamespaceFeatureId();
     }
 
-    private static List<ApplicationFeatureId> pathIds(final ApplicationFeatureId id) {
-        final List<ApplicationFeatureId> featureIds = _Lists.newArrayList();
-        return Collections.unmodifiableList(appendParents(id, featureIds));
+    private static Can<ApplicationFeatureId> pathIds(final ApplicationFeatureId featureId) {
+        val featureIds = _Lists.<ApplicationFeatureId>newArrayList();
+        visitSelfAndParents(featureId, featureIds::add);
+        return Can.ofCollection(featureIds);
     }
 
-    private static List<ApplicationFeatureId> appendParents(final ApplicationFeatureId featureId, final List<ApplicationFeatureId> parentIds) {
+    private static void visitSelfAndParents(
+            final ApplicationFeatureId featureId, 
+            final Consumer<ApplicationFeatureId> onNext) {
         if(featureId != null) {
-            parentIds.add(featureId);
-            appendParents(featureId.getParentId(), parentIds);
+            onNext.accept(featureId);
+            visitSelfAndParents(featureId.getParentFeatureId(), onNext);
         }
-        return parentIds;
     }
 
     // -- OBJECT CONTRACT
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index d325519..6efee8c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -212,7 +212,7 @@ implements ApplicationFeatureRepository {
 
 
     ApplicationFeatureId addClassParent(final ApplicationFeatureId classFeatureId) {
-        final ApplicationFeatureId parentPackageId = classFeatureId.getParentPackageId();
+        final ApplicationFeatureId parentPackageId = classFeatureId.getParentNamespaceFeatureId();
         final ApplicationFeature parentPackage = findPackageElseCreate(parentPackageId);
 
         parentPackage.addToContents(classFeatureId);
@@ -220,7 +220,7 @@ implements ApplicationFeatureRepository {
     }
 
     void addParents(final ApplicationFeatureId classOrPackageId) {
-        final ApplicationFeatureId parentPackageId = classOrPackageId.getParentPackageId();
+        final ApplicationFeatureId parentPackageId = classOrPackageId.getParentNamespaceFeatureId();
         if (parentPackageId == null) {
             return;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java
index bfca014..13a9c22 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/_Predicates.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.services.appfeat;
 
+import java.util.Objects;
 import java.util.function.Predicate;
 
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
@@ -27,10 +28,10 @@ import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 final class _Predicates {
 
     public static Predicate<ApplicationFeatureId> isClassContaining(
-            final ApplicationMemberType memberType, final ApplicationFeatureRepositoryDefault applicationFeatures) {
-        return new Predicate<ApplicationFeatureId>() {
-            @Override
-            public boolean test(final ApplicationFeatureId input) {
+            final ApplicationMemberType memberType, 
+            final ApplicationFeatureRepositoryDefault applicationFeatures) {
+        
+        return (final ApplicationFeatureId input) -> {
                 if(input.getSort() != ApplicationFeatureSort.TYPE) {
                     return false;
                 }
@@ -38,13 +39,15 @@ final class _Predicates {
                 if(feature == null) {
                     return false;
                 }
-                return memberType == null || !feature.membersOf(memberType).isEmpty();
-            }
+                return memberType == null 
+                        || !feature.membersOf(memberType).isEmpty();
         };
     }
 
-    public static Predicate<ApplicationFeatureId> isClassRecursivelyWithin(final ApplicationFeatureId packageId) {
-        return (ApplicationFeatureId input) -> input.getParentIds().contains(packageId);
+    public static Predicate<ApplicationFeatureId> isClassRecursivelyWithin(
+            final ApplicationFeatureId packageId) {
+        return (final ApplicationFeatureId input) -> 
+            input.getPathIds().stream().skip(1L).anyMatch(id->Objects.equals(id, packageId));
     }
 
 }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
index 5f1da3d..b4d49e1 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureIdTest.java
@@ -181,7 +181,8 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com");
 
             // when
-            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentIds();
+            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentFeatureIds()
+                    .toList();
 
             // then
             assertThat(parentIds, emptyCollectionOf(ApplicationFeatureId.class));
@@ -194,7 +195,8 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com.mycompany");
 
             // when
-            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentIds();
+            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentFeatureIds()
+                    .toList();
 
             // then
             assertThat(parentIds, contains(ApplicationFeatureId.newNamespace("com")));
@@ -207,7 +209,8 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com.mycompany.bish.bosh");
 
             // when
-            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentIds();
+            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentFeatureIds()
+                    .toList();
 
             // then
             assertThat(parentIds, contains(
@@ -224,7 +227,8 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newType("com.mycompany.Bar");
 
             // when
-            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentIds();
+            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentFeatureIds()
+                    .toList();
 
             // then
             assertThat(parentIds, contains(
@@ -240,7 +244,8 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newMember("com.mycompany.Bar", "foo");
 
             // when
-            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentIds();
+            final List<ApplicationFeatureId> parentIds = applicationFeatureId.getParentFeatureIds()
+                    .toList();
 
             // then
             assertThat(parentIds, contains(
@@ -259,7 +264,7 @@ public class ApplicationFeatureIdTest {
             // given
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com.mycompany");
             // when
-            val parentPackageId = applicationFeatureId.getParentPackageId();
+            val parentPackageId = applicationFeatureId.getParentNamespaceFeatureId();
             // then
             assertThat(parentPackageId.getSort(), is(ApplicationFeatureSort.NAMESPACE));
             assertThat(parentPackageId.getNamespace(), is("com"));
@@ -272,7 +277,7 @@ public class ApplicationFeatureIdTest {
             // given
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com");
             // when
-            val parentPackageId = applicationFeatureId.getParentPackageId();
+            val parentPackageId = applicationFeatureId.getParentNamespaceFeatureId();
             // then
             assertThat(parentPackageId, is(nullValue()));
         }
@@ -282,7 +287,7 @@ public class ApplicationFeatureIdTest {
             // given
             val applicationFeatureId = ApplicationFeatureId.newNamespace("");
             // when
-            val parentPackageId = applicationFeatureId.getParentPackageId();
+            val parentPackageId = applicationFeatureId.getParentNamespaceFeatureId();
             // then
             assertThat(parentPackageId, is(nullValue()));
         }
@@ -293,7 +298,7 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newType("com.mycompany.Bar");
 
             // when
-            val parentPackageId = applicationFeatureId.getParentPackageId();
+            val parentPackageId = applicationFeatureId.getParentNamespaceFeatureId();
 
             // then
             assertThat(parentPackageId.getSort(), is(ApplicationFeatureSort.NAMESPACE));
@@ -308,7 +313,7 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newType("Bar");
 
             // when
-            val parentPackageId = applicationFeatureId.getParentPackageId();
+            val parentPackageId = applicationFeatureId.getParentNamespaceFeatureId();
 
             // then
             assertThat(parentPackageId.getSort(), is(ApplicationFeatureSort.NAMESPACE));
@@ -324,10 +329,10 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newMember("com.mycompany.Bar", "foo");
 
             // then
-            expectedException.expect(IllegalStateException.class);
+            expectedException.expect(AssertionError.class);
 
             // when
-            applicationFeatureId.getParentPackageId();
+            applicationFeatureId.getParentNamespaceFeatureId();
         }
 
     }
@@ -340,7 +345,7 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newMember("com.mycompany.Bar", "foo");
 
             // when
-            val parentClassId = applicationFeatureId.getParentClassId();
+            val parentClassId = applicationFeatureId.getParentTypeFeatureId();
 
             // then
             assertThat(parentClassId.getSort(), is(ApplicationFeatureSort.TYPE));
@@ -355,10 +360,10 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newNamespace("com");
 
             // then
-            expectedException.expect(IllegalStateException.class);
+            expectedException.expect(AssertionError.class);
 
             // when
-            applicationFeatureId.getParentClassId();
+            applicationFeatureId.getParentTypeFeatureId();
         }
 
         @Test
@@ -368,10 +373,10 @@ public class ApplicationFeatureIdTest {
             val applicationFeatureId = ApplicationFeatureId.newType("com.mycompany.Bar");
 
             // then
-            expectedException.expect(IllegalStateException.class);
+            expectedException.expect(AssertionError.class);
 
             // when
-            applicationFeatureId.getParentClassId();
+            applicationFeatureId.getParentTypeFeatureId();
         }
     }
 
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
index a37c42c..2818b99 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefaultTest.java
@@ -289,7 +289,7 @@ public class ApplicationFeatureRepositoryDefaultTest {
             final ApplicationFeatureId classParentId = applicationFeatureRepository.addClassParent(classFeatureId);
 
             // then
-            Assert.assertThat(classParentId, is(equalTo(classFeatureId.getParentPackageId())));
+            Assert.assertThat(classParentId, is(equalTo(classFeatureId.getParentNamespaceFeatureId())));
             final ApplicationFeature classPackage = applicationFeatureRepository.findPackage(classParentId);
             assertThat(classPackage, is(newlyCreatedParent));
         }
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
index 6bd68ab..3545049 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValue.java
@@ -109,8 +109,7 @@ public class ApplicationPermissionValue implements Comparable<ApplicationPermiss
 
     private boolean onPathOf(final ApplicationFeatureId featureId) {
 
-        final List<ApplicationFeatureId> pathIds = featureId.getPathIds();
-        for (final ApplicationFeatureId pathId : pathIds) {
+        for (final ApplicationFeatureId pathId : featureId.getPathIds()) {
             if(getFeatureId().equals(pathId)) {
                 return true;
             }
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
index 6ffa62f..b80476f 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionValueSet.java
@@ -142,8 +142,8 @@ public class ApplicationPermissionValueSet implements Serializable {
     public Evaluation evaluate(
             final ApplicationFeatureId featureId,
             final ApplicationPermissionMode mode) {
-        final List<ApplicationFeatureId> pathIds = featureId.getPathIds();
-        for (final ApplicationFeatureId pathId : pathIds) {
+        
+        for (final ApplicationFeatureId pathId : featureId.getPathIds()) {
             final Collection<ApplicationPermissionValue> permissionValues = permissionsByFeature.get(pathId);
             final Evaluation evaluation = permissionsEvaluationService.evaluate(featureId, mode, permissionValues);
             if(evaluation != null) {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
index e143702..1dad3e5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/feature/ApplicationFeatureViewModel.java
@@ -237,8 +237,8 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
     public ApplicationFeatureViewModel getParent() {
         final ApplicationFeatureId parentId;
         parentId = getType() == ApplicationFeatureSort.MEMBER
-                ? getFeatureId().getParentClassId()
-                : getFeatureId().getParentPackageId();
+                ? getFeatureId().getParentTypeFeatureId()
+                : getFeatureId().getParentNamespaceFeatureId();
         if(parentId == null) {
             return null;
         }
@@ -275,7 +275,7 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
     @Programmatic
     public ApplicationFeatureViewModel getParentPackage() {
         return Functions.asViewModelForId(applicationFeatureRepository, factory)
-                .apply(getFeatureId().getParentPackageId());
+                .apply(getFeatureId().getParentNamespaceFeatureId());
     }
 
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
index bfdd50c..36d1451 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/ApplicationUser_filterPermissions.java
@@ -84,19 +84,19 @@ public class ApplicationUser_filterPermissions {
     }
 
 
-    static Predicate<ApplicationFeature> within(final String packageFqn, final String className) {
+    static Predicate<ApplicationFeature> within(final String namespace, final String logicalTypeSimpleName) {
         return (ApplicationFeature input) -> {
             final ApplicationFeatureId inputFeatureId = input.getFeatureId();
 
             // recursive match on package
-            final ApplicationFeatureId packageId = ApplicationFeatureId.newNamespace(packageFqn);
-            final List<ApplicationFeatureId> pathIds = inputFeatureId.getPathIds();
-            if(!pathIds.contains(packageId)) {
+            val namespaceId = ApplicationFeatureId.newNamespace(namespace);
+            if(!inputFeatureId.getPathIds().contains(namespaceId)) {
                 return false;
             }
 
             // match on class (if specified)
-            return className == null || Objects.equals(inputFeatureId.getTypeSimpleName(), className);
+            return logicalTypeSimpleName == null 
+                    || Objects.equals(inputFeatureId.getTypeSimpleName(), logicalTypeSimpleName);
         };
     }