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 2020/02/18 10:18:35 UTC

[isis] branch master updated: ISIS-2291: generic type param for ApplicationPermissionRepository

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 86e6298  ISIS-2291: generic type param for ApplicationPermissionRepository
86e6298 is described below

commit 86e62987e7fdf6f501e119a8a5c034ff69e89a79
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Feb 18 11:18:25 2020 +0100

    ISIS-2291: generic type param for ApplicationPermissionRepository
---
 .../ApplicationPermissionRepository.java           |  33 ++--
 .../app/feature/ApplicationFeatureViewModel.java   |  20 +-
 .../model/app/user/UserPermissionViewModel.java    |   8 +-
 .../dom/permission/ApplicationPermissionMenu.java  |  12 +-
 .../model/dom/role/ApplicationRole_addAction.java  |   3 +-
 .../model/dom/role/ApplicationRole_addClass.java   |   3 +-
 .../dom/role/ApplicationRole_addCollection.java    |   3 +-
 .../model/dom/role/ApplicationRole_addPackage.java |   3 +-
 .../dom/role/ApplicationRole_addProperty.java      |   3 +-
 .../dom/role/ApplicationRole_removePermission.java |   8 +-
 .../facets/TenantedAuthorizationFacetDefault.java  |  10 +-
 .../ApplicationPermissionRepository.java           | 204 +++++++++------------
 12 files changed, 138 insertions(+), 172 deletions(-)

diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
index 9da38e2..fe49246 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/ApplicationPermissionRepository.java
@@ -18,40 +18,39 @@
  */
 package org.apache.isis.extensions.secman.api.permission;
 
-import java.util.List;
+import java.util.Collection;
+import java.util.Optional;
 
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
 import org.apache.isis.extensions.secman.api.role.ApplicationRole;
 
