Allow ClassPathResources to be filtered by FilteredClassLoader
See gh-14774
This commit is contained in:
parent
29c0aa4445
commit
d3ca1a7b0e
|
@ -20,12 +20,15 @@ import java.net.URL;
|
|||
import java.net.URLClassLoader;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
/**
|
||||
* Test {@link URLClassLoader} that can filter the classes it can load.
|
||||
* Test {@link URLClassLoader} that can filter the classes and resources it can load.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
* @author Phillip Webb
|
||||
* @author Roy Jacobs
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class FilteredClassLoader extends URLClassLoader {
|
||||
|
@ -48,10 +51,19 @@ public class FilteredClassLoader extends URLClassLoader {
|
|||
this(PackageFilter.of(hiddenPackages));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link FilteredClassLoader} that hides resources from the given packages.
|
||||
* @param hiddenResources the resources to hide
|
||||
*/
|
||||
public FilteredClassLoader(ClassPathResource... hiddenResources) {
|
||||
this(ClassPathResourceFilter.of(hiddenResources));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link FilteredClassLoader} that filters based on the given predicate.
|
||||
* @param filters a set of filters to determine when a class name should be hidden. A
|
||||
* {@link Predicate#test(Object) result} of {@code true} indicates a filtered class.
|
||||
* @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
|
||||
* filtered class or resource.
|
||||
*/
|
||||
@SafeVarargs
|
||||
public FilteredClassLoader(Predicate<String>... filters) {
|
||||
|
@ -70,6 +82,16 @@ public class FilteredClassLoader extends URLClassLoader {
|
|||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
for (Predicate<String> filter : this.filters) {
|
||||
if (filter.test(name)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return super.getResource(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to restrict the classes that can be loaded.
|
||||
*/
|
||||
|
@ -124,4 +146,32 @@ public class FilteredClassLoader extends URLClassLoader {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to restrict the resources that can be loaded.
|
||||
*/
|
||||
public static final class ClassPathResourceFilter implements Predicate<String> {
|
||||
|
||||
private final ClassPathResource[] hiddenResources;
|
||||
|
||||
private ClassPathResourceFilter(ClassPathResource[] hiddenResources) {
|
||||
this.hiddenResources = hiddenResources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(String resourceName) {
|
||||
for (ClassPathResource hiddenResource : this.hiddenResources) {
|
||||
if (hiddenResource.getFilename() != null
|
||||
&& resourceName.equals(hiddenResource.getPath())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ClassPathResourceFilter of(ClassPathResource... hiddenResources) {
|
||||
return new ClassPathResourceFilter(hiddenResources);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
package org.springframework.boot.test.context;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
|
@ -25,9 +29,13 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||
* Tests for {@link FilteredClassLoader}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Roy Jacobs
|
||||
*/
|
||||
public class FilteredClassLoaderTests {
|
||||
|
||||
private static ClassPathResource TEST_RESOURCE = new ClassPathResource(
|
||||
"org/springframework/boot/test/context/FilteredClassLoaderTestResource.txt");
|
||||
|
||||
@Test
|
||||
public void loadClassWhenFilteredOnPackageShouldThrowClassNotFound()
|
||||
throws Exception {
|
||||
|
@ -55,4 +63,22 @@ public class FilteredClassLoaderTests {
|
|||
classLoader.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWhenFilteredOnResourceShouldReturnNotFound()
|
||||
throws Exception {
|
||||
try (FilteredClassLoader classLoader = new FilteredClassLoader(TEST_RESOURCE)) {
|
||||
final URL loaded = classLoader.getResource(TEST_RESOURCE.getPath());
|
||||
assertThat(loaded).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadResourceWhenNotFilteredShouldLoadResource() throws Exception {
|
||||
try (FilteredClassLoader classLoader = new FilteredClassLoader(
|
||||
(resourceName) -> false)) {
|
||||
final URL loaded = classLoader.getResource(TEST_RESOURCE.getPath());
|
||||
assertThat(loaded).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Used by FilteredClassLoaderTests.java
|
Loading…
Reference in New Issue