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 15:12:39 UTC
[isis] branch master updated: ISIS-2774: method finder overhaul (9)
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 d9f06a8 ISIS-2774: method finder overhaul (9)
d9f06a8 is described below
commit d9f06a89561f0cd5fe982ab2b78217285eda94ad
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Sep 8 17:12:29 2021 +0200
ISIS-2774: method finder overhaul (9)
---
.../isis/commons/internal/reflection/_Reflect.java | 10 +
.../isis/core/metamodel/facets/ActionSupport.java | 18 +-
.../facets/HasPostConstructMethodCache.java | 6 +-
.../core/metamodel/facets/ParameterSupport.java | 14 +-
.../ActionValidationFacetViaMethodFactory.java | 8 +-
.../DescribedAsFacetForMemberViaMethodFactory.java | 6 +-
.../DisableForContextFacetViaMethodFactory.java | 6 +-
.../HideForContextFacetViaMethodFactory.java | 6 +-
.../NamedFacetForMemberViaMethodFactory.java | 6 +-
.../support/MemberSupportFacetFactoryAbstract.java | 6 +-
.../object/callbacks/CallbackFacetFactory.java | 4 +-
.../choices/enums/EnumValueSemanticsProvider.java | 6 +-
.../object/support/ObjectSupportFacetFactory.java | 6 +-
.../PropertyAutoCompleteFacetMethodFactory.java | 6 +-
.../PropertyChoicesFacetViaMethodFactory.java | 6 +-
.../PropertyDefaultFacetViaMethodFactory.java | 6 +-
.../update/PropertySetterFacetFactory.java | 4 +-
.../PropertyValidateFacetViaMethodFactory.java | 6 +-
.../isis/core/metamodel/methods/MethodFinder.java | 265 +++++++++++++++++--
.../metamodel/methods/MethodFinderOptions.java | 281 ---------------------
.../core/metamodel/methods/MethodFinderPAT.java | 15 +-
.../restfulobjects/viewer/mappers/FailureUtil.java | 34 ++-
22 files changed, 323 insertions(+), 402 deletions(-)
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java b/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
index 9dbcbd1..45e78e3 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
@@ -564,6 +564,15 @@ public final class _Reflect {
@UtilityClass
public static class Filter {
+ 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 Predicate<Executable> isPublic() {
return ex->Modifier.isPublic(ex.getModifiers());
}
@@ -576,6 +585,7 @@ public final class _Reflect {
return ex->ex.getParameterTypes()[paramIndex].isAssignableFrom(paramType);
}
+ //TODO simple array compare should do
public static Predicate<Executable> paramSignatureMatch(final Class<?>[] matchingParamTypes) {
return ex->{
// check params (if required)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
index 264a876..75f6ae3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ActionSupport.java
@@ -29,8 +29,7 @@ import org.springframework.lang.Nullable;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.collections._Arrays;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodFinderPAT;
import org.apache.isis.core.metamodel.methods.MethodFinderPAT.MethodAndPatConstructor;
@@ -48,12 +47,9 @@ public final class ActionSupport {
public static class ActionSupportingMethodSearchRequest {
@NonNull FacetFactory.ProcessMethodContext processMethodContext;
- @Getter @NonNull MethodFinderOptions finderOptions;
+ @Getter @NonNull MethodFinder methodFinder;
@NonNull EnumSet<SearchAlgorithm> searchAlgorithms;
- @Deprecated
- @NonNull ReturnTypePattern returnTypePattern;
-
Class<?> additionalParamType;
@Getter(lazy = true)
@@ -107,14 +103,12 @@ public final class ActionSupport {
final Consumer<ActionSupportingMethodSearchResult> onMethodFound) {
val paramTypes = searchRequest.getParamTypes();
- val finderOptions = searchRequest.getFinderOptions();
+ val finderOptions = searchRequest.getMethodFinder();
val additionalParamTypes = Can.ofNullable(searchRequest.getAdditionalParamType());
- val anyOfReturnTypes = searchRequest.getReturnTypePattern().matchingTypes(void.class); // ignores actual type
MethodFinderPAT
- .findMethodWithPATArg_returningAnyOf(
+ .findMethodWithPATArg(
finderOptions,
- anyOfReturnTypes,
paramTypes, additionalParamTypes)
.map(ActionSupport::toSearchResult)
.forEach(onMethodFound);
@@ -134,7 +128,7 @@ public final class ActionSupport {
final Consumer<ActionSupportingMethodSearchResult> onMethodFound) {
val paramTypes = searchRequest.getParamTypes();
- val finderOptions = searchRequest.getFinderOptions();
+ val finderOptions = searchRequest.getMethodFinder();
val additionalParamType = searchRequest.getAdditionalParamType();
val additionalParamCount = additionalParamType!=null ? 1 : 0;
@@ -143,10 +137,8 @@ public final class ActionSupport {
if(paramsConsideredCount>=0) {
val signature = concat(paramTypes, paramsConsideredCount, additionalParamType);
- val anyOfReturnTypes = searchRequest.getReturnTypePattern().matchingTypes(void.class); // ignores actual type
finderOptions
- .withReturnTypeAnyOf(anyOfReturnTypes)
.streamMethodsMatchingSignature(signature)
.map(ActionSupport::toSearchResult)
.forEach(onMethodFound);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
index 1812557..2ce3d4e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/HasPostConstructMethodCache.java
@@ -24,7 +24,7 @@ import java.lang.reflect.Method;
import javax.annotation.PostConstruct;
import org.apache.isis.core.metamodel.methods.MethodByClassMap;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -38,14 +38,14 @@ public interface HasPostConstructMethodCache {
default Method postConstructMethodFor(final Object pojo) {
return findAnnotatedMethod(
// @PostConstruct is allowed to appear on non-public methods
- MethodFinderOptions.notNecessarilyPublic(pojo.getClass(), MethodFinderOptions.ANY_NAME)
+ MethodFinder.notNecessarilyPublic(pojo.getClass(), MethodFinder.ANY_NAME)
.withRequiredReturnType(void.class),
PostConstruct.class,
getPostConstructMethodsCache());
}
private static Method findAnnotatedMethod(
- final MethodFinderOptions options,
+ final MethodFinder options,
final Class<? extends Annotation> annotationClass,
final MethodByClassMap methods) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
index c402034..8c9f59b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ParameterSupport.java
@@ -31,7 +31,7 @@ import org.springframework.lang.Nullable;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.internal.collections._Arrays;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodFinderPAT;
import org.apache.isis.core.metamodel.methods.MethodFinderPAT.MethodAndPatConstructor;
@@ -132,10 +132,10 @@ public final class ParameterSupport {
val additionalParamTypes = Can.ofNullable(searchRequest.getAdditionalParamType());
MethodFinderPAT
- .findMethodWithPATArg_returningAnyOf(
- MethodFinderOptions
- .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy()),
- searchRequest.getReturnTypePattern().matchingTypes(paramType),
+ .findMethodWithPATArg(
+ MethodFinder
+ .memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
+ .withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType)),
paramTypes, additionalParamTypes)
.map(methodAndPatConstructor->toSearchResult(paramIndex, paramType, methodAndPatConstructor))
.forEach(onMethodFound);
@@ -164,7 +164,7 @@ public final class ParameterSupport {
val paramType = paramTypes[paramIndex];
val signature = new Class<?>[]{paramType};
- MethodFinderOptions
+ MethodFinder
.memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
.withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType))
.streamMethodsMatchingSignature(signature)
@@ -194,7 +194,7 @@ public final class ParameterSupport {
val signature = concat(paramTypes, paramsConsideredCount, additionalParamType);
val supportingMethod =
- MethodFinderOptions
+ MethodFinder
.memberSupport(type, methodNames, processMethodContext.getIntrospectionPolicy())
.withReturnTypeAnyOf(searchRequest.getReturnTypePattern().matchingTypes(paramType))
.streamMethodsMatchingSignature(signature)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
index 7d30916..e971ba2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/validate/method/ActionValidationFacetViaMethodFactory.java
@@ -23,14 +23,13 @@ import java.util.EnumSet;
import javax.inject.Inject;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSupportPrefix;
-import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.ReturnTypePattern;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.ActionSupport;
import org.apache.isis.core.metamodel.facets.ActionSupport.SearchAlgorithm;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
import org.apache.isis.core.metamodel.facets.param.validate.method.ActionParameterValidationFacetViaMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -48,12 +47,11 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
val searchRequest = ActionSupport.ActionSupportingMethodSearchRequest.builder()
.processMethodContext(processMethodContext)
- .returnTypePattern(ReturnTypePattern.TEXT)
- .finderOptions(methodFinderOptions)
+ .methodFinder(methodFinder)
.searchAlgorithms(EnumSet.of(SearchAlgorithm.PAT, SearchAlgorithm.ALL_PARAM_TYPES))
.build();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
index d781ceb..392605e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/described/method/DescribedAsFacetForMemberViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
public class DescribedAsFacetForMemberViaMethodFactory
extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(describedMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
index 06d85d8..0fd8ece 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/disabled/method/DisableForContextFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
public class DisableForContextFacetViaMethodFactory
extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(disableMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
index 50af462..e80d19a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/hidden/method/HideForContextFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
public class HideForContextFacetViaMethodFactory
extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(hideMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
index fbc9396..952042d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/named/method/NamedFacetForMemberViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
public class NamedFacetForMemberViaMethodFactory
extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(namedMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
index b263104..858e9a3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/members/support/MemberSupportFacetFactoryAbstract.java
@@ -22,7 +22,7 @@ import org.apache.isis.commons.collections.ImmutableEnumSet;
import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSupportPrefix;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.NonNull;
import lombok.val;
@@ -69,7 +69,7 @@ extends MemberAndPropertySupportFacetFactoryAbstract {
.flatMap(processMethodContext::memberSupportCandidates);
search(processMethodContext,
- MethodFinderOptions
+ MethodFinder
.memberSupport(processMethodContext.getCls(),
methodNameCandidates,
processMethodContext.getIntrospectionPolicy())
@@ -80,6 +80,6 @@ extends MemberAndPropertySupportFacetFactoryAbstract {
protected abstract void search(
ProcessMethodContext processMethodContext,
- MethodFinderOptions methodFinderOptions);
+ MethodFinder methodFinder);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
index f94896c..76fd7aa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/callbacks/CallbackFacetFactory.java
@@ -29,7 +29,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.CallbackM
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
import lombok.val;
@@ -66,7 +66,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
val callbackMethods =
- MethodFinderOptions
+ MethodFinder
.livecycleCallback(
cls,
callbackMethodEnum.getMethodNames(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
index 33f337e..febcde9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/choices/enums/EnumValueSemanticsProvider.java
@@ -31,7 +31,7 @@ import org.apache.isis.core.metamodel.commons.MethodExtensions;
import org.apache.isis.core.metamodel.facetapi.Facet;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueSemanticsProviderAndFacetAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -82,13 +82,13 @@ implements EnumFacet {
titleMethod =
- MethodFinderOptions
+ MethodFinder
.objectSupport(
getAdaptedClass(),
supportMethodEnum.getMethodNames(),
introspectionPolicy)
.withReturnTypeAnyOf(supportMethodEnum.getReturnTypeCategory().getReturnTypes())
- .streamMethodsMatchingSignature(MethodFinderOptions.NO_ARG)
+ .streamMethodsMatchingSignature(MethodFinder.NO_ARG)
.findFirst()
.orElse(null);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
index 794e892..2b527a6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/support/ObjectSupportFacetFactory.java
@@ -43,7 +43,7 @@ import org.apache.isis.core.metamodel.facets.object.icon.method.IconFacetViaIcon
import org.apache.isis.core.metamodel.facets.object.layout.LayoutFacetViaLayoutMethod;
import org.apache.isis.core.metamodel.facets.object.title.methods.TitleFacetInferredFromToStringMethod;
import org.apache.isis.core.metamodel.facets.object.title.methods.TitleFacetViaTitleMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
@@ -111,7 +111,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
val toString = ObjectSupportMethod.TO_STRING;
- MethodFinderOptions
+ MethodFinder
.publicOnly(
processClassContext.getCls(),
toString.getMethodNames())
@@ -131,7 +131,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
final BiFunction<Method, FacetHolder, Optional<? extends Facet>> ojectSupportFacetConstructor) {
- MethodFinderOptions
+ MethodFinder
.objectSupport(
processClassContext.getCls(),
objectSupportMethodEnum.getMethodNames(),
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
index 8ff0d19..630a817 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/autocomplete/method/PropertyAutoCompleteFacetMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
val getterOrMixinMain = processMethodContext.getMethod();
val getterType = getterOrMixinMain.getReturnType();
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(STRING_ARG)
.peek(processMethodContext::removeMethod)
.forEach(autoCompleteMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
index 992d520..4223af4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/choices/method/PropertyChoicesFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
val getterOrMixinMain = processMethodContext.getMethod();
val getterType = getterOrMixinMain.getReturnType();
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(choicesMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
index 95893e3..c1f530f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/defaults/method/PropertyDefaultFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
public class PropertyDefaultFacetViaMethodFactory
extends MemberSupportFacetFactoryAbstract {
@@ -37,9 +37,9 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(NO_ARG)
.peek(processMethodContext::removeMethod)
.forEach(defaultMethod->{
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
index 5bfc1eb..40b304b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/update/PropertySetterFacetFactory.java
@@ -32,7 +32,7 @@ import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.properties.update.clear.PropertyClearFacetViaSetterMethod;
import org.apache.isis.core.metamodel.facets.properties.update.init.PropertyInitializationFacetViaSetterMethod;
import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySetterFacetViaSetterMethod;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import org.apache.isis.core.metamodel.methods.MethodPrefixBasedFacetFactoryAbstract;
import lombok.val;
@@ -61,7 +61,7 @@ extends MethodPrefixBasedFacetFactoryAbstract {
final Class<?>[] signature = new Class[] { getterMethod.getReturnType() };
val setterMethods =
- MethodFinderOptions
+ MethodFinder
.accessor(processMethodContext.getCls(), methodNameCandidates, processMethodContext.getIntrospectionPolicy())
.withReturnTypeAnyOf(ReturnTypeCategory.VOID.getReturnTypes())
.streamMethodsMatchingSignature(signature)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
index f24184a..0da1927 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/validating/method/PropertyValidateFacetViaMethodFactory.java
@@ -24,7 +24,7 @@ import org.apache.isis.core.config.progmodel.ProgrammingModelConstants.MemberSup
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.members.support.MemberSupportFacetFactoryAbstract;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
+import org.apache.isis.core.metamodel.methods.MethodFinder;
import lombok.val;
@@ -39,12 +39,12 @@ extends MemberSupportFacetFactoryAbstract {
@Override
protected void search(
final ProcessMethodContext processMethodContext,
- final MethodFinderOptions methodFinderOptions) {
+ final MethodFinder methodFinder) {
val getterMethod = processMethodContext.getMethod();
val argType = getterMethod.getReturnType();
- methodFinderOptions
+ methodFinder
.streamMethodsMatchingSignature(new Class[] { argType })
.peek(processMethodContext::removeMethod)
.forEach(validateMethod->{
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 3fe0385..aeb95a3 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
@@ -18,44 +18,263 @@
*/
package org.apache.isis.core.metamodel.methods;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream;
+import org.springframework.lang.Nullable;
+
+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;
-/**
- * Support of multiple concurrent naming conventions.
- */
-//@Log4j2
-public final class MethodFinder {
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public class MethodFinder {
+
+ public static MethodFinder of(
+ final @NonNull Class<?> correspondingClass,
+ final @NonNull Can<String> methodNameCandidatesPossiblyDuplicated,
+ final @NonNull EncapsulationPolicy encapsulationPolicy,
+ final @NonNull Predicate<Method> mustSatisfy) {
+
+ final Predicate<Method> isNotStatic = MethodUtil::isNotStatic;
+ val methodNameCandidates = methodNameCandidatesPossiblyDuplicated.distinct();
+
+ return new MethodFinder(
+ correspondingClass,
+ encapsulationPolicy,
+ methodNameCandidates.equals(ANY_NAME)
+ ? isNotStatic.and(mustSatisfy)
+ : isNotStatic
+ .and(method->methodNameCandidates.contains(method.getName()))
+ .and(mustSatisfy),
+ methodNameCandidates);
+ }
+
+ public static final Can<String> ANY_NAME = Can.of(""); // arbitrary marker
+ public static final Class<?>[] NO_ARG = new Class<?>[0];
+
+ public static MethodFinder notNecessarilyPublic(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates) {
+ return of(
+ correspondingClass,
+ methodNameCandidates,
+ EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
+ _Predicates.alwaysTrue()
+ );
+ }
+
+ public static MethodFinder publicOnly(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates) {
+ return of(
+ correspondingClass,
+ methodNameCandidates,
+ EncapsulationPolicy.ONLY_PUBLIC_MEMBERS_SUPPORTED,
+ _Predicates.alwaysTrue()
+ );
+ }
+
+ public static MethodFinder accessor(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy) {
+ return havingAnyOrNoAnnotation(
+ correspondingClass,
+ methodNameCandidates,
+ memberIntrospectionPolicy);
+ }
+
+ public static MethodFinder objectSupport(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy) {
+ return supportMethod(
+ correspondingClass,
+ methodNameCandidates,
+ memberIntrospectionPolicy,
+ Domain.Include.class,
+ ProgrammingModelConstants.ConflictingAnnotations.OBJECT_SUPPORT);
+ }
+
+ public static MethodFinder livecycleCallback(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy) {
+ return supportMethod(
+ correspondingClass,
+ methodNameCandidates,
+ memberIntrospectionPolicy,
+ Domain.Include.class,
+ ProgrammingModelConstants.ConflictingAnnotations.OBJECT_LIFECYCLE);
+ }
+
+ public static MethodFinder memberSupport(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy) {
+ return supportMethod(
+ correspondingClass,
+ methodNameCandidates,
+ memberIntrospectionPolicy,
+ Domain.Include.class,
+ ProgrammingModelConstants.ConflictingAnnotations.MEMBER_SUPPORT);
+ }
+
+ @Getter private final @NonNull Class<?> correspondingClass;
+ @Getter private final @NonNull EncapsulationPolicy encapsulationPolicy;
+ @Getter private final @NonNull Predicate<Method> mustSatisfy;
+ private final @NonNull Can<String> methodNameCandidates;
+
+ public Stream<Method> streamMethodsMatchingSignature(
+ final @Nullable Class<?>[] paramTypes) {
+
+ if(paramTypes==null) {
+ return streamMethodsIgnoringSignature();
+ }
+
+ val type = getCorrespondingClass();
+ val classCache = _ClassCache.getInstance();
+ val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
- public static Predicate<Method> hasReturnType(final Class<?> expectedReturnType) {
- return method->expectedReturnType.isAssignableFrom(method.getReturnType());
+ if(methodNameCandidates.equals(ANY_NAME)) {
+ //stream all
+ return (isEncapsulationSupported
+ ? classCache.streamPublicOrDeclaredMethods(type)
+ : classCache.streamPublicMethods(type))
+ .filter(method->Arrays.equals(paramTypes, method.getParameterTypes()))
+ .filter(mustSatisfy);
+ }
+
+ return methodNameCandidates.stream()
+ .map(name->isEncapsulationSupported
+ ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
+ : classCache.lookupPublicMethod(type, name, paramTypes))
+ .filter(_NullSafe::isPresent)
+ .filter(mustSatisfy);
+
+ }
+
+ public Stream<Method> streamMethodsIgnoringSignature() {
+ val type = getCorrespondingClass();
+ val classCache = _ClassCache.getInstance();
+ val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
+ return (isEncapsulationSupported
+ ? classCache.streamPublicOrDeclaredMethods(type)
+ : classCache.streamPublicMethods(type))
+ .filter(mustSatisfy);
+ }
+
+ // -- WITHERS
+
+ public MethodFinder withRequiredReturnType(final @NonNull Class<?> requiredReturnType) {
+ return new MethodFinder(
+ correspondingClass,
+ encapsulationPolicy,
+ mustSatisfy.and(_Reflect.Filter.hasReturnType(requiredReturnType)),
+ methodNameCandidates);
+ }
+
+ public MethodFinder withReturnTypeAnyOf(final @NonNull Can<Class<?>> anyOfReturnTypes) {
+ return new MethodFinder(
+ correspondingClass,
+ encapsulationPolicy,
+ mustSatisfy.and(_Reflect.Filter.hasReturnTypeAnyOf(anyOfReturnTypes)),
+ methodNameCandidates);
+ }
+
+
+ // -- HELPER
+
+ private static MethodFinder havingAnyOrNoAnnotation(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy) {
+ return of(
+ correspondingClass,
+ methodNameCandidates,
+ memberIntrospectionPolicy.getEncapsulationPolicy(),
+ _Predicates.alwaysTrue());
}
- public static Predicate<Method> hasReturnTypeAnyOf(final Can<Class<?>> allowedReturnTypes) {
- return method->allowedReturnTypes.stream()
- .anyMatch(allowedReturnType->allowedReturnType.isAssignableFrom(method.getReturnType()));
+ private static MethodFinder supportMethod(
+ final Class<?> correspondingClass,
+ final Can<String> methodNameCandidates,
+ final IntrospectionPolicy memberIntrospectionPolicy,
+ final Class<? extends Annotation> annotationType,
+ final ConflictingAnnotations conflictingAnnotations) {
+
+ return of(
+ correspondingClass,
+ methodNameCandidates,
+ // support methods are always allowed private
+ EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
+ havingAnnotationIfEnforcedByPolicyOrAccessibility(
+ memberIntrospectionPolicy,
+ annotationType,
+ conflictingAnnotations.getProhibits()));
+
}
- public static Stream<Method> findMethod(
- final MethodFinderOptions options,
- final Class<?>[] signature) {
- return options.streamMethodsMatchingSignature(signature);
+ private static Predicate<Method> havingAnnotationIfEnforcedByPolicyOrAccessibility(
+ final IntrospectionPolicy memberIntrospectionPolicy,
+ final Class<? extends Annotation> annotationType,
+ final Can<Class<? extends Annotation>> conflictingAnnotations) {
+
+ //MemberAnnotationPolicy
+ // when REQUIRED -> annot. on support also required
+ // when OPTIONAL -> annot. on support only required when support method is private
+
+ return memberIntrospectionPolicy.getMemberAnnotationPolicy().isMemberAnnotationsRequired()
+ ? method->havingAnnotation(method, annotationType, conflictingAnnotations)
+ : method-> !_Reflect.isAccessible(method)
+ ? havingAnnotation(method, annotationType, conflictingAnnotations)
+ : true;
+
}
- // -- SEARCH FOR MULTIPLE NAME CANDIDATES
+ //FIXME[ISIS-2774] if annotation appears on an abstract method that was inherited with given method,
+ // its not detected here
+ private static boolean havingAnnotation(
+ final Method method,
+ final Class<? extends Annotation> annotationType,
+ final Can<Class<? extends Annotation>> conflictingAnnotations) {
- @Deprecated
- public static Stream<Method> findMethod_returningAnyOf(
- final MethodFinderOptions options,
- final Can<Class<?>> anyOfReturnTypes,
- final Class<?>[] signature) {
+ val isMarkerAnnotationPresent = _Annotations.synthesizeInherited(method, annotationType).isPresent();
+ if(isMarkerAnnotationPresent) {
- return options
- .withReturnTypeAnyOf(anyOfReturnTypes)
- .streamMethodsMatchingSignature(signature);
+ val isConflictingAnnotationPresent = conflictingAnnotations
+ .stream()
+ .anyMatch(conflictingAnnotationType->
+ _Annotations.synthesizeInherited(method, conflictingAnnotationType).isPresent());
+
+ // do not pickup this method if conflicting - so meta-model validation will fail later on
+ return !isConflictingAnnotationPresent;
+ }
+ return isMarkerAnnotationPresent;
}
+
+
+
+
+
}
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
deleted file mode 100644
index 355fa82..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderOptions.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.core.metamodel.methods;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-import org.springframework.lang.Nullable;
-
-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.RequiredArgsConstructor;
-import lombok.val;
-
-@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-public class MethodFinderOptions {
-
- public static MethodFinderOptions of(
- final @NonNull Class<?> correspondingClass,
- final @NonNull Can<String> methodNameCandidatesPossiblyDuplicated,
- final @NonNull EncapsulationPolicy encapsulationPolicy,
- final @NonNull Predicate<Method> mustSatisfy) {
-
- final Predicate<Method> isNotStatic = MethodUtil::isNotStatic;
- val methodNameCandidates = methodNameCandidatesPossiblyDuplicated.distinct();
-
- return new MethodFinderOptions(
- correspondingClass,
- encapsulationPolicy,
- methodNameCandidates.equals(ANY_NAME)
- ? isNotStatic.and(mustSatisfy)
- : isNotStatic
- .and(method->methodNameCandidates.contains(method.getName()))
- .and(mustSatisfy),
- methodNameCandidates);
- }
-
- public static final Can<String> ANY_NAME = Can.of(""); // arbitrary marker
- public static final Class<?>[] NO_ARG = new Class<?>[0];
- //private static final Class<?>[] ANY_ARG = new Class<?>[] {void.class}; // arbitrary marker
-
- public static MethodFinderOptions notNecessarilyPublic(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates) {
- return of(
- correspondingClass,
- methodNameCandidates,
- EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
- _Predicates.alwaysTrue()
- );
- }
-
- public static MethodFinderOptions publicOnly(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates) {
- return of(
- correspondingClass,
- methodNameCandidates,
- EncapsulationPolicy.ONLY_PUBLIC_MEMBERS_SUPPORTED,
- _Predicates.alwaysTrue()
- );
- }
-
- public static MethodFinderOptions accessor(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy) {
- return havingAnyOrNoAnnotation(
- correspondingClass,
- methodNameCandidates,
- memberIntrospectionPolicy);
- }
-
- public static MethodFinderOptions objectSupport(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy) {
- return supportMethod(
- correspondingClass,
- methodNameCandidates,
- memberIntrospectionPolicy,
- Domain.Include.class,
- ProgrammingModelConstants.ConflictingAnnotations.OBJECT_SUPPORT);
- }
-
- public static MethodFinderOptions livecycleCallback(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy) {
- return supportMethod(
- correspondingClass,
- methodNameCandidates,
- memberIntrospectionPolicy,
- Domain.Include.class,
- ProgrammingModelConstants.ConflictingAnnotations.OBJECT_LIFECYCLE);
- }
-
- public static MethodFinderOptions memberSupport(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy) {
- return supportMethod(
- correspondingClass,
- methodNameCandidates,
- memberIntrospectionPolicy,
- Domain.Include.class,
- ProgrammingModelConstants.ConflictingAnnotations.MEMBER_SUPPORT);
- }
-
- @Getter private final @NonNull Class<?> correspondingClass;
- @Getter private final @NonNull EncapsulationPolicy encapsulationPolicy;
- @Getter private final @NonNull Predicate<Method> mustSatisfy;
- private final @NonNull Can<String> methodNameCandidates;
-
- public Stream<Method> streamMethodsMatchingSignature(
- final @Nullable Class<?>[] paramTypes) {
-
- if(paramTypes==null) {
- return streamMethodsIgnoringSignature();
- }
-
- val type = getCorrespondingClass();
- val classCache = _ClassCache.getInstance();
- val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
-
- if(methodNameCandidates.equals(ANY_NAME)) {
- //stream all
- return (isEncapsulationSupported
- ? classCache.streamPublicOrDeclaredMethods(type)
- : classCache.streamPublicMethods(type))
- .filter(method->Arrays.equals(paramTypes, method.getParameterTypes()))
- .filter(mustSatisfy);
- }
-
- return methodNameCandidates.stream()
- .map(name->isEncapsulationSupported
- ? classCache.lookupPublicOrDeclaredMethod(type, name, paramTypes)
- : classCache.lookupPublicMethod(type, name, paramTypes))
- .filter(_NullSafe::isPresent)
- .filter(mustSatisfy);
-
- }
-
- public Stream<Method> streamMethodsIgnoringSignature() {
- val type = getCorrespondingClass();
- val classCache = _ClassCache.getInstance();
- val isEncapsulationSupported = getEncapsulationPolicy().isEncapsulatedMembersSupported();
- return (isEncapsulationSupported
- ? classCache.streamPublicOrDeclaredMethods(type)
- : classCache.streamPublicMethods(type))
- .filter(mustSatisfy);
- }
-
- // -- WITHERS
-
- public MethodFinderOptions withRequiredReturnType(final @NonNull Class<?> requiredReturnType) {
- return new MethodFinderOptions(
- correspondingClass,
- encapsulationPolicy,
- mustSatisfy.and(MethodFinder.hasReturnType(requiredReturnType)),
- methodNameCandidates);
- }
-
- public MethodFinderOptions withReturnTypeAnyOf(final @NonNull Can<Class<?>> anyOfReturnTypes) {
- return new MethodFinderOptions(
- correspondingClass,
- encapsulationPolicy,
- mustSatisfy.and(MethodFinder.hasReturnTypeAnyOf(anyOfReturnTypes)),
- methodNameCandidates);
- }
-
-
- // -- HELPER
-
- private static MethodFinderOptions havingAnyOrNoAnnotation(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy) {
- return of(
- correspondingClass,
- methodNameCandidates,
- memberIntrospectionPolicy.getEncapsulationPolicy(),
- _Predicates.alwaysTrue());
- }
-
- private static MethodFinderOptions supportMethod(
- final Class<?> correspondingClass,
- final Can<String> methodNameCandidates,
- final IntrospectionPolicy memberIntrospectionPolicy,
- final Class<? extends Annotation> annotationType,
- final ConflictingAnnotations conflictingAnnotations) {
-
- return of(
- correspondingClass,
- methodNameCandidates,
- // support methods are always allowed private
- EncapsulationPolicy.ENCAPSULATED_MEMBERS_SUPPORTED,
- havingAnnotationIfEnforcedByPolicyOrAccessibility(
- memberIntrospectionPolicy,
- annotationType,
- conflictingAnnotations.getProhibits()));
-
- }
-
- private static Predicate<Method> havingAnnotationIfEnforcedByPolicyOrAccessibility(
- final IntrospectionPolicy memberIntrospectionPolicy,
- final Class<? extends Annotation> annotationType,
- final Can<Class<? extends Annotation>> conflictingAnnotations) {
-
- //MemberAnnotationPolicy
- // when REQUIRED -> annot. on support also required
- // when OPTIONAL -> annot. on support only required when support method is private
-
- return memberIntrospectionPolicy.getMemberAnnotationPolicy().isMemberAnnotationsRequired()
- ? method->havingAnnotation(method, annotationType, conflictingAnnotations)
- : method-> !_Reflect.isAccessible(method)
- ? havingAnnotation(method, annotationType, conflictingAnnotations)
- : true;
-
- }
-
- //FIXME[ISIS-2774] if annotation appears on an abstract method that was inherited with given method,
- // its not detected here
- private static boolean havingAnnotation(
- final Method method,
- final Class<? extends Annotation> annotationType,
- final Can<Class<? extends Annotation>> conflictingAnnotations) {
-
- val isMarkerAnnotationPresent = _Annotations.synthesizeInherited(method, annotationType).isPresent();
- if(isMarkerAnnotationPresent) {
-
- val isConflictingAnnotationPresent = conflictingAnnotations
- .stream()
- .anyMatch(conflictingAnnotationType->
- _Annotations.synthesizeInherited(method, conflictingAnnotationType).isPresent());
-
- // do not pickup this method if conflicting - so meta-model validation will fail later on
- return !isConflictingAnnotationPresent;
- }
- return isMarkerAnnotationPresent;
- }
-
-
-
-
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
index 766ff0f..c5df6f3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/methods/MethodFinderPAT.java
@@ -51,30 +51,17 @@ public final class MethodFinderPAT {
// -- SEARCH FOR MULTIPLE NAME CANDIDATES (PAT)
public Stream<MethodAndPatConstructor> findMethodWithPATArg(
- final MethodFinderOptions options,
- final Class<?> returnType,
+ final MethodFinder options,
final Class<?>[] signature,
final Can<Class<?>> additionalParamTypes) {
return options.streamMethodsIgnoringSignature()
- .filter(method -> returnType == null
- || returnType.isAssignableFrom(method.getReturnType()))
.filter(MethodUtil.Predicates.paramCount(1 + additionalParamTypes.size()))
.filter(MethodUtil.Predicates.matchParamTypes(1, additionalParamTypes))
.map(method->lookupPatConstructor(method, signature))
.flatMap(Optional::stream);
}
- public Stream<MethodAndPatConstructor> findMethodWithPATArg_returningAnyOf(
- final MethodFinderOptions options,
- final Can<Class<?>> returnTypes,
- final Class<?>[] signature,
- final Can<Class<?>> additionalParamTypes) {
-
- return returnTypes.stream()
- .flatMap(returnType->findMethodWithPATArg(options, returnType, signature, additionalParamTypes));
- }
-
// -- HELPER
private Optional<MethodAndPatConstructor> lookupPatConstructor(
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 791476b..b677020 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
@@ -18,15 +18,15 @@
*/
package org.apache.isis.viewer.restfulobjects.viewer.mappers;
-import java.lang.reflect.InvocationTargetException;
+import java.util.Optional;
import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.internal.reflection._Reflect;
import org.apache.isis.core.metamodel.methods.MethodFinder;
-import org.apache.isis.core.metamodel.methods.MethodFinderOptions;
import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.isis.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
-import lombok.val;
import lombok.experimental.UtilityClass;
@UtilityClass
@@ -34,22 +34,18 @@ final class FailureUtil {
public static HttpStatusCode getFailureStatusCodeIfAny(final Throwable ex) {
- val errorCodeGetter = MethodFinderOptions.publicOnly(ex.getClass(), Can.ofSingleton("getErrorCode"))
- .streamMethodsMatchingSignature(MethodFinderOptions.NO_ARG)
- .filter(MethodFinder.hasReturnType(int.class))
- .findFirst()
- .orElse(null);
-
- if(errorCodeGetter!=null) {
- try {
- val errorCode = (int)errorCodeGetter.invoke(ex);
- return RestfulResponse.HttpStatusCode.statusFor(errorCode);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- // ignore
- }
- }
-
- return null;
+ return MethodFinder
+ .publicOnly(ex.getClass(), Can.ofSingleton("getErrorCode"))
+ .withRequiredReturnType(int.class)
+ .streamMethodsMatchingSignature(MethodFinder.NO_ARG)
+ .findFirst()
+ .map(errorCodeGetter->_Reflect.invokeMethodOn(errorCodeGetter, ex))
+ .map(Result::getValue)
+ .map(Optional::stream)
+ .map(Integer.class::isInstance)
+ .map(Integer.class::cast)
+ .map(RestfulResponse.HttpStatusCode::statusFor)
+ .orElse(null);
}