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 14:51:20 UTC
[isis] 01/01: ISIS-3051: remove mixin facet copy around hackery
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3051-mm-regression
in repository https://gitbox.apache.org/repos/asf/isis.git
commit c70ddc1f25deb2a99b3027317a45c8ceb22435c5
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat May 14 12:52:15 2022 +0200
ISIS-3051: remove mixin facet copy around hackery
---
.../metamodel/facetapi/FacetHolderAbstract.java | 116 +++++++++++++++++++++
.../isis/core/metamodel/facetapi/FacetUtil.java | 19 ++--
...ctionParameterChoicesFacetViaMethodFactory.java | 10 ++
.../ParameterNameFacetFactoryUsingReflection.java | 7 +-
.../param/ChoicesAndDefaultsPostProcessor.java | 8 ++
.../isis/core/metamodel/spec/Specification.java | 5 +-
.../specloader/specimpl/ObjectActionMixedIn.java | 10 +-
.../specimpl/OneToManyAssociationMixedIn.java | 13 +--
.../specimpl/OneToOneAssociationMixedIn.java | 14 +--
9 files changed, 160 insertions(+), 42 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
index 044b6ec801..a5f2045c4f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
@@ -18,6 +18,7 @@
*/
package org.apache.isis.core.metamodel.facetapi;
+import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
@@ -53,6 +54,119 @@ implements FacetHolder {
return facetHolder;
}
+ public static FacetHolder wrapped(
+ final @NonNull MetaModelContext mmc,
+ final @NonNull Identifier featureIdentifier,
+ final @NonNull FacetHolder delegate) {
+ return new WrappedFacetHolder(mmc, featureIdentifier, delegate);
+ }
+
+ /**
+ * @see FacetHolderAbstract#wrapped(MetaModelContext, Identifier, FacetHolder)
+ */
+ @RequiredArgsConstructor
+ static class WrappedFacetHolder implements FacetHolder {
+
+ @Getter(onMethod_ = {@Override})
+ private final @NonNull MetaModelContext metaModelContext;
+ private final @NonNull Identifier featureIdentifierOverride;
+ private final @NonNull FacetHolder delegate;
+
+ @Override public Identifier getFeatureIdentifier() {
+ return featureIdentifierOverride; }
+ @Override public int getFacetCount() {
+ return delegate.getFacetCount(); }
+ @Override public <T extends Facet> T getFacet(final Class<T> facetType) {
+ return delegate.getFacet(facetType); }
+ @Override public boolean containsFacet(final Class<? extends Facet> facetType) {
+ return delegate.containsFacet(facetType); }
+ @Override public Stream<Facet> streamFacets() {
+ return delegate.streamFacets(); }
+ @Override public Stream<FacetRanking> streamFacetRankings() {
+ return delegate.streamFacetRankings(); }
+ @Override public Optional<FacetRanking> getFacetRanking(final Class<? extends Facet> facetType) {
+ return delegate.getFacetRanking(facetType); }
+ @Override public void addFacet(final @NonNull Facet facet) {
+ delegate.addFacet(facet);
+ }
+
+ }
+
+ /**
+ * @see FacetHolderAbstract#layered(MetaModelContext, Identifier, FacetHolder)
+ */
+ static class LayeredFacetHolder extends FacetHolderAbstract {
+
+ private final @NonNull FacetHolder parentLayer;
+
+ private LayeredFacetHolder(final MetaModelContext metaModelContext, final FacetHolder parentLayer) {
+ super(metaModelContext);
+ this.parentLayer = parentLayer;
+ }
+
+ @Override
+ public int getFacetCount() {
+ // cannot simply add up this and parent
+ return (int)streamFacets().count();
+ }
+
+ @Override
+ public <T extends Facet> T getFacet(final Class<T> facetType) {
+ return Optional.ofNullable(super.getFacet(facetType))
+ .orElse(parentLayer.getFacet(facetType));
+ }
+
+ @Override
+ public boolean containsFacet(final Class<? extends Facet> facetType) {
+ return super.containsFacet(facetType)
+ || parentLayer.containsFacet(facetType);
+ }
+
+ @Override
+ public Stream<Facet> streamFacets() {
+ val localFacetTypes = new HashSet<Class<? extends Facet>>();
+ return Stream.concat(
+ super.streamFacets()
+ .peek(facet->localFacetTypes.add(facet.facetType()))
+ ,
+ parentLayer.streamFacets()
+ .filter(facet->!localFacetTypes.contains(facet.facetType())));
+ }
+
+ @Override
+ public Stream<FacetRanking> streamFacetRankings() {
+ val localFacetTypes = new HashSet<Class<? extends Facet>>();
+ return Stream.concat(
+ super.streamFacetRankings()
+ .peek(ranking->localFacetTypes.add(ranking.facetType()))
+ ,
+ parentLayer.streamFacetRankings()
+ .filter(ranking->!localFacetTypes.contains(ranking.facetType())));
+ }
+
+ @Override
+ public Optional<FacetRanking> getFacetRanking(final Class<? extends Facet> facetType) {
+ return Optional.ofNullable(super.getFacetRanking(facetType))
+ .orElse(parentLayer.getFacetRanking(facetType));
+ }
+
+ }
+
+ /**
+ * Adds a new (transparent) layer on top of the {@code parentLayer}.
+ * <p>
+ * Facets can be added to this holder, while not affecting its parent.
+ * However, the parent acts as a fallback for {@link Facet} lookups.
+ */
+ private static FacetHolder layered(
+ final @NonNull MetaModelContext mmc,
+ final @NonNull Identifier featureIdentifier,
+ final @NonNull FacetHolder parentLayer) {
+ val facetHolder = new LayeredFacetHolder(mmc, parentLayer);
+ facetHolder.featureIdentifier = featureIdentifier;
+ return facetHolder;
+ }
+
// -- FIELDS
@Getter(onMethod_ = {@Override}) private final @NonNull MetaModelContext metaModelContext;
@@ -148,4 +262,6 @@ implements FacetHolder {
}
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
index 014c84572b..3f8a62adce 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetUtil.java
@@ -38,7 +38,7 @@ public final class FacetUtil {
* @param facet - non-null
* @return the argument as is
*/
- public static <F extends Facet> F addFacet(final @NonNull F facet) {
+ public <F extends Facet> F addFacet(final @NonNull F facet) {
facet.getFacetHolder().addFacet(facet);
return facet;
}
@@ -49,7 +49,7 @@ public final class FacetUtil {
* @param facetIfAny - null-able (for fail-safety)
* @return the argument as is - or just in case if null converted to an Optional.empty()
*/
- public static <F extends Facet> Optional<F> addFacetIfPresent(final @Nullable Optional<F> facetIfAny) {
+ public <F extends Facet> Optional<F> addFacetIfPresent(final @Nullable Optional<F> facetIfAny) {
if (facetIfAny == null) {
return Optional.empty();
}
@@ -64,7 +64,7 @@ public final class FacetUtil {
*
* @return whether given {@code facetList} contains any non-<tt>null</tt> facets
*/
- public static boolean addFacets(final @NonNull Iterable<Facet> facetList) {
+ public boolean addFacets(final @NonNull Iterable<Facet> facetList) {
boolean addedFacets = false;
for (val facet : facetList) {
addedFacets = addFacetIfPresent(Optional.ofNullable(facet)).isPresent()
@@ -73,7 +73,7 @@ public final class FacetUtil {
return addedFacets;
}
- public static <T extends Facet> XmlSchema.ExtensionData<T> getFacetsByType(final FacetHolder facetHolder) {
+ public <T extends Facet> XmlSchema.ExtensionData<T> getFacetsByType(final FacetHolder facetHolder) {
return new XmlSchema.ExtensionData<T>() {
@@ -92,18 +92,13 @@ public final class FacetUtil {
};
}
- public static void copyFacetsTo(final FacetHolder source, final FacetHolder target) {
- source.streamFacets()
- .forEach(target::addFacet);
- }
-
// -- DYNAMIC UPDATE SUPPORT
/**
* Removes any facet that matches the facet's java class from its FacetHolder,
* then adds the facet to the facetHolder.
*/
- public static <F extends Facet> void updateFacet(
+ public <F extends Facet> void updateFacet(
final @NonNull F facet) {
purgeIf(facet.facetType(), facet.getClass()::isInstance, facet.getFacetHolder());
@@ -114,7 +109,7 @@ public final class FacetUtil {
* Removes any facet of facet-type from facetHolder if it passes the given filter,
* then if present adds facetIfAny to the facetHolder.
*/
- public static <F extends Facet> void updateFacet(
+ public <F extends Facet> void updateFacet(
final @NonNull Class<F> facetType,
final @NonNull Predicate<? super F> filter,
final @NonNull Optional<? extends F> facetIfAny,
@@ -127,7 +122,7 @@ public final class FacetUtil {
/**
* Removes any facet of facet-type from facetHolder if it passes the given filter.
*/
- public static <F extends Facet> void purgeIf(
+ public <F extends Facet> void purgeIf(
final Class<F> facetType,
final Predicate<? super F> filter,
final FacetHolder facetHolder) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethodFactory.java
index 480f190f5b..a29bb6e25c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethodFactory.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.core.metamodel.facets.param.choices.methodnum;
+import java.util.Optional;
+
import javax.inject.Inject;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSupportPrefix;
@@ -43,6 +45,14 @@ extends ActionParameterSupportFacetFactoryAbstract {
val choicesMethod = searchResult.getSupportingMethod();
val returnType = searchResult.getReturnType();
val patConstructor = searchResult.getPatConstructor();
+
+ if(Optional.ofNullable(paramAsHolder.getFeatureIdentifier().getClassName()).orElse("")
+ .contains("HasCommunicationChannels_removeCommunicationChannel")) {
+ System.err.println("==ActionParameterChoicesFacetViaMethodFactory");
+ System.err.printf("%s%n", paramAsHolder.getFeatureIdentifier());
+ System.err.printf("\t%d: %s%n", paramAsHolder.getParamIndex(), paramAsHolder.getFeatureIdentifier().toString());
+ }
+
addFacet(
new ActionParameterChoicesFacetViaMethod(
choicesMethod, returnType, patConstructor, paramAsHolder));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/name/ParameterNameFacetFactoryUsingReflection.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/name/ParameterNameFacetFactoryUsingReflection.java
index 62379efdd0..a28203f2e9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/name/ParameterNameFacetFactoryUsingReflection.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/name/ParameterNameFacetFactoryUsingReflection.java
@@ -68,7 +68,12 @@ extends FacetFactoryAbstract {
val naturalName = StringExtensions.asNaturalName2(parameterName);
val facetHolder = processParameterContext.getFacetHolder();
-
+ if(Optional.ofNullable(facetHolder.getFeatureIdentifier().getClassName()).orElse("")
+ .contains("HasCommunicationChannels_removeCommunicationChannel")) {
+ System.err.println("==ParameterNameFacetFactoryUsingReflection");
+ System.err.printf("%s%n", facetHolder.getFeatureIdentifier());
+ System.err.printf("\t%d: %s%n", facetHolder.getParamIndex(), facetHolder.getFeatureIdentifier().toString());
+ }
FacetUtil.addFacet(
new NamedFacetForParameterUsingReflection(naturalName, facetHolder));
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
index 6114953025..93473f4828 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
@@ -67,6 +67,14 @@ extends ObjectSpecificationPostProcessorAbstract {
val paramAsHolder = param;
+ if(Optional.ofNullable(paramAsHolder.getFeatureIdentifier().getClassName()).orElse("")
+ .contains("HasCommunicationChannels_removeCommunicationChannel")) {
+ System.err.println("==ChoicesAndDefaultsPostProcessor");
+ System.err.printf("%s%n", paramAsHolder.getFeatureIdentifier());
+ System.err.printf("\t%d: %s%n", paramAsHolder.getParameterIndex(), paramAsHolder.getFeatureIdentifier().toString());
+ System.err.printf("\thasMemberLevelChoices: %b%n", hasMemberLevelChoices(param));
+ }
+
if(!hasMemberLevelChoices(param)) {
param.getElementType()
.lookupNonFallbackFacet(ChoicesFacet.class)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Specification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Specification.java
index 4adc9b1faa..c905164163 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Specification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/Specification.java
@@ -55,8 +55,9 @@ public interface Specification extends HasFacetHolder {
* </li><li>for a {@link OneToManyAssociation collection} it will be the type of
* element the collection holds (not the type of collection)
* </li><li>for an {@link ObjectAction action} will return {@link ObjectAction#getReturnType()}
- * </li><li>for an {@link ObjectActionParameter action parameter}, will return the type of
- * the parameter
+ * </li><li>for an {@link ObjectActionParameter action parameter}, will return the element type of
+ * the parameter (this is the parameter type itself if scalar, otherwise the type of
+ * element the collection (non-scalar) parameter holds)
* </li>
* </ul>
* @since 2.0
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index 47de4a1e27..c8944e2814 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -29,7 +29,6 @@ import org.apache.isis.commons.internal.reflection._Annotations;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FacetHolderAbstract;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
import org.apache.isis.core.metamodel.facets.all.named.MemberNamedFacet;
import org.apache.isis.core.metamodel.facets.all.named.MemberNamedFacetForStaticMemberName;
import org.apache.isis.core.metamodel.interactions.InteractionHead;
@@ -81,16 +80,15 @@ implements MixedInMember {
mixinAction.getFacetedMethod().getFeatureIdentifier().getMemberParameterClassNames()),
mixinAction.getFacetedMethod(), false);
- this.facetHolder = FacetHolderAbstract.simple(
+ this.facetHolder = FacetHolderAbstract.wrapped(
mixedInType.getMetaModelContext(),
- super.getFeatureIdentifier());
+ super.getFeatureIdentifier(),
+ mixinAction.getFacetedMethod());
+
this.mixinType = mixinType;
this.mixinAction = mixinAction;
this.mixedInType = mixedInType;
- // copy over facets from mixin action to self
- FacetUtil.copyFacetsTo(mixinAction.getFacetedMethod(), facetHolder);
-
// adjust name if necessary
val isExplicitlyNamed = lookupNonFallbackFacet(MemberNamedFacet.class)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index e96f592dd1..837855d20a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -97,9 +97,10 @@ implements MixedInMember {
_MixedInMemberNamingStrategy.determineIdFrom(mixinAction)),
mixinAction.getFacetedMethod(), typeOfSpec(mixinAction));
- this.facetHolder = FacetHolderAbstract.simple(
+ this.facetHolder = FacetHolderAbstract.wrapped(
mixeeSpec.getMetaModelContext(),
- super.getFeatureIdentifier());
+ super.getFeatureIdentifier(),
+ mixinAction.getFacetedMethod());
this.mixinType = mixinType;
this.mixinAction = mixinAction;
@@ -112,14 +113,6 @@ implements MixedInMember {
FacetUtil.addFacet(disabledFacet());
FacetUtil.addFacet(new TypeOfFacetAbstract(getElementType().getCorrespondingClass(), this) {});
- //
- // in addition, copy over facets from contributed to own.
- //
- // These could include everything under @Collection(...) because the
- // CollectionAnnotationFacetFactory is also run against actions.
- //
- FacetUtil.copyFacetsTo(mixinAction.getFacetedMethod(), facetHolder);
-
// adjust name if necessary
val isExplicitlyNamed = lookupNonFallbackFacet(MemberNamedFacet.class)
.isPresent();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index 8ee7f5dd91..0d83de2592 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -80,9 +80,10 @@ implements MixedInMember {
_MixedInMemberNamingStrategy.determineIdFrom(mixinAction)),
mixinAction.getFacetedMethod(), mixinAction.getReturnType());
- this.facetHolder = FacetHolderAbstract.simple(
+ this.facetHolder = FacetHolderAbstract.wrapped(
mixeeSpec.getMetaModelContext(),
- super.getFeatureIdentifier());
+ super.getFeatureIdentifier(),
+ mixinAction.getFacetedMethod());
this.mixinType = mixinType;
this.mixinAction = mixinAction;
@@ -93,15 +94,6 @@ implements MixedInMember {
//
FacetUtil.addFacet(disabledFacet());
- //
- // in addition, copy over facets from contributed to own.
- //
- // These could include everything under @Property(...) because the
- // PropertyAnnotationFacetFactory is also run against actions.
- //
-
- FacetUtil.copyFacetsTo(mixinAction.getFacetedMethod(), facetHolder);
-
// adjust name if necessary
val isExplicitlyNamed = lookupNonFallbackFacet(MemberNamedFacet.class)
.isPresent();