From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Sat, 30 Apr 2016 04:19:14 -0400
Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates

---
 src/main/java/com/gitblit/utils/FileUtils.java |  141 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 96 insertions(+), 45 deletions(-)

diff --git a/src/main/java/com/gitblit/utils/FileUtils.java b/src/main/java/com/gitblit/utils/FileUtils.java
index a21b512..ad2509d 100644
--- a/src/main/java/com/gitblit/utils/FileUtils.java
+++ b/src/main/java/com/gitblit/utils/FileUtils.java
@@ -26,15 +26,17 @@
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 
 /**
  * Common file utilities.
- * 
+ *
  * @author James Moger
- * 
+ *
  */
 public class FileUtils {
-	
+
 	/** 1024 (number of bytes in one kilobyte) */
 	public static final int KB = 1024;
 
@@ -47,7 +49,7 @@
 	/**
 	 * Returns an int from a string representation of a file size.
 	 * e.g. 50m = 50 megabytes
-	 * 
+	 *
 	 * @param aString
 	 * @param defaultValue
 	 * @return an int value or the defaultValue if aString can not be parsed
@@ -55,24 +57,24 @@
 	public static int convertSizeToInt(String aString, int defaultValue) {
 		return (int) convertSizeToLong(aString, defaultValue);
 	}
-	
+
 	/**
 	 * Returns a long from a string representation of a file size.
 	 * e.g. 50m = 50 megabytes
-	 * 
+	 *
 	 * @param aString
 	 * @param defaultValue
 	 * @return a long value or the defaultValue if aString can not be parsed
 	 */
 	public static long convertSizeToLong(String aString, long defaultValue) {
-		// trim string and remove all spaces 
+		// trim string and remove all spaces
 		aString = aString.toLowerCase().trim();
 		StringBuilder sb = new StringBuilder();
 		for (String a : aString.split(" ")) {
 			sb.append(a);
 		}
 		aString = sb.toString();
-		
+
 		// identify value and unit
 		int idx = 0;
 		int len = aString.length();
@@ -99,39 +101,49 @@
 		}
 		return defaultValue;
 	}
