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 2022/05/14 05:40:43 UTC

[isis] branch master updated: ISIS-3051: consolidate defaults and choices post-processors

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 2e4e331d55 ISIS-3051: consolidate defaults and choices  post-processors
2e4e331d55 is described below

commit 2e4e331d5538799a31479b6145ac1ec39fe84c46
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat May 14 07:40:38 2022 +0200

    ISIS-3051: consolidate defaults and choices  post-processors
    
    - fixes check for hasMemberLevelChoices ... we need to consider
    auto-complete as well
---
 ...ectionParamDefaultsAndChoicesPostProcessor.java | 119 --------------
 .../propparam/ChoicesAndDefaultsPostProcessor.java | 180 +++++++++++++++++++++
 .../propparam/ChoicesFromTypePostProcessor.java    |  77 ---------
 .../propparam/DefaultFromTypePostProcessor.java    |  56 -------
 .../TypicalLengthFromTypePostProcessor.java        |   9 +-
 .../dflt/ProgrammingModelFacetsJava11.java         |   8 +-
 .../spec/feature/ObjectActionParameter.java        |  69 +++-----
 7 files changed, 213 insertions(+), 305 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/collparam/CollectionParamDefaultsAndChoicesPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/collparam/CollectionParamDefaultsAndChoicesPostProcessor.java