-public interface ApplicationPermissionRepository {
+public interface ApplicationPermissionRepository<P extends ApplicationPermission> {
 
-    ApplicationPermission findByUserAndPermissionValue(String username,
-            ApplicationPermissionValue changingPermissionValue);
+    Optional<P> findByUserAndPermissionValue(String username, ApplicationPermissionValue changingPermissionValue);
 
-    List<ApplicationPermission> findByFeatureCached(ApplicationFeatureId featureId);
-
-    List<ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
-            ApplicationRole holder,
-            ApplicationPermissionRule rule, 
-            ApplicationFeatureType type);
-    
-    ApplicationPermission findByRoleAndRuleAndFeature(
+    Optional<P> findByRoleAndRuleAndFeature(
             ApplicationRole holder, 
             ApplicationPermissionRule rule,
             ApplicationFeatureType type, 
             String featureFqn);
+
+    Collection<P> allPermissions();
     
-    List<ApplicationPermission> findOrphaned();
+    Collection<P> findOrphaned();
+    Collection<P> findByFeatureCached(ApplicationFeatureId featureId);
+    Collection<P> findByRoleAndRuleAndFeatureTypeCached(
+            ApplicationRole holder,
+            ApplicationPermissionRule rule, 
+            ApplicationFeatureType type);
 
-    List<ApplicationPermission> allPermissions();
 
     /**
      * @return detached entity
      */
-    ApplicationPermission newApplicationPermission();
+    P newApplicationPermission();
     
-    ApplicationPermission newPermission(
+    P newPermission(
             ApplicationRole role,
             ApplicationPermissionRule rule, 
             ApplicationPermissionMode mode,
@@ -59,7 +58,7 @@ public interface ApplicationPermissionRepository {
             String className, 
             String memberName);
 
-    ApplicationPermission newPermission(
+    P newPermission(
             ApplicationRole holder, 
             ApplicationPermissionRule rule, 
             ApplicationPermissionMode mode,
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 6f3cc9a..1760a46 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
@@ -33,20 +33,19 @@ import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.factory.FactoryService;
-import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.util.Equality;
 import org.apache.isis.applib.util.Hashing;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.ToString;
 import org.apache.isis.core.commons.internal.base._Casts;
 import org.apache.isis.core.commons.internal.collections._Lists;
-import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
-import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureRepositoryDefault;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 
 import lombok.val;
 
@@ -61,12 +60,12 @@ import lombok.val;
 public abstract class ApplicationFeatureViewModel implements ViewModel {
 
     public static abstract class PropertyDomainEvent<S extends ApplicationFeatureViewModel,T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<S, T> {}
-
     public static abstract class CollectionDomainEvent<S extends ApplicationFeatureViewModel,T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<S, T> {}
-
     public static abstract class ActionDomainEvent<S extends ApplicationFeatureViewModel> extends IsisModuleExtSecmanApi.ActionDomainEvent<S> {}
 
-
+    @Inject private FactoryService factory;
+    @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
 
     // -- constructors
     public static ApplicationFeatureViewModel newViewModel(
@@ -283,7 +282,7 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
             defaultView="table"
             )
     @MemberOrder(sequence = "10")
-    public List<? extends ApplicationPermission> getPermissions() {
+    public java.util.Collection<? extends ApplicationPermission> getPermissions() {
         return applicationPermissionRepository.findByFeatureCached(getFeatureId());
     }
 
@@ -360,12 +359,7 @@ public abstract class ApplicationFeatureViewModel implements ViewModel {
         }
     }
 
-    // -- DEPENDENCIES
 
-    @Inject RepositoryService repository;
-    @Inject FactoryService factory;
-    @Inject ApplicationFeatureRepositoryDefault applicationFeatureRepository;
-    @Inject ApplicationPermissionRepository applicationPermissionRepository;
 
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
index 1e2af68..71a7422 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/app/user/UserPermissionViewModel.java
@@ -82,7 +82,7 @@ public class UserPermissionViewModel implements ViewModel {
     @Inject private ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     @Inject private FactoryService factory;
     @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
 
     // -- constructors, factory methods
     public static UserPermissionViewModel newViewModel(
@@ -329,7 +329,8 @@ public class UserPermissionViewModel implements ViewModel {
         if(getViewingPermissionValue() == null) {
             return null;
         }
-        return applicationPermissionRepository.findByUserAndPermissionValue(username, getViewingPermissionValue());
+        return applicationPermissionRepository.findByUserAndPermissionValue(username, getViewingPermissionValue())
+                .orElse(null);
     }
 
     private ApplicationPermissionValue getViewingPermissionValue() {
@@ -359,7 +360,8 @@ public class UserPermissionViewModel implements ViewModel {
         if(getChangingPermissionValue() == null) {
             return null;
         }
-        return applicationPermissionRepository.findByUserAndPermissionValue(username, getChangingPermissionValue());
+        return applicationPermissionRepository.findByUserAndPermissionValue(username, getChangingPermissionValue())
+                .orElse(null);
     }
 
     private ApplicationPermissionValue getChangingPermissionValue() {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
index 0e8b1bd..2c4f20f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/permission/ApplicationPermissionMenu.java
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.extensions.secman.model.dom.permission;
 
-import java.util.List;
+import java.util.Collection;
 
 import javax.inject.Inject;
 
@@ -45,11 +45,10 @@ public class ApplicationPermissionMenu {
 
     // -- domain event classes
     public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermissionMenu, T> {}
-
     public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermissionMenu, T> {}
-
     public static abstract class ActionDomainEvent extends IsisModuleExtSecmanApi.ActionDomainEvent<ApplicationPermissionMenu> {}
 
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
 
     // -- iconName
     public String iconName() {
@@ -65,7 +64,7 @@ public class ApplicationPermissionMenu {
             semantics = SemanticsOf.SAFE
             )
     @MemberOrder(sequence = "100.50.1")
-    public List<? extends ApplicationPermission> findOrphanedPermissions() {
+    public Collection<? extends ApplicationPermission> findOrphanedPermissions() {
         return applicationPermissionRepository.findOrphaned();
     }
 
@@ -79,12 +78,9 @@ public class ApplicationPermissionMenu {
             restrictTo = RestrictTo.PROTOTYPING
             )
     @MemberOrder(sequence = "100.50.2")
-    public List<? extends ApplicationPermission> allPermissions() {
+    public Collection<? extends ApplicationPermission> allPermissions() {
         return applicationPermissionRepository.allPermissions();
     }
 
-    // -- DEPENDENCIES
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
-
 
 }
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
index 179b291..0df9363 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addAction.java
@@ -28,6 +28,7 @@ import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
@@ -41,7 +42,7 @@ import lombok.RequiredArgsConstructor;
 public class ApplicationRole_addAction {
     
     @Inject private ApplicationFeatureRepository applicationFeatureRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
index f112312..3b2297c 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addClass.java
@@ -26,6 +26,7 @@ import org.apache.isis.applib.annotation.MemberOrder;
 import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
@@ -38,7 +39,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class ApplicationRole_addClass {
     
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
index e44d04a..15b51ae 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addCollection.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
@@ -43,7 +44,7 @@ import lombok.RequiredArgsConstructor;
 public class ApplicationRole_addCollection {
     
     @Inject private ApplicationFeatureRepository applicationFeatureRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
index 489d9bf..96bcd1f 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addPackage.java
@@ -27,6 +27,7 @@ import org.apache.isis.applib.annotation.ParameterLayout;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
@@ -40,7 +41,7 @@ import lombok.RequiredArgsConstructor;
 public class ApplicationRole_addPackage {
     
     @Inject private ApplicationFeatureRepository applicationFeatureRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
     
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
index f16ae38..d9d56c1 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_addProperty.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureType;
+import org.apache.isis.extensions.secman.api.permission.ApplicationPermission;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository;
 import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRule;
@@ -43,7 +44,7 @@ import lombok.RequiredArgsConstructor;
 public class ApplicationRole_addProperty {
     
     @Inject private ApplicationFeatureRepository applicationFeatureRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
 
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
index c95a28a..7e9e4d5 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/dom/role/ApplicationRole_removePermission.java
@@ -19,7 +19,6 @@
 package org.apache.isis.extensions.secman.model.dom.role;
 
 import java.util.Collection;
-import java.util.List;
 
 import javax.enterprise.inject.Model;
 import javax.inject.Inject;
@@ -48,7 +47,7 @@ public class ApplicationRole_removePermission {
     @Inject private SecurityModuleConfig configBean;
     @Inject private RepositoryService repository;
     @Inject private ApplicationRoleRepository<? extends ApplicationRole> applicationRoleRepository;
-    @Inject private ApplicationPermissionRepository applicationPermissionRepository;
+    @Inject private ApplicationPermissionRepository<? extends ApplicationPermission> applicationPermissionRepository;
     
     private final ApplicationRole holder;
 
@@ -62,7 +61,8 @@ public class ApplicationRole_removePermission {
             final String featureFqn) {
         
         final ApplicationPermission permission = applicationPermissionRepository
-                .findByRoleAndRuleAndFeature(holder, rule, type, featureFqn);
+                .findByRoleAndRuleAndFeature(holder, rule, type, featureFqn)
+                .orElse(null);
         if(permission != null) {
             repository.remove(permission);
         }
@@ -99,7 +99,7 @@ public class ApplicationRole_removePermission {
             final ApplicationPermissionRule rule,
             final ApplicationFeatureType type) {
         
-        final List<ApplicationPermission> permissions = applicationPermissionRepository
+        final Collection<? extends ApplicationPermission> permissions = applicationPermissionRepository
                 .findByRoleAndRuleAndFeatureTypeCached(holder, rule, type);
         return _Lists.map(
                 permissions,
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
index 20c2cef..b6340fc 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/facets/TenantedAuthorizationFacetDefault.java
@@ -25,14 +25,14 @@ import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
 import org.apache.isis.applib.services.user.UserService;
 import org.apache.isis.applib.services.wrapper.events.UsabilityEvent;
 import org.apache.isis.applib.services.wrapper.events.VisibilityEvent;
-import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyEvaluator;
-import org.apache.isis.extensions.secman.api.user.ApplicationUser;
-import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
+import org.apache.isis.extensions.secman.api.tenancy.ApplicationTenancyEvaluator;
+import org.apache.isis.extensions.secman.api.user.ApplicationUser;
+import org.apache.isis.extensions.secman.api.user.ApplicationUserRepository;
 
 public class TenantedAuthorizationFacetDefault extends FacetAbstract implements TenantedAuthorizationFacet {
 
@@ -41,13 +41,13 @@ public class TenantedAuthorizationFacetDefault extends FacetAbstract implements
     }
 
     private final List<ApplicationTenancyEvaluator> evaluators;
-    private final ApplicationUserRepository applicationUserRepository;
+    private final ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository;
     private final QueryResultsCache queryResultsCache;
     private final UserService userService;
 
     public TenantedAuthorizationFacetDefault(
             final List<ApplicationTenancyEvaluator> evaluators,
-            final ApplicationUserRepository applicationUserRepository,
+            final ApplicationUserRepository<? extends ApplicationUser> applicationUserRepository,
             final QueryResultsCache queryResultsCache,
             final UserService userService,
             final FacetHolder holder) {
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
index 7899255..75adcb4 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/dom/permission/ApplicationPermissionRepository.java
@@ -20,9 +20,8 @@ package org.apache.isis.extensions.secman.jdo.dom.permission;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.stream.Collectors;
 
 import javax.inject.Inject;
@@ -41,6 +40,7 @@ import org.apache.isis.core.commons.internal.base._NullSafe;
 import org.apache.isis.core.commons.internal.base._Strings;
 import org.apache.isis.core.commons.internal.collections._Lists;
 import org.apache.isis.core.commons.internal.collections._Multimaps;
+import org.apache.isis.core.commons.internal.collections._Multimaps.ListMultimap;
 import org.apache.isis.core.commons.internal.collections._Sets;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeature;
 import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId;
@@ -52,35 +52,32 @@ import org.apache.isis.extensions.secman.api.permission.ApplicationPermissionVal
 import org.apache.isis.extensions.secman.jdo.dom.role.ApplicationRole;
 import org.apache.isis.extensions.secman.jdo.dom.user.ApplicationUser;
 
+import lombok.NonNull;
 import lombok.val;
 
 @Repository
 @Named("isisExtSecman.applicationPermissionRepository")
-public class ApplicationPermissionRepository 
-implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository {
+public class ApplicationPermissionRepository
+implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissionRepository<ApplicationPermission> {
 
     @Inject private RepositoryService repository;
     @Inject private ApplicationFeatureRepositoryDefault applicationFeatureRepository;
     @Inject private QueryResultsCache queryResultsCache;
     @Inject private FactoryService factory;
     @Inject private MessageService messages;
-    
+
     @Override
     public ApplicationPermission newApplicationPermission() {
         return factory.detachedEntity(ApplicationPermission.class);
     }
-    
+
     // -- findByRole (programmatic)
-    public List<ApplicationPermission> findByRoleCached(final ApplicationRole role) {
-        return queryResultsCache.execute(new Callable<List<ApplicationPermission>>() {
-            @Override
-            public List<ApplicationPermission> call() throws Exception {
-                return findByRole(role);
-            }
-        }, ApplicationPermissionRepository.class, "findByRoleCached", role);
+    public List<ApplicationPermission> findByRoleCached(@NonNull final ApplicationRole role) {
+        return queryResultsCache.execute(this::findByRole,
+                ApplicationPermissionRepository.class, "findByRoleCached", role);
     }
 
-    public List<ApplicationPermission> findByRole(final ApplicationRole role) {
+    public List<ApplicationPermission> findByRole(@NonNull final ApplicationRole role) {
         return repository.allMatches(
                 new QueryDefault<>(
                         ApplicationPermission.class, "findByRole",
@@ -89,17 +86,13 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
 
     // -- findByUser (programmatic)
-    public List<ApplicationPermission> findByUserCached(final ApplicationUser user) {
-        return queryResultsCache.execute(new Callable<List<ApplicationPermission>>() {
-            @Override public List<ApplicationPermission> call() throws Exception {
-                return findByUser(user);
-            }
-        }, ApplicationPermissionRepository.class, "findByUserCached", user);
+    public List<ApplicationPermission> findByUserCached(@NonNull final ApplicationUser user) {
+        return queryResultsCache.execute(this::findByUser, 
+                ApplicationPermissionRepository.class, "findByUserCached", user);
     }
 
-    public List<ApplicationPermission> findByUser(final ApplicationUser user) {
-        final String username = user.getUsername();
-        return findByUser(username);
+    public List<ApplicationPermission> findByUser(@NonNull final ApplicationUser user) {
+        return findByUser(user.getUsername());
     }
 
     private List<ApplicationPermission> findByUser(final String username) {
@@ -116,82 +109,88 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
      * multiple lookups from <code>org.apache.isis.extensions.secman.jdo.app.user.UserPermissionViewModel</code>.
      */
     @Override
-    public ApplicationPermission findByUserAndPermissionValue(final String username, final ApplicationPermissionValue permissionValue) {
+    public Optional<ApplicationPermission> findByUserAndPermissionValue(final String username, final ApplicationPermissionValue permissionValue) {
 
         // obtain all permissions for this user, map by its value, and
         // put into query cache (so that this method can be safely called in a tight loop)
-        final Map<ApplicationPermissionValue, List<ApplicationPermission>> permissions =
-                queryResultsCache.execute(new Callable<Map<ApplicationPermissionValue, List<ApplicationPermission>>>() {
-                    @Override
-                    public Map<ApplicationPermissionValue, List<ApplicationPermission>> call() throws Exception {
-
-                        val permissions = findByUser(username);
-
-                        val permissionsByPermissionValue = 
-                                _Multimaps.<ApplicationPermissionValue, ApplicationPermission>newListMultimap();
-
-                        _NullSafe.stream(permissions)
-                        .forEach(permission->{
-                            val permissionValue = ApplicationPermission.Functions.AS_VALUE.apply(permission);
-                            permissionsByPermissionValue.putElement(permissionValue, permission);
-                        });
-
-                        return permissionsByPermissionValue;
-                    }
-                    // note: it is correct that only username (and not permissionValue) is the key
-                    // (we are obtaining all the perms for this user)
-                }, ApplicationPermissionRepository.class, "findByUserAndPermissionValue", username);
+        val permissions =
+                queryResultsCache.execute(
+                        this::permissionsByPermissionValue, 
+                        ApplicationPermissionRepository.class, "findByUserAndPermissionValue", 
+                        username);
 
         // now simply return the permission from the required value (if it exists)
         final List<ApplicationPermission> applicationPermissions = permissions.get(permissionValue);
         return applicationPermissions != null && !applicationPermissions.isEmpty()
-                ? applicationPermissions.get(0)
-                        : null;
+                ? Optional.of(applicationPermissions.get(0))
+                        : Optional.empty();
     }
+    
+    private ListMultimap<ApplicationPermissionValue, ApplicationPermission> permissionsByPermissionValue(
+            final String username) {
+
+        // only username (and not permissionValue) is the key
+        // (we are obtaining all the perms for this user)
+        
+        val permissionsByPermissionValue =
+                _Multimaps.<ApplicationPermissionValue, ApplicationPermission>newListMultimap();
+        
+        val permissions = findByUser(username);
 
+        _NullSafe.stream(permissions)
+        .forEach(permission->{
+            val newPermissionValue = ApplicationPermission.Functions.AS_VALUE.apply(permission);
+            permissionsByPermissionValue.putElement(newPermissionValue, permission);
+        });
+
+        return permissionsByPermissionValue;
+    }
 
     // -- findByRoleAndRuleAndFeatureType (programmatic)
-    public List<ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
-            final ApplicationRole role, final ApplicationPermissionRule rule,
-            final ApplicationFeatureType type) {
-        return queryResultsCache.execute(new Callable<List<ApplicationPermission>>() {
-            @Override public List<ApplicationPermission> call() throws Exception {
-                return findByRoleAndRuleAndFeatureType(role, rule, type);
-            }
-        }, ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached", role, rule, type);
+    @Override
+    public Collection<ApplicationPermission> findByRoleAndRuleAndFeatureTypeCached(
+            org.apache.isis.extensions.secman.api.role.ApplicationRole role,
+            ApplicationPermissionRule rule,
+            ApplicationFeatureType type) {
+        return queryResultsCache.execute(this::findByRoleAndRuleAndFeatureType, 
+                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureTypeCached", 
+                role, rule, type);
     }
 
-    public List<ApplicationPermission> findByRoleAndRuleAndFeatureType(
-            final ApplicationRole role, final ApplicationPermissionRule rule,
+    public Collection<ApplicationPermission> findByRoleAndRuleAndFeatureType(
+            org.apache.isis.extensions.secman.api.role.ApplicationRole role, 
+            final ApplicationPermissionRule rule,
             final ApplicationFeatureType type) {
         return repository.allMatches(
                 new QueryDefault<>(
                         ApplicationPermission.class, "findByRoleAndRuleAndFeatureType",
                         "role", role,
                         "rule", rule,
-                        "featureType", type));
+                        "featureType", type))
+                .stream()
+                .collect(_Sets.toUnmodifiableSorted());
     }
 
 
     // -- findByRoleAndRuleAndFeature (programmatic)
-    public ApplicationPermission findByRoleAndRuleAndFeatureCached(
-            final ApplicationRole role,
+    public Optional<ApplicationPermission> findByRoleAndRuleAndFeatureCached(
+            final org.apache.isis.extensions.secman.api.role.ApplicationRole role,
             final ApplicationPermissionRule rule,
             final ApplicationFeatureType type,
             final String featureFqn) {
-        return queryResultsCache.execute(new Callable<ApplicationPermission>() {
-            @Override public ApplicationPermission call() throws Exception {
-                return findByRoleAndRuleAndFeature(role, rule, type, featureFqn);
-            }
-        }, ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureCached", role, rule, type, featureFqn);
+        return queryResultsCache.execute(
+                this::findByRoleAndRuleAndFeature,
+                ApplicationPermissionRepository.class, "findByRoleAndRuleAndFeatureCached",
+                role, rule, type, featureFqn);
     }
 
-    public ApplicationPermission findByRoleAndRuleAndFeature(
-            final ApplicationRole role,
-            final ApplicationPermissionRule rule, 
-            final ApplicationFeatureType type, 
+    @Override
+    public Optional<ApplicationPermission> findByRoleAndRuleAndFeature(
+            final org.apache.isis.extensions.secman.api.role.ApplicationRole role,
+            final ApplicationPermissionRule rule,
+            final ApplicationFeatureType type,
             final String featureFqn) {
-        
+
         return repository
                 .uniqueMatch(
                         new QueryDefault<>(
@@ -199,55 +198,29 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
                                 "role", role,
                                 "rule", rule,
                                 "featureType", type,
-                                "featureFqn", featureFqn ))
-                .orElse(null);
+                                "featureFqn", featureFqn ));
     }
 
 
     // -- findByFeature (programmatic)
 
     @Override
-    public List<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> 
-    findByFeatureCached(final ApplicationFeatureId featureId) {
-        return queryResultsCache.execute(new Callable<List<ApplicationPermission>>() {
-            @Override public List<ApplicationPermission> call() throws Exception {
-                return findByFeature(featureId);
-            }
-        }, ApplicationPermissionRepository.class, "findByFeatureCached", featureId)
-        .stream()
-        .map(org.apache.isis.extensions.secman.api.permission.ApplicationPermission.class::cast)
-        .collect(Collectors.toList());
+    public Collection<ApplicationPermission> findByFeatureCached(final ApplicationFeatureId featureId) {
+        return queryResultsCache.execute(
+                this::findByFeature, ApplicationPermissionRepository.class, "findByFeatureCached",
+                featureId);
     }
 
-    public List<ApplicationPermission> findByFeature(final ApplicationFeatureId featureId) {
+    public Collection<ApplicationPermission> findByFeature(final ApplicationFeatureId featureId) {
         return repository.allMatches(
                 new QueryDefault<>(
                         ApplicationPermission.class, "findByFeature",
                         "featureType", featureId.getType(),
-                        "featureFqn", featureId.getFullyQualifiedName()));
-    }
-    
-    @Override
-    public List<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> 
-    findByRoleAndRuleAndFeatureTypeCached(
-            org.apache.isis.extensions.secman.api.role.ApplicationRole holder, 
-            ApplicationPermissionRule rule,
-            ApplicationFeatureType type) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public org.apache.isis.extensions.secman.api.permission.ApplicationPermission 
-    findByRoleAndRuleAndFeature(
-            org.apache.isis.extensions.secman.api.role.ApplicationRole holder, 
-            ApplicationPermissionRule rule,
-            ApplicationFeatureType type, String featureFqn) {
-        // TODO Auto-generated method stub
-        return null;
+                        "featureFqn", featureId.getFullyQualifiedName()))
+                .stream()
+                .collect(_Sets.toUnmodifiableSorted());
     }
 
-
     // -- newPermission (programmatic)
 
     @Override
@@ -257,9 +230,9 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final ApplicationPermissionMode mode,
             final ApplicationFeatureType featureType,
             final String featureFqn) {
-        
+
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-        
+
         final ApplicationFeatureId featureId = ApplicationFeatureId.newFeature(featureType, featureFqn);
         final ApplicationFeature feature = applicationFeatureRepository.findFeature(featureId);
         if(feature == null) {
@@ -276,7 +249,8 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final ApplicationFeatureType featureType,
             final String featureFqn) {
 
-        ApplicationPermission permission = findByRoleAndRuleAndFeature(role, rule, featureType, featureFqn);
+        ApplicationPermission permission = findByRoleAndRuleAndFeature(role, rule, featureType, featureFqn)
+                .orElse(null);
         if (permission != null) {
             return permission;
         }
@@ -300,7 +274,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             final String featureMemberName) {
 
         val role = _Casts.<ApplicationRole>uncheckedCast(genericRole);
-        
+
         val featureId = ApplicationFeatureId.newFeature(featurePackage, featureClassName, featureMemberName);
         val featureType = featureId.getType();
         val featureFqn = featureId.getFullyQualifiedName();
@@ -325,20 +299,16 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
 
     // -- allPermission (programmatic)
     @Override
-    public List<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> 
-    allPermissions() {
+    public Collection<ApplicationPermission> allPermissions() {
         return repository.allInstances(ApplicationPermission.class)
                 .stream()
-                .map(org.apache.isis.extensions.secman.api.permission.ApplicationPermission.class::cast)
-                .collect(Collectors.toList());
+                .collect(_Sets.toUnmodifiableSorted());
     }
 
-
     // -- findOrphaned (programmatic)
 
     @Override
-    public List<org.apache.isis.extensions.secman.api.permission.ApplicationPermission> 
-    findOrphaned() {
+    public Collection<ApplicationPermission> findOrphaned() {
 
         final Collection<String> packageNames = applicationFeatureRepository.packageNames();
         final Set<String> availableClasses = _Sets.newTreeSet();
@@ -348,7 +318,7 @@ implements org.apache.isis.extensions.secman.api.permission.ApplicationPermissio
             appendClasses(packageName, ApplicationMemberType.ACTION, availableClasses);
         }
 
-        val orphaned = _Lists.<org.apache.isis.extensions.secman.api.permission.ApplicationPermission>newArrayList();
+        val orphaned = _Lists.<ApplicationPermission>newArrayList();
 
         val permissions = allPermissions();
         for (val permission : permissions) {