Skip to content

Commit 9e8ed1c

Browse files
christophstroblmp911de
authored andcommitted
Consider filter configuration in AotMappingContext.
Closes #3474 Original pull request: #3475
1 parent 5f87412 commit 9e8ed1c

5 files changed

Lines changed: 107 additions & 3 deletions

File tree

src/main/java/org/springframework/data/aot/AotMappingContext.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.aot;
1717

18+
import java.io.File;
1819
import java.math.BigDecimal;
1920
import java.text.Format;
2021
import java.time.LocalDateTime;
@@ -35,18 +36,33 @@
3536
import org.springframework.data.mapping.model.EntityInstantiators;
3637
import org.springframework.data.mapping.model.Property;
3738
import org.springframework.data.mapping.model.SimpleTypeHolder;
39+
import org.springframework.data.util.TypeCollector;
3840

3941
/**
4042
* Simple {@link AbstractMappingContext} for processing of AOT contributions.
4143
*
4244
* @author Mark Paluch
45+
* @author Christoph Strobl
4346
* @since 4.0
4447
*/
4548
class AotMappingContext extends
4649
AbstractMappingContext<BasicPersistentEntity<?, AotMappingContext.AotPersistentProperty>, AotMappingContext.AotPersistentProperty> {
4750

4851
private final EntityInstantiators instantiators = new EntityInstantiators();
4952
private final AotAccessorFactory propertyAccessorFactory = new AotAccessorFactory();
53+
private final Predicate<Class<?>> typeCollectorFilter;
54+
55+
AotMappingContext() {
56+
this(TypeCollector.typeFilter(typeCollector -> {}));
57+
}
58+
59+
/**
60+
* @param typeFilter used for filtering during {@link #shouldCreatePersistentEntityFor(TypeInformation)}
61+
* @since 4.1
62+
*/
63+
AotMappingContext(Predicate<Class<?>> typeFilter) {
64+
this.typeCollectorFilter = typeFilter;
65+
}
5066

5167
/**
5268
* Contribute entity instantiators and property accessors for the given {@link PersistentEntity} that are captured
@@ -85,12 +101,17 @@ protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> typeInforma
85101
|| isInPackage.test(BigDecimal.class) // java.math
86102
|| isInPackage.test(LocalDateTime.class) // java.time
87103
|| isInPackage.test(Format.class) // java.text
104+
|| isInPackage.test(File.class) // java.io
88105
|| isInPackage.test(Point.class) // org.springframework.data.geo
89106
|| isInPackage.test(Page.class) // org.springframework.data.domain
90107
|| type.getPackageName().startsWith("javax")) {
91108
return false;
92109
}
93110

111+
if (!typeCollectorFilter.test(type)) {
112+
return false;
113+
}
114+
94115
return super.shouldCreatePersistentEntityFor(typeInformation);
95116
}
96117

src/main/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ public void setEnvironment(Environment environment) {
8282
return null;
8383
}
8484

85-
DefaultAotContext aotContext = new DefaultAotContext(registeredBean.getBeanFactory(), getConfiguredEnvironmentOrTryToResolveOne(registeredBean));
85+
DefaultAotContext aotContext = new DefaultAotContext(registeredBean.getBeanFactory(),
86+
getConfiguredEnvironmentOrTryToResolveOne(registeredBean),
87+
new AotMappingContext(TypeCollector.typeFilter(typeCollectorCustomizer())));
8688
return contribute(aotContext, resolveManagedTypes(registeredBean), registeredBean);
8789
}
8890

src/main/java/org/springframework/data/util/TypeCollector.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,32 @@ public TypeCollector filterFields(Predicate<Field> filter) {
126126
return this;
127127
}
128128

129+
/**
130+
* Return the combined type filter used when collecting reachable types (SPI {@link TypeCollectorFilters} plus any
131+
* {@link #filterTypes(Predicate) filterTypes} predicates).
132+
*
133+
* @return the type filter; never {@literal null}.
134+
* @since 4.1
135+
*/
136+
public Predicate<Class<?>> getTypeFilter() {
137+
return this.typeFilter;
138+
}
139+
140+
/**
141+
* Build the combined type filter for the given configuration, matching the filter applied by
142+
* {@link #inspect(Consumer, Collection)} for the same customizer.
143+
*
144+
* @param customizer configures the collector; must not be {@literal null}.
145+
* @return the type filter; never {@literal null}.
146+
* @since 4.1
147+
*/
148+
public static Predicate<Class<?>> typeFilter(Consumer<TypeCollector> customizer) {
149+
150+
TypeCollector collector = new TypeCollector();
151+
customizer.accept(collector);
152+
return collector.getTypeFilter();
153+
}
154+
129155
/**
130156
* Inspect the given type and resolve those reachable via fields, methods, generics, ...
131157
*

src/test/java/org/springframework/data/aot/AotMappingContextUnitTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
import static org.assertj.core.api.Assertions.*;
1919

2020
import java.util.BitSet;
21+
import java.util.function.Predicate;
2122

2223
import org.junit.jupiter.api.Test;
2324

2425
import org.springframework.data.annotation.Id;
2526
import org.springframework.data.annotation.Reference;
2627
import org.springframework.data.core.TypeInformation;
28+
import org.springframework.data.util.TypeCollector;
2729

2830
/**
2931
* Unit tests for {@link AotMappingContext}.
@@ -62,6 +64,17 @@ void doesNotContributeGeneratedAccessorForUnsupportedType() {
6264
});
6365
}
6466

67+
@Test // GH-3474
68+
void doesNotCreateEntityWhenTypeCollectorFilterExcludesNestedType() {
69+
70+
Predicate<Class<?>> filter = TypeCollector
71+
.typeFilter(c -> c.filterTypes(cls -> cls != ExcludedByFilterNested.class));
72+
AotMappingContext filteredContext = new AotMappingContext(filter);
73+
74+
assertThat(filteredContext.getPersistentEntity(EntityWithFilteredNested.class)).isNotNull();
75+
assertThat(filteredContext.getPersistentEntity(ExcludedByFilterNested.class)).isNull();
76+
}
77+
6578
static class DemoEntity {
6679

6780
@Id String id;
@@ -112,4 +125,15 @@ public void setName(String name) {
112125
}
113126
}
114127

128+
static class ExcludedByFilterNested {
129+
130+
String value;
131+
}
132+
133+
static class EntityWithFilteredNested {
134+
135+
@Id String id;
136+
ExcludedByFilterNested nested;
137+
}
138+
115139
}

src/test/java/org/springframework/data/aot/TypeCollectorUnitTests.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,22 @@
1515
*/
1616
package org.springframework.data.aot;
1717

18-
import static org.assertj.core.api.Assertions.*;
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import java.util.function.Predicate;
1921

2022
import org.junit.jupiter.api.Test;
21-
import org.springframework.data.aot.types.*;
23+
import org.springframework.data.aot.types.AbstractType;
24+
import org.springframework.data.aot.types.CyclicGenerics;
25+
import org.springframework.data.aot.types.CyclicPropertiesA;
26+
import org.springframework.data.aot.types.CyclicPropertiesB;
27+
import org.springframework.data.aot.types.CyclicPropertiesSelf;
28+
import org.springframework.data.aot.types.EmptyType1;
29+
import org.springframework.data.aot.types.EmptyType2;
30+
import org.springframework.data.aot.types.FieldsAndMethods;
31+
import org.springframework.data.aot.types.InterfaceType;
32+
import org.springframework.data.aot.types.TypesInMethodSignatures;
33+
import org.springframework.data.aot.types.WithDeclaredClass;
2234
import org.springframework.data.util.TypeCollector;
2335

2436
/**
@@ -77,4 +89,23 @@ void appliesFilterPredicate() {
7789
.list()).containsOnly(TypesInMethodSignatures.class, EmptyType1.class);
7890
}
7991

92+
@Test // GH-3474
93+
void typeFilterStaticMatchesInspectWithSameCustomizer() {
94+
95+
Predicate<Class<?>> fromStatic = TypeCollector.typeFilter(tc -> {});
96+
TypeCollector collector = new TypeCollector();
97+
98+
assertThat(fromStatic.test(FieldsAndMethods.class))
99+
.isEqualTo(collector.getTypeFilter().test(FieldsAndMethods.class));
100+
}
101+
102+
@Test // GH-3474
103+
void typeFilterReflectsAdditionalTypeFilters() {
104+
105+
Predicate<Class<?>> filter = TypeCollector.typeFilter(c -> c.filterTypes(cls -> false));
106+
107+
assertThat(filter.test(FieldsAndMethods.class)).isFalse();
108+
assertThat(TypeCollector.inspect(c -> c.filterTypes(cls -> false), FieldsAndMethods.class).list()).isEmpty();
109+
}
110+
80111
}

0 commit comments

Comments
 (0)