Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add javadoc and make methods more robust #24

Merged
merged 3 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import gov.hhs.aspr.ms.util.errors.ContractError;

public enum ResourceError implements ContractError {
UNKNOWN_FILE("Provided file does not exist");
UNKNOWN_FILE("Provided file does not exist"),
FILE_PATH_IS_DIRECTORY("The provided file path points to a directory and not a file"),
DIRECTORY_PATH_IS_FILE("The provided directory path points to a file and not a directory");

private final String description;

Expand Down
261 changes: 224 additions & 37 deletions src/main/java/gov/hhs/aspr/ms/util/resourcehelper/ResourceHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,83 +5,270 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;

import gov.hhs.aspr.ms.util.errors.ContractException;

/**
* ResourceHelper is a class designed to solve the issue that sometimes arises
* when running UnitTests and using files from the resources directory within
* the src/test folder.
* <p>
* The issue is that the relative path to the resource folder is dependant on
* what folder you are executing the test from. This can vary from IDE to IDE
* and even from where you run the maven command if using maven to run the unit
* tests.
* <p>
* This solves the issues by obtaining an absolute reference to the resource
* directory by using the class loader and an empty resource.
* <p>
* In addition to the above, this class also provides convience methods to
* validate file paths and directory paths, and create directories and files.
*/
public class ResourceHelper {

private ResourceHelper() {
}

/**
* Given a class ref, uses the class loader from the classref and an empty
* resource name to obtain a URI and then creates and returns a Path from that
* URI. This path will be an absolute path and not a relative path. Because it
* uses the classloader, it no longer matters from where this method gets called
* with respect to the java command used to call it.
* <p>
* This solves the problem of unit tests that use files from the
* src/test/resources sometimes failing because of the directory from which the
* test was executed.
*
* @throws RuntimeException if the url provided by the classloader cannot be
* converted to a valid URI. Note that the
* RuntimeException wraps the thrown
* {@link URISyntaxException}
*/
public static Path getResourceDir(Class<?> classRef) {
return Path.of(getURI(classRef.getClassLoader().getResource("")));
}

protected static URI getURI(URL url) {
try {
return url.toURI();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
/**
* Given a path, creates the directory. This internally calls
* dirPath.toFile().mkdirs().
*/
public static Path createDirectory(Path dirPath) {
if (dirPath.toFile().exists()) {
return dirPath;
}
}

public static Path makeOutputDir(Path dirPath) {
dirPath.toFile().mkdirs();

return dirPath;
}

public static Path makeOutputDir(Path basepath, String subDir) {
Path dirPath = basepath.resolve(subDir);
/**
* Given a string that is a valid path, creates the directory.
* <p>
* calls {@link ResourceHelper#createDirectory(Path)}
*/
public static Path createDirectory(String directory) {
Path dirPath = Path.of(directory);

return createDirectory(dirPath);
}

/**
* Given a base directory path and a sub directory, resolves the sub directory
* against the base path and calls {@link ResourceHelper#createDirectory(Path)}
* <p>
* returns the resolved path
*/
public static Path createDirectory(Path baseDirPath, String subDir) {
Path dirPath = baseDirPath.resolve(subDir);

return createDirectory(dirPath);
}

/**
* Given a base directory and a sub directory, resolves the sub directory
* against the base path and calls {@link ResourceHelper#createDirectory(Path)}
* <p>
* returns the resolved path
*/
public static Path createDirectory(String baseDir, String subDir) {
Path dirPath = Path.of(baseDir, subDir);

return createDirectory(dirPath);
}

/**
* Given a directory path and a file name, creates a file with the given name in
* the given directory.
*
* @throws RuntimeException if the file cannot be created. Note that the
* RuntimeException wraps the thrown
* {@link IOException}
*/
public static void createFile(Path directory, String fileName) {

File file = directory.resolve(fileName).toFile();

if (file.exists()) {
return;
}

_createFile(file);
}

/**
* Given a directory path and a file name, creates a file with the given name in
* the given directory.
* <p>
* Deletes the file if it exists before creating the file.
*
* @throws RuntimeException if the file cannot be created. Note that the
* RuntimeException wraps the thrown
* {@link IOException}
*/
public static void createNewFile(Path directory, String fileName) {

File file = directory.resolve(fileName).toFile();

if (file.exists()) {
file.delete();
}

_createFile(file);
}

/**
* Given a file path, validates that the file exists.
* <p>
* calls {@link ResourceHelper#validateFilePath(Path)}
*
* @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the
* file path refers to a directory
*/
public static Path validateFile(String file) {
Path filePath = Path.of(file);

return makeOutputDir(dirPath);
validateFile(filePath);

return filePath;
}

public static void createOutputFile(Path filePath, String fileName) {
/**
* Given a file path, validates that the file exists.
*
* @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the
* file path refers to a directory
*/
public static Path validateFile(Path filePath) {
File file = filePath.toFile();

File isAfile = filePath.resolve(fileName).toFile();
if (file.isDirectory()) {
throw new ContractException(ResourceError.FILE_PATH_IS_DIRECTORY);
}

if (isAfile.exists()) {
isAfile.delete();
if (!file.exists()) {
throw new ContractException(ResourceError.UNKNOWN_FILE);
}

createFile(isAfile);
return filePath;
}

/**
* Given a file path, validates that the file exists.
* <p>
* calls {@link ResourceHelper#validateFilePath(Path)}
*
* @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the
* file path refers to a directory
*/
public static Path validateFilePath(String file) {
Path filePath = Path.of(file);

validateFilePath(filePath);

return filePath;
}

public static Path validatePath(String path, boolean isOutput) {
Path maybePath = Path.of(path);
File maybeFile = maybePath.toFile();
/**
* Given a file path, validates that the file exists.
*
* @throws ContractException {@link ResourceError#FILE_PATH_IS_DIRECTORY} if the
* file path refers to a directory
*/
public static Path validateFilePath(Path filePath) {
File file = filePath.toFile();

boolean isDirectory = maybeFile.isDirectory();
boolean isFile = maybeFile.isFile();
if (file.isDirectory()) {
throw new ContractException(ResourceError.FILE_PATH_IS_DIRECTORY);
}

// if the given string corresponds to a file that exists, return path
if (isFile) {
return maybePath;
if (!file.exists()) {
validateDirectoryPath(filePath.getParent());
}

// if file does not exist, ensure the path is not a directory and that the
// parent directory of the outputFile exists.
if (isOutput && !isDirectory) {
Path parentPath = maybePath.getParent();
return filePath;
}

/**
* Given a directory path, validates that the directory exists.
* <p>
* calls {@link ResourceHelper#validateDirectoryPath(Path)}
*
* @throws ContractException {@link ResourceError#DIRECTORY_PATH_IS_FILE} if the
* directory path refers to a file
*/
public static Path validateDirectoryPath(String directory) {
Path maybePath = Path.of(directory);

validateDirectoryPath(maybePath);

return maybePath;
}

/**
* Given a directory path, validates that the directory exists.
*
* @throws ContractException {@link ResourceError#DIRECTORY_PATH_IS_FILE} if the
* directory path refers to a file
*/
public static Path validateDirectoryPath(Path directoryPath) {
File maybeFile = directoryPath.toFile();

if (maybeFile.isFile()) {
throw new ContractException(ResourceError.DIRECTORY_PATH_IS_FILE);
}

if (Files.exists(parentPath)) {
return maybePath;
}
if (!maybeFile.exists()) {
createDirectory(directoryPath);
}

// otherwise throw an exception
throw new ContractException(ResourceError.UNKNOWN_FILE, path);
return directoryPath;
}

/**
* Given a url, converts it to a URI
*/
protected static URI getURI(URL url) {
try {
return url.toURI();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}

protected static void createFile(File file) {
/**
* Given a file, attempts to create the file
*
* package access for testing
*/
static void _createFile(File file) {
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private ResourceHelper() {
}

}
Loading