package jj.resource;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* presents a consistent interface to the notion of resolution of resource
* names to a {@link Path} if one can be made. The main motivation is to allow
* disparate parts of the system to contribute to how resource resolution occurs,
* but to do so in a fairly controlled manner, in a way that keeps the interface
* from caring too much about it.
* @author jason
*
*/
@Singleton
class PathResolverImpl implements PathResolver {
private final Map<Class<? extends Location>, LocationResolver> resolvers;
private final List<Location> watchedLocations;
@Inject
PathResolverImpl(Map<Class<? extends Location>, LocationResolver> resolvers) {
this.resolvers = resolvers;
List<Location> builder = new ArrayList<>();
for (LocationResolver resolver : resolvers.values()) {
builder.addAll(resolver.watchedLocations());
}
watchedLocations = Collections.unmodifiableList(builder);
}
@Override
public Path resolvePath(Location base) {
return resolvePath(base, "");
}
@Override
public Path resolvePath(Location base, String name) {
LocationResolver resolver = resolvers.get(base.getClass());
assert resolver != null : base;
Path result = resolver.resolvePath(base, name);
return result == null ? null : result.normalize().toAbsolutePath();
}
@Override
public Location resolveLocation(Path path) {
Location result = null;
for (LocationResolver resolver : resolvers.values()) {
result = resolver.resolveBase(path);
if (result != null) {
break;
}
}
return result;
}
@Override
public List<Location> watchedLocations() {
return watchedLocations;
}
@Override
public Location specLocationFor(Location base) {
LocationResolver resolver = resolvers.get(base.getClass());
assert resolver != null : base;
return resolver.specLocationFor(base);
}
@Override
public Location normalizedLocation(Location base, String name) {
LocationResolver resolver = resolvers.get(base.getClass());
assert resolver != null : base;
Path path = resolver.resolvePath(base, name);
return path == null ? base : resolver.resolveBase(path);
}
@Override
public String normalizedName(Location originalBase, Location normalizedBase, String name) {
assert originalBase.getClass() == normalizedBase.getClass() : "bases need to be the same!";
LocationResolver resolver = resolvers.get(originalBase.getClass());
assert resolver != null : originalBase;
return originalBase == normalizedBase ?
name :
resolver.normalizedName(originalBase, normalizedBase, name);
}
}