package io.dropwizard.metrics.graphite;
class GraphiteSanitize {
/** Replaces all characters from a given string that are not ascii and not alphanumeric
* with a dash */
static String sanitize(String string, char replacement) {
String replaced = replaceFrom(string, replacement);
// Consolidate multiple dashes into a single one
String result = replaced.replace("--", "-");
while (!result.equals(replaced)) {
replaced = result;
result = replaced.replace("--", "-");
}
// Remove any leading or trailing dashes
return strip(result, replacement);
}
/** A char matches when it is a letter or digit and it is ASCII, in Guava terminology,
* this would be CharMatcher.ASCII.and(CharMatcher.JAVA_LETTER_OR_DIGIT).negate() */
private static boolean matches(char c) {
return !(Character.isLetterOrDigit(c) && c <= '\u007f');
}
/** Replace all characters that we're interested in with a replacement character,
* heavily inspired by the same code in Guava's CharMatcher */
private static String replaceFrom(String string, char replacement) {
int pos = indexIn(string, 0);
if (pos == -1) {
return string;
}
char[] chars = string.toCharArray();
chars[pos] = replacement;
for (int i = pos + 1; i < chars.length; i++) {
if (matches(chars[i])) {
chars[i] = replacement;
}
}
return new String(chars).trim();
}
/** Finds the first index (or -1) of a character we're interested in */
private static int indexIn(String sequence, int start) {
int length = sequence.length();
for (int i = start; i < length; i++) {
if (matches(sequence.charAt(i))) {
return i;
}
}
return -1;
}
/** Strips a given character from the beginning and end of a string,
* heavily inspired by Apache's StringUtils.strip
*/
private static String strip(String str, char strip) {
int strLen = str.length();
int start = 0;
int end = strLen - 1;
while (start != strLen && str.charAt(start) == strip) {
start++;
}
while (end > start && str.charAt(end) == strip) {
end--;
}
return start != 0 || end != strLen - 1 ? str.substring(start, end + 1) : str;
}
}