parent
5c2870ebd9
commit
40c8b7c59f
|
@ -36,6 +36,7 @@ import org.springframework.util.ReflectionUtils;
|
||||||
* match the expected behavior for reflection.
|
* match the expected behavior for reflection.
|
||||||
*
|
*
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public class ReflectionHintsPredicates {
|
public class ReflectionHintsPredicates {
|
||||||
|
@ -248,15 +249,17 @@ public class ReflectionHintsPredicates {
|
||||||
abstract Predicate<RuntimeHints> exactMatch();
|
abstract Predicate<RuntimeHints> exactMatch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicate whether the first {@code ExecutableHint} covers the reflection needs for the other one.
|
* Indicate whether the specified {@code ExecutableHint} covers the
|
||||||
* For that, both hints must apply to the same member (same type, name and parameters)
|
* reflection needs of the specified executable definition.
|
||||||
* and the configured {@code ExecutableMode} of the first must cover the second.
|
* @return {@code true} if the member matches (same type, name and parameters),
|
||||||
|
* and the configured {@code ExecutableMode} is compatibe
|
||||||
*/
|
*/
|
||||||
static boolean includes(ExecutableHint hint, ExecutableHint other) {
|
static boolean includes(ExecutableHint hint, String name,
|
||||||
return hint.getName().equals(other.getName())
|
List<TypeReference> parameterTypes, List<ExecutableMode> executableModes) {
|
||||||
&& hint.getParameterTypes().equals(other.getParameterTypes())
|
return hint.getName().equals(name)
|
||||||
|
&& hint.getParameterTypes().equals(parameterTypes)
|
||||||
&& (hint.getModes().contains(ExecutableMode.INVOKE)
|
&& (hint.getModes().contains(ExecutableMode.INVOKE)
|
||||||
|| !other.getModes().contains(ExecutableMode.INVOKE));
|
|| !executableModes.contains(ExecutableMode.INVOKE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,31 +272,32 @@ public class ReflectionHintsPredicates {
|
||||||
@Override
|
@Override
|
||||||
MemberCategory[] getPublicMemberCategories() {
|
MemberCategory[] getPublicMemberCategories() {
|
||||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||||
return new MemberCategory[] {MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS,
|
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS,
|
||||||
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS};
|
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS };
|
||||||
}
|
}
|
||||||
return new MemberCategory[] {MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS};
|
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemberCategory[] getDeclaredMemberCategories() {
|
MemberCategory[] getDeclaredMemberCategories() {
|
||||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||||
return new MemberCategory[] {MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
|
return new MemberCategory[] { MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
|
||||||
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS};
|
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS };
|
||||||
}
|
}
|
||||||
return new MemberCategory[] {MemberCategory.INVOKE_DECLARED_CONSTRUCTORS};
|
return new MemberCategory[] { MemberCategory.INVOKE_DECLARED_CONSTRUCTORS };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Predicate<RuntimeHints> exactMatch() {
|
Predicate<RuntimeHints> exactMatch() {
|
||||||
return hints -> (hints.reflection().getTypeHint(this.executable.getDeclaringClass()) != null) &&
|
return hints -> (hints.reflection().getTypeHint(this.executable.getDeclaringClass()) != null) &&
|
||||||
hints.reflection().getTypeHint(this.executable.getDeclaringClass()).constructors().anyMatch(executableHint -> {
|
hints.reflection().getTypeHint(this.executable.getDeclaringClass()).constructors().anyMatch(executableHint -> {
|
||||||
List<TypeReference> parameters = Arrays.stream(this.executable.getParameterTypes()).map(TypeReference::of).toList();
|
List<TypeReference> parameters = Arrays.stream(this.executable.getParameterTypes())
|
||||||
ExecutableHint syntheticHint = ExecutableHint.ofConstructor(parameters)
|
.map(TypeReference::of).toList();
|
||||||
.setModes(this.executableMode).build();
|
return includes(executableHint, "<init>",
|
||||||
return includes(executableHint, syntheticHint);
|
parameters, List.of(this.executableMode));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MethodHintPredicate extends ExecutableHintPredicate<Method> {
|
public static class MethodHintPredicate extends ExecutableHintPredicate<Method> {
|
||||||
|
@ -306,32 +310,33 @@ public class ReflectionHintsPredicates {
|
||||||
@Override
|
@Override
|
||||||
MemberCategory[] getPublicMemberCategories() {
|
MemberCategory[] getPublicMemberCategories() {
|
||||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||||
return new MemberCategory[] {MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
return new MemberCategory[] { MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
||||||
MemberCategory.INVOKE_PUBLIC_METHODS};
|
MemberCategory.INVOKE_PUBLIC_METHODS };
|
||||||
}
|
}
|
||||||
return new MemberCategory[] {MemberCategory.INVOKE_PUBLIC_METHODS};
|
return new MemberCategory[] { MemberCategory.INVOKE_PUBLIC_METHODS };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
MemberCategory[] getDeclaredMemberCategories() {
|
MemberCategory[] getDeclaredMemberCategories() {
|
||||||
|
|
||||||
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
if (this.executableMode == ExecutableMode.INTROSPECT) {
|
||||||
return new MemberCategory[] {MemberCategory.INTROSPECT_DECLARED_METHODS,
|
return new MemberCategory[] { MemberCategory.INTROSPECT_DECLARED_METHODS,
|
||||||
MemberCategory.INVOKE_DECLARED_METHODS};
|
MemberCategory.INVOKE_DECLARED_METHODS };
|
||||||
}
|
}
|
||||||
return new MemberCategory[] {MemberCategory.INVOKE_DECLARED_METHODS};
|
return new MemberCategory[] { MemberCategory.INVOKE_DECLARED_METHODS };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Predicate<RuntimeHints> exactMatch() {
|
Predicate<RuntimeHints> exactMatch() {
|
||||||
return hints -> (hints.reflection().getTypeHint(this.executable.getDeclaringClass()) != null) &&
|
return hints -> (hints.reflection().getTypeHint(this.executable.getDeclaringClass()) != null) &&
|
||||||
hints.reflection().getTypeHint(this.executable.getDeclaringClass()).methods().anyMatch(executableHint -> {
|
hints.reflection().getTypeHint(this.executable.getDeclaringClass()).methods().anyMatch(executableHint -> {
|
||||||
List<TypeReference> parameters = Arrays.stream(this.executable.getParameterTypes()).map(TypeReference::of).toList();
|
List<TypeReference> parameters = Arrays.stream(this.executable.getParameterTypes())
|
||||||
ExecutableHint syntheticHint = ExecutableHint.ofMethod(this.executable.getName(), parameters)
|
.map(TypeReference::of).toList();
|
||||||
.setModes(this.executableMode).build();
|
return includes(executableHint, this.executable.getName(),
|
||||||
return includes(executableHint, syntheticHint);
|
parameters, List.of(this.executableMode));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FieldHintPredicate implements Predicate<RuntimeHints> {
|
public static class FieldHintPredicate implements Predicate<RuntimeHints> {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.aot.hint;
|
package org.springframework.aot.hint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -27,6 +29,7 @@ import org.springframework.util.ConcurrentLruCache;
|
||||||
* match the expected behavior for resources.
|
* match the expected behavior for resources.
|
||||||
*
|
*
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public class ResourceHintsPredicates {
|
public class ResourceHintsPredicates {
|
||||||
|
@ -78,16 +81,31 @@ public class ResourceHintsPredicates {
|
||||||
* @return the {@link RuntimeHints} predicate
|
* @return the {@link RuntimeHints} predicate
|
||||||
*/
|
*/
|
||||||
public Predicate<RuntimeHints> forResource(String resourceName) {
|
public Predicate<RuntimeHints> forResource(String resourceName) {
|
||||||
return hints -> hints.resources().resourcePatterns().reduce(ResourcePatternHints::merge)
|
return hints -> {
|
||||||
.map(hint -> {
|
AggregatedResourcePatternHints aggregatedResourcePatternHints = AggregatedResourcePatternHints.of(
|
||||||
boolean isExcluded = hint.getExcludes().stream()
|
hints.resources());
|
||||||
.anyMatch(excluded -> CACHED_RESOURCE_PATTERNS.get(excluded).matcher(resourceName).matches());
|
boolean isExcluded = aggregatedResourcePatternHints.excludes().stream().anyMatch(excluded ->
|
||||||
|
CACHED_RESOURCE_PATTERNS.get(excluded).matcher(resourceName).matches());
|
||||||
if (isExcluded) {
|
if (isExcluded) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return hint.getIncludes().stream()
|
return aggregatedResourcePatternHints.includes().stream().anyMatch(included ->
|
||||||
.anyMatch(included -> CACHED_RESOURCE_PATTERNS.get(included).matcher(resourceName).matches());
|
CACHED_RESOURCE_PATTERNS.get(included).matcher(resourceName).matches());
|
||||||
}).orElse(false);
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private record AggregatedResourcePatternHints(List<ResourcePatternHint> includes, List<ResourcePatternHint> excludes) {
|
||||||
|
|
||||||
|
static AggregatedResourcePatternHints of(ResourceHints resourceHints) {
|
||||||
|
List<ResourcePatternHint> includes = new ArrayList<>();
|
||||||
|
List<ResourcePatternHint> excludes = new ArrayList<>();
|
||||||
|
resourceHints.resourcePatterns().forEach(resourcePatternHint -> {
|
||||||
|
includes.addAll(resourcePatternHint.getIncludes());
|
||||||
|
excludes.addAll(resourcePatternHint.getExcludes());
|
||||||
|
});
|
||||||
|
return new AggregatedResourcePatternHints(includes, excludes);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,11 +45,6 @@ public final class ResourcePatternHints {
|
||||||
this.excludes = new ArrayList<>(builder.excludes);
|
this.excludes = new ArrayList<>(builder.excludes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourcePatternHints(List<ResourcePatternHint> includes, List<ResourcePatternHint> excludes) {
|
|
||||||
this.includes = includes;
|
|
||||||
this.excludes = excludes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the include patterns to use to identify the resources to match.
|
* Return the include patterns to use to identify the resources to match.
|
||||||
* @return the include patterns
|
* @return the include patterns
|
||||||
|
@ -66,16 +61,6 @@ public final class ResourcePatternHints {
|
||||||
return this.excludes;
|
return this.excludes;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourcePatternHints merge(ResourcePatternHints resourcePatternHints) {
|
|
||||||
List<ResourcePatternHint> includes = new ArrayList<>();
|
|
||||||
includes.addAll(this.includes);
|
|
||||||
includes.addAll(resourcePatternHints.includes);
|
|
||||||
List<ResourcePatternHint> excludes = new ArrayList<>();
|
|
||||||
excludes.addAll(this.excludes);
|
|
||||||
excludes.addAll(resourcePatternHints.excludes);
|
|
||||||
return new ResourcePatternHints(includes, excludes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for {@link ResourcePatternHints}.
|
* Builder for {@link ResourcePatternHints}.
|
||||||
|
|
Loading…
Reference in New Issue