This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v3
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/v3 by this push:
new c9f3923003f CAUSEWAY-3837: proper element-type detection for Map 'as
collection'
c9f3923003f is described below
commit c9f3923003fc09de35158b6e9e3112822aa5c5e1
Author: andi-huber <[email protected]>
AuthorDate: Mon Dec 16 08:38:19 2024 +0100
CAUSEWAY-3837: proper element-type detection for Map 'as collection'
---
.../commons/internal/reflection/_GenericResolver.java | 17 +++++++++--------
.../causeway/commons/semantics/CollectionSemantics.java | 4 ++++
.../facets/object/navchild/TreeTraversalTest.java | 1 +
.../core/metamodel/spec/TypeOfAnyCardinalityTest.java | 17 +++++++++++++++++
4 files changed, 31 insertions(+), 8 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 711a4f04409..d0e8f049003 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
@@ -168,7 +168,7 @@ public class _GenericResolver {
.anyMatch(this::isReturnTypeATypeOf);
}
Class<?> resolveFirstGenericTypeArgumentOnParameter(int paramIndex);
- Class<?> resolveFirstGenericTypeArgumentOnMethodReturn();
+ Class<?> resolveGenericTypeArgumentOnMethodReturn(int argumentIndex);
/**
* Is NOT compliant with the weak-sameness relation
* {@link ResolvedMethod#methodsWeaklySame(ResolvedMethod,
ResolvedMethod)}.
@@ -278,7 +278,7 @@ public class _GenericResolver {
return CollectionSemantics.valueOf(methodReturn)
.map(collectionSemantics->
ResolvedType.plural(
-
resolvedMethod.resolveFirstGenericTypeArgumentOnMethodReturn(),
+
resolvedMethod.resolveGenericTypeArgumentOnMethodReturn(collectionSemantics.genericTypeArgumentIndex()),
methodReturn,
collectionSemantics)
)
@@ -351,13 +351,13 @@ public class _GenericResolver {
return isResolved ? Optional.of(this) : Optional.empty();
}
@Override
- public Class<?> resolveFirstGenericTypeArgumentOnMethodReturn() {
- return genericTypeArg(ResolvableType.forMethodReturnType(method,
implementationClass))
+ public Class<?> resolveGenericTypeArgumentOnMethodReturn(final int
argumentIndex) {
+ return genericTypeArg(ResolvableType.forMethodReturnType(method,
implementationClass), argumentIndex)
.toClass();
}
@Override
public Class<?> resolveFirstGenericTypeArgumentOnParameter(final int
paramIndex) {
- return genericTypeArg(ResolvableType.forMethodParameter(method,
paramIndex, implementationClass))
+ return genericTypeArg(ResolvableType.forMethodParameter(method,
paramIndex, implementationClass), 0)
.toClass();
}
@Override
@@ -383,6 +383,7 @@ public class _GenericResolver {
if(!_Reflect.hasGenericReturn(method)) return true; // skip check
return !returnType.equals(Object.class);
}
+
// private Try<SimpleResolvedMethod> adopt(final @NonNull ClassLoader
classLoader) {
// return Try.call(()->{
// var ownerReloaded =
Class.forName(implementationClass.getName(), true, classLoader);
@@ -413,7 +414,7 @@ public class _GenericResolver {
}
@Override
public Class<?> resolveFirstGenericTypeArgumentOnParameter(final int
paramIndex) {
- return
genericTypeArg(ResolvableType.forConstructorParameter(constructor, paramIndex,
implementationClass))
+ return
genericTypeArg(ResolvableType.forConstructorParameter(constructor, paramIndex,
implementationClass), 0)
.toClass();
}
@Override
@@ -485,10 +486,10 @@ public class _GenericResolver {
m, a.method(), b.method()));
}
- private ResolvableType genericTypeArg(final ResolvableType pluralType){
+ private ResolvableType genericTypeArg(final ResolvableType pluralType,
final int genericTypeArgumentIndex){
var genericTypeArg = pluralType.isArray()
? pluralType.getComponentType()
- : pluralType.getGeneric(0);
+ : pluralType.getGeneric(genericTypeArgumentIndex);
return genericTypeArg;
}
diff --git
a/commons/src/main/java/org/apache/causeway/commons/semantics/CollectionSemantics.java
b/commons/src/main/java/org/apache/causeway/commons/semantics/CollectionSemantics.java
index ee26b07ef16..043e1cace9d 100644
---
a/commons/src/main/java/org/apache/causeway/commons/semantics/CollectionSemantics.java
+++
b/commons/src/main/java/org/apache/causeway/commons/semantics/CollectionSemantics.java
@@ -178,6 +178,10 @@ public enum CollectionSemantics {
protected abstract Object asContainerType(
final Class<?> elementType, final @NonNull List<?> nonScalar);
+
+ public int genericTypeArgumentIndex() {
+ return isMap() ? 1 : 0;
+ }
}
//TODO perhaps needs an update to reflect Java 7->11 Language changes
diff --git
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/navchild/TreeTraversalTest.java
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/navchild/TreeTraversalTest.java
index 7f26873b136..3b0f58fe442 100644
---
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/navchild/TreeTraversalTest.java
+++
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/object/navchild/TreeTraversalTest.java
@@ -79,6 +79,7 @@ extends FacetFactoryTestAbstract {
var assocAC = specA.getAssociationElseFail("childrenC");
assertTrue(assocAC.isCollection());
assertTrue(assocAC.containsFacet(NavigableSubtreeSequenceFacet.class));
+ assertEquals(_TreeSample.C.class,
assocAC.getElementType().getCorrespondingClass());
// second: post-processor should generate NavigableSubtreeFacet
assertTrue(specA.containsFacet(NavigableSubtreeFacet.class));
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 59c0c31f803..eb63da82511 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
@@ -19,6 +19,7 @@
package org.apache.causeway.core.metamodel.spec;
import java.util.Collections;
+import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -122,6 +123,22 @@ class TypeOfAnyCardinalityTest {
Set.class, Set.class, SortedSet.class);
}
+ // -- SCENARIO: MAP
+
+ static class M {
+ public Map<Integer, String> someStrings() {
+ return Map.of(1, "a");
+ }
+ }
+
+ @Test
+ void mapAsCollection() {
+ var method = _GenericResolver.testing.resolveMethod(M.class,
"someStrings");
+ assertNotNull(method);
+ var elementType =
_GenericResolver.forMethodReturn(method).elementType();
+ assertEquals(String.class, elementType);
+ }
+
// -- HELPER
@SneakyThrows