From fe326255202dcfac8b0991ca9d28e3cf4bcc4fe6 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Sun, 23 Oct 2011 12:28:48 -0400 Subject: [PATCH] Per-repository setting to skip summary metrics --- src/com/gitblit/utils/StringUtils.java | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 242 insertions(+), 1 deletions(-) diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java index b53b5e1..8adf1e4 100644 --- a/src/com/gitblit/utils/StringUtils.java +++ b/src/com/gitblit/utils/StringUtils.java @@ -19,21 +19,49 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.regex.PatternSyntaxException; +/** + * Utility class of string functions. + * + * @author James Moger + * + */ public class StringUtils { public static final String MD5_TYPE = "MD5:"; + /** + * Returns true if the string is null or empty. + * + * @param value + * @return true if string is null or empty + */ public static boolean isEmpty(String value) { return value == null || value.trim().length() == 0; } + /** + * Replaces carriage returns and line feeds with html line breaks. + * + * @param string + * @return plain text with html line breaks + */ public static String breakLinesForHtml(String string) { return string.replace("\r\n", "<br/>").replace("\r", "<br/>").replace("\n", "<br/>"); } + /** + * Prepare text for html presentation. Replace sensitive characters with + * html entities. + * + * @param inStr + * @param changeSpace + * @return plain text escaped for html + */ public static String escapeForHtml(String inStr, boolean changeSpace) { StringBuffer retStr = new StringBuffer(); int i = 0; @@ -58,6 +86,23 @@ return retStr.toString(); } + /** + * Decode html entities back into plain text characters. + * + * @param inStr + * @return returns plain text from html + */ + public static String decodeFromHtml(String inStr) { + return inStr.replace("&", "&").replace("<", "<").replace(">", ">") + .replace(""", "\"").replace(" ", " "); + } + + /** + * Encodes a url parameter by escaping troublesome characters. + * + * @param inStr + * @return properly escaped url + */ public static String encodeURL(String inStr) { StringBuffer retStr = new StringBuffer(); int i = 0; @@ -74,18 +119,45 @@ return retStr.toString(); } + /** + * Flatten the list of strings into a single string with a space separator. + * + * @param values + * @return flattened list + */ public static String flattenStrings(List<String> values) { return flattenStrings(values, " "); } + /** + * Flatten the list of strings into a single string with the specified + * separator. + * + * @param values + * @param separator + * @return flattened list + */ public static String flattenStrings(List<String> values, String separator) { StringBuilder sb = new StringBuilder(); for (String value : values) { sb.append(value).append(separator); } + if (sb.length() > 0) { + // truncate trailing separator + sb.setLength(sb.length() - separator.length()); + } return sb.toString().trim(); } + /** + * Returns a string trimmed to a maximum length with trailing ellipses. If + * the string length is shorter than the max, the original string is + * returned. + * + * @param value + * @param max + * @return trimmed string + */ public static String trimString(String value, int max) { if (value.length() <= max) { return value; @@ -93,10 +165,25 @@ return value.substring(0, max - 3) + "..."; } + /** + * Returns a trimmed shortlog message. + * + * @param string + * @return trimmed shortlog message + */ public static String trimShortLog(String string) { return trimString(string, 60); } + /** + * Left pad a string with the specified character, if the string length is + * less than the specified length. + * + * @param input + * @param length + * @param pad + * @return left-padded string + */ public static String leftPad(String input, int length, char pad) { if (input.length() < length) { StringBuilder sb = new StringBuilder(); @@ -109,6 +196,15 @@ return input; } + /** + * Right pad a string with the specified character, if the string length is + * less then the specified length. + * + * @param input + * @param length + * @param pad + * @return right-padded string + */ public static String rightPad(String input, int length, char pad) { if (input.length() < length) { StringBuilder sb = new StringBuilder(); @@ -121,6 +217,12 @@ return input; } + /** + * Calculates the SHA1 of the string. + * + * @param text + * @return sha1 of the string + */ public static String getSHA1(String text) { try { byte[] bytes = text.getBytes("iso-8859-1"); @@ -130,6 +232,12 @@ } } + /** + * Calculates the SHA1 of the byte array. + * + * @param bytes + * @return sha1 of the byte array + */ public static String getSHA1(byte[] bytes) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); @@ -141,6 +249,12 @@ } } + /** + * Calculates the MD5 of the string. + * + * @param string + * @return md5 of the string + */ public static String getMD5(String string) { try { MessageDigest md = MessageDigest.getInstance("MD5"); @@ -155,6 +269,12 @@ } } + /** + * Returns the hex representation of the byte array. + * + * @param bytes + * @return byte array as hex string + */ private static String toHex(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { @@ -165,7 +285,14 @@ } return sb.toString(); } - + + /** + * Returns the root path of the specified path. Returns a blank string if + * there is no root path. + * + * @param path + * @return root path or blank + */ public static String getRootPath(String path) { if (path.indexOf('/') > -1) { return path.substring(0, path.lastIndexOf('/')); @@ -173,6 +300,14 @@ return ""; } + /** + * Returns the path remainder after subtracting the basePath from the + * fullPath. + * + * @param basePath + * @param fullPath + * @return the relative path + */ public static String getRelativePath(String basePath, String fullPath) { String relativePath = fullPath.substring(basePath.length()).replace('\\', '/'); if (relativePath.charAt(0) == '/') { @@ -181,10 +316,23 @@ return relativePath; } + /** + * Splits the space-separated string into a list of strings. + * + * @param value + * @return list of strings + */ public static List<String> getStringsFromValue(String value) { return getStringsFromValue(value, " "); } + /** + * Splits the string into a list of string by the specified separator. + * + * @param value + * @param separator + * @return list of strings + */ public static List<String> getStringsFromValue(String value, String separator) { List<String> strings = new ArrayList<String>(); try { @@ -200,4 +348,97 @@ } return strings; } + + /** + * Validates that a name is composed of letters, digits, or limited other + * characters. + * + * @param name + * @return the first invalid character found or null if string is acceptable + */ + public static Character findInvalidCharacter(String name) { + char[] validChars = { '/', '.', '_', '-' }; + for (char c : name.toCharArray()) { + if (!Character.isLetterOrDigit(c)) { + boolean ok = false; + for (char vc : validChars) { + ok |= c == vc; + } + if (!ok) { + return c; + } + } + } + return null; + } + + /** + * Simple fuzzy string comparison. This is a case-insensitive check. A + * single wildcard * value is supported. + * + * @param value + * @param pattern + * @return true if the value matches the pattern + */ + public static boolean fuzzyMatch(String value, String pattern) { + if (value.equalsIgnoreCase(pattern)) { + return true; + } + if (pattern.contains("*")) { + boolean prefixMatches = false; + boolean suffixMatches = false; + + int wildcard = pattern.indexOf('*'); + String prefix = pattern.substring(0, wildcard).toLowerCase(); + prefixMatches = value.toLowerCase().startsWith(prefix); + + if (pattern.length() > (wildcard + 1)) { + String suffix = pattern.substring(wildcard + 1).toLowerCase(); + suffixMatches = value.toLowerCase().endsWith(suffix); + return prefixMatches && suffixMatches; + } + return prefixMatches || suffixMatches; + } + return false; + } + + /** + * Compare two repository names for proper group sorting. + * + * @param r1 + * @param r2 + * @return + */ + public static int compareRepositoryNames(String r1, String r2) { + // sort root repositories first, alphabetically + // then sort grouped repositories, alphabetically + int s1 = r1.indexOf('/'); + int s2 = r2.indexOf('/'); + if (s1 == -1 && s2 == -1) { + // neither grouped + return r1.compareTo(r2); + } else if (s1 > -1 && s2 > -1) { + // both grouped + return r1.compareTo(r2); + } else if (s1 == -1) { + return -1; + } else if (s2 == -1) { + return 1; + } + return 0; + } + + /** + * Sort grouped repository names. + * + * @param list + */ + public static void sortRepositorynames(List<String> list) { + Collections.sort(list, new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + return compareRepositoryNames(o1, o2); + } + }); + } } -- Gitblit v1.9.1