diff --git a/src/main/java/com/sheepit/client/Utils.java b/src/main/java/com/sheepit/client/Utils.java index 6c3e129..8799bf3 100644 --- a/src/main/java/com/sheepit/client/Utils.java +++ b/src/main/java/com/sheepit/client/Utils.java @@ -50,8 +50,16 @@ import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Provides various general utility methods for the SheepIt client codebase + */ public class Utils { + /** + * This is a hashmap of media types currently consisting of two image formats, tga and exr + * The first string is the filename extension. + * The second string is the media/MIME type + */ private static Map mimeTypes = new HashMap<>(); static { @@ -59,6 +67,15 @@ public class Utils { mimeTypes.put(".exr", "image/x-exr"); } + /** + * Extracts (and optionally decrypts) contents of a given zip file to a target directory + * + * @param zipFileName_ Path to the zipfiles + * @param destinationDirectory Path to the target directory where files will be extracted to + * @param password Optional password for decrypting the zip archive which will only be used if it's not null and if the zip is truly encrypted + * @param log The SheepIt Debug log where log messages might be logged into + * @return A status code as an integer, -1 if it encounters a ZipException, 0 otherwise + */ public static int unzipFileIntoDirectory(String zipFileName_, String destinationDirectory, char[] password, Log log) { try { ZipFile zipFile = new ZipFile(zipFileName_); @@ -80,6 +97,16 @@ public class Utils { return 0; } + /** + * Takes the list of zip file chunks and combines them to a zip archive in memory to + * extract (and optionally decrypt) the contents to the target directory + * + * @param full_path_chunks List of paths to the chunks of which a zip file will be constructed from + * @param destinationDirectory Path to the target directory where files will be extracted to + * @param password Optional password for decrypting the zip archive which will only be used if it's not null + * @param log The SheepIt Debug log where log messages might be logged into + * @return A status code as an integer, -1 if it encounters a IOException, 0 otherwise + */ public static int unzipChunksIntoDirectory(List full_path_chunks, String destinationDirectory, char[] password, Log log) { try { // STEP 1: assemble the chunks into an actual zip (in RAM) @@ -138,11 +165,22 @@ public class Utils { return 0; } + /** + * Gets a MD5 checksum either from the cache or computes it and puts it into the cache + * + * @param path_of_file_ Path of the file to get the MD5 checksum for + * @return the string The MD5 checksum + */ public static String md5(String path_of_file_) { Md5 md5 = new Md5(); return md5.get(path_of_file_); } + /** + * Takes an array of bytes and encodes them as a string of hexadecimal digits + * @param bytes An array of bytes to be encoded, the order of which dictates the output in big-endian + * @return A string of hexadecimal digits, two digits for a byte each. Constructed from left to right. + */ public static String convertBinaryToHex(byte[] bytes) { StringBuilder hexStringBuilder = new StringBuilder(); for (byte aByte : bytes) { @@ -154,6 +192,11 @@ public class Utils { return hexStringBuilder.toString(); } + /** + * Returns the latest (highest) of a modification time of a file in the directory recursively + * @param directory_ The root directory from which to search from + * @return The latest (highest) modification time in milliseconds since epoch or 0 if no files exist in the target directory tree + */ public static double lastModificationTime(File directory_) { double max = 0.0; if (directory_.isDirectory()) { @@ -190,7 +233,8 @@ public class Utils { } /** - * Will recursively delete a directory + * Deletes a file or directory recursively + * @param file The filesystem element to be deleted */ public static void delete(File file) { if (file == null) { @@ -211,8 +255,10 @@ public class Utils { } /** - * Parse a number string to a number. - * Input can be as "32", "10k", "100K", "100G", "1.3G", "0.4T" + * Converts a number string to a number. + * @param in The number string with an ending up to Tera (10^12) + * Example inputs: "32", "10k", "100K", "100G", "1.3G", "0.4T" + * @return A numerical representation of the number string */ public static long parseNumber(String in) { in = in.trim(); @@ -246,6 +292,12 @@ public class Utils { return Math.round(Double.parseDouble(m.group(1)) * scale); } + /** + * Gives a human-readable representation in hours, minutes and seconds when a given date will be reached + * @param date The target time + * @return A string in the format of Xh Ymin Ys as long as none of them are zero + * Examples: 69h 42min 13s, 20min, 1h 23s + */ public static String humanDuration(Date date) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.setTime(date); @@ -267,6 +319,14 @@ public class Utils { return output; } + /** + * Checks for a given path if there is enough free space i.e. at-least over half a megabyte. + * If the first check fails, it polls again for up to 3 times with increasing delay + * to work around a Java limitation where getUsableSpace might just return 0 on a busy disk + * @param destination_ The path to check the for enough free space for + * @param log The SheepIt Debug log where log messages might be logged into + * @return True if there is not enough free space, false otherwise + */ public static boolean noFreeSpaceOnDisk(String destination_, Log log) { try { File file = new File(destination_); @@ -290,7 +350,13 @@ public class Utils { return false; } - + + /** + * Tries to detect media/MIME type of given file based on characteristics like the file contents or file extension + * @param file Path to the file for which to detect the MIME type for + * @return The MIME type of the file + * @throws IOException If an I/O error occurs + */ public static String findMimeType(String file) throws IOException { String mimeType = Files.probeContentType(Paths.get(file)); if (mimeType == null) { @@ -314,6 +380,15 @@ public class Utils { return mimeType; } + /** + * Format a number of bytes into a human-readable format with metric prefixes (base 1024) + * @param bytes The amount of bytes to convert + * @return Human-readable formatted string (respecting locale of the machine) + * representing the amount of bytes + * Examples: 4.20GB, 20.00TB, 3.69MB + * In a different locale (here for German): + * Examples: 4,20GB, 20,00TB, 3,69MB + */ public static String formatDataConsumption(long bytes) { float divider = 0; String suffix = "";