You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/05/24 14:23:39 UTC

[isis] 02/05: ISIS-2614: converts api.ApplicationPermission from interface to an abstract class

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

danhaywood pushed a commit to branch ISIS-2614
in repository https://gitbox.apache.org/repos/asf/isis.git

commit e900d543ef90d7aff6f21269c98cc804b5bea85d
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon May 24 14:33:15 2021 +0100

    ISIS-2614: converts api.ApplicationPermission from interface to an abstract class
---
 .../api/permission/dom/ApplicationPermission.java  | 139 ++++++++++++---------
 .../dom/ApplicationPermission.layout.fallback.xml  |   0
 .../secman/api/user/dom/ApplicationUser.java       |   4 -
 .../jdo/permission/dom/ApplicationPermission.java  |  50 +-------
 .../dom/ApplicationPermission.layout.fallback.xml  |  76 -----------
 .../secman/jdo/role/dom/ApplicationRole.java       |   8 --
 .../jpa/permission/dom/ApplicationPermission.java  |  55 +-------
 .../secman/jpa/role/dom/ApplicationRole.java       |  10 --
 8 files changed, 87 insertions(+), 255 deletions(-)

diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.java
index 9d33abf..46a2d33 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.java
@@ -27,6 +27,8 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Function;
 
+import javax.inject.Inject;
+
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Editing;
 import org.apache.isis.applib.annotation.Programmatic;
@@ -35,8 +37,10 @@ import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.appfeat.ApplicationFeature;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
+import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureSort;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberSort;
+import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.extensions.secman.api.IsisModuleExtSecmanApi;
 import org.apache.isis.extensions.secman.api.role.dom.ApplicationRole;
@@ -78,29 +82,28 @@ import lombok.experimental.UtilityClass;
 @DomainObject(
         objectType = ApplicationPermission.OBJECT_TYPE
 )
