package gov.loc.repository.bagit.util;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.DosFileAttributes;
import gov.loc.repository.bagit.domain.Bag;
import gov.loc.repository.bagit.domain.Version;
/**
* Convenience class for dealing with various path issues
*/
public final class PathUtils {
private static final String PAYLOAD_DIR_NAME = "data";
//@Incubating
private static final String DOT_BAGIT_DIR_NAME = ".bagit";
private PathUtils(){
//intentionally left blank
}
/**
* Needed to get rid of findbugs "dodgy code warnings" in regards to getting the filename of a path as a string
*
* @param path the path that you which to get the filename as a string
* @return the filename or an empty string
*/
public static String getFilename(final Path path){
String filename = "";
if(path != null){
final Path filenamePath = path.getFileName();
if(filenamePath != null){
filename = filenamePath.toString();
}
}
return filename;
}
/**
* as per https://github.com/jkunze/bagitspec/commit/152d42f6298b31a4916ea3f8f644ca4490494070 decode percent encoded filenames
* @param encoded the encoded filename
* @return the decoded filename
*/
public static String decodeFilname(final String encoded){
return encoded.replaceAll("%0A", "\n").replaceAll("%0D", "\r");
}
/**
* as per https://github.com/jkunze/bagitspec/commit/152d42f6298b31a4916ea3f8f644ca4490494070 encode any new lines or carriage returns
* @param path the path to encode
* @return the encoded filename
*/
public static String encodeFilename(final Path path){
return path.toString().replaceAll("\n", "%0A").replaceAll("\r", "%0D");
}
/**
* Due to the way that windows handles hidden files vs. *nix
* we use this method to determine if a file or folder is really hidden
* @param path the file or folder to check if hidden
* @return if the file or folder is hidden
* @throws IOException if there is an error reading the file/folder
*/
public static boolean isHidden(final Path path) throws IOException{
//cause Files.isHidden() doesn't work properly for windows if the file is a directory
if (System.getProperty("os.name").contains("Windows")){
return Files.readAttributes(path, DosFileAttributes.class).isHidden();
}
return Files.isHidden(path);
}
/**
* With bagit version 2.0 (.bagit)
* payload files are no longer in the "data" directory. This method accounts for this
* and will return the directory that contains the payload files
*
* @param bag that contains the payload files you want
* @return the directory that contains the payload files
*/
public static Path getDataDir(final Bag bag){
if(bag.getVersion().isSameOrNewer(new Version(2, 0))){ //is it a .bagit version?
return bag.getRootDir();
}
return bag.getRootDir().resolve(PAYLOAD_DIR_NAME);
}
/**
* With bagit version 2.0 (.bagit)
* payload files are no longer in the "data" directory. This method accounts for this
* and will return the directory that contains the payload files
*
* @param version the bag version
* @param output where the bag is being or was written to
*
* @return the payload directory for the output directory
*/
public static Path getDataDir(final Version version, final Path output){
if(version.isSameOrNewer(new Version(2, 0))){ //is it a .bagit version?
return output;
}
return output.resolve(PAYLOAD_DIR_NAME);
}
/**
* With bagit version 2.0 (.bagit) bagit specific files are no longer at the bag root directory.
* This method accounts for this and will return the directory that contains the bag specific files.
*
* @param version the bag version
* @param bagRoot the root directory of the bag
*
* @return the directory which contains the bag specific files, like manifests or bagit.txt
*/
public static Path getBagitDir(final Version version, final Path bagRoot){
if(version.isSameOrNewer(new Version(2, 0))){ //is it a .bagit version?
return bagRoot.resolve(DOT_BAGIT_DIR_NAME);
}
return bagRoot;
}
}