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 2021/09/08 08:37:36 UTC
[isis] branch master updated: ISIS-2774: method finder overhaul
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 c507416 ISIS-2774: method finder overhaul
c507416 is described below
commit c5074166ecb4c617a124d1e110507fd1d592294b
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 8 10:37:27 2021 +0200
ISIS-2774: method finder overhaul
---
.../org/apache/isis/commons/collections/Can.java | 4 +-
.../apache/isis/commons/collections/Can_Empty.java | 4 +-
.../isis/commons/collections/Can_Multiple.java | 4 +-
.../isis/commons/collections/Can_Singleton.java | 4 +-
.../apache/isis/commons/collections/CanTest.java | 20 +-
.../DomainObjectAnnotationFacetFactory.java | 2 +-
.../recreatable/RecreatableObjectFacetFactory.java | 2 +-
.../annotation/TitleAnnotationFacetFactory.java | 2 +-
.../isis/core/metamodel/methods/MethodFinder.java | 86 +++-----
.../metamodel/methods/MethodFinderOptions.java | 66 +++++-
.../core/metamodel/methods/MethodFinderUtils.java | 241 +--------------------
.../metamodel/facets/MethodFinderUtilsTest.java | 6 +-
.../restfulobjects/viewer/mappers/FailureUtil.java | 12 +-
13 files changed, 136 insertions(+), 317 deletions(-)
diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can.java b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
index 5c1e293..d252f2d 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can.java
@@ -361,14 +361,14 @@ extends Iterable<T>, Comparable<Can<T>>, Serializable {
* {@link Object#equals(Object)} object equality.
* @return non-null
*/
- public Can<T> unique();
+ public Can<T> distinct();
/**
* Returns a {@code Can} with all the elements from this {@code Can}, but
* duplicated elements removed, based on given {@code equality} relation.
* @return non-null
*/
- public Can<T> unique(@NonNull BiPredicate<T, T> equality);
+ public Can<T> distinct(@NonNull BiPredicate<T, T> equality);
/**
* Returns a {@code Can} with all the elements from this {@code Can}, but
diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
index 6fa3786..e86b6ef 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can_Empty.java
@@ -102,12 +102,12 @@ final class Can_Empty<T> implements Can<T> {
}
@Override
- public Can<T> unique() {
+ public Can<T> distinct() {
return this;
}
@Override
- public Can<T> unique(final @NonNull BiPredicate<T, T> equality) {
+ public Can<T> distinct(final @NonNull BiPredicate<T, T> equality) {
return this;
}
diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java b/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
index a2d7bba..761c8b9 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can_Multiple.java
@@ -115,14 +115,14 @@ final class Can_Multiple<T> implements Can<T> {
}
@Override
- public Can<T> unique() {
+ public Can<T> distinct() {
val set = new LinkedHashSet<T>(); // preserve order
set.addAll(elements);
return Can.ofCollection(set);
}
@Override
- public Can<T> unique(final @NonNull BiPredicate<T, T> equality) {
+ public Can<T> distinct(final @NonNull BiPredicate<T, T> equality) {
final int initialSize = Math.min(1024, elements.size());
val uniqueElements = _Lists.<T>newArrayList(initialSize);
elements
diff --git a/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java b/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
index 72b26c9..67c4464 100644
--- a/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
+++ b/commons/src/main/java/org/apache/isis/commons/collections/Can_Singleton.java
@@ -103,12 +103,12 @@ final class Can_Singleton<T> implements Can<T> {
}
@Override
- public Can<T> unique() {
+ public Can<T> distinct() {
return this;
}
@Override
- public Can<T> unique(final @NonNull BiPredicate<T, T> equality) {
+ public Can<T> distinct(final @NonNull BiPredicate<T, T> equality) {
return this;
}
diff --git a/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java b/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
index b07344c..d07590a 100644
--- a/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
+++ b/commons/src/test/java/org/apache/isis/commons/collections/CanTest.java
@@ -195,23 +195,23 @@ class CanTest {
assertEquals(
Can.empty(),
- Can.empty().unique());
+ Can.empty().distinct());
assertEquals(
Can.of("a"),
- Can.of("a").unique());
+ Can.of("a").distinct());
assertEquals(
Can.of("a"),
- Can.of("a", "a", "a").unique());
+ Can.of("a", "a", "a").distinct());
assertEquals(
Can.of("a", "b", "c"),
- Can.of("a", "b", "c").unique());
+ Can.of("a", "b", "c").distinct());
assertEquals(
Can.of("a", "b"),
- Can.of("a", "b", "a").unique());
+ Can.of("a", "b", "a").distinct());
}
@Test
@@ -222,23 +222,23 @@ class CanTest {
assertEquals(
Can.empty(),
- Can.<String>empty().unique(firstCharEquility));
+ Can.<String>empty().distinct(firstCharEquility));
assertEquals(
Can.of("a"),
- Can.of("a").unique(firstCharEquility));
+ Can.of("a").distinct(firstCharEquility));
assertEquals(
Can.of("aDog"),
- Can.of("aDog", "aCat", "aMonkey").unique(firstCharEquility));
+ Can.of("aDog", "aCat", "aMonkey").distinct(firstCharEquility));
assertEquals(
Can.of("aDog", "bCat", "cMonkey"),
- Can.of("aDog", "bCat", "cMonkey").unique(firstCharEquility));
+ Can.of("aDog", "bCat", "cMonkey").distinct(firstCharEquility));
assertEquals(
Can.of("aDog", "bCat"),
- Can.of("aDog", "bCat", "aMonkey").unique(firstCharEquility));
+ Can.of("aDog", "bCat", "aMonkey").distinct(firstCharEquility));
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index c085e33..16db365 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -646,7 +646,7 @@ implements
public Method postConstructMethodFor(final Object pojo) {
return MethodFinderUtils.findAnnotatedMethod(
// @PostConstruct is allowed to appear on non-public methods
- MethodFinderOptions.notNecessarilyPublic(),
+ MethodFinderOptions.notNecessarilyPublic(MethodFinderOptions.ANY_NAME),
pojo, PostConstruct.class, postConstructMethodsCache);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
index ca43a5e..f7c3ed6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetFactory.java
@@ -131,7 +131,7 @@ implements
public Method postConstructMethodFor(final Object pojo) {
return MethodFinderUtils.findAnnotatedMethod(
// @PostConstruct is allowed to appear on non-public methods
- MethodFinderOptions.notNecessarilyPublic(),
+ MethodFinderOptions.notNecessarilyPublic(MethodFinderOptions.ANY_NAME),
pojo, PostConstruct.class, postConstructMethodsCache);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
index a4fa539..fc3418e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
@@ -75,7 +75,7 @@ implements MetaModelRefiner {
.getFacetRanking(TitleFacet.class)
.map(facetRanking->facetRanking.getTopRank(TitleFacet.class))
.orElse(Can.empty())
- .unique(TitleFacet::semanticEquals);
+ .distinct(TitleFacet::semanticEquals);
// top-rank if present must not be ambiguous
if(titleFacetTopRank.isCardinalityMultiple()) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
index aced3b3..276cb08 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinder.java
@@ -19,10 +19,10 @@
package org.apache.isis.core.metamodel.methods;
import java.lang.reflect.Method;
+import java.util.function.Predicate;
import java.util.stream.Stream;
import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypeCategory;
import org.apache.isis.core.metamodel.methods.MethodFinderUtils.MethodAndPpmConstructor;
@@ -33,17 +33,23 @@ import org.apache.isis.core.metamodel.methods.MethodFinderUtils.MethodAndPpmCons
//@Log4j2
public final class MethodFinder {
+ public static Predicate<Method> hasReturnType(final Class<?> expectedReturnType) {
+ return method->expectedReturnType.isAssignableFrom(method.getReturnType());
+ }
+
+ public static Predicate<Method> hasReturnTypeAnyOf(final Can<Class<?>> allowedReturnTypes) {
+ return method->allowedReturnTypes.stream()
+ .anyMatch(allowedReturnType->allowedReturnType.isAssignableFrom(method.getReturnType()));
+ }
+
public static Stream<Method> findMethod(
final MethodFinderOptions options,
final Class<?> type,
final Class<?> expectedReturnType,
final Class<?>[] paramTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethod(options, type, name, expectedReturnType, paramTypes))
- .filter(_NullSafe::isPresent);
+ return options.streamMethods(type, paramTypes)
+ .filter(hasReturnType(expectedReturnType));
}
// -- SEARCH FOR MULTIPLE NAME CANDIDATES
@@ -54,11 +60,8 @@ public final class MethodFinder {
final Class<?> type,
final Class<?>[] paramTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethod_returningCategory(options, returnTypeCategory, type, name, paramTypes))
- .filter(_NullSafe::isPresent);
+ return options.streamMethods(type, paramTypes)
+ .filter(hasReturnTypeAnyOf(returnTypeCategory.getReturnTypes()));
}
public static Stream<Method> findMethod_returningBoolean(
@@ -66,11 +69,7 @@ public final class MethodFinder {
final Class<?> type,
final Class<?>[] paramTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethod_returningBoolean(options, type, name, paramTypes))
- .filter(_NullSafe::isPresent);
+ return findMethod_returningCategory(options, ReturnTypeCategory.BOOLEAN, type, paramTypes);
}
public static Stream<Method> findMethod_returningText(
@@ -78,11 +77,7 @@ public final class MethodFinder {
final Class<?> type,
final Class<?>[] paramTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethod_returningText(options, type, name, paramTypes))
- .filter(_NullSafe::isPresent);
+ return findMethod_returningCategory(options, ReturnTypeCategory.TRANSLATABLE, type, paramTypes);
}
public static Stream<Method> findMethod_returningNonScalar(
@@ -91,15 +86,13 @@ public final class MethodFinder {
final Class<?> elementReturnType,
final Class<?>[] paramTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethod_returningNonScalar(options, type, name, elementReturnType, paramTypes))
- .filter(_NullSafe::isPresent);
+ return options.streamMethods(type, paramTypes)
+ .filter(hasReturnTypeAnyOf(ReturnTypeCategory.nonScalar(elementReturnType)));
}
// -- SEARCH FOR MULTIPLE NAME CANDIDATES (PPM)
+ @Deprecated // redundant
public static Stream<MethodAndPpmConstructor> findMethodWithPPMArg(
final MethodFinderOptions options,
final Class<?> type,
@@ -107,13 +100,11 @@ public final class MethodFinder {
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethodWithPPMArg(options, type, name, returnType, paramTypes, additionalParamTypes))
- .filter(_NullSafe::isPresent);
+ return MethodFinderUtils
+ .findMethodWithPPMArg(options, type, returnType, paramTypes, additionalParamTypes);
}
+ @Deprecated // redundant
public static Stream<MethodAndPpmConstructor> findMethodWithPPMArg_returningAnyOf(
final MethodFinderOptions options,
final Can<Class<?>> returnTypes,
@@ -121,11 +112,9 @@ public final class MethodFinder {
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethodWithPPMArg_returningAnyOf(options, returnTypes, type, name, paramTypes, additionalParamTypes))
- .filter(_NullSafe::isPresent);
+ return MethodFinderUtils
+ .findMethodWithPPMArg_returningAnyOf(
+ options, returnTypes, type, paramTypes, additionalParamTypes);
}
public static Stream<MethodAndPpmConstructor> findMethodWithPPMArg_returningBoolean(
@@ -134,11 +123,9 @@ public final class MethodFinder {
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethodWithPPMArg_returningBoolean(options, type, name, paramTypes, additionalParamTypes))
- .filter(_NullSafe::isPresent);
+ return MethodFinderUtils
+ .findMethodWithPPMArg_returningAnyOf(
+ options, ReturnTypeCategory.BOOLEAN.getReturnTypes(), type, paramTypes, additionalParamTypes);
}
public static Stream<MethodAndPpmConstructor> findMethodWithPPMArg_returningText(
@@ -147,11 +134,9 @@ public final class MethodFinder {
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethodWithPPMArg_returningText(options, type, name, paramTypes, additionalParamTypes))
- .filter(_NullSafe::isPresent);
+ return MethodFinderUtils
+ .findMethodWithPPMArg_returningAnyOf(
+ options, ReturnTypeCategory.TRANSLATABLE.getReturnTypes(), type, paramTypes, additionalParamTypes);
}
public static Stream<MethodAndPpmConstructor> findMethodWithPPMArg_returningNonScalar(
@@ -161,12 +146,9 @@ public final class MethodFinder {
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return options.getMethodNameCandidates().stream()
- .distinct()
- .map(name->MethodFinderUtils
- .findMethodWithPPMArg_returningNonScalar(options, type, name, elementReturnType, paramTypes, additionalParamTypes))
- .filter(_NullSafe::isPresent);
+ return MethodFinderUtils
+ .findMethodWithPPMArg_returningAnyOf(
+ options, ReturnTypeCategory.nonScalar(elementReturnType), type, paramTypes, additionalParamTypes);
}
-
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
index 347a27c..8701091 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
@@ -21,27 +21,55 @@ package org.apache.isis.core.metamodel.methods;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.function.Predicate;
+import java.util.stream.Stream;
import org.apache.isis.applib.annotation.Domain;
import org.apache.isis.applib.annotation.Introspection.EncapsulationPolicy;
import org.apache.isis.applib.annotation.Introspection.IntrospectionPolicy;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.functions._Predicates;
import org.apache.isis.commons.internal.reflection._Annotations;
+import org.apache.isis.commons.internal.reflection._ClassCache;
import org.apache.isis.commons.internal.reflection._Reflect;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ConflictingAnnotations;
+import org.apache.isis.core.metamodel.commons.MethodUtil;
+import lombok.AccessLevel;
+import lombok.Getter;
import lombok.NonNull;
-import lombok.Value;
+import lombok.RequiredArgsConstructor;
import lombok.val;
-@Value(staticConstructor = "of")
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class MethodFinderOptions {
- public static MethodFinderOptions notNecessarilyPublic() {
+ public static MethodFinderOptions of(
+ @NonNull final Can<String> methodNameCandidatesPossiblyDuplicated,
+ @NonNull final EncapsulationPolicy encapsulationPolicy,
+ @NonNull final Predicate<Method> mustSatisfy) {
+
+ final Predicate<Method> isNotStatic = MethodUtil::isNotStatic;
+ val methodNameCandidates = methodNameCandidatesPossiblyDuplicated.distinct();
+
+ return new MethodFinderOptions(
+ encapsulationPolicy,
+ methodNameCandidates.equals(ANY_NAME)
+ ? isNotStatic.and(mustSatisfy)
+ : isNotStatic
+ .and(method->methodNameCandidates.contains(method.getName()))
+ .and(mustSatisfy),
+ methodNameCandidates.distinct());
+ }
+
+ public static final Can<String> ANY_NAME = Can.of("");
+ public static final Class<?>[] NO_ARG = new Class<?>[0];
+
+ public static MethodFinderOptions notNecessarilyPublic(
+ final Can<String> methodNameCandidates) {
return of(
- Can.empty(), //FIXME
+ methodNameCandidates,
EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
_Predicates.alwaysTrue()
);
@@ -94,9 +122,33 @@ public class MethodFinderOptions {
ProgrammingModelConstants.ConflictingAnnotations.MEMBER_SUPPORT);
}
+ @Getter private final @NonNull EncapsulationPolicy encapsulationPolicy;
+ @Getter private final @NonNull Predicate<Method> mustSatisfy;
private final @NonNull Can<String> methodNameCandidates;
- private final @NonNull EncapsulationPolicy encapsulationPolicy;
- private final @NonNull Predicate<Method> mustSatisfy;
+
+ public Stream<Method> streamMethods(
+ final Class<?> type,
+ final Class<?>[] paramTypes) {
+
+ val classCache = _ClassCache.getInstance();
+ val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
+
+ if(methodNameCandidates.equals(ANY_NAME)) {
+ //stream all
+ return (isEncapsulationSupported
+ ? classCache.streamPublicOrDeclaredMethods(type)
+ : classCache.streamPublicMethods(type))
+ .filter(mustSatisfy);
+ }
+
+ return methodNameCandidates.stream()
+ .map(name->isEncapsulationSupported
+ ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
+ : classCache.lookupPublicMethod(type, name, paramTypes))
+ .filter(_NullSafe::isPresent)
+ .filter(mustSatisfy);
+
+ }
// -- HELPER
@@ -165,4 +217,6 @@ public class MethodFinderOptions {
}
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
index 4dcadc0..0aa9d9d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderUtils.java
@@ -28,9 +28,7 @@ import java.util.stream.Stream;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.reflection._ClassCache;
import org.apache.isis.commons.internal.reflection._Reflect;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypeCategory;
import org.apache.isis.core.metamodel.commons.MethodUtil;
-import org.apache.isis.core.metamodel.facetapi.MethodRemover;
import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramSignatureMatch;
@@ -45,114 +43,14 @@ public final class MethodFinderUtils {
private MethodFinderUtils() {
}
- /**
- * Returns a specific public methods that: have the specified prefix; have
- * the specified return type (or some subtype), and has the
- * specified number of parameters.
- *
- * <p>
- * If the returnType is specified as null then the return type is ignored.
- * If void.class is passed in, then searches for void methods.
- *
- * <p>
- * If the parameter type array is null, is also not checked.
- */
- public static Method findMethod(
+ private static Stream<Method> streamMethods(
final MethodFinderOptions options,
final Class<?> type,
- final String name,
- final Class<?> expectedReturnType,
- final Class<?>[] paramTypes) {
-
- val classCache = _ClassCache.getInstance();
-
- val method = options.getEncapsulationPolicy().isEncapsulatedMembersSupported()
- ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
- : classCache.lookupPublicMethod(type, name, paramTypes);
- if(method == null) {
- return null;
- }
-
- if(!options.getEncapsulationPolicy().isEncapsulatedMembersSupported()) {
- if (!MethodUtil.isPublic(method)) {
- return null;
- }
- }
-
- if(MethodUtil.isStatic(method)) {
- return null;
- }
-
- if (!method.getName().equals(name)) {
- return null;
- }
-
- if (expectedReturnType != null && !expectedReturnType.isAssignableFrom(method.getReturnType())) {
- return null;
- }
-
- if (paramTypes != null) {
- val parameterTypes = method.getParameterTypes();
- if (paramTypes.length != parameterTypes.length) {
- return null;
- }
-
- for (int c = 0; c < paramTypes.length; c++) {
- if ((paramTypes[c] != null) && (paramTypes[c] != parameterTypes[c])) {
- return null;
- }
- }
- }
-
- if(!options.getMustSatisfy().test(method)) {
- return null;
- }
-
- return method;
- }
-
- public static Method findMethod_returningAnyOf(
- final MethodFinderOptions options,
- final Can<Class<?>> returnTypes,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes) {
-
- for (val returnType : returnTypes) {
- val method = findMethod(options, type, name, returnType, paramTypes);
- if(method != null) {
- return method;
- }
- }
- return null;
- }
-
- public static Optional<Method> findNoArgMethod(
- final MethodFinderOptions options,
- final Class<?> type, final Class<?> returnType) {
- return streamMethods(options, type, options.getMethodNameCandidates(), returnType)
- .filter(MethodUtil.Predicates.paramCount(0))
- .findFirst();
- }
-
- public static Optional<Method> findSingleArgMethod(
- final MethodFinderOptions options,
- final Class<?> type, final String name, final Class<?> returnType) {
- return streamMethods(options, type, Can.ofSingleton(name), returnType)
- .filter(MethodUtil.Predicates.paramCount(1))
- .findFirst();
- }
-
- public static Stream<Method> streamMethods(
- final MethodFinderOptions options,
- final Class<?> type,
- final Can<String> names,
final Class<?> returnType) {
try {
return streamMethods(options, type)
- .filter(MethodUtil::isNotStatic)
- .filter(method -> names.contains(method.getName()))
+ .filter(options.getMustSatisfy())
.filter(method -> returnType == null
|| returnType.isAssignableFrom(method.getReturnType())
//XXX for non-scalar types we should probably be a bit smarter
@@ -165,38 +63,6 @@ public final class MethodFinderUtils {
}
}
- public static Stream<Method> streamMethodsWithAnnotation(
- final @NonNull MethodFinderOptions options,
- final @NonNull Class<?> type,
- final @NonNull Class<? extends Annotation> annotationClass) {
-
- // Find methods annotated with the specified annotation
- return streamMethods(options, type)
- .filter(method -> !MethodUtil.isStatic(method))
- .filter(method -> method.isAnnotationPresent(annotationClass));
- }
-
- public static void removeMethod(final MethodRemover methodRemover, final Method method) {
- if (methodRemover != null && method != null) {
- methodRemover.removeMethod(method);
- }
- }
-
- public static Class<?>[] paramTypesOrNull(final Class<?> type) {
- return type == null ? null : new Class[] { type };
- }
-
- public static boolean allParametersOfSameType(final Class<?>[] params) {
- final Class<?> firstParam = params[0];
- for (int i = 1; i < params.length; i++) {
- if (params[i] != firstParam) {
- return false;
- }
- }
- return true;
- }
-
-
public static Method findAnnotatedMethod(
final MethodFinderOptions options,
final Object pojo,
@@ -220,47 +86,6 @@ public final class MethodFinderUtils {
.findFirst();
}
- // -- SHORTCUTS
-
- public static Method findMethod_returningCategory(
- final MethodFinderOptions options,
- final ReturnTypeCategory returnTypeCategory,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes) {
- return findMethod_returningAnyOf(
- options, returnTypeCategory.getReturnTypes(), type, name, paramTypes);
- }
-
- public static Method findMethod_returningBoolean(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes) {
- return findMethod_returningAnyOf(
- options, ReturnTypeCategory.BOOLEAN.getReturnTypes(), type, name, paramTypes);
- }
-
- public static Method findMethod_returningText(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes) {
- return findMethod_returningAnyOf(
- options, ReturnTypeCategory.TRANSLATABLE.getReturnTypes(), type, name, paramTypes);
- }
-
- public static Method findMethod_returningNonScalar(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?> elementReturnType,
- final Class<?>[] paramTypes) {
-
- return findMethod_returningAnyOf(
- options, ReturnTypeCategory.nonScalar(elementReturnType), type, name, paramTypes);
- }
-
// -- PPM SUPPORT
@@ -282,85 +107,41 @@ public final class MethodFinderUtils {
}
}
- public static MethodAndPpmConstructor findMethodWithPPMArg(
+ static Stream<MethodAndPpmConstructor> findMethodWithPPMArg(
final MethodFinderOptions options,
final Class<?> type,
- final String name,
final Class<?> returnType,
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return streamMethods(options, type, Can.ofSingleton(name), returnType)
+ return streamMethods(options, type, returnType)
.filter(MethodUtil.Predicates.paramCount(additionalParamTypes.size()+1))
.filter(MethodUtil.Predicates.matchParamTypes(1, additionalParamTypes))
.map(method->MethodAndPpmCandidate.of(method, method.getParameterTypes()[0]))
.map(ppmCandidate->ppmCandidate.lookupConstructor(paramTypes))
- .filter(Optional::isPresent)
- .map(Optional::get)
- .findFirst()
- .orElse(null);
+ .flatMap(Optional::stream);
}
- public static MethodAndPpmConstructor findMethodWithPPMArg_returningAnyOf(
+ static Stream<MethodAndPpmConstructor> findMethodWithPPMArg_returningAnyOf(
final MethodFinderOptions options,
final Can<Class<?>> returnTypes,
final Class<?> type,
- final String name,
- final Class<?>[] paramTypes,
- final Can<Class<?>> additionalParamTypes) {
-
- for (val returnType : returnTypes) {
- val result = findMethodWithPPMArg(options, type, name, returnType, paramTypes, additionalParamTypes);
- if(result != null) {
- return result;
- }
- }
- return null;
- }
-
- public static MethodAndPpmConstructor findMethodWithPPMArg_returningBoolean(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes,
- final Can<Class<?>> additionalParamTypes) {
-
- return findMethodWithPPMArg_returningAnyOf(
- options, ReturnTypeCategory.BOOLEAN.getReturnTypes(), type, name, paramTypes, additionalParamTypes);
- }
-
- public static MethodAndPpmConstructor findMethodWithPPMArg_returningText(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?>[] paramTypes,
- final Can<Class<?>> additionalParamTypes) {
-
- return findMethodWithPPMArg_returningAnyOf(
- options, ReturnTypeCategory.TRANSLATABLE.getReturnTypes(), type, name, paramTypes, additionalParamTypes);
- }
-
- public static MethodAndPpmConstructor findMethodWithPPMArg_returningNonScalar(
- final MethodFinderOptions options,
- final Class<?> type,
- final String name,
- final Class<?> elementReturnType,
final Class<?>[] paramTypes,
final Can<Class<?>> additionalParamTypes) {
- return findMethodWithPPMArg_returningAnyOf(
- options, ReturnTypeCategory.nonScalar(elementReturnType), type, name, paramTypes, additionalParamTypes);
+ return returnTypes.stream()
+ .flatMap(returnType->findMethodWithPPMArg(options, type, returnType, paramTypes, additionalParamTypes));
}
// -- HELPER
- public static Stream<Method> streamMethods(
+ private static Stream<Method> streamMethods(
final MethodFinderOptions options,
final Class<?> type) {
val classCache = _ClassCache.getInstance();
- return options.getEncapsulationPolicy().isEncapsulatedMembersSupported()
+ return (options.getEncapsulationPolicy().isEncapsulatedMembersSupported()
? classCache.streamPublicOrDeclaredMethods(type)
- : classCache.streamPublicMethods(type)
+ : classCache.streamPublicMethods(type))
.filter(options.getMustSatisfy()::test);
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
index f62fba6..b52ab9b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/MethodFinderUtilsTest.java
@@ -30,8 +30,8 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
import org.apache.isis.core.metamodel.methods.MethodByClassMap;
+import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
import org.apache.isis.core.metamodel.methods.MethodFinderUtils;
import lombok.val;
@@ -52,7 +52,7 @@ public class MethodFinderUtilsTest {
val cache = new MethodByClassMap();
final Method method = MethodFinderUtils
.findAnnotatedMethod(
- MethodFinderOptions.notNecessarilyPublic(),
+ MethodFinderOptions.notNecessarilyPublic(MethodFinderOptions.ANY_NAME),
new WithPostConstruct(), PostConstruct.class, cache );
assertThat(method, is(not(nullValue())));
@@ -68,7 +68,7 @@ public class MethodFinderUtilsTest {
val cache = new MethodByClassMap();
final Method method = MethodFinderUtils
.findAnnotatedMethod(
- MethodFinderOptions.notNecessarilyPublic(),
+ MethodFinderOptions.notNecessarilyPublic(MethodFinderOptions.ANY_NAME),
new NoPostConstruct(), PostConstruct.class, cache);
assertThat(method, is(nullValue()));
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
index 37d66e9..af39b8a 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/mappers/FailureUtil.java
@@ -21,8 +21,8 @@ package org.apache.isis.viewer.restfulobjects.viewer.mappers;
import java.lang.reflect.InvocationTargetException;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
-import org.apache.isis.core.metamodel.methods.MethodFinderUtils;
import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
@@ -34,10 +34,12 @@ final class FailureUtil {
public static HttpStatusCode getFailureStatusCodeIfAny(final Throwable ex) {
- val errorCodeGetter = MethodFinderUtils.findNoArgMethod(
- MethodFinderOptions.publicOnly(Can.ofSingleton("getErrorCode")),
- ex.getClass(), int.class)
- .orElse(null);
+ val errorCodeGetter = MethodFinderOptions.publicOnly(Can.ofSingleton("getErrorCode"))
+ .streamMethods(ex.getClass(), MethodFinderOptions.NO_ARG)
+ .filter(MethodFinder.hasReturnType(int.class))
+ .findFirst()
+ .orElse(null);
+
if(errorCodeGetter!=null) {
try {
val errorCode = (int)errorCodeGetter.invoke(ex);