You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/09/14 07:19:50 UTC
[causeway] branch 3571-generic.type.resolver updated: CAUSEWAY-3571: moves TypeOfAnyCardinality from 'metamodel' to 'commons'
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3571-generic.type.resolver
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/3571-generic.type.resolver by this push:
new a6aaa39e5d CAUSEWAY-3571: moves TypeOfAnyCardinality from 'metamodel' to 'commons'
a6aaa39e5d is described below
commit a6aaa39e5d0f9e1bda692cd17c01e4935a58d51f
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Sep 14 09:19:45 2023 +0200
CAUSEWAY-3571: moves TypeOfAnyCardinality from 'metamodel' to 'commons'
---
.../internal/reflection/_GenericResolver.java | 100 ++++++++++++++----
.../core/metamodel/facets/FacetedMethod.java | 9 +-
.../metamodel/facets/FacetedMethodParameter.java | 5 +-
.../core/metamodel/facets/ParameterSupport.java | 7 +-
.../core/metamodel/facets/TypedHolder.java | 2 +-
.../core/metamodel/facets/TypedHolderAbstract.java | 2 +-
.../facets/actcoll/typeof/TypeOfFacet.java | 9 +-
.../facets/actcoll/typeof/TypeOfFacetAbstract.java | 2 +-
.../actcoll/typeof/TypeOfFacetFromFeature.java | 2 +-
.../facets/actcoll/typeof/TypeOfFacetFromType.java | 2 +-
.../typeof/TypeOfFacetForActionAnnotation.java | 2 +-
.../typeof/TypeOfFacetForCollectionAnnotation.java | 2 +-
.../ActionParameterAutoCompleteFacetViaMethod.java | 2 +-
.../ActionParameterChoicesFacetViaMethod.java | 2 +-
...ality.java => TypeOfAnyCardinalityFactory.java} | 113 +++++----------------
.../metamodel/spec/feature/OneToManyFeature.java | 2 +-
.../specimpl/OneToManyActionParameterDefault.java | 2 +-
.../specimpl/OneToManyAssociationDefault.java | 2 +-
.../causeway/core/metamodel/util/Facets.java | 2 +-
.../objects/OneToManyAssociationDefaultTest.java | 7 +-
.../metamodel/spec/TypeOfAnyCardinalityTest.java | 6 +-
.../wicket/model/links/ListOfLinksModel.java | 1 -
22 files changed, 138 insertions(+), 145 deletions(-)
diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_GenericResolver.java b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_GenericResolver.java
index 31522ea789..9369a1d840 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_GenericResolver.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_GenericResolver.java
@@ -28,6 +28,7 @@ import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Collection;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -76,8 +77,57 @@ public class _GenericResolver {
@NonNull Optional<CollectionSemantics> collectionSemantics();
default boolean isSingular() { return containerType().isEmpty(); }
+ default boolean isPlural() { return containerType().isPresent(); }
default boolean isArray() { return containerType().map(Class::isArray).orElse(false); }
+ /**
+ * Always <code>true</code> for <i>scalar</i> or <i>array</i>.
+ * Otherwise, whether {@link #containerType()} exactly matches
+ * the container type from {@link #collectionSemantics()}.
+ */
+ default boolean isSupportedForActionParameter() {
+ return isSingular()
+ || isArray()
+ ? true
+ : Objects.equals(
+ containerType().orElse(null),
+ collectionSemantics().map(CollectionSemantics::getContainerType).orElse(null));
+ }
+
+ // -- WITHERS
+
+ default TypeOfAnyCardinality withElementType(final @NonNull Class<?> elementType) {
+ return new SimpleTypeOfAnyCardinality(assertSingular(elementType), this.containerType(), this.collectionSemantics());
+ }
+
+ // -- INTERNAL FACTORIES
+ public static TypeOfAnyCardinality singular(final @NonNull Class<?> singularType) {
+ return new SimpleTypeOfAnyCardinality(assertSingular(singularType), Optional.empty(), Optional.empty());
+ }
+ public static TypeOfAnyCardinality plural(
+ final @NonNull Class<?> elementType,
+ final @NonNull Class<?> pluralType,
+ final @NonNull CollectionSemantics collectionSemantics) {
+ if(CollectionSemantics.valueOf(elementType).isPresent()) {
+ System.err.printf("nested plural detected %s: will fail later%n", elementType);
+ }
+ return new SimpleTypeOfAnyCardinality(assertSingular(elementType),
+ Optional.of(assertPlural(pluralType)),
+ Optional.of(collectionSemantics));
+ }
+ private static Class<?> assertSingular(final @NonNull Class<?> singularType) {
+ _Assert.assertEquals(
+ Optional.empty(),
+ CollectionSemantics.valueOf(singularType),
+ ()->String.format("%s should not match any supported plural (collection) types", singularType));
+ return singularType;
+ }
+ private static Class<?> assertPlural(final @NonNull Class<?> pluralType) {
+ _Assert.assertTrue(
+ CollectionSemantics.valueOf(pluralType).isPresent(),
+ ()->String.format("%s should match a supported plural (collection) type", pluralType));
+ return pluralType;
+ }
}
public static interface ResolvedMethod {
@@ -154,31 +204,18 @@ public class _GenericResolver {
return new SimpleResolvedConstructor(constructor, implementationClass);
}
- /**
- * JUnit
- */
- @UtilityClass
- public static class testing {
- @SneakyThrows
- public ResolvedMethod resolveMethod(
- final @NonNull Class<?> implementationClass,
- final @NonNull String methodName,
- final Class<?>... parameterTypes) {
-
- val candidate = _ClassCache.getInstance().findMethodUniquelyByNameOrFail(implementationClass, methodName);
- val paramTypesFound = Can.ofArray(candidate.paramTypes());
- val paramTypesRequested = Can.ofArray(parameterTypes);
- _Assert.assertEquals(paramTypesFound, paramTypesRequested);
- return candidate;
+ // -- IMPLEMENTATIONS
-// return _GenericResolver.resolveMethod(implementationClass.getMethod(methodName, parameterTypes), implementationClass)
-// .orElseThrow(()->new NoSuchMethodException(String.format("%s#%s(%s)", implementationClass, methodName,
-// paramTypesRequested.stream().map(Class::getSimpleName).collect(Collectors.joining(",")))));
- }
+ @lombok.Value @Accessors(fluent=true)
+ private static class SimpleTypeOfAnyCardinality implements TypeOfAnyCardinality {
+ @Getter(onMethod_={@Override})
+ private final @NonNull Class<?> elementType;
+ @Getter(onMethod_={@Override})
+ private final @NonNull Optional<Class<?>> containerType;
+ @Getter(onMethod_={@Override})
+ private final @NonNull Optional<CollectionSemantics> collectionSemantics;
}
- // -- IMPLEMENTATIONS
-
@EqualsAndHashCode
@Getter @Accessors(fluent=true)
private static class SimpleResolvedMethod implements ResolvedMethod {
@@ -312,4 +349,23 @@ public class _GenericResolver {
m, a.method(), b.method()));
}
+ /**
+ * JUnit
+ */
+ @UtilityClass
+ public static class testing {
+ @SneakyThrows
+ public ResolvedMethod resolveMethod(
+ final @NonNull Class<?> implementationClass,
+ final @NonNull String methodName,
+ final Class<?>... parameterTypes) {
+
+ val candidate = _ClassCache.getInstance().findMethodUniquelyByNameOrFail(implementationClass, methodName);
+ val paramTypesFound = Can.ofArray(candidate.paramTypes());
+ val paramTypesRequested = Can.ofArray(parameterTypes);
+ _Assert.assertEquals(paramTypesFound, paramTypesRequested);
+ return candidate;
+ }
+ }
+
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethod.java
index 657236dfd9..e842b78471 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethod.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethod.java
@@ -29,13 +29,14 @@ import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.internal.collections._Lists;
import org.apache.causeway.commons.internal.reflection._GenericResolver;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
+import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinalityFactory;
import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
import lombok.Getter;
@@ -55,7 +56,7 @@ extends TypedHolderAbstract {
final ResolvedMethod getterMethod) {
val methodFacade = _MethodFacades.regular(getterMethod);
return new FacetedMethod(mmc, FeatureType.PROPERTY,
- declaringType, methodFacade, TypeOfAnyCardinality.forMethodReturn(declaringType, getterMethod), Can.empty());
+ declaringType, methodFacade, TypeOfAnyCardinalityFactory.forMethodReturn(declaringType, getterMethod), Can.empty());
}
public static FacetedMethod createForCollection(
@@ -64,7 +65,7 @@ extends TypedHolderAbstract {
final ResolvedMethod getterMethod) {
val methodFacade = _MethodFacades.regular(getterMethod);
return new FacetedMethod(mmc, FeatureType.COLLECTION,
- declaringType, methodFacade, TypeOfAnyCardinality.forMethodReturn(declaringType, getterMethod), Can.empty());
+ declaringType, methodFacade, TypeOfAnyCardinalityFactory.forMethodReturn(declaringType, getterMethod), Can.empty());
}
public static FacetedMethod createForAction(
@@ -72,7 +73,7 @@ extends TypedHolderAbstract {
final Class<?> declaringType,
final MethodFacade methodFacade) {
return new FacetedMethod(mmc, FeatureType.ACTION,
- declaringType, methodFacade, TypeOfAnyCardinality.forMethodFacadeReturn(declaringType, methodFacade),
+ declaringType, methodFacade, TypeOfAnyCardinalityFactory.forMethodFacadeReturn(declaringType, methodFacade),
getParameters(mmc, declaringType, methodFacade));
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethodParameter.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethodParameter.java
index 40af9e3252..b624656bea 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethodParameter.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/FacetedMethodParameter.java
@@ -19,10 +19,11 @@
package org.apache.causeway.core.metamodel.facets;
import org.apache.causeway.applib.id.LogicalType;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
+import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinalityFactory;
import lombok.Getter;
@@ -40,7 +41,7 @@ extends TypedHolderAbstract {
super(mmc,
featureType,
- TypeOfAnyCardinality.forMethodFacadeParameter(declaringType, methodFacade, paramIndex),
+ TypeOfAnyCardinalityFactory.forMethodFacadeParameter(declaringType, methodFacade, paramIndex),
FeatureType.ACTION.identifierFor(
LogicalType.lazy(
declaringType,
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ParameterSupport.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ParameterSupport.java
index 74e73ab42e..1a935db75e 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ParameterSupport.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/ParameterSupport.java
@@ -28,11 +28,12 @@ import org.apache.causeway.commons.internal._Constants;
import org.apache.causeway.commons.internal.collections._Arrays;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
import org.apache.causeway.core.metamodel.methods.MethodFinder;
import org.apache.causeway.core.metamodel.methods.MethodFinderPAT;
import org.apache.causeway.core.metamodel.methods.MethodFinderPAT.MethodAndPatConstructor;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
+import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinalityFactory;
import lombok.Builder;
import lombok.Getter;
@@ -154,7 +155,7 @@ public final class ParameterSupport {
.of(paramIndex, paramType,
supportingMethodAndPatConstructor.getSupportingMethod(),
Optional.of(supportingMethodAndPatConstructor.getPatConstructor()),
- TypeOfAnyCardinality.forMethodReturn(
+ TypeOfAnyCardinalityFactory.forMethodReturn(
declaringClass, supportingMethodAndPatConstructor.getSupportingMethod()));
}
@@ -219,7 +220,7 @@ public final class ParameterSupport {
.of(paramIndex, paramType,
supportingMethod,
Optional.empty(),
- TypeOfAnyCardinality.forMethodReturn(
+ TypeOfAnyCardinalityFactory.forMethodReturn(
declaringClass, supportingMethod));
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolder.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolder.java
index d2b1c8e19d..79f211cabb 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolder.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolder.java
@@ -18,11 +18,11 @@
*/
package org.apache.causeway.core.metamodel.facets;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.facetapi.HasFacetHolder;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
/**
* A {@link FacetHolder} that also has a {@link ObjectSpecification type}.
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolderAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolderAbstract.java
index 57ae4a8edc..ec5b2d9b54 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolderAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/TypedHolderAbstract.java
@@ -19,11 +19,11 @@
package org.apache.causeway.core.metamodel.facets;
import org.apache.causeway.applib.Identifier;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import lombok.Getter;
import lombok.NonNull;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
index 9a3b743a7b..1269f28585 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
@@ -23,11 +23,12 @@ import java.util.function.BiFunction;
import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
+import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinalityFactory;
import lombok.val;
@@ -57,7 +58,7 @@ public interface TypeOfFacet extends Facet {
final MethodFacade method,
final int paramIndex,
final FacetHolder holder) {
- val type = TypeOfAnyCardinality.forMethodFacadeParameter(implementationClass, method, paramIndex);
+ val type = TypeOfAnyCardinalityFactory.forMethodFacadeParameter(implementationClass, method, paramIndex);
return toInferredFrom(TypeOfFacet::inferredFromFeature, type, holder);
}
@@ -65,13 +66,13 @@ public interface TypeOfFacet extends Facet {
final Class<?> implementationClass,
final MethodFacade method,
final FacetHolder holder) {
- val type = TypeOfAnyCardinality.forMethodFacadeReturn(implementationClass, method);
+ val type = TypeOfAnyCardinalityFactory.forMethodFacadeReturn(implementationClass, method);
return toInferredFrom(TypeOfFacet::inferredFromFeature, type, holder);
}
static Optional<TypeOfFacet> inferFromNonScalarType(
final CollectionSemantics collectionSemantics, final Class<?> nonScalarType, final FacetHolder holder) {
- val type = TypeOfAnyCardinality.forPluralType(nonScalarType, collectionSemantics);
+ val type = TypeOfAnyCardinalityFactory.forPluralType(nonScalarType, collectionSemantics);
return toInferredFrom(TypeOfFacet::inferredFromType, type, holder);
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetAbstract.java
index 9ad3e6b674..56c03e037f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetAbstract.java
@@ -22,11 +22,11 @@ import java.util.Optional;
import java.util.function.BiConsumer;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.Facet;
import org.apache.causeway.core.metamodel.facetapi.FacetAbstract;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import lombok.Getter;
import lombok.NonNull;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromFeature.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromFeature.java
index 1fd1769b18..c373c4ed5f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromFeature.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromFeature.java
@@ -18,8 +18,8 @@
*/
package org.apache.causeway.core.metamodel.facets.actcoll.typeof;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
public class TypeOfFacetFromFeature
extends TypeOfFacetAbstract {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromType.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromType.java
index 4c03d6b5ff..ffd9276bd9 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromType.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actcoll/typeof/TypeOfFacetFromType.java
@@ -18,8 +18,8 @@
*/
package org.apache.causeway.core.metamodel.facets.actcoll.typeof;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
public class TypeOfFacetFromType
extends TypeOfFacetAbstract {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/typeof/TypeOfFacetForActionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/typeof/TypeOfFacetForActionAnnotation.java
index ca596b813a..f85d7869a4 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/typeof/TypeOfFacetForActionAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/typeof/TypeOfFacetForActionAnnotation.java
@@ -22,10 +22,10 @@ import java.util.Optional;
import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacetAbstract;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
public class TypeOfFacetForActionAnnotation
extends TypeOfFacetAbstract {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/typeof/TypeOfFacetForCollectionAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/typeof/TypeOfFacetForCollectionAnnotation.java
index 179733949a..34d5eb431d 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/typeof/TypeOfFacetForCollectionAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/typeof/TypeOfFacetForCollectionAnnotation.java
@@ -22,11 +22,11 @@ import java.util.Optional;
import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.FacetedMethod;
import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacetAbstract;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
public class TypeOfFacetForCollectionAnnotation
extends TypeOfFacetAbstract {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java
index 6e77cabae7..df9d6df44d 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/autocomplete/method/ActionParameterAutoCompleteFacetViaMethod.java
@@ -25,6 +25,7 @@ import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
@@ -35,7 +36,6 @@ import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.object.MmInvokeUtils;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import lombok.Getter;
import lombok.NonNull;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
index 6f40debdde..0d2add0e49 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
@@ -25,6 +25,7 @@ import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedConstructor;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
@@ -35,7 +36,6 @@ import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.core.metamodel.object.MmInvokeUtils;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import lombok.Getter;
import lombok.NonNull;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinality.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityFactory.java
similarity index 59%
rename from core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinality.java
rename to core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityFactory.java
index b60fcc0607..48c5004731 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinality.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityFactory.java
@@ -20,74 +20,30 @@ package org.apache.causeway.core.metamodel.spec;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
-import java.util.Objects;
-import java.util.Optional;
import org.springframework.core.ResolvableType;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
-import org.apache.causeway.commons.internal.assertions._Assert;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
-import org.apache.causeway.commons.internal.reflection._GenericResolver;
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.commons.internal.reflection._MethodFacades.MethodFacade;
import org.apache.causeway.commons.internal.reflection._Reflect.ConstructorAndImplementingClass;
import org.apache.causeway.commons.internal.reflection._Reflect.MethodAndImplementingClass;
-import lombok.Getter;
import lombok.NonNull;
import lombok.val;
-import lombok.experimental.Accessors;
-
-@lombok.Value(staticConstructor = "of") @Accessors(fluent=true)
-public class TypeOfAnyCardinality implements _GenericResolver.TypeOfAnyCardinality {
-
- @Getter(onMethod_={@Override})
- private final @NonNull Class<?> elementType;
- @Getter(onMethod_={@Override})
- private final @NonNull Optional<Class<?>> containerType;
- @Getter(onMethod_={@Override})
- private final @NonNull Optional<CollectionSemantics> collectionSemantics;
-
- /**
- * Always <code>true</code> for <i>scalar</i> or <i>array</i>.
- * Otherwise, whether {@link #containerType()} exactly matches
- * the container type from {@link #collectionSemantics()}.
- */
- public boolean isSupportedForActionParameter() {
- return isSingular()
- || isArray()
- ? true
- : Objects.equals(
- containerType().orElse(null),
- collectionSemantics().map(CollectionSemantics::getContainerType).orElse(null));
+import lombok.experimental.UtilityClass;
- }
-
- // -- FACTORIES
-
- public static TypeOfAnyCardinality singular(final @NonNull Class<?> singularType) {
- return of(assertSingular(singularType), Optional.empty(), Optional.empty());
- }
-
- public static TypeOfAnyCardinality plural(
- final @NonNull Class<?> elementType,
- final @NonNull Class<?> pluralType,
- final @NonNull CollectionSemantics collectionSemantics) {
- if(CollectionSemantics.valueOf(elementType).isPresent()) {
- System.err.printf("nested plural detected %s: yields unpredicted behavior%n", elementType);
- }
- return of(assertSingular(elementType),
- Optional.of(assertPlural(pluralType)),
- Optional.of(collectionSemantics));
- }
+@UtilityClass
+public class TypeOfAnyCardinalityFactory {
- public static TypeOfAnyCardinality forMethodFacadeReturn(
+ public TypeOfAnyCardinality forMethodFacadeReturn(
final Class<?> _implementationClass, final MethodFacade methodFacade) {
return forMethodReturn(_implementationClass, methodFacade.asMethodForIntrospection());
}
- public static TypeOfAnyCardinality forMethodReturn(
+ public TypeOfAnyCardinality forMethodReturn(
final Class<?> _implementationClass, final ResolvedMethod _method) {
val methodReturnGuess = _method.returnType();
return CollectionSemantics.valueOf(methodReturnGuess)
@@ -105,17 +61,17 @@ public class TypeOfAnyCardinality implements _GenericResolver.TypeOfAnyCardinali
return CollectionSemantics.valueOf(methodReturn)
.map(collectionSemantics->
- plural(
+ TypeOfAnyCardinality.plural(
adopted.resolveFirstGenericTypeArgumentOnMethodReturn(),
methodReturn,
collectionSemantics)
)
- .orElseGet(()->singular(methodReturn));
+ .orElseGet(()->TypeOfAnyCardinality.singular(methodReturn));
})
- .orElseGet(()->singular(methodReturnGuess));
+ .orElseGet(()->TypeOfAnyCardinality.singular(methodReturnGuess));
}
- public static TypeOfAnyCardinality forMethodFacadeParameter(
+ public TypeOfAnyCardinality forMethodFacadeParameter(
final Class<?> _implementationClass, final MethodFacade methodFacade, final int paramIndex) {
val executable = methodFacade.asExecutable();
if(executable instanceof Method) {
@@ -126,7 +82,7 @@ public class TypeOfAnyCardinality implements _GenericResolver.TypeOfAnyCardinali
throw _Exceptions.unexpectedCodeReach();
}
- public static TypeOfAnyCardinality forConstructorParameter(
+ public TypeOfAnyCardinality forConstructorParameter(
final Class<?> _implementationClass, final Constructor<?> _constructor, final int paramIndex) {
val paramTypeGuess = _constructor.getParameters()[paramIndex].getType();
return CollectionSemantics.valueOf(paramTypeGuess)
@@ -144,17 +100,17 @@ public class TypeOfAnyCardinality implements _GenericResolver.TypeOfAnyCardinali
return CollectionSemantics.valueOf(paramType)
.map(collectionSemantics->
- plural(
+ TypeOfAnyCardinality.plural(
adopted.resolveFirstGenericTypeArgumentOnParameter(paramIndex),
paramType,
collectionSemantics)
)
- .orElseGet(()->singular(paramType));
+ .orElseGet(()->TypeOfAnyCardinality.singular(paramType));
})
- .orElseGet(()->singular(paramTypeGuess));
+ .orElseGet(()->TypeOfAnyCardinality.singular(paramTypeGuess));
}
- public static TypeOfAnyCardinality forMethodParameter(
+ public TypeOfAnyCardinality forMethodParameter(
final Class<?> _implementationClass, final Method _method, final int paramIndex) {
val paramTypeGuess = _method.getParameters()[paramIndex].getType();
return CollectionSemantics.valueOf(paramTypeGuess)
@@ -172,49 +128,28 @@ public class TypeOfAnyCardinality implements _GenericResolver.TypeOfAnyCardinali
return CollectionSemantics.valueOf(paramType)
.map(collectionSemantics->
- plural(
+ TypeOfAnyCardinality.plural(
adopted.resolveFirstGenericTypeArgumentOnParameter(paramIndex),
paramType,
collectionSemantics)
)
- .orElseGet(()->singular(paramType));
+ .orElseGet(()->TypeOfAnyCardinality.singular(paramType));
})
- .orElseGet(()->singular(paramTypeGuess));
+ .orElseGet(()->TypeOfAnyCardinality.singular(paramTypeGuess));
}
- public static TypeOfAnyCardinality forPluralType(
- final @NonNull Class<?> nonScalarType,
+ public TypeOfAnyCardinality forPluralType(
+ final @NonNull Class<?> pluralType,
final @NonNull CollectionSemantics collectionSemantics) {
- return plural(
- toClass(ResolvableType.forClass(nonScalarType)),
- nonScalarType,
+ return TypeOfAnyCardinality.plural(
+ toClass(ResolvableType.forClass(pluralType)),
+ pluralType,
collectionSemantics);
}
- // -- WITHERS
-
- public TypeOfAnyCardinality withElementType(final @NonNull Class<?> elementType) {
- return of(assertSingular(elementType), this.containerType(), this.collectionSemantics());
- }
-
// -- HELPER
- private static Class<?> assertSingular(final @NonNull Class<?> singularType) {
- _Assert.assertEquals(
- Optional.empty(),
- CollectionSemantics.valueOf(singularType),
- ()->String.format("%s should not match any supported plural (collection) types", singularType));
- return singularType;
- }
-
- private static Class<?> assertPlural(final @NonNull Class<?> pluralType) {
- _Assert.assertTrue(
- CollectionSemantics.valueOf(pluralType).isPresent(),
- ()->String.format("%s should match a supported plural (collection) type", pluralType));
- return pluralType;
- }
-
- private static Class<?> toClass(final ResolvableType pluralType){
+ private Class<?> toClass(final ResolvableType pluralType){
val genericTypeArg = pluralType.isArray()
? pluralType.getComponentType()
: pluralType.getGeneric(0);
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToManyFeature.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToManyFeature.java
index d16b73c881..3516495319 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToManyFeature.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/OneToManyFeature.java
@@ -20,7 +20,7 @@ package org.apache.causeway.core.metamodel.spec.feature;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
/**
* Base interface for {@link OneToManyAssociation} only.
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyActionParameterDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyActionParameterDefault.java
index 849b8a01b4..72fbe3de30 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyActionParameterDefault.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyActionParameterDefault.java
@@ -19,9 +19,9 @@
package org.apache.causeway.core.metamodel.specloader.specimpl;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.spec.feature.OneToManyActionParameter;
import org.apache.causeway.core.metamodel.util.Facets;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
index 629c88dbac..cc3880a611 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
@@ -24,6 +24,7 @@ import org.apache.causeway.applib.annotation.CollectionLayout;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.commons.ToString;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
@@ -36,7 +37,6 @@ import org.apache.causeway.core.metamodel.interactions.UsabilityContext;
import org.apache.causeway.core.metamodel.interactions.VisibilityContext;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.causeway.core.metamodel.util.Facets;
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
index f3a70a2979..4e7261d01f 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/util/Facets.java
@@ -41,6 +41,7 @@ import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.commons.internal.factory._InstanceUtil;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.config.metamodel.facets.ParameterConfigOptions;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.causeway.core.metamodel.facetapi.Facet;
@@ -77,7 +78,6 @@ import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty;
import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature;
diff --git a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/objects/OneToManyAssociationDefaultTest.java b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/objects/OneToManyAssociationDefaultTest.java
index 5cf729c17f..1433a827ab 100644
--- a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/objects/OneToManyAssociationDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/objects/OneToManyAssociationDefaultTest.java
@@ -19,7 +19,6 @@
package org.apache.causeway.core.metamodel.objects;
import java.util.List;
-import java.util.Optional;
//import com.sun.xml.bind.v2.schemagen.xmlschema.List;
@@ -35,12 +34,12 @@ import static org.mockito.Mockito.when;
import org.apache.causeway.applib.Identifier;
import org.apache.causeway.commons.collectionsemantics.CollectionSemantics;
import org.apache.causeway.commons.functional.Either;
+import org.apache.causeway.commons.internal.reflection._GenericResolver.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.MetaModelTestAbstract;
import org.apache.causeway.core.metamodel.facets.FacetedMethod;
import org.apache.causeway.core.metamodel.facets.all.i8n.staatic.HasStaticText;
import org.apache.causeway.core.metamodel.facets.all.named.MemberNamedFacet;
import org.apache.causeway.core.metamodel.id.TypeIdentifierTestFactory;
-import org.apache.causeway.core.metamodel.spec.TypeOfAnyCardinality;
import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.causeway.core.metamodel.specloader.specimpl.OneToManyAssociationDefault;
@@ -55,8 +54,8 @@ extends MetaModelTestAbstract {
}
private static final Class<?> COLLECTION_TYPE = Order.class;
- private static final TypeOfAnyCardinality TOAC = TypeOfAnyCardinality.of(
- COLLECTION_TYPE, Optional.of(List.class), Optional.of(CollectionSemantics.LIST));
+ private static final TypeOfAnyCardinality TOAC = TypeOfAnyCardinality.plural(
+ COLLECTION_TYPE, List.class, CollectionSemantics.LIST);
private OneToManyAssociation association;
diff --git a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityTest.java b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityTest.java
index 0a06bf2b85..e8467cb884 100644
--- a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityTest.java
+++ b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/spec/TypeOfAnyCardinalityTest.java
@@ -159,9 +159,9 @@ class TypeOfAnyCardinalityTest {
assertEquals(genericB, genericArgB.toClass());
assertEquals(genericC, genericArgC.toClass());
- val typeA = TypeOfAnyCardinality.forMethodReturn(a, methodInA);
- val typeB = TypeOfAnyCardinality.forMethodReturn(b, methodInB);
- val typeC = TypeOfAnyCardinality.forMethodReturn(c, methodInC);
+ val typeA = TypeOfAnyCardinalityFactory.forMethodReturn(a, methodInA);
+ val typeB = TypeOfAnyCardinalityFactory.forMethodReturn(b, methodInB);
+ val typeC = TypeOfAnyCardinalityFactory.forMethodReturn(c, methodInC);
assertEquals(genericA, typeA.elementType());
assertEquals(genericB, typeB.elementType());
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java
index fbcb3ad404..9f24d51c2f 100644
--- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/links/ListOfLinksModel.java
@@ -51,5 +51,4 @@ extends ChainingModel<List<LinkAndLabel>> {
return false;
}
-
}