-	
+
 	/**
 	 * Returns the byte [] content of the specified file.
-	 * 
+	 *
 	 * @param file
 	 * @return the byte content of the file
 	 */
 	public static byte [] readContent(File file) {
 		byte [] buffer = new byte[(int) file.length()];
+		BufferedInputStream is = null;
 		try {
-			BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
+			is = new BufferedInputStream(new FileInputStream(file));
 			is.read(buffer,  0,  buffer.length);
-			is.close();
 		} catch (Throwable t) {
 			System.err.println("Failed to read byte content of " + file.getAbsolutePath());
 			t.printStackTrace();
+		} finally {
+			if (is != null) {
+				try {
+					is.close();
+				} catch (IOException ioe) {
+					System.err.println("Failed to close file " + file.getAbsolutePath());
+					ioe.printStackTrace();
+				}
+			}
 		}
 		return buffer;
 	}
 
 	/**
 	 * Returns the string content of the specified file.
-	 * 
+	 *
 	 * @param file
 	 * @param lineEnding
 	 * @return the string content of the file
 	 */
 	public static String readContent(File file, String lineEnding) {
 		StringBuilder sb = new StringBuilder();
+		InputStreamReader is = null;
+		BufferedReader reader = null;
 		try {
-			InputStreamReader is = new InputStreamReader(new FileInputStream(file),
-					Charset.forName("UTF-8"));
-			BufferedReader reader = new BufferedReader(is);
+			is = new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8"));
+			reader = new BufferedReader(is);
 			String line = null;
 			while ((line = reader.readLine()) != null) {
 				sb.append(line);
@@ -139,44 +151,69 @@
 					sb.append(lineEnding);
 				}
 			}
-			reader.close();
 		} catch (Throwable t) {
 			System.err.println("Failed to read content of " + file.getAbsolutePath());
 			t.printStackTrace();
+		} finally {
+			if (reader != null){
+				try {
+					reader.close();
+				} catch (IOException ioe) {
+					System.err.println("Failed to close file " + file.getAbsolutePath());
+					ioe.printStackTrace();
+				}
+			}
+			if (is != null) {
+				try {
+					is.close();
+				} catch (IOException ioe) {
+					System.err.println("Failed to close file " + file.getAbsolutePath());
+					ioe.printStackTrace();
+				}
+			}
 		}
 		return sb.toString();
 	}
 
 	/**
 	 * Writes the string content to the file.
-	 * 
+	 *
 	 * @param file
 	 * @param content
 	 */
 	public static void writeContent(File file, String content) {
+		OutputStreamWriter os = null;
 		try {
-			OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(file),
-					Charset.forName("UTF-8"));
+			os = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8"));
 			BufferedWriter writer = new BufferedWriter(os);
 			writer.append(content);
-			writer.close();
+			writer.flush();
 		} catch (Throwable t) {
 			System.err.println("Failed to write content of " + file.getAbsolutePath());
 			t.printStackTrace();
+		} finally {
+			if (os != null) {
+				try {
+					os.close();
+				} catch (IOException ioe) {
+					System.err.println("Failed to close file " + file.getAbsolutePath());
+					ioe.printStackTrace();
+				}
+			}
 		}
 	}
 
 	/**
 	 * Recursively traverses a folder and its subfolders to calculate the total
 	 * size in bytes.
-	 * 
+	 *
 	 * @param directory
 	 * @return folder size in bytes
 	 */
 	public static long folderSize(File directory) {
 		if (directory == null || !directory.exists()) {
 			return -1;
-		}		
+		}
 		if (directory.isDirectory()) {
 			long length = 0;
 			for (File file : directory.listFiles()) {
@@ -190,8 +227,32 @@
 	}
 
 	/**
+	 * Delete a file or recursively delete a folder.
+	 *
+	 * @param fileOrFolder
+	 * @return true, if successful
+	 */
+	public static boolean delete(File fileOrFolder) {
+		boolean success = false;
+		if (fileOrFolder.isDirectory()) {
+			File [] files = fileOrFolder.listFiles();
+			if (files != null) {
+				for (File file : files) {
+					if (file.isDirectory()) {
+						success |= delete(file);
+					} else {
+						success |= file.delete();
+					}
+				}
+			}
+		}
+		success |= fileOrFolder.delete();
+		return success;
+	}
+
+	/**
 	 * Copies a file or folder (recursively) to a destination folder.
-	 * 
+	 *
 	 * @param destinationFolder
 	 * @param filesOrFolders
 	 * @return
@@ -219,11 +280,11 @@
 					}
 				} finally {
 					try {
-						bufin.close();
+						if (bufin != null) bufin.close();
 					} catch (Throwable t) {
 					}
 					try {
-						fos.close();
+						if (fos != null) fos.close();
 					} catch (Throwable t) {
 					}
 				}
@@ -231,39 +292,29 @@
 			}
 		}
 	}
-	
+
 	/**
 	 * Determine the relative path between two files.  Takes into account
 	 * canonical paths, if possible.
-	 * 
+	 *
 	 * @param basePath
 	 * @param path
 	 * @return a relative path from basePath to path
 	 */
 	public static String getRelativePath(File basePath, File path) {
-		File exactBase = getExactFile(basePath);
-		File exactPath = getExactFile(path);
-		if (path.getAbsolutePath().startsWith(basePath.getAbsolutePath())) {
-			// absolute base-path match
-			return StringUtils.getRelativePath(basePath.getAbsolutePath(), path.getAbsolutePath());
-		} else if (exactPath.getPath().startsWith(exactBase.getPath())) {
-			// canonical base-path match
-			return StringUtils.getRelativePath(exactBase.getPath(), exactPath.getPath());
-		} else if (exactPath.getPath().startsWith(basePath.getAbsolutePath())) {
-			// mixed path match
-			return StringUtils.getRelativePath(basePath.getAbsolutePath(), exactPath.getPath());
-		} else if (path.getAbsolutePath().startsWith(exactBase.getPath())) {
-			// mixed path match
-			return StringUtils.getRelativePath(exactBase.getPath(), path.getAbsolutePath());
+		Path exactBase = Paths.get(getExactFile(basePath).toURI());
+		Path exactPath = Paths.get(getExactFile(path).toURI());
+		if (exactPath.startsWith(exactBase)) {
+			return exactBase.relativize(exactPath).toString().replace('\\', '/');
 		}
 		// no relative relationship
 		return null;
 	}
-	
+
 	/**
 	 * Returns the exact path for a file. This path will be the canonical path
 	 * unless an exception is thrown in which case it will be the absolute path.
-	 * 
+	 *
 	 * @param path
 	 * @return the exact file
 	 */
@@ -277,7 +328,7 @@
 
 	public static File resolveParameter(String parameter, File aFolder, String path) {
 		if (aFolder == null) {
-			// strip any parameter reference		
+			// strip any parameter reference
 			path = path.replace(parameter, "").trim();
 			if (path.length() > 0 && path.charAt(0) == '/') {
 				// strip leading /

--
Gitblit v1.9.1