ResourceResolverAssertions.java
package fr.sii.ogham.testing.assertion.internal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.reflect.FieldUtils;
import fr.sii.ogham.core.resource.resolver.ClassPathResolver;
import fr.sii.ogham.core.resource.resolver.FileResolver;
import fr.sii.ogham.core.resource.resolver.FirstSupportingResourceResolver;
import fr.sii.ogham.core.resource.resolver.RelativeResolver;
import fr.sii.ogham.core.resource.resolver.ResourceResolver;
import fr.sii.ogham.testing.util.HasParent;
/**
* Make assertions on resource resolution.
*
*
* <pre>
* {@code
* classpath()
* .pathPrefix(is("prefix/")
* }
* </pre>
*
* @param <P>
* the parent type
*/
public class ResourceResolverAssertions<P> extends HasParent<P> {
private final Set<ResourceResolver> resolvers;
public ResourceResolverAssertions(P parent, Set<ResourceResolver> resourceResolvers) {
super(parent);
this.resolvers = resourceResolvers;
}
/**
* Make assertions on classpath resolution.
*
* <pre>
* {@code
* .pathPrefix(is("/custom/"))
* .pathSuffix(is(".html"))
* }
* </pre>
*
* @return the builder for fluent chaining
*/
public RelativeResolutionAssertions<ResourceResolverAssertions<P>> classpath() {
return new RelativeResolutionAssertions<>(this, "classpath", getRelativeResolversFor(ClassPathResolver.class));
}
/**
* Make assertions on file resolution.
*
* <pre>
* {@code
* .pathPrefix(is("/custom/"))
* .pathSuffix(is(".html"))
* }
* </pre>
*
* @return the builder for fluent chaining
*/
public RelativeResolutionAssertions<ResourceResolverAssertions<P>> file() {
return new RelativeResolutionAssertions<>(this, "file", getRelativeResolversFor(FileResolver.class));
}
private <T> Set<RelativeResolver> getRelativeResolversFor(Class<T> resolverClass) {
Set<RelativeResolver> found = new HashSet<>();
for (ResourceResolver resolver : resolvers) {
Set<RelativeResolver> relativeResolvers = findResolvers(resolver, RelativeResolver.class);
for (RelativeResolver relative : relativeResolvers) {
if (resolverClass.isAssignableFrom(relative.getActualResourceResolver().getClass())) {
found.add(relative);
}
}
}
return found;
}
@SuppressWarnings("unchecked")
private static <T> Set<T> findResolvers(ResourceResolver resolver, Class<T> resolverClass) {
Set<T> found = new HashSet<>();
if (resolverClass.isAssignableFrom(resolver.getClass())) {
found.add((T) resolver);
}
if (resolver instanceof FirstSupportingResourceResolver) {
found.addAll(findResolvers((FirstSupportingResourceResolver) resolver, resolverClass));
}
if (resolver instanceof RelativeResolver) {
found.addAll(findResolvers((RelativeResolver) resolver, resolverClass));
}
return found;
}
@SuppressWarnings("unchecked")
private static <T> Set<T> findResolvers(FirstSupportingResourceResolver resolver, Class<T> resolverClass) {
try {
Set<T> found = new HashSet<>();
List<ResourceResolver> subresolvers = (List<ResourceResolver>) FieldUtils.readField(resolver, "resolvers", true);
for (ResourceResolver r : subresolvers) {
found.addAll(findResolvers(r, resolverClass));
}
return found;
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to get 'resolvers' field of FirstSupportingResourceResolver", e);
}
}
@SuppressWarnings("unchecked")
private static <T> Set<T> findResolvers(RelativeResolver resolver, Class<T> resolverClass) {
try {
Set<T> found = new HashSet<>();
if (resolverClass.isAssignableFrom(resolver.getClass())) {
found.add((T) resolver);
}
ResourceResolver delegate = (ResourceResolver) FieldUtils.readField(resolver, "delegate", true);
if (resolverClass.isAssignableFrom(resolver.getActualResourceResolver().getClass())) {
found.add((T) delegate);
}
return found;
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to get 'delegate' field of RelativeResolver", e);
}
}
}