org.jtwig.resource.ResourceService Maven / Gradle / Ivy
package org.jtwig.resource;
import com.google.common.base.Optional;
import org.jtwig.resource.exceptions.ResourceException;
import org.jtwig.resource.loader.ResourceLoader;
import org.jtwig.resource.loader.TypedResourceLoader;
import org.jtwig.resource.metadata.EmptyResourceMetadata;
import org.jtwig.resource.metadata.ResourceMetadata;
import org.jtwig.resource.metadata.ResourceResourceMetadata;
import org.jtwig.resource.reference.ResourceReference;
import org.jtwig.resource.reference.ResourceReferenceExtractor;
import org.jtwig.resource.resolver.RelativeResourceResolver;
import org.jtwig.value.environment.ValueEnvironment;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class ResourceService {
private final Map loaderMap;
private final List loaderList;
private final Collection absoluteResourceTypes;
private final Collection relativeResourceResolvers;
private final ResourceReferenceExtractor resourceReferenceExtractor;
public ResourceService(Map loaderMap, List loaderList, Collection absoluteResourceTypes, Collection relativeResourceResolvers, ResourceReferenceExtractor resourceReferenceExtractor) {
this.loaderMap = loaderMap;
this.loaderList = loaderList;
this.absoluteResourceTypes = absoluteResourceTypes;
this.relativeResourceResolvers = relativeResourceResolvers;
this.resourceReferenceExtractor = resourceReferenceExtractor;
}
public ResourceReference resolve(ResourceReference current, Object path, ValueEnvironment valueEnvironment) {
ResourceReference resourceReference = null;
if(path instanceof Iterable) {
for(Object relativePath : (Iterable) path) {
ResourceReference newReference = resolve(current, valueEnvironment.getStringConverter().convert(relativePath));
ResourceMetadata resourceMetadata = loadMetadata(newReference);
if(resourceMetadata.exists()) {
resourceReference = newReference;
break;
}
}
}
else if(path.getClass().isArray()) {
for(Object relativePath : (Object[]) path) {
ResourceReference newReference = resolve(current, valueEnvironment.getStringConverter().convert(relativePath));
ResourceMetadata resourceMetadata = loadMetadata(newReference);
if(resourceMetadata.exists()) {
resourceReference = newReference;
break;
}
}
}
if(resourceReference == null) {
resourceReference = resolve(current, valueEnvironment.getStringConverter().convert(path));
}
return resourceReference;
}
public ResourceReference resolve(ResourceReference current, String path) {
ResourceReference resourceReference = resourceReferenceExtractor.extract(path);
if (absoluteResourceTypes.contains(current.getType()) || absoluteResourceTypes.contains(resourceReference.getType())) {
return resourceReference;
} else {
if (ResourceReference.ANY_TYPE.equals(resourceReference.getType()) || resourceReference.getType().equals(current.getType())) {
for (RelativeResourceResolver resourceResolver : relativeResourceResolvers) {
Optional referenceOptional = resourceResolver.resolve(current, resourceReference);
if (referenceOptional.isPresent()) return referenceOptional.get();
}
}
}
return resourceReference;
}
public ResourceMetadata loadMetadata(ResourceReference reference) {
ResourceLoader result;
if (ResourceReference.ANY_TYPE.equals(reference.getType())) {
Optional resourceLoader = getFirstExistingResourceLoader(reference);
if (!resourceLoader.isPresent())
return EmptyResourceMetadata.instance();
else
result = resourceLoader.get();
} else {
Optional loaderOptional = Optional.fromNullable(loaderMap.get(reference.getType()));
if (!loaderOptional.isPresent()) {
throw new ResourceException(String.format("Cannot load resource %s. Resource loader for type '%s' not configured", reference, reference.getType()));
} else {
result = loaderOptional.get();
}
}
return new ResourceResourceMetadata(result, reference);
}
private Optional getFirstExistingResourceLoader(ResourceReference reference) {
for (TypedResourceLoader typedResourceLoader : loaderList) {
if (!ResourceReference.STRING.equals(typedResourceLoader.getType()) && typedResourceLoader.getResourceLoader().exists(reference.getPath())) {
return Optional.of(typedResourceLoader.getResourceLoader());
}
}
return Optional.absent();
}
}