deleted file mode 100644
index 70ddeff4b6..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/collparam/CollectionParamDefaultsAndChoicesPostProcessor.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.postprocessors.collparam;
-
-import javax.inject.Inject;
-
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
-import org.apache.isis.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacet;
-import org.apache.isis.core.metamodel.postprocessors.ObjectSpecificationPostProcessorAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.MixedIn;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-import lombok.val;
-
-/**
- * Sets up all the {@link Facet}s for an action in a single shot.
- */
-public class CollectionParamDefaultsAndChoicesPostProcessor
-extends ObjectSpecificationPostProcessorAbstract {
-
-    @Inject
-    public CollectionParamDefaultsAndChoicesPostProcessor(final MetaModelContext metaModelContext) {
-        super(metaModelContext);
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final OneToManyAssociation collection) {
-
-        // ... see if any of its actions has a collection parameter of the same type
-        //
-        // eg Order#getItems() and Order#removeItems(List<OrderItem>)
-        //
-        final ObjectSpecification specification = collection.getElementType();
-
-        final ObjectActionParameter.Predicates.CollectionParameter whetherCollectionParamOfType =
-                new ObjectActionParameter.Predicates.CollectionParameter(specification);
-
-        final ObjectActionParameter.Predicates.ScalarParameter whetherScalarParamOfType =
-                new ObjectActionParameter.Predicates.ScalarParameter(specification);
-
-        objectSpecification.streamRuntimeActions(MixedIn.INCLUDED)
-        .filter(ObjectAction.Predicates.choicesFromAndHavingCollectionParameterFor(collection))
-        .forEach(action->{
-
-            val parameters = action.getParameters();
-
-            val compatibleCollectionParams = parameters.filter(whetherCollectionParamOfType);
-            val compatibleScalarParams = parameters.filter(whetherScalarParamOfType);
-
-            // for collection parameters, install an defaults facet (if there isn't one already)
-            // this will cause the UI to render the collection with toggleboxes
-            // with a thread-local used to provide the selected objects
-            for (final ObjectActionParameter collectionParam : compatibleCollectionParams) {
-                addCollectionParamDefaultsFacetIfNoneAlready(collectionParam);
-            }
-
-            // for compatible collection parameters, install a choices facet (if there isn't one already)
-            // using the associated collection for its values
-            for (final ObjectActionParameter collectionParam : compatibleCollectionParams) {
-                addCollectionParamChoicesFacetIfNoneAlready(collection, collectionParam);
-            }
-
-            // similarly for compatible scalar parameters, install a choices facet (if there isn't one already)
-            // using the associated collection for its values.
-            for (final ObjectActionParameter scalarParam : compatibleScalarParams) {
-                addCollectionParamChoicesFacetIfNoneAlready(collection, scalarParam);
-            }
-        });
-    }
-
-    // -- HELPER
-
-    private static void addCollectionParamDefaultsFacetIfNoneAlready(
-            final ObjectActionParameter collectionParam) {
-        if(collectionParam.getParameterIndex()!=0) {
-            return; // with current programming model this can only be the first parameter of an action dialog
-        }
-        if(collectionParam.containsNonFallbackFacet(ActionParameterDefaultsFacet.class)) {
-            return;
-        }
-        FacetUtil.addFacet(ActionParameterDefaultsFacetFromAssociatedCollection
-                .create(collectionParam));
-    }
-
-    private static void addCollectionParamChoicesFacetIfNoneAlready(
-            final OneToManyAssociation otma,
-            final ObjectActionParameter scalarOrCollectionParam) {
-        if (scalarOrCollectionParam.containsNonFallbackFacet(ActionParameterChoicesFacet.class) ||
-                scalarOrCollectionParam.containsNonFallbackFacet(ActionParameterAutoCompleteFacet.class)) {
-            return;
-        }
-        FacetUtil.addFacet(new ActionParameterChoicesFacetFromParentedCollection(
-                        scalarOrCollectionParam, otma));
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesAndDefaultsPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesAndDefaultsPostProcessor.java
new file mode 100644
index 0000000000..a5d7cc91b0
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesAndDefaultsPostProcessor.java
@@ -0,0 +1,180 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.postprocessors.propparam;
+
+import javax.inject.Inject;
+
+import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facets.object.defaults.DefaultedFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
+import org.apache.isis.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.enums.ActionParameterChoicesFacetFromChoicesFacet;
+import org.apache.isis.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacet;
+import org.apache.isis.core.metamodel.facets.properties.autocomplete.PropertyAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.choices.enums.PropertyChoicesFacetFromChoicesFacet;
+import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
+import org.apache.isis.core.metamodel.facets.properties.defaults.fromtype.PropertyDefaultFacetFromDefaultedFacet;
+import org.apache.isis.core.metamodel.postprocessors.ObjectSpecificationPostProcessorAbstract;
+import org.apache.isis.core.metamodel.postprocessors.collparam.ActionParameterChoicesFacetFromParentedCollection;
+import org.apache.isis.core.metamodel.postprocessors.collparam.ActionParameterDefaultsFacetFromAssociatedCollection;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.MixedIn;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+
+import lombok.val;
+
+/**
+ * Does post-processing of
+ * {@link ActionParameterDefaultsFacet} and {@link ActionParameterChoicesFacet},
+ * as well as
+ * {@link PropertyDefaultFacet} and {@link PropertyChoicesFacet}.
+ */
+public class ChoicesAndDefaultsPostProcessor
+extends ObjectSpecificationPostProcessorAbstract {
+
+    @Inject
+    public ChoicesAndDefaultsPostProcessor(final MetaModelContext metaModelContext) {
+        super(metaModelContext);
+    }
+
+    @Override
+    protected void doPostProcess(
+            final ObjectSpecification objectSpecification,
+            final ObjectAction objectAction,
+            final ObjectActionParameter param) {
+        if(!hasMemberLevelChoices(param)) {
+            param.getElementType()
+            .lookupNonFallbackFacet(ChoicesFacet.class)
+            .ifPresent(choicesFacet -> FacetUtil
+                    .addFacet(new ActionParameterChoicesFacetFromChoicesFacet(peerFor(param))));
+        }
+    }
+
+    @Override
+    protected void doPostProcess(
+            final ObjectSpecification objectSpecification,
+            final OneToOneAssociation prop) {
+        if(!hasMemberLevelDefaults(prop)) {
+            prop.getElementType()
+            .lookupNonFallbackFacet(DefaultedFacet.class)
+            .ifPresent(specFacet -> FacetUtil.addFacet(new PropertyDefaultFacetFromDefaultedFacet(
+                                        specFacet, facetedMethodFor(prop))));
+        }
+        if(!hasMemberLevelChoices(prop)) {
+            prop.getElementType()
+            .lookupNonFallbackFacet(ChoicesFacet.class)
+            .ifPresent(specFacet -> FacetUtil
+                    .addFacet(new PropertyChoicesFacetFromChoicesFacet(facetedMethodFor(prop))));
+        }
+    }
+
+    @Override
+    protected void doPostProcess(
+            final ObjectSpecification objectSpecification,
+            final OneToManyAssociation coll) {
+
+        // ... see if any of its actions has a collection parameter of the same type
+        //
+        // eg Order#getItems() and Order#removeItems(List<OrderItem>)
+        //
+
+        // setting up filters ...
+        val elementType = coll.getElementType();
+        val whetherCollectionParamOfType =
+                new ObjectActionParameter.Predicates.CollectionParameter(elementType);
+        val whetherScalarParamOfType =
+                new ObjectActionParameter.Predicates.ScalarParameter(elementType);
+
+        // processing actions ...
+        objectSpecification.streamRuntimeActions(MixedIn.INCLUDED)
+        .filter(ObjectAction.Predicates.choicesFromAndHavingCollectionParameterFor(coll))
+        .forEach(action->{
+
+            val parameters = action.getParameters();
+
+            val compatibleCollectionParams = parameters.filter(whetherCollectionParamOfType);
+            val compatibleScalarParams = parameters.filter(whetherScalarParamOfType);
+
+            // for collection parameters, install an defaults facet (if there isn't one already)
+            // this will cause the UI to render the collection with toggleboxes
+            for (final ObjectActionParameter collectionParam : compatibleCollectionParams) {
+                addCollectionParamDefaultsFacetIfNoneAlready(collectionParam);
+            }
+
+            // for compatible collection parameters, install a choices facet (if there isn't one already)
+            // using the associated collection for its values
+            for (final ObjectActionParameter collectionParam : compatibleCollectionParams) {
+                addCollectionParamChoicesFacetIfNoneAlready(coll, collectionParam);
+            }
+
+            // similarly for compatible scalar parameters, install a choices facet (if there isn't one already)
+            // using the associated collection for its values.
+            for (final ObjectActionParameter scalarParam : compatibleScalarParams) {
+                addCollectionParamChoicesFacetIfNoneAlready(coll, scalarParam);
+            }
+        });
+    }
+
+    // -- HELPER
+
+    private static boolean hasMemberLevelDefaults(final ObjectActionParameter param) {
+        return param.containsNonFallbackFacet(ActionParameterDefaultsFacet.class);
+    }
+
+    private static boolean hasMemberLevelDefaults(final OneToOneAssociation prop) {
+        return prop.containsNonFallbackFacet(PropertyDefaultFacet.class);
+    }
+
+    private static boolean hasMemberLevelChoices(final ObjectActionParameter param) {
+        return param.containsNonFallbackFacet(ActionParameterChoicesFacet.class)
+                || param.containsNonFallbackFacet(ActionParameterAutoCompleteFacet.class);
+    }
+
+    private static boolean hasMemberLevelChoices(final OneToOneAssociation prop) {
+        return prop.containsNonFallbackFacet(PropertyDefaultFacet.class)
+                || prop.containsNonFallbackFacet(PropertyAutoCompleteFacet.class);
+    }
+
+    private static void addCollectionParamDefaultsFacetIfNoneAlready(
+            final ObjectActionParameter collectionParam) {
+        // with current programming model this can only be the first parameter of an action dialog
+        if(collectionParam.getParameterIndex()==0
+                && !hasMemberLevelDefaults(collectionParam)) {
+            FacetUtil.addFacet(
+                    ActionParameterDefaultsFacetFromAssociatedCollection
+                    .create(collectionParam));
+        }
+    }
+
+    private static void addCollectionParamChoicesFacetIfNoneAlready(
+            final OneToManyAssociation otma,
+            final ObjectActionParameter param) {
+        if(!hasMemberLevelChoices(param)) {
+            FacetUtil.addFacet(
+                    new ActionParameterChoicesFacetFromParentedCollection(param, otma));
+        }
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesFromTypePostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesFromTypePostProcessor.java
deleted file mode 100644
index 40be54df86..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/ChoicesFromTypePostProcessor.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.postprocessors.propparam;
-
-import javax.inject.Inject;
-
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.enums.ActionParameterChoicesFacetFromChoicesFacet;
-import org.apache.isis.core.metamodel.facets.param.choices.enums.ActionParameterChoicesFacetFromChoicesFacetFactory;
-import org.apache.isis.core.metamodel.facets.properties.choices.PropertyChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.choices.enums.PropertyChoicesFacetFromChoicesFacet;
-import org.apache.isis.core.metamodel.facets.properties.choices.enums.PropertyChoicesFacetFromChoicesFacetFactory;
-import org.apache.isis.core.metamodel.postprocessors.ObjectSpecificationPostProcessorAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-
-/**
- * Replaces {@link ActionParameterChoicesFacetFromChoicesFacetFactory}
- * and {@link PropertyChoicesFacetFromChoicesFacetFactory}
- */
-public class ChoicesFromTypePostProcessor
-extends ObjectSpecificationPostProcessorAbstract {
-
-    @Inject
-    public ChoicesFromTypePostProcessor(final MetaModelContext metaModelContext) {
-        super(metaModelContext);
-    }
-
-    @Override
-    protected void doPostProcess(
-            final ObjectSpecification objectSpecification,
-            final ObjectAction objectAction,
-            final ObjectActionParameter parameter) {
-        if(parameter.containsNonFallbackFacet(ActionParameterChoicesFacet.class)) {
-            return;
-        }
-        parameter.getElementType()
-        .lookupNonFallbackFacet(ChoicesFacet.class)
-        .ifPresent(choicesFacet -> FacetUtil
-                .addFacet(new ActionParameterChoicesFacetFromChoicesFacet(peerFor(parameter))));
-    }
-
-    @Override
-    protected void doPostProcess(
-            final ObjectSpecification objectSpecification,
-            final OneToOneAssociation property) {
-        if(property.containsNonFallbackFacet(PropertyChoicesFacet.class)) {
-            return;
-        }
-        property.getElementType()
-        .lookupNonFallbackFacet(ChoicesFacet.class)
-        .ifPresent(specFacet -> FacetUtil
-                .addFacet(new PropertyChoicesFacetFromChoicesFacet(facetedMethodFor(property))));
-   }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/DefaultFromTypePostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/DefaultFromTypePostProcessor.java
deleted file mode 100644
index 6c6d1c4c26..0000000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/DefaultFromTypePostProcessor.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.metamodel.postprocessors.propparam;
-
-import javax.inject.Inject;
-
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facets.object.defaults.DefaultedFacet;
-import org.apache.isis.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
-import org.apache.isis.core.metamodel.facets.properties.defaults.fromtype.PropertyDefaultFacetFromDefaultedFacet;
-import org.apache.isis.core.metamodel.facets.properties.defaults.fromtype.PropertyDefaultFacetFromTypeFactory;
-import org.apache.isis.core.metamodel.postprocessors.ObjectSpecificationPostProcessorAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-
-
-/**
- * Installs {@link PropertyDefaultFacetFromTypeFactory} as a fallback.
- */
-public class DefaultFromTypePostProcessor
-extends ObjectSpecificationPostProcessorAbstract {
-
-    @Inject
-    public DefaultFromTypePostProcessor(final MetaModelContext metaModelContext) {
-        super(metaModelContext);
-    }
-
-    @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
-        if(property.containsNonFallbackFacet(PropertyDefaultFacet.class)) {
-            return;
-        }
-        property.getElementType()
-        .lookupNonFallbackFacet(DefaultedFacet.class)
-        .ifPresent(specFacet -> FacetUtil.addFacet(new PropertyDefaultFacetFromDefaultedFacet(
-                                    specFacet, facetedMethodFor(property))));
-    }
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/TypicalLengthFromTypePostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/TypicalLengthFromTypePostProcessor.java
index 28988c89c8..cbed874658 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/TypicalLengthFromTypePostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/propparam/TypicalLengthFromTypePostProcessor.java
@@ -40,7 +40,10 @@ extends ObjectSpecificationPostProcessorAbstract {
     }
 
     @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final ObjectAction objectAction, final ObjectActionParameter parameter) {
+    protected void doPostProcess(
+            final ObjectSpecification objectSpecification,
+            final ObjectAction objectAction,
+            final ObjectActionParameter parameter) {
         if(parameter.containsNonFallbackFacet(TypicalLengthFacet.class)) {
             return;
         }
@@ -54,7 +57,9 @@ extends ObjectSpecificationPostProcessorAbstract {
     }
 
     @Override
-    protected void doPostProcess(final ObjectSpecification objectSpecification, final OneToOneAssociation property) {
+    protected void doPostProcess(
+            final ObjectSpecification objectSpecification,
+            final OneToOneAssociation property) {
         if(property.containsNonFallbackFacet(TypicalLengthFacet.class)) {
             return;
         }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava11.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava11.java
index a4a2907bbf..2dbc93d62b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava11.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodels/dflt/ProgrammingModelFacetsJava11.java
@@ -90,13 +90,11 @@ import org.apache.isis.core.metamodel.postprocessors.all.DescribedAsFromTypePost
 import org.apache.isis.core.metamodel.postprocessors.all.i18n.SynthesizeObjectNamingPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.all.i18n.TranslationPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.allbutparam.authorization.AuthorizationPostProcessor;
-import org.apache.isis.core.metamodel.postprocessors.collparam.CollectionParamDefaultsAndChoicesPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.members.TweakDomainEventsForMixinPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.members.navigation.NavigationFacetFromHiddenTypePostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.object.ProjectionFacetsPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.properties.DisabledFromImmutablePostProcessor;
-import org.apache.isis.core.metamodel.postprocessors.propparam.ChoicesFromTypePostProcessor;
-import org.apache.isis.core.metamodel.postprocessors.propparam.DefaultFromTypePostProcessor;
+import org.apache.isis.core.metamodel.postprocessors.propparam.ChoicesAndDefaultsPostProcessor;
 import org.apache.isis.core.metamodel.postprocessors.propparam.TypicalLengthFromTypePostProcessor;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
@@ -262,10 +260,8 @@ extends ProgrammingModelAbstract {
 
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DescribedAsFromTypePostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new TypicalLengthFromTypePostProcessor(mmc));
-        addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DefaultFromTypePostProcessor(mmc));
-        addPostProcessor(PostProcessingOrder.A1_BUILTIN, new ChoicesFromTypePostProcessor(mmc));
+        addPostProcessor(PostProcessingOrder.A1_BUILTIN, new ChoicesAndDefaultsPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new DisabledFromImmutablePostProcessor(mmc));
-        addPostProcessor(PostProcessingOrder.A1_BUILTIN, new CollectionParamDefaultsAndChoicesPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new TweakDomainEventsForMixinPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new ProjectionFacetsPostProcessor(mmc));
         addPostProcessor(PostProcessingOrder.A1_BUILTIN, new NavigationFacetFromHiddenTypePostProcessor(mmc));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index 85669351f5..1badc0083e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@ -38,6 +38,8 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.memento.ActionParameterMemento;
 
 import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.experimental.UtilityClass;
 
 /**
  * Analogous to {@link ObjectAssociation}.
@@ -175,75 +177,52 @@ extends ObjectFeature, CurrentHolder {
             InteractionInitiatedBy interactionInitiatedBy);
 
     @Vetoed
+    @UtilityClass
     public static class Predicates {
-        private Predicates(){}
 
         /**
          * A predicate for action parameters that checks that the parameter collection element type
          * is the same as assignable (that is, the same or a supertype of, supporting co-variance) the
          * {@link ObjectSpecification element type} provided in the constructor.
-         *
          * <p>
-         *     For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
-         *     into the constructor.  An action with signature <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on
-         *     its (first) parameter.
-         * </p>
-         *
+         * For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
+         * into the constructor.  An action with signature <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on
+         * its (first) parameter.
          * <p>
-         *     For example, a parented collection of <tt>LeaseTermForServiceCharge</tt>s provides an elementSpec
-         *     of <tt>LeaseTermForServiceCharge</tt> into the constructor.  An action with signature
-         *     <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on its (first) parameter.
-         * </p>
+         * For example, a parented collection of <tt>LeaseTermForServiceCharge</tt>s provides an elementSpec
+         * of <tt>LeaseTermForServiceCharge</tt> into the constructor.  An action with signature
+         * <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on its (first) parameter.
          */
-        public static class CollectionParameter implements Predicate<ObjectActionParameter> {
+        @RequiredArgsConstructor
+        public class CollectionParameter implements Predicate<ObjectActionParameter> {
 
-            private final ObjectSpecification elementSpecification;
-
-            public CollectionParameter(final ObjectSpecification elementSpecification) {
-                this.elementSpecification = elementSpecification;
-            }
+            private final @NonNull ObjectSpecification elementType;
 
             @Override
             public boolean test(final @Nullable ObjectActionParameter objectActionParameter) {
-                if (!(objectActionParameter instanceof OneToManyActionParameter)) {
-                    return false;
-                }
-
-                final OneToManyActionParameter otmap =
-                        (OneToManyActionParameter) objectActionParameter;
-                final ObjectSpecification paramElementSpecification = otmap.getElementType();
-                return this.elementSpecification.isOfType(paramElementSpecification);
+                return objectActionParameter instanceof OneToManyActionParameter
+                        && elementType.isOfType(objectActionParameter.getElementType());
             }
         }
 
         /**
          * A predicate for action parameters that checks that the parameter collection element type
-         * is exactly the same as the {@link ObjectSpecification element type} (no co/contra-variance) provided in the constructor.
-         *
+         * is exactly the same as the {@link ObjectSpecification element type} (no co/contra-variance)
+         * provided in the constructor.
          * <p>
-         *     For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
-         *     into the constructor.  An action with signature <tt>addTerm(LeaseTerm)</tt> would match on
-         *     its (first) parameter.
-         * </p>
+         * For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
+         * into the constructor.  An action with signature <tt>addTerm(LeaseTerm)</tt> would match on
+         * its (first) parameter.
          */
-        public static class ScalarParameter implements Predicate<ObjectActionParameter> {
+        @RequiredArgsConstructor
+        public class ScalarParameter implements Predicate<ObjectActionParameter> {
 
-            private final ObjectSpecification specification;
-
-            public ScalarParameter(final ObjectSpecification specification) {
-                this.specification = specification;
-            }
+            private final @NonNull ObjectSpecification elementType;
 
             @Override
             public boolean test(final @Nullable ObjectActionParameter objectActionParameter) {
-                if (!(objectActionParameter instanceof OneToOneActionParameter)) {
-                    return false;
-                }
-
-                final OneToOneActionParameter otoap =
-                        (OneToOneActionParameter) objectActionParameter;
-                final ObjectSpecification paramSecification = otoap.getElementType();
-                return paramSecification == this.specification;
+                return objectActionParameter instanceof OneToOneActionParameter
+                        && elementType == objectActionParameter.getElementType();
             }
         }
     }