Skip to content

Commit

Permalink
add javadoc and make methods more robust (#24)
Browse files Browse the repository at this point in the history
* add javadoc and make methods more robust

* fix javadoc

* fix test errors
  • Loading branch information
bischoffz authored Apr 22, 2024
1 parent f8a5719 commit 228b41b
Show file tree
Hide file tree
Showing 3 changed files with 491 additions and 87 deletions.
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

0 comments on commit 228b41b

Please sign in to comment.