io.nosqlbench.nb.api.content.PathFinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nb-api Show documentation
Show all versions of nb-api Show documentation
The top level API module for NoSQLBench. This module should have no internal
module dependencies other than the mvn-default module.
All modules within NoSQLBench can safely depend on this module with circular
dependencies. This module provides cross-cutting code infrastracture, such as
path utilities and ways of describing services used between modules.
It is also the transitive aggregation point for system-wide library dependencies
for logging and testing or similar needs.
package io.nosqlbench.nb.api.content;
import io.nosqlbench.nb.api.errors.BasicError;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.util.*;
import java.util.stream.Collectors;
/**
* A central API for finding and accessing Paths which are either in
* the classpath or in the file system, or both.
*/
public class PathFinder {
private final static Logger logger = LogManager.getLogger(PathFinder.class);
/**
* Find exactly zero or one matching Paths, and return an {@link Optional} of {@link Path}.
* Or, if more than one are found, throw a basic error.
*
* @param names The names of paths to find, with tailing slashes signifying directories
* @return An optional Path
* @throws BasicError if there is more than one matching path found.
*/
public static Optional find(String... names) {
List paths = findAll(names);
if (paths.size() == 0) {
return Optional.empty();
}
if (paths.size() > 1) {
throw new BasicError("Found " + paths.size() + " paths, when only one is allowed:" +
paths.stream()
.map(p -> p.toString() + " on " + p.getFileSystem())
.collect(Collectors.joining(","))
);
}
return Optional.of(paths.get(0));
}
/**
* Find one or more matching path, and return a list.
*
* @param pathspecs The names of paths to search for.
* @return A list of matching paths, possibly empty.
*/
static List findAll(String... pathspecs) {
List founds = new ArrayList<>();
for (String pathspec : pathspecs) {
boolean wantsADirectory = pathspec.endsWith(FileSystems.getDefault().getSeparator());
String candidatePath = wantsADirectory ? pathspec.substring(0, pathspec.length() - 1) : pathspec;
Path candidate = Path.of(candidatePath);
findPathOnRemoteURL(pathspec).ifPresent(founds::add);
findPathOnFilesystem(candidatePath, wantsADirectory).ifPresent(founds::add);
findPathOnClasspath(candidatePath, wantsADirectory).ifPresent(founds::add);
}
return founds;
}
private static Optional findPathOnRemoteURL(String pathspec) {
if (pathspec.toLowerCase().startsWith("http:") ||
pathspec.toLowerCase().startsWith("https:")) {
Optional inputStreamForUrl = getInputStreamForUrl(pathspec);
if (inputStreamForUrl.isPresent()) {
Path found = Path.of(URI.create(pathspec));
logger.debug("Found accessible remote file at " + found.toString());
return Optional.of(found);
}
}
return Optional.empty();
}
private static Optional findPathOnClasspath(String candidatePath, boolean wantsADirectory) {
try {
URL url = ClassLoader.getSystemResource(candidatePath);
if (url != null) {
URI uri = URI.create(url.toExternalForm());
FileSystem fileSystem = null;
try {
fileSystem = FileSystems.getFileSystem(uri);
} catch (FileSystemNotFoundException retried) {
try {
fileSystem = FileSystems.newFileSystem(uri, new HashMap<>());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
logger.debug("Found path in classpath: " + candidatePath + ": " + candidatePath);
return Optional.of(Path.of(uri));
}
return Optional.empty();
} catch (Exception e) {
logger.trace("Error while looking in classpath for " + candidatePath, e);
return Optional.empty();
}
}
private static Optional findPathOnFilesystem(String pathName, boolean wantsADirectory) {
try {
Path candidatePath = Path.of(pathName);
FileSystemProvider provider = candidatePath.getFileSystem().provider();
provider.checkAccess(candidatePath, AccessMode.READ);
BasicFileAttributes attrs = provider.readAttributes(candidatePath, BasicFileAttributes.class);
boolean foundADirectory = attrs.isDirectory();
if (wantsADirectory != foundADirectory) {
throw new RuntimeException("for path " + candidatePath + ", user wanted a " +
(wantsADirectory ? "directory" : "file") + ", but found a " +
(foundADirectory ? "directory" : "file") + " while searching for " +
pathName);
}
return Optional.of(candidatePath);
} catch (Exception ignored) {
return Optional.empty();
}
}
private static Optional getInputStreamForUrl(String path) {
URL url;
try {
url = new URL(path);
InputStream inputStream = url.openStream();
return Optional.ofNullable(inputStream);
} catch (Exception e) {
return Optional.empty();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy