From 27ae9095639bb228a1b7ff86a3ebe4264abf05be Mon Sep 17 00:00:00 2001
From: mschaefers <mschaefers@scoop-gmbh.de>
Date: Thu, 29 Nov 2012 12:33:09 -0500
Subject: [PATCH] feature: when using LdapUserService one can configure Gitblit to fetch all users from ldap that can possibly login. This allows to see newly generated LDAP users instantly in Gitblit. By now an LDAP user had to log in once to appear in GitBlit.

---
 src/com/gitblit/utils/StringUtils.java |  155 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 141 insertions(+), 14 deletions(-)

diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java
index baed5f0..8684004 100644
--- a/src/com/gitblit/utils/StringUtils.java
+++ b/src/com/gitblit/utils/StringUtils.java
@@ -15,6 +15,7 @@
  */
 package com.gitblit.utils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -33,6 +34,8 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
 /**
@@ -76,7 +79,7 @@
 	 * @return plain text escaped for html
 	 */
 	public static String escapeForHtml(String inStr, boolean changeSpace) {
-		StringBuffer retStr = new StringBuffer();
+		StringBuilder retStr = new StringBuilder();
 		int i = 0;
 		while (i < inStr.length()) {
 			if (inStr.charAt(i) == '&') {
@@ -117,7 +120,7 @@
 	 * @return properly escaped url
 	 */
 	public static String encodeURL(String inStr) {
-		StringBuffer retStr = new StringBuffer();
+		StringBuilder retStr = new StringBuilder();
 		int i = 0;
 		while (i < inStr.length()) {
 			if (inStr.charAt(i) == '/') {
@@ -260,13 +263,25 @@
 	 */
 	public static String getMD5(String string) {
 		try {
-			MessageDigest md = MessageDigest.getInstance("MD5");
-			md.reset();
-			md.update(string.getBytes("iso-8859-1"));
-			byte[] digest = md.digest();
-			return toHex(digest);
+			return getMD5(string.getBytes("iso-8859-1"));
 		} catch (UnsupportedEncodingException u) {
 			throw new RuntimeException(u);
+		}
+	}
+	
+	/**
+	 * Calculates the MD5 of the string.
+	 * 
+	 * @param string
+	 * @return md5 of the string
+	 */
+	public static String getMD5(byte [] bytes) {
+		try {
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			md.reset();
+			md.update(bytes);
+			byte[] digest = md.digest();
+			return toHex(digest);
 		} catch (NoSuchAlgorithmException t) {
 			throw new RuntimeException(t);
 		}
@@ -312,11 +327,16 @@
 	 * @return the relative path
 	 */
 	public static String getRelativePath(String basePath, String fullPath) {
-		String relativePath = fullPath.substring(basePath.length()).replace('\\', '/');
-		if (relativePath.charAt(0) == '/') {
-			relativePath = relativePath.substring(1);
+		String bp = basePath.replace('\\', '/').toLowerCase();
+		String fp = fullPath.replace('\\', '/').toLowerCase();
+		if (fp.startsWith(bp)) {
+			String relativePath = fullPath.substring(basePath.length()).replace('\\', '/');
+			if (relativePath.charAt(0) == '/') {
+				relativePath = relativePath.substring(1);
+			}
+			return relativePath;
 		}
-		return relativePath;
+		return fullPath;
 	}
 
 	/**
@@ -364,7 +384,7 @@
 	 * @return the first invalid character found or null if string is acceptable
 	 */
 	public static Character findInvalidCharacter(String name) {
-		char[] validChars = { '/', '.', '_', '-' };
+		char[] validChars = { '/', '.', '_', '-', '~' };
 		for (char c : name.toCharArray()) {
 			if (!Character.isLetterOrDigit(c)) {
 				boolean ok = false;
@@ -419,6 +439,8 @@
 	public static int compareRepositoryNames(String r1, String r2) {
 		// sort root repositories first, alphabetically
 		// then sort grouped repositories, alphabetically
+		r1 = r1.toLowerCase();
+		r2 = r2.toLowerCase();
 		int s1 = r1.indexOf('/');
 		int s2 = r2.indexOf('/');
 		if (s1 == -1 && s2 == -1) {
@@ -575,13 +597,15 @@
 		if (!ArrayUtils.isEmpty(charsets)) {
 			sets.addAll(Arrays.asList(charsets));
 		}
+		String value = null;
 		sets.addAll(Arrays.asList("UTF-8", "ISO-8859-1", Charset.defaultCharset().name()));
 		for (String charset : sets) {
 			try {
 				Charset cs = Charset.forName(charset);
 				CharsetDecoder decoder = cs.newDecoder();
 				CharBuffer buffer = decoder.decode(ByteBuffer.wrap(content));
-				return buffer.toString();
+				value = buffer.toString();
+				break;
 			} catch (CharacterCodingException e) {
 				// ignore and advance to the next charset
 			} catch (IllegalCharsetNameException e) {
@@ -590,6 +614,109 @@
 				// ignore unsupported charsets
 			}
 		}
-		return new String(content, Charset.forName("UTF-8"));
+		if (value.startsWith("\uFEFF")) {
+			// strip UTF-8 BOM
+            return value.substring(1);
+        }
+		return value;
+	}
+	
+	/**
+	 * Attempt to extract a repository name from a given url using regular
+	 * expressions.  If no match is made, then return whatever trails after
+	 * the final / character.
+	 * 
+	 * @param regexUrls
+	 * @return a repository path
+	 */
+	public static String extractRepositoryPath(String url, String... urlpatterns) {
+		for (String urlPattern : urlpatterns) {
+			Pattern p = Pattern.compile(urlPattern);
+			Matcher m = p.matcher(url);
+			while (m.find()) {
+				String repositoryPath = m.group(1);
+				return repositoryPath;
+			}
+		}
+		// last resort
+		if (url.lastIndexOf('/') > -1) {
+			return url.substring(url.lastIndexOf('/') + 1);
+		}
+		return url;
+	}
+	
+	/**
+	 * Converts a string with \nnn sequences into a UTF-8 encoded string.
+	 * @param input
+	 * @return
+	 */
+	public static String convertOctal(String input) {
+		try {
+			ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+			Pattern p = Pattern.compile("(\\\\\\d{3})");
+			Matcher m = p.matcher(input);
+			int i = 0;
+			while (m.find()) {
+				bytes.write(input.substring(i, m.start()).getBytes("UTF-8"));
+				// replace octal encoded value
+				// strip leading \ character
+				String oct = m.group().substring(1);
+				bytes.write(Integer.parseInt(oct, 8));
+				i = m.end();			
+			}
+			if (bytes.size() == 0) {
+				// no octal matches
+				return input;
+			} else {
+				if (i < input.length()) {
+					// add remainder of string
+					bytes.write(input.substring(i).getBytes("UTF-8"));
+				}
+			}
+			return bytes.toString("UTF-8");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return input;
+	}
+	
+	/**
+	 * Returns the first path element of a path string.  If no path separator is
+	 * found in the path, an empty string is returned. 
+	 * 
+	 * @param path
+	 * @return the first element in the path
+	 */
+	public static String getFirstPathElement(String path) {
+		if (path.indexOf('/') > -1) {
+			return path.substring(0, path.indexOf('/')).trim();
+		}
+		return "";
+	}
+	
+	/**
+	 * Returns the last path element of a path string
+	 * 
+	 * @param path
+	 * @return the last element in the path
+	 */
+	public static String getLastPathElement(String path) {
+		if (path.indexOf('/') > -1) {
+			return path.substring(path.lastIndexOf('/') + 1);
+		}
+		return path;
+	}
+	
+	/**
+	 * Variation of String.matches() which disregards case issues.
+	 * 
+	 * @param regex
+	 * @param input
+	 * @return true if the pattern matches
+	 */
+	public static boolean matchesIgnoreCase(String input, String regex) {
+		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+		Matcher m = p.matcher(input);
+		return m.matches();
 	}
 }
\ No newline at end of file

--
Gitblit v1.9.1