-public interface ApplicationPermission extends Comparable<ApplicationPermission> {
+public abstract class ApplicationPermission implements Comparable<ApplicationPermission> {
+
+    public static final String OBJECT_TYPE = IsisModuleExtSecmanApi.NAMESPACE + ".ApplicationPermission";
 
-    String OBJECT_TYPE = IsisModuleExtSecmanApi.NAMESPACE + ".ApplicationPermission";
+    public static final String NAMED_QUERY_FIND_BY_FEATURE = "ApplicationPermission.findByFeature";
+    public static final String NAMED_QUERY_FIND_BY_ROLE = "ApplicationPermission.findByRole";
+    public static final String NAMED_QUERY_FIND_BY_ROLE_RULE_FEATURE = "ApplicationPermission.findByRoleAndRuleAndFeature";
+    public static final String NAMED_QUERY_FIND_BY_ROLE_RULE_FEATURE_FQN = "ApplicationPermission.findByRoleAndRuleAndFeatureAndFqn";
+    public static final String NAMED_QUERY_FIND_BY_USER = "ApplicationPermission.findByUser";
 
-    String NAMED_QUERY_FIND_BY_FEATURE = "ApplicationPermission.findByFeature";
-    String NAMED_QUERY_FIND_BY_ROLE = "ApplicationPermission.findByRole";
-    String NAMED_QUERY_FIND_BY_ROLE_RULE_FEATURE = "ApplicationPermission.findByRoleAndRuleAndFeature";
-    String NAMED_QUERY_FIND_BY_ROLE_RULE_FEATURE_FQN = "ApplicationPermission.findByRoleAndRuleAndFeatureAndFqn";
-    String NAMED_QUERY_FIND_BY_USER = "ApplicationPermission.findByUser";
 
+    @Inject transient ApplicationFeatureRepository featureRepository;
 
     // -- DOMAIN EVENTS
 
-    abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermission, T> {}
-    abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermission, T> {}
+    public static abstract class PropertyDomainEvent<T> extends IsisModuleExtSecmanApi.PropertyDomainEvent<ApplicationPermission, T> {}
+    public static abstract class CollectionDomainEvent<T> extends IsisModuleExtSecmanApi.CollectionDomainEvent<ApplicationPermission, T> {}
+
 
     // -- MODEL
 
-    /**
-     * having a title() method (rather than using @Title annotation) is necessary as a workaround to be able to use
-     * wrapperFactory#unwrap(...) method, which is otherwise broken in Isis 1.6.0
-     */
-    default String title() {
+    public String title() {
         val buf = new StringBuilder();
         buf.append(getRole().getName()).append(":")  // admin:
         .append(" ").append(getRule().toString()) // Allow|Veto
@@ -149,13 +152,13 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
-    @interface Role {
-        class DomainEvent extends PropertyDomainEvent<ApplicationRole> {}
+    public @interface Role {
+        public static class DomainEvent extends PropertyDomainEvent<ApplicationRole> {}
     }
 
     @Role
-    ApplicationRole getRole();
-    void setRole(ApplicationRole applicationRole);
+    public abstract ApplicationRole getRole();
+    public abstract void setRole(ApplicationRole applicationRole);
 
 
     // -- RULE
@@ -170,13 +173,13 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
-    @interface Rule {
+    public @interface Rule {
         class DomainEvent extends PropertyDomainEvent<ApplicationPermissionRule> {}
     }
 
     @Rule
-    ApplicationPermissionRule getRule();
-    void setRule(ApplicationPermissionRule rule);
+    public abstract ApplicationPermissionRule getRule();
+    public abstract void setRule(ApplicationPermissionRule rule);
 
 
     // -- MODE
@@ -191,15 +194,13 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
-    @interface Mode {
+    public @interface Mode {
         class DomainEvent extends PropertyDomainEvent<ApplicationPermissionMode> {}
     }
 
     @Mode
-    default ApplicationPermissionMode getMode() {
-        throw _Exceptions.unsupportedOperation("please implement me");
-    }
-    void setMode(ApplicationPermissionMode changing);
+    public abstract ApplicationPermissionMode getMode();
+    public abstract void setMode(ApplicationPermissionMode mode);
 
 
     // -- SORT
@@ -218,14 +219,14 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
-    @interface Sort {
+    public @interface Sort {
         int TYPICAL_LENGTH = 7;  // ApplicationFeatureType.PACKAGE is longest
 
         class DomainEvent extends PropertyDomainEvent<String> {}
     }
 
     @Sort
-    default String getSort() {
+    public String getSort() {
         final Enum<?> e = getFeatureSort() != ApplicationFeatureSort.MEMBER
                 ? getFeatureSort()
                 : getMemberSort().orElse(null);
@@ -247,8 +248,8 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
      * @see #getFeatureFqn()
      */
     @Programmatic
-    ApplicationFeatureSort getFeatureSort();
-    void setFeatureSort(ApplicationFeatureSort featureSort);
+    public abstract ApplicationFeatureSort getFeatureSort();
+    public abstract void setFeatureSort(ApplicationFeatureSort featureSort);
 
 
     // -- FQN
@@ -274,34 +275,28 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     )
     @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
     @Retention(RetentionPolicy.RUNTIME)
-    @interface FeatureFqn {
+    public @interface FeatureFqn {
         class DomainEvent extends PropertyDomainEvent<String> {}
     }
 
     @FeatureFqn
-    String getFeatureFqn();
-    void setFeatureFqn(String featureFqn);
+    public abstract String getFeatureFqn();
+    public abstract void setFeatureFqn(String featureFqn);
 
 
     // -- FIND FEATURE
 
     @Programmatic
-    ApplicationFeature findFeature(ApplicationFeatureId featureId);
-
-
-    // -- MEMBER SORT
+    public ApplicationFeature findFeature(ApplicationFeatureId featureId) {
+        return featureRepository.findFeature(featureId);
+    }
 
-    @Programmatic
-    default Optional<ApplicationMemberSort> getMemberSort() {
+    private Optional<ApplicationMemberSort> getMemberSort() {
         return getFeature()
                 .flatMap(ApplicationFeature::getMemberSort);
     }
 
-
-    // -- FEATURE ID
-
-    @Programmatic
-    default Optional<ApplicationFeature> getFeature() {
+    private Optional<ApplicationFeature> getFeature() {
         return asFeatureId()
                 .map(this::findFeature);
     }
@@ -310,29 +305,57 @@ public interface ApplicationPermission extends Comparable<ApplicationPermission>
     // -- HELPER
 
     @Programmatic
-    default Optional<ApplicationFeatureId> asFeatureId() {
+    Optional<ApplicationFeatureId> asFeatureId() {
         return Optional.ofNullable(getFeatureSort())
                 .map(featureSort -> ApplicationFeatureId.newFeature(featureSort, getFeatureFqn()));
     }
 
-    @UtilityClass
-    public static final class Functions {
-        public static final Function<ApplicationPermission, ApplicationPermissionValue> AS_VALUE =
-                new Function<ApplicationPermission, ApplicationPermissionValue>() {
-                    @Override
-                    public ApplicationPermissionValue apply(ApplicationPermission input) {
-                        return new ApplicationPermissionValue(
-                                input.asFeatureId().orElseThrow(_Exceptions::noSuchElement),
-                                input.getRule(),
-                                input.getMode());
-                    }
-                };
+
+    // -- CONTRACT
+
+    private static final ObjectContracts.ObjectContract<ApplicationPermission> contract	=
+            ObjectContracts.contract(ApplicationPermission.class)
+                    .thenUse("role", ApplicationPermission::getRole)
+                    .thenUse("featureSort", ApplicationPermission::getFeatureSort)
+                    .thenUse("featureFqn", ApplicationPermission::getFeatureFqn)
+                    .thenUse("mode", ApplicationPermission::getMode);
+
+    @Override
+    public int compareTo(final org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission other) {
+        return contract.compare(this, (ApplicationPermission)other);
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        return contract.equals(this, other);
+    }
+
+    @Override
+    public int hashCode() {
+        return contract.hashCode(this);
+    }
+
+    @Override
+    public String toString() {
+        return contract.toString(this);
     }
 
-    class DefaultComparator implements Comparator<ApplicationPermission> {
+
+    public static class DefaultComparator implements Comparator<ApplicationPermission> {
         @Override
         public int compare(final ApplicationPermission o1, final ApplicationPermission o2) {
             return Objects.compare(o1, o2, Comparator.naturalOrder());
         }
     }
+
+    @UtilityClass
+    public static final class Functions {
+        public static final Function<ApplicationPermission, ApplicationPermissionValue> AS_VALUE =
+                input -> new ApplicationPermissionValue(
+                        input.asFeatureId().orElseThrow(_Exceptions::noSuchElement),
+                        input.getRule(),
+                        input.getMode());
+    }
+
+
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.layout.fallback.xml b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.layout.fallback.xml
similarity index 100%
rename from extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.layout.fallback.xml
rename to extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/permission/dom/ApplicationPermission.layout.fallback.xml
diff --git a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/dom/ApplicationUser.java b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/dom/ApplicationUser.java
index d5e18fd..a8d6cfb 100644
--- a/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/dom/ApplicationUser.java
+++ b/extensions/security/secman/api/src/main/java/org/apache/isis/extensions/secman/api/user/dom/ApplicationUser.java
@@ -116,10 +116,6 @@ public abstract class ApplicationUser
 
     // -- MODEL
 
-    /**
-     * having a title() method (rather than using @Title annotation) is necessary as a workaround to be able to use
-     * wrapperFactory#unwrap(...) method, which is otherwise broken in Isis 1.6.0
-     */
     public String title() {
         return getName();
     }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.java
index 74fd5ce..76ab9e7 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.extensions.secman.jdo.permission.dom;
 
-import javax.inject.Inject;
 import javax.jdo.annotations.Column;
 import javax.jdo.annotations.DatastoreIdentity;
 import javax.jdo.annotations.IdGeneratorStrategy;
@@ -37,12 +36,7 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.appfeat.ApplicationFeature;
-import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureSort;
-import org.apache.isis.applib.util.ObjectContracts;
-import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermissionRule;
@@ -105,12 +99,10 @@ import org.apache.isis.extensions.secman.api.role.dom.ApplicationRole;
         bookmarking = BookmarkPolicy.AS_CHILD
 )
 public class ApplicationPermission
-    implements org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission {
+    extends org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission {
 
     protected final static String FQCN = "org.apache.isis.extensions.secman.jdo.permission.dom.ApplicationPermission";
 
-    @Inject ApplicationFeatureRepository featureRepository;
-
 
     // -- ROLE
 
@@ -160,8 +152,6 @@ public class ApplicationPermission
     }
 
 
-
-
     // -- FEATURE SORT
 
     @Column(allowsNull = "false")
@@ -194,42 +184,4 @@ public class ApplicationPermission
     }
 
 
-    // FIND FEATURE
-
-    @Override
-    @Programmatic
-    public ApplicationFeature findFeature(ApplicationFeatureId featureId) {
-        return featureRepository.findFeature(featureId);
-    }
-
-
-    // -- CONTRACT
-
-    private static final ObjectContract<ApplicationPermission> contract	=
-            ObjectContracts.contract(ApplicationPermission.class)
-            .thenUse("role", ApplicationPermission::getRole)
-            .thenUse("featureSort", ApplicationPermission::getFeatureSort)
-            .thenUse("featureFqn", ApplicationPermission::getFeatureFqn)
-            .thenUse("mode", ApplicationPermission::getMode);
-
-    @Override
-    public int compareTo(final org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission other) {
-        return contract.compare(this, (ApplicationPermission)other);
-    }
-
-    @Override
-    public boolean equals(final Object other) {
-        return contract.equals(this, other);
-    }
-
-    @Override
-    public int hashCode() {
-        return contract.hashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return contract.toString(this);
-    }
-
 }
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.layout.fallback.xml b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.layout.fallback.xml
deleted file mode 100644
index ee2238a..0000000
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/permission/dom/ApplicationPermission.layout.fallback.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-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.
--->
-<bs3:grid
-        xsi:schemaLocation="http://isis.apache.org/applib/layout/component http://isis.apache.org/applib/layout/component/component.xsd   http://isis.apache.org/applib/layout/grid/bootstrap3 http://isis.apache.org/applib/layout/grid/bootstrap3/bootstrap3.xsd"
-        xmlns:bs3="http://isis.apache.org/applib/layout/grid/bootstrap3"
-        xmlns:cpt="http://isis.apache.org/applib/layout/component"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <bs3:row>
-        <bs3:col span="12" unreferencedActions="true">
-            <cpt:domainObject/>
-        </bs3:col>
-    </bs3:row>
-    <bs3:row>
-        <bs3:col span="6">
-            <bs3:tabGroup>
-                <bs3:tab name="Identity">
-                    <bs3:row>
-                        <bs3:col span="12">
-                            <cpt:fieldSet name="Identity" id="identity"/>
-                        </bs3:col>
-                    </bs3:row>
-                </bs3:tab>
-                <bs3:tab name="Other">
-                    <bs3:row>
-                        <bs3:col span="12">
-                            <cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
-                        </bs3:col>
-                    </bs3:row>
-                </bs3:tab>
-                <bs3:tab name="Metadata">
-                    <bs3:row>
-                        <bs3:col span="12">
-                            <cpt:fieldSet name="Metadata" id="metadata"/>
-                        </bs3:col>
-                    </bs3:row>
-                </bs3:tab>
-            </bs3:tabGroup>
-        </bs3:col>
-        <bs3:col span="6">
-            <bs3:tabGroup collapseIfOne="false">
-                <bs3:tab name="Permissions">
-                    <bs3:row>
-                        <bs3:col span="6">
-                            <cpt:fieldSet name="Rule" id="rule"/>
-                        </bs3:col>
-                        <bs3:col span="6">
-                            <cpt:fieldSet name="Mode" id="mode"/>
-                        </bs3:col>
-                    </bs3:row>
-                </bs3:tab>
-            </bs3:tabGroup>
-        </bs3:col>
-    </bs3:row>
-    <bs3:row>
-        <bs3:col span="12">
-            <bs3:tabGroup unreferencedCollections="true"/>
-        </bs3:col>
-    </bs3:row>
-</bs3:grid>
diff --git a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/role/dom/ApplicationRole.java b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/role/dom/ApplicationRole.java
index 84d6a82..70475b9 100644
--- a/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/role/dom/ApplicationRole.java
+++ b/extensions/security/secman/persistence-jdo/src/main/java/org/apache/isis/extensions/secman/jdo/role/dom/ApplicationRole.java
@@ -18,12 +18,9 @@
  */
 package org.apache.isis.extensions.secman.jdo.role.dom;
 
-import java.util.Comparator;
-import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-import javax.inject.Inject;
 import javax.jdo.annotations.Column;
 import javax.jdo.annotations.DatastoreIdentity;
 import javax.jdo.annotations.IdGeneratorStrategy;
@@ -41,13 +38,8 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.annotation.Bounding;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
-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.commons.internal.base._Casts;
 import org.apache.isis.extensions.secman.api.user.dom.ApplicationUser;
-import org.apache.isis.extensions.secman.jdo.permission.dom.ApplicationPermissionRepository;
 
 
 @PersistenceCapable(
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.java
index 2871724..f89e61e 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/permission/dom/ApplicationPermission.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.extensions.secman.jpa.permission.dom;
 
-import javax.inject.Inject;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.EntityListeners;
@@ -32,17 +31,13 @@ import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
+import javax.persistence.Version;
 
 import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.appfeat.ApplicationFeature;
-import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureSort;
-import org.apache.isis.applib.util.ObjectContracts;
-import org.apache.isis.applib.util.ObjectContracts.ObjectContract;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermissionMode;
 import org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermissionRule;
@@ -102,15 +97,16 @@ import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPoin
         bookmarking = BookmarkPolicy.AS_CHILD
 )
 public class ApplicationPermission
-implements org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission {
-
-    @Inject private transient ApplicationFeatureRepository featureRepository;
+    extends org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission {
 
 
     @Id
     @GeneratedValue
     private Long id;
 
+    @Version
+    private Long version;
+
 
     // -- ROLE
 
@@ -163,8 +159,6 @@ implements org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermi
     }
 
 
-
-
     // -- FEATURE SORT
 
     @Column(nullable = false)
@@ -198,43 +192,4 @@ implements org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermi
     }
 
 
-    // FIND FEATURE
-
-    @Override
-    @Programmatic
-    public ApplicationFeature findFeature(ApplicationFeatureId featureId) {
-        return featureRepository.findFeature(featureId);
-    }
-
-
-    // -- CONTRACT
-
-    private static final ObjectContract<ApplicationPermission> contract	=
-            ObjectContracts.contract(ApplicationPermission.class)
-            .thenUse("role", ApplicationPermission::getRole)
-            .thenUse("featureSort", ApplicationPermission::getFeatureSort)
-            .thenUse("featureFqn", ApplicationPermission::getFeatureFqn)
-            .thenUse("rule", ApplicationPermission::getRule)
-            .thenUse("mode", ApplicationPermission::getMode);
-
-    @Override
-    public int compareTo(final org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermission other) {
-        return contract.compare(this, (ApplicationPermission)other);
-    }
-
-    @Override
-    public boolean equals(final Object other) {
-        return contract.equals(this, other);
-    }
-
-    @Override
-    public int hashCode() {
-        return contract.hashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return contract.toString(this);
-    }
-
 }
diff --git a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/role/dom/ApplicationRole.java b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/role/dom/ApplicationRole.java
index 224c75f..20593e8 100644
--- a/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/role/dom/ApplicationRole.java
+++ b/extensions/security/secman/persistence-jpa/src/main/java/org/apache/isis/extensions/secman/jpa/role/dom/ApplicationRole.java
@@ -18,12 +18,9 @@
  */
 package org.apache.isis.extensions.secman.jpa.role.dom;
 
-import java.util.Comparator;
-import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
 
-import javax.inject.Inject;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.EntityListeners;
@@ -40,13 +37,8 @@ import org.apache.isis.applib.annotation.BookmarkPolicy;
 import org.apache.isis.applib.annotation.Bounding;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
-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.commons.internal.base._Casts;
 import org.apache.isis.extensions.secman.api.user.dom.ApplicationUser;
-import org.apache.isis.extensions.secman.jpa.permission.dom.ApplicationPermissionRepository;
 import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
 
 @Entity
@@ -83,8 +75,6 @@ import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPoin
 public class ApplicationRole
     extends org.apache.isis.extensions.secman.api.role.dom.ApplicationRole {
 
-
-
     @Id
     @GeneratedValue
     private Long id;