Commit baf83aec authored by Stephane Nicoll's avatar Stephane Nicoll

Polish "Allow ClassPathResources to be filtered by FilteredClassLoader"

Closes gh-14774
parent d3ca1a7b
...@@ -18,6 +18,9 @@ package org.springframework.boot.test.context; ...@@ -18,6 +18,9 @@ package org.springframework.boot.test.context;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Predicate; import java.util.function.Predicate;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
...@@ -33,14 +36,17 @@ import org.springframework.core.io.ClassPathResource; ...@@ -33,14 +36,17 @@ import org.springframework.core.io.ClassPathResource;
*/ */
public class FilteredClassLoader extends URLClassLoader { public class FilteredClassLoader extends URLClassLoader {
private final Predicate<String>[] filters; private final Collection<Predicate<String>> classesFilters;
private final Collection<Predicate<String>> resourcesFilters;
/** /**
* Create a {@link FilteredClassLoader} that hides the given classes. * Create a {@link FilteredClassLoader} that hides the given classes.
* @param hiddenClasses the classes to hide * @param hiddenClasses the classes to hide
*/ */
public FilteredClassLoader(Class<?>... hiddenClasses) { public FilteredClassLoader(Class<?>... hiddenClasses) {
this(ClassFilter.of(hiddenClasses)); this(Collections.singleton(ClassFilter.of(hiddenClasses)),
Collections.emptyList());
} }
/** /**
...@@ -48,33 +54,43 @@ public class FilteredClassLoader extends URLClassLoader { ...@@ -48,33 +54,43 @@ public class FilteredClassLoader extends URLClassLoader {
* @param hiddenPackages the packages to hide * @param hiddenPackages the packages to hide
*/ */
public FilteredClassLoader(String... hiddenPackages) { public FilteredClassLoader(String... hiddenPackages) {
this(PackageFilter.of(hiddenPackages)); this(Collections.singleton(PackageFilter.of(hiddenPackages)),
Collections.emptyList());
} }
/** /**
* Create a {@link FilteredClassLoader} that hides resources from the given packages. * Create a {@link FilteredClassLoader} that hides resources from the given
* {@link ClassPathResource classpath resources}.
* @param hiddenResources the resources to hide * @param hiddenResources the resources to hide
*/ */
public FilteredClassLoader(ClassPathResource... hiddenResources) { public FilteredClassLoader(ClassPathResource... hiddenResources) {
this(ClassPathResourceFilter.of(hiddenResources)); this(Collections.emptyList(),
Collections.singleton(ClassPathResourceFilter.of(hiddenResources)));
} }
/** /**
* Create a {@link FilteredClassLoader} that filters based on the given predicate. * Create a {@link FilteredClassLoader} that filters based on the given predicate.
* @param filters a set of filters to determine when a class name or resource should * @param filters a set of filters to determine when a class name or resource should
* be hidden. A {@link Predicate#test(Object) result} of {@code true} indicates a * be hidden. A {@link Predicate#test(Object) result} of {@code true} indicates a
* filtered class or resource. * filtered class or resource. The input of the predicate can either be the binary
* name of a class or a resource name.
*/ */
@SafeVarargs @SafeVarargs
public FilteredClassLoader(Predicate<String>... filters) { public FilteredClassLoader(Predicate<String>... filters) {
this(Arrays.asList(filters), Arrays.asList(filters));
}
private FilteredClassLoader(Collection<Predicate<String>> classesFilters,
Collection<Predicate<String>> resourcesFilters) {
super(new URL[0], FilteredClassLoader.class.getClassLoader()); super(new URL[0], FilteredClassLoader.class.getClassLoader());
this.filters = filters; this.classesFilters = classesFilters;
this.resourcesFilters = resourcesFilters;
} }
@Override @Override
protected Class<?> loadClass(String name, boolean resolve) protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException { throws ClassNotFoundException {
for (Predicate<String> filter : this.filters) { for (Predicate<String> filter : this.classesFilters) {
if (filter.test(name)) { if (filter.test(name)) {
throw new ClassNotFoundException(); throw new ClassNotFoundException();
} }
...@@ -84,7 +100,7 @@ public class FilteredClassLoader extends URLClassLoader { ...@@ -84,7 +100,7 @@ public class FilteredClassLoader extends URLClassLoader {
@Override @Override
public URL getResource(String name) { public URL getResource(String name) {
for (Predicate<String> filter : this.filters) { for (Predicate<String> filter : this.resourcesFilters) {
if (filter.test(name)) { if (filter.test(name)) {
return null; return null;
} }
......
...@@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; ...@@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
public class FilteredClassLoaderTests { public class FilteredClassLoaderTests {
private static ClassPathResource TEST_RESOURCE = new ClassPathResource( private static ClassPathResource TEST_RESOURCE = new ClassPathResource(
"org/springframework/boot/test/context/FilteredClassLoaderTestResource.txt"); "org/springframework/boot/test/context/FilteredClassLoaderTestsResource.txt");
@Test @Test
public void loadClassWhenFilteredOnPackageShouldThrowClassNotFound() public void loadClassWhenFilteredOnPackageShouldThrowClassNotFound()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment