package restx.common;
import com.google.common.io.Resources;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import static java.util.Arrays.asList;
/**
* User: xavierhanin
* Date: 6/2/13
* Time: 9:13 PM
*/
public class MoreResources {
public static URL getResource(String resourceName, boolean searchInSources) {
URL resource = null;
if (searchInSources) {
// in DEV mode we try to load resource from sources if we find them
Set<URL> urls = ClasspathHelper.forResource(resourceName);
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
for (String classesLocation : asList("target/classes/", "bin/")) {
if (url.getFile().endsWith(classesLocation)) {
for (String sourcesLocation : asList("src/main/resources/", "src/")) {
File file = new File(url.getFile().replace(classesLocation, ""),
sourcesLocation + resourceName);
if (file.exists()) {
try {
resource = file.toURI().toURL();
} catch (MalformedURLException e) {
// ignored
}
break;
}
}
}
}
}
}
}
if (resource == null) {
resource = Resources.getResource(resourceName);
}
return resource;
}
public static Map<String, URL> findResources(String packageName, final Pattern p, boolean searchInSources) {
final Map<String, URL> resourcesUrls = new LinkedHashMap<>();
if (searchInSources) {
// here we try to find resources from sources
Set<Path> sourceRoots = findSourceRoots();
for (final Path sourceRoot : sourceRoots) {
try {
Files.walkFileTree(sourceRoot.resolve(packageName.replace('.', '/')), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (p.matcher(file.getFileName().toString()).matches()) {
try {
String resource = sourceRoot.relativize(file).toString();
if (!resourcesUrls.containsKey(resource)) {
resourcesUrls.put(resource, file.toUri().toURL());
}
} catch (MalformedURLException e) {
// ignore
}
}
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
// ignore
}
}
}
// now we search for real resources, but avoid duplicates, especially for the one found in sources
for (String r : new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage(packageName))
.setScanners(new ResourcesScanner())
.build()
.getResources(p)) {
if (!resourcesUrls.containsKey(r) && r.startsWith(packageName.replace('.', '/'))) {
resourcesUrls.put(r, Resources.getResource(r));
}
}
return resourcesUrls;
}
private static Set<Path> findSourceRoots() {
Set<Path> sourceRoots = new LinkedHashSet<>();
Set<URL> urls = ClasspathHelper.forClassLoader();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
for (String classesLocation : asList("target/classes/", "bin/")) {
if (url.getFile().endsWith(classesLocation)) {
for (String sourcesLocation : asList("src/main/resources/", "src/")) {
final File sourceRoot = new File(url.getFile().replace(classesLocation, ""),
sourcesLocation);
if (sourceRoot.exists()) {
sourceRoots.add(sourceRoot.toPath());
break;
}
}
}
}
}
}
return sourceRoots;
}
}