Skip to content

Commit 03b31ba

Browse files
committed
CAUSEWAY-3991: Metamodel Introspection Policy not honored for Java
Records as Viewmodels Task-Url: https://issues.apache.org/jira/browse/CAUSEWAY-3991
1 parent 2bdf117 commit 03b31ba

2 files changed

Lines changed: 56 additions & 45 deletions

File tree

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/ignore/annotation/RemoveAnnotatedMethodsFacetFactory.java

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
*/
1919
package org.apache.causeway.core.metamodel.facets.object.ignore.annotation;
2020

21+
import java.util.function.Consumer;
2122
import java.util.function.Predicate;
2223

2324
import jakarta.inject.Inject;
2425

26+
import org.jspecify.annotations.NonNull;
27+
2528
import org.apache.causeway.commons.internal.functions._Predicates;
2629
import org.apache.causeway.commons.internal.reflection._ClassCache.Attribute;
2730
import org.apache.causeway.commons.internal.reflection._GenericResolver.ResolvedMethod;
@@ -31,8 +34,6 @@
3134
import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract;
3235
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
3336

34-
import org.jspecify.annotations.NonNull;
35-
3637
public class RemoveAnnotatedMethodsFacetFactory
3738
extends FacetFactoryAbstract {
3839

@@ -46,45 +47,55 @@ public void process(final ProcessClassContext processClassContext) {
4647

4748
var policy = getMetaModelContext().getConfiguration().core().metaModel().introspector().policy();
4849
switch (policy) {
49-
case ENCAPSULATION_ENABLED:
50-
getClassCache()
51-
.streamResolvedMethods(processClassContext.getCls())
52-
/* honor exclude markers (always) */
53-
.filter(method->{
54-
if(ProgrammingModelConstants.MethodExcludeMarker.anyMatchOn(method)) {
55-
processClassContext.removeMethod(method);
56-
return false; // stop processing
57-
}
58-
return true; // continue processing
59-
})
60-
/* don't throw away mixin main methods,
61-
* those we keep irrespective of IntrospectionPolicy */
62-
.filter(_Predicates.not(isMixinMainMethod(processClassContext)))
63-
.forEach(method -> {
64-
if (!ProgrammingModelConstants.MethodIncludeMarker.anyMatchOn(method)) {
65-
processClassContext.removeMethod(method);
66-
}
67-
});
68-
break;
69-
70-
case ANNOTATION_REQUIRED:
71-
// TODO: this could probably be more precise and insist on @Domain.Include for members.
50+
case ENCAPSULATION_ENABLED -> getClassCache()
51+
.streamResolvedMethods(processClassContext.getCls())
52+
/* honor exclude markers (always) */
53+
.filter(filterAndRemoveExclusions(processClassContext))
54+
/* don't throw away mixin main methods,
55+
* those we keep irrespective of IntrospectionPolicy */
56+
.filter(_Predicates.not(isMixinMainMethod(processClassContext)))
57+
.forEach(removeNonInclusions(processClassContext));
58+
case ANNOTATION_REQUIRED -> getClassCache()
59+
.streamPublicMethods(processClassContext.getCls())
60+
/* honor exclude markers (always) */
61+
.filter(filterAndRemoveExclusions(processClassContext))
62+
/* don't throw away mixin main methods,
63+
* those we keep irrespective of IntrospectionPolicy */
64+
.filter(_Predicates.not(isMixinMainMethod(processClassContext)))
65+
.forEach(removeNonInclusions(processClassContext));
66+
case ANNOTATION_OPTIONAL -> getClassCache()
67+
.streamPublicMethods(processClassContext.getCls())
68+
.forEach(removeExclusions(processClassContext));
69+
}
70+
}
7271

73-
case ANNOTATION_OPTIONAL:
72+
// -- HELPER
7473

75-
getClassCache()
76-
.streamPublicMethods(processClassContext.getCls())
77-
.forEach(method->{
78-
if(ProgrammingModelConstants.MethodExcludeMarker.anyMatchOn(method)) {
79-
processClassContext.removeMethod(method);
80-
}
81-
});
74+
private Predicate<? super ResolvedMethod> filterAndRemoveExclusions(final ProcessClassContext processClassContext) {
75+
return method->{
76+
if(ProgrammingModelConstants.MethodExcludeMarker.anyMatchOn(method)) {
77+
processClassContext.removeMethod(method);
78+
return false; // stop processing
79+
}
80+
return true; // continue processing
81+
};
82+
}
8283

83-
break;
84-
}
84+
private Consumer<? super ResolvedMethod> removeExclusions(final ProcessClassContext processClassContext) {
85+
return method->{
86+
if(ProgrammingModelConstants.MethodExcludeMarker.anyMatchOn(method)) {
87+
processClassContext.removeMethod(method);
88+
}
89+
};
8590
}
8691

87-
// -- HELPER
92+
private Consumer<? super ResolvedMethod> removeNonInclusions(final ProcessClassContext processClassContext) {
93+
return method->{
94+
if(!ProgrammingModelConstants.MethodIncludeMarker.anyMatchOn(method)) {
95+
processClassContext.removeMethod(method);
96+
}
97+
};
98+
}
8899

89100
/**
90101
* We have no MixinFacet yet, so we need to revert to low level introspection tactics.
@@ -94,9 +105,8 @@ private Predicate<ResolvedMethod> isMixinMainMethod(final @NonNull ProcessClassC
94105
// shortcut, when we already know the class is not a mixin
95106
if(processClassContext.getFacetHolder() instanceof ObjectSpecification) {
96107
var spec = (ObjectSpecification) processClassContext.getFacetHolder();
97-
if(!spec.getBeanSort().isMixin()) {
108+
if(!spec.getBeanSort().isMixin())
98109
return method->false;
99-
}
100110
}
101111
// lookup attribute from class-cache as it should have been already processed by the BeanTypeClassifier
102112
var cls = processClassContext.getCls();

core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/FacetedMethodsBuilder.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -385,18 +385,19 @@ private boolean isAllParamTypesValid(final MethodFacade actionMethod) {
385385
}
386386

387387
/**
388-
* At time of writing only filtering for Java Records,
389-
* because those have not type-hierarchy
390-
* (except potentially interfaces),
388+
* At time of writing only filtering for Java Records,
389+
* because those have not type-hierarchy
390+
* (except potentially interfaces),
391391
* where the check for explicit annotations is simple.
392392
*/
393393
private <A extends Annotation> boolean satisfiesIntrospectionPolicy(
394394
final ResolvedMethod accessorMethod,
395395
final Class<A> requiredAnnotationType) {
396-
return inspectedTypeSpec.getCorrespondingClass().isRecord()
397-
&& introspectionPolicy().getMemberAnnotationPolicy().isMemberAnnotationsRequired()
398-
? _Annotations.isPresent(accessorMethod.method(), requiredAnnotationType)
399-
: true;
396+
return true;
397+
// inspectedTypeSpec.getCorrespondingClass().isRecord()
398+
// && introspectionPolicy().getMemberAnnotationPolicy().isMemberAnnotationsRequired()
399+
// ? _Annotations.isPresent(accessorMethod.method(), requiredAnnotationType)
400+
// : true;
400401
}
401402

402403
private boolean representsAction(final ResolvedMethod actionMethod) {

0 commit comments

Comments
 